diff --git a/elepower_wireless/craftitems.lua b/elepower_wireless/craftitems.lua index 7f52e98..daa4ee3 100644 --- a/elepower_wireless/craftitems.lua +++ b/elepower_wireless/craftitems.lua @@ -35,6 +35,7 @@ ele.register_tool("elepower_wireless:wireless_porter", { -- Teleport player player:set_pos(top) + -- TODO: Sound nmeta:set_int("storage", nstorage - nusage) -- Add wear @@ -61,7 +62,7 @@ ele.register_tool("elepower_wireless:wireless_porter", { local strpos = minetest.pos_to_string(pos) local curpos = minetest.string_to_pos(meta:get_string("receiver")) - if (curpos and curpos ~= "") and curpos == strpos then + if (curpos and curpos ~= "") and curpos == pos then minetest.chat_send_player(player, "Wireless Porter is already bound to this location!") return itemstack end diff --git a/elepower_wireless/machines/dialler.lua b/elepower_wireless/machines/dialler.lua new file mode 100644 index 0000000..02acb64 --- /dev/null +++ b/elepower_wireless/machines/dialler.lua @@ -0,0 +1,200 @@ + +local function escape_comma(str) + return str:gsub(",","\\,") +end + +local function get_formspec(power, player, transmitters, receivers) + local list_tr = {} + local tr_selct = nil + local list_re = {} + local re_selct = nil + + if transmitters then + for _,trn in pairs(transmitters) do + local indx = #list_tr + 1 + if trn.select then + tr_selct = indx + end + list_tr[indx] = trn.name .. " " .. escape_comma(trn.pos) + end + end + + if receivers then + for _,rec in pairs(receivers) do + local indx = #list_re + 1 + if rec.select then + re_selct = indx + end + list_re[indx] = rec.name .. " " .. escape_comma(rec.pos) + end + end + + local tr_spc = "" + if tr_selct then tr_spc = ";" .. tr_selct end + + local re_spc = "" + if re_selct then re_spc = ";" .. re_selct end + + return "size[8,10.5]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + ele.formspec.power_meter(power).. + "textlist[1,0;6.8,2.5;transmitter;" .. table.concat(list_tr, ",") .. tr_spc .. "]".. + "textlist[1,3;6.8,2.5;receiver;" .. table.concat(list_re, ",") .. re_spc .. "]".. + "label[0,5.75;Owned by " .. player .. "]".. + "list[current_player;main;0,6.25;8,1;]".. + "list[current_player;main;0,7.5;8,3;8]".. + "listring[current_player;main]".. + default.get_hotbar_bg(0, 6.25) +end + +local function get_is_active_node(meta, pos) + local storage = ele.helpers.get_node_property(meta, pos, "storage") + local usage = ele.helpers.get_node_property(meta, pos, "usage") + return storage >= usage +end + +local function get_transmitters_in_range(pos, player, selected, range) + local transmitters = {} + for spos, data in pairs(elewi.loaded_transmitters) do + local npos = minetest.string_to_pos(spos) + local node = minetest.get_node_or_nil(npos) + if node and ele.helpers.get_item_group(node.name, "matter_transmitter") then + if data.player == player and vector.distance(pos, npos) <= range then + local meta = minetest.get_meta(npos) + if get_is_active_node(meta, npos) then + transmitters[#transmitters + 1] = { + name = data.name, + player = player, + pos = spos, + select = npos == selected, + } + end + end + end + end + return transmitters +end + +local function get_player_receivers(player) + local receivers = {} + for spos, data in pairs(elewi.loaded_receivers) do + local npos = minetest.string_to_pos(spos) + local node = minetest.get_node_or_nil(npos) + if node and ele.helpers.get_item_group(node.name, "matter_receiver") then + if data.player == player then + local meta = minetest.get_meta(npos) + local target = minetest.string_to_pos(meta:get_string("target")) + if get_is_active_node(meta, npos) then + receivers[#receivers + 1] = { + name = data.name, + player = player, + pos = spos, + select = target == npos, + } + end + end + end + end + return receivers +end + +local function dialler_timer(pos) + local meta = minetest.get_meta(pos) + local player = meta:get_string("player") + + local capacity = ele.helpers.get_node_property(meta, pos, "capacity") + local storage = ele.helpers.get_node_property(meta, pos, "storage") + local usage = ele.helpers.get_node_property(meta, pos, "usage") + + local transmitter = minetest.string_to_pos(meta:get_string("transmitter")) + local pow_percent = math.floor((storage / capacity) * 100) + + if storage >= usage then + ele.helpers.swap_node(pos, "elepower_wireless:dialler_active") + else + ele.helpers.swap_node(pos, "elepower_wireless:dialler") + end + + local transmitters = get_transmitters_in_range(pos, player, transmitter, 16) + local receivers = {} + if transmitter then + receivers = get_player_receivers(player) + end + + meta:set_string("formspec", get_formspec(pow_percent, player, transmitters, receivers)) + meta:set_string("infotext", "Dialler\n" .. ele.capacity_text(capacity, storage)) + + return false +end + +ele.register_machine("elepower_wireless:dialler", { + description = "Dialler", + tiles = { + "elewireless_device_side.png", "elewireless_device_side.png", "elewireless_device_side.png", + "elewireless_device_side.png", "elewireless_device_side.png", "elewireless_dialler_inactive.png" + }, + ele_active_node = true, + ele_active_nodedef = { + tiles = { + "elewireless_device_side.png", "elewireless_device_side.png", "elewireless_device_side.png", + "elewireless_device_side.png", "elewireless_device_side.png", "elewireless_dialler.png" + }, + }, + groups = {cracky = 1, ele_user = 1, dialler = 1}, + ele_capacity = 8000, + ele_usage = 120, + ele_inrush = 240, + on_timer = dialler_timer, + after_place_node = function (pos, placer, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + if not placer or placer:get_player_name() == "" then return false end + + meta:set_string("player", placer:get_player_name()) + end, + on_receive_fields = function (pos, formname, fields, sender) + if sender and sender ~= "" and minetest.is_protected(pos, sender:get_player_name()) then + return + end + + if not fields["transmitter"] and not fields["receiver"] then + return + end + + local meta = minetest.get_meta(pos) + local trans = minetest.string_to_pos(meta:get_string("transmitter")) + + local player = sender:get_player_name() + local transmitters = get_transmitters_in_range(pos, player, trans, 16) + local receivers = {} + if trans then + receivers = get_player_receivers(player) + end + + if fields["transmitter"] then + if fields.transmitter:match("DCL:") then + local pinx = tonumber(fields.transmitter:sub(5)) + if pinx and transmitters[pinx] then + meta:set_string("transmitter", transmitters[pinx].pos) + minetest.get_node_timer(pos):start(0.2) + return + end + end + end + + if fields["receiver"] and #receivers > 0 then + if fields.receiver:match("DCL:") then + local pinx = tonumber(fields.receiver:sub(5)) + if pinx and receivers[pinx] then + local meta = minetest.get_meta(trans) + + meta:set_string("target", receivers[pinx].pos) + + minetest.get_node_timer(trans):start(0.2) + minetest.get_node_timer(pos):start(0.2) + end + end + end + end, +}) diff --git a/elepower_wireless/machines/init.lua b/elepower_wireless/machines/init.lua index 195708d..b59b4fb 100644 --- a/elepower_wireless/machines/init.lua +++ b/elepower_wireless/machines/init.lua @@ -2,3 +2,5 @@ local mp = elewi.modpath .. "/machines/" dofile(mp .. "matter_receiver.lua") +dofile(mp .. "matter_transmitter.lua") +dofile(mp .. "dialler.lua") diff --git a/elepower_wireless/machines/matter_receiver.lua b/elepower_wireless/machines/matter_receiver.lua index cb012b6..3d02687 100644 --- a/elepower_wireless/machines/matter_receiver.lua +++ b/elepower_wireless/machines/matter_receiver.lua @@ -1,4 +1,6 @@ +elewi.loaded_receivers = {} + local function get_formspec(power, name, player) return "size[8,8.5]".. default.gui_bg.. @@ -41,10 +43,29 @@ local function matter_receiver_timer(pos) return false end +local function save_receiver(pos) + local strname = minetest.pos_to_string(pos) + + if elewi.loaded_receivers[strname] then return end + + local meta = minetest.get_meta(pos) + local name = meta:get_string("name") + local player = meta:get_string("player") + + if name == "" then + name = "Matter Receiver" + end + + elewi.loaded_receivers[strname] = { + name = name, + player = player, + } +end + ele.register_machine("elepower_wireless:matter_receiver", { description = "Matter Receiver", tiles = { - "elewireless_receiver_top_inactive.png", "elewireless_device_side.png^elepower_power_port.png", "elewireless_device_side.png", + "elewireless_teleport_top.png", "elewireless_device_side.png^elepower_power_port.png", "elewireless_device_side.png", "elewireless_device_side.png", "elewireless_device_side.png", "elewireless_device_side.png" }, ele_active_node = true, @@ -66,6 +87,7 @@ ele.register_machine("elepower_wireless:matter_receiver", { groups = {cracky = 1, ele_user = 1, matter_receiver = 1}, ele_capacity = 8000, ele_usage = 120, + ele_inrush = 240, ele_no_automatic_ports = true, on_timer = matter_receiver_timer, after_place_node = function (pos, placer, itemstack, pointed_thing) @@ -73,6 +95,7 @@ ele.register_machine("elepower_wireless:matter_receiver", { if not placer or placer:get_player_name() == "" then return false end meta:set_string("player", placer:get_player_name()) + save_receiver(pos) end, on_receive_fields = function (pos, formname, fields, sender) if sender and sender ~= "" and minetest.is_protected(pos, sender:get_player_name()) then @@ -84,5 +107,18 @@ ele.register_machine("elepower_wireless:matter_receiver", { if fields["name"] and fields["key_enter"] == "true" then meta:set_string("name", fields["name"]) end - end + end, + after_destruct = function (pos) + local strname = minetest.pos_to_string(pos) + if not elewi.loaded_receivers[strname] then return end + elewi.loaded_receivers[strname] = nil + end, +}) + +minetest.register_lbm({ + label = "Load Receiver into memory", + name = "elepower_wireless:matter_receiver", + nodenames = {"group:matter_receiver"}, + run_at_every_load = true, + action = save_receiver, }) diff --git a/elepower_wireless/machines/matter_transmitter.lua b/elepower_wireless/machines/matter_transmitter.lua new file mode 100644 index 0000000..ef79ded --- /dev/null +++ b/elepower_wireless/machines/matter_transmitter.lua @@ -0,0 +1,162 @@ + +elewi.loaded_transmitters = {} + +local function get_formspec(power, name, player) + return "size[8,8.5]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + ele.formspec.power_meter(power).. + "field[1.5,0.5;5,1;name;Transmitter Name;".. name .."]".. + "field_close_on_enter[name;false]".. + "label[0,3.75;Owned by " .. player .. "]".. + "list[current_player;main;0,4.25;8,1;]".. + "list[current_player;main;0,5.5;8,3;8]".. + "listring[current_player;main]".. + default.get_hotbar_bg(0, 4.25) +end + +local function matter_transmitter_timer(pos) + local meta = minetest.get_meta(pos) + local name = meta:get_string("name") + local player = meta:get_string("player") + local target = meta:get_string("target") + + if name == "" then + name = "Matter Transmitter" + end + + local capacity = ele.helpers.get_node_property(meta, pos, "capacity") + local storage = ele.helpers.get_node_property(meta, pos, "storage") + local usage = ele.helpers.get_node_property(meta, pos, "usage") + + local pow_percent = math.floor((storage / capacity) * 100) + + if storage >= usage then + ele.helpers.swap_node(pos, "elepower_wireless:matter_transmitter_active") + else + ele.helpers.swap_node(pos, "elepower_wireless:matter_transmitter") + end + + local extra = "" + if target ~= "" then + extra = "\nDialled to " .. target + end + + meta:set_string("formspec", get_formspec(pow_percent, name, player, target)) + meta:set_string("infotext", "Matter Transmitter\n" .. ele.capacity_text(capacity, storage) .. extra) + + return false +end + +local function save_transmitter(pos) + local strname = minetest.pos_to_string(pos) + + if elewi.loaded_transmitters[strname] then return end + + local meta = minetest.get_meta(pos) + local name = meta:get_string("name") + local player = meta:get_string("player") + + if name == "" then + name = "Matter Transmitter" + end + + elewi.loaded_transmitters[strname] = { + name = name, + player = player, + } +end + +ele.register_machine("elepower_wireless:matter_transmitter", { + description = "Matter Transmitter", + tiles = { + "elewireless_teleport_top.png", "elewireless_device_side.png^elepower_power_port.png", "elewireless_device_side.png", + "elewireless_device_side.png", "elewireless_device_side.png", "elewireless_device_side.png" + }, + ele_active_node = true, + ele_active_nodedef = { + tiles = { + { + name = "elewireless_transmitter_top_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + speed = 5, + }, + }, + "elewireless_device_side.png^elepower_power_port.png", "elewireless_device_side.png", + "elewireless_device_side.png", "elewireless_device_side.png", "elewireless_device_side.png" + }, + }, + groups = {cracky = 1, ele_user = 1, matter_transmitter = 1}, + ele_capacity = 8000, + ele_usage = 120, + ele_inrush = 240, + ele_no_automatic_ports = true, + on_timer = matter_transmitter_timer, + after_place_node = function (pos, placer, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + if not placer or placer:get_player_name() == "" then return false end + + meta:set_string("player", placer:get_player_name()) + save_transmitter(pos) + end, + on_receive_fields = function (pos, formname, fields, sender) + if sender and sender ~= "" and minetest.is_protected(pos, sender:get_player_name()) then + return + end + + -- Set Name + local meta = minetest.get_meta(pos) + if fields["name"] and fields["key_enter"] == "true" then + meta:set_string("name", fields["name"]) + end + end, + after_destruct = function (pos) + local strname = minetest.pos_to_string(pos) + if not elewi.loaded_transmitters[strname] then return end + elewi.loaded_transmitters[strname] = nil + end, +}) + +minetest.register_lbm({ + label = "Load Transmitter into memory", + name = "elepower_wireless:matter_transmitter", + nodenames = {"group:matter_transmitter"}, + run_at_every_load = true, + action = save_transmitter, +}) + +minetest.register_abm({ + nodenames = {"group:matter_transmitter"}, + interval = 1.0, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local objs = minetest.get_objects_inside_radius(pos, 1) + for k, player in pairs(objs) do + if player:get_player_name() ~= nil then + local meta = minetest.get_meta(pos) + local tpos = minetest.string_to_pos(meta:get_string("target")) + + if tpos then + local storage = ele.helpers.get_node_property(meta, pos, "storage") + local usage = ele.helpers.get_node_property(meta, pos, "usage") + + if storage >= usage then + local top = vector.add(tpos, {x = 0, y = 1, z = 0}) + local topnode = minetest.get_node_or_nil(top) + + if not topnode or topnode.name == "air" then + player:set_pos(top) + meta:set_int("storage", storage - usage) + -- TODO: Sound + break + end + end + end + end + end + end +}) diff --git a/elepower_wireless/textures/elewireless_dialler.png b/elepower_wireless/textures/elewireless_dialler.png new file mode 100644 index 0000000..09d8b92 Binary files /dev/null and b/elepower_wireless/textures/elewireless_dialler.png differ diff --git a/elepower_wireless/textures/elewireless_dialler_inactive.png b/elepower_wireless/textures/elewireless_dialler_inactive.png new file mode 100644 index 0000000..f392038 Binary files /dev/null and b/elepower_wireless/textures/elewireless_dialler_inactive.png differ diff --git a/elepower_wireless/textures/elewireless_receiver_top.png b/elepower_wireless/textures/elewireless_receiver_top.png deleted file mode 100644 index 0271d04..0000000 Binary files a/elepower_wireless/textures/elewireless_receiver_top.png and /dev/null differ diff --git a/elepower_wireless/textures/elewireless_receiver_top_animated.png b/elepower_wireless/textures/elewireless_receiver_top_animated.png index a57f6e3..6c1617a 100644 Binary files a/elepower_wireless/textures/elewireless_receiver_top_animated.png and b/elepower_wireless/textures/elewireless_receiver_top_animated.png differ diff --git a/elepower_wireless/textures/elewireless_receiver_top_inactive.png b/elepower_wireless/textures/elewireless_receiver_top_inactive.png deleted file mode 100644 index 8190d0e..0000000 Binary files a/elepower_wireless/textures/elewireless_receiver_top_inactive.png and /dev/null differ diff --git a/elepower_wireless/textures/elewireless_teleport_top.png b/elepower_wireless/textures/elewireless_teleport_top.png new file mode 100644 index 0000000..69e1d1f Binary files /dev/null and b/elepower_wireless/textures/elewireless_teleport_top.png differ diff --git a/elepower_wireless/textures/elewireless_transmitter_top_animated.png b/elepower_wireless/textures/elewireless_transmitter_top_animated.png new file mode 100644 index 0000000..d0070e0 Binary files /dev/null and b/elepower_wireless/textures/elewireless_transmitter_top_animated.png differ