From 62d6d4d5aeced03397f88acaaccabc5e2a469735 Mon Sep 17 00:00:00 2001 From: SX Date: Thu, 13 Feb 2020 19:56:34 +0200 Subject: Refactor mod structure --- init.lua | 160 ++++------------------------------------------------------- register.lua | 119 ++++++++++++++++++++++++++++++++++++++++++++ storage.lua | 33 ++++++++++++ 3 files changed, 161 insertions(+), 151 deletions(-) create mode 100644 register.lua create mode 100644 storage.lua diff --git a/init.lua b/init.lua index 84ea482..f0d7cac 100644 --- a/init.lua +++ b/init.lua @@ -8,43 +8,15 @@ local VERSION = 8 local PTIMEOUT = 120 -- Detect optional mods. -local technic_path = minetest.get_modpath("technic") -local chains_path = minetest.get_modpath("chains") -local homedecor_path = minetest.get_modpath("homedecor") local armor_path = minetest.get_modpath("3d_armor") --- Central "network" table. -local elevator = { - motors = {}, -} - -local str = minetest.get_mod_storage and minetest.get_mod_storage() +-- global runtime storage for data and references +-- contains .motors loaded from mod storage and api functions +elevator = {} -local elevator_file = minetest.get_worldpath() .. "/elevator" - -local function load_elevator() - if str and ((str.contains and str:contains("data")) or (str:get_string("data") and str:get_string("data") ~= "")) then - elevator = minetest.deserialize(str:get_string("data")) - return - end - local file = io.open(elevator_file) - if file then - elevator = minetest.deserialize(file:read("*all")) or {} - file:close() - end -end - -local function save_elevator() - if str then - str:set_string("data", minetest.serialize(elevator)) - return - end - local f = io.open(elevator_file, "w") - f:write(minetest.serialize(elevator)) - f:close() -end - -load_elevator() +local MP = minetest.get_modpath(minetest.get_current_modname()) +dofile(MP .. "/storage.lua") +dofile(MP .. "/register.lua") -- Elevator boxes in action. local boxes = {} @@ -65,36 +37,6 @@ local function get_node(pos) return minetest.get_node_or_nil(pos) end --- Use homedecor's placeholder if possible. -local placeholder = homedecor_path and "homedecor:expansion_placeholder" or "elevator:placeholder" -if homedecor_path then - minetest.register_alias("elevator:placeholder", "homedecor:expansion_placeholder") -else - -- Placeholder node, in the style of homedecor. - minetest.register_node(placeholder, { - description = "Expansion Placeholder", - selection_box = { - type = "fixed", - fixed = {0, 0, 0, 0, 0, 0}, - }, - groups = { - not_in_creative_inventory=1 - }, - drawtype = "airlike", - paramtype = "light", - sunlight_propagates = true, - - walkable = false, - buildable_to = false, - is_ground_content = false, - - on_dig = function(pos, node, player) - minetest.remove_node(pos) - minetest.set_node(pos, {name=placeholder}) - end - }) -end - local VISUAL_INCREASE = 1.75 -- Cause to ride beginning at and targetting . @@ -443,7 +385,7 @@ for _,mode in ipairs({"on", "off"}) do -- Add a placeholder to avoid nodes being placed in the top. local p = vector.add(pos, {x=0, y=1, z=0}) local p2 = minetest.dir_to_facedir(placer:get_look_dir()) - minetest.set_node(p, {name=placeholder, paramtype2="facedir", param2=p2}) + minetest.set_node(p, {name="elevator:placeholder", paramtype2="facedir", param2=p2}) -- Try to build a motor above. local motor = locate_motor(pos) @@ -459,7 +401,7 @@ for _,mode in ipairs({"on", "off"}) do on_place = function(itemstack, placer, pointed_thing) local pos = pointed_thing.above local node = minetest.get_node(vector.add(pos, {x=0, y=1, z=0})) - if (node ~= nil and node.name ~= "air" and node.name ~= placeholder) then + if (node ~= nil and node.name ~= "air" and node.name ~= "elevator:placeholder") then return end return minetest.item_place(itemstack, placer, pointed_thing) @@ -540,7 +482,7 @@ for _,mode in ipairs({"on", "off"}) do on_destruct = function(pos) local p = vector.add(pos, {x=0, y=1, z=0}) - if get_node(p).name == placeholder then + if get_node(p).name == "elevator:placeholder" then minetest.remove_node(p) end end, @@ -880,87 +822,3 @@ local box_entity = { } minetest.register_entity("elevator:box", box_entity) - -if technic_path and chains_path then - minetest.register_craft({ - output = "elevator:elevator", - recipe = { - {"technic:cast_iron_ingot", "chains:chain", "technic:cast_iron_ingot"}, - {"technic:cast_iron_ingot", "default:mese_crystal", "technic:cast_iron_ingot"}, - {"technic:stainless_steel_ingot", "default:glass", "technic:stainless_steel_ingot"}, - }, - }) - - minetest.register_craft({ - output = "elevator:shaft", - recipe = { - {"technic:cast_iron_ingot", "default:glass"}, - {"default:glass", "glooptest:chainlink"}, - }, - }) - - minetest.register_craft({ - output = "elevator:motor", - recipe = { - {"default:diamond", "technic:control_logic_unit", "default:diamond"}, - {"default:steelblock", "technic:motor", "default:steelblock"}, - {"chains:chain", "default:diamond", "chains:chain"} - }, - }) -elseif technic_path and farming and farming.mod and farming.mod == "redo" then - -- add alternative recipe with hemp rope - minetest.register_craft({ - output = "elevator:elevator", - recipe = { - {"technic:cast_iron_ingot", "farming:hemp_rope", "technic:cast_iron_ingot"}, - {"technic:cast_iron_ingot", "default:mese_crystal", "technic:cast_iron_ingot"}, - {"technic:stainless_steel_ingot", "default:glass", "technic:stainless_steel_ingot"}, - }, - }) - - minetest.register_craft({ - output = "elevator:shaft", - recipe = { - {"technic:cast_iron_ingot", "default:glass"}, - {"default:glass", "farming:hemp_rope"}, - }, - }) - - minetest.register_craft({ - output = "elevator:motor", - recipe = { - {"default:diamond", "technic:control_logic_unit", "default:diamond"}, - {"default:steelblock", "technic:motor", "default:steelblock"}, - {"farming:hemp_rope", "default:diamond", "farming:hemp_rope"} - }, - }) - - -- Recipes without technic & chains required. --- Recipes for default dependency fallback. -else - minetest.register_craft({ - output = "elevator:elevator", - recipe = { - {"default:steel_ingot", "farming:cotton", "default:steel_ingot"}, - {"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"}, - {"xpanes:pane_flat", "default:glass", "xpanes:pane_flat"}, - }, - }) - - minetest.register_craft({ - output = "elevator:shaft", - recipe = { - {"default:steel_ingot", "default:obsidian_glass"}, - {"default:obsidian_glass", "default:steel_ingot"}, - }, - }) - - minetest.register_craft({ - output = "elevator:motor", - recipe = { - {"default:diamond", "default:copper_ingot", "default:diamond"}, - {"default:steelblock", "default:furnace", "default:steelblock"}, - {"farming:cotton", "default:diamond", "farming:cotton"} - }, - }) -end diff --git a/register.lua b/register.lua new file mode 100644 index 0000000..6b60724 --- /dev/null +++ b/register.lua @@ -0,0 +1,119 @@ +-- Detect optional mods. +local technic_path = minetest.get_modpath("technic") +local chains_path = minetest.get_modpath("chains") +local technic_path = minetest.get_modpath("technic") +local chains_path = minetest.get_modpath("chains") +local homedecor_path = minetest.get_modpath("homedecor") + +-- Use homedecor's placeholder if possible. +if homedecor_path then + minetest.register_alias("elevator:placeholder", "homedecor:expansion_placeholder") +else + -- Placeholder node, in the style of homedecor. + minetest.register_node("elevator:placeholder", { + description = "Expansion Placeholder", + selection_box = { + type = "fixed", + fixed = {0, 0, 0, 0, 0, 0}, + }, + groups = { + not_in_creative_inventory=1 + }, + drawtype = "airlike", + paramtype = "light", + sunlight_propagates = true, + + walkable = false, + buildable_to = false, + is_ground_content = false, + + on_dig = function(pos, node, player) + minetest.remove_node(pos) + minetest.set_node(pos, {name="elevator:placeholder"}) + end + }) +end + +if technic_path and chains_path then + minetest.register_craft({ + output = "elevator:elevator", + recipe = { + {"technic:cast_iron_ingot", "chains:chain", "technic:cast_iron_ingot"}, + {"technic:cast_iron_ingot", "default:mese_crystal", "technic:cast_iron_ingot"}, + {"technic:stainless_steel_ingot", "default:glass", "technic:stainless_steel_ingot"}, + }, + }) + + minetest.register_craft({ + output = "elevator:shaft", + recipe = { + {"technic:cast_iron_ingot", "default:glass"}, + {"default:glass", "glooptest:chainlink"}, + }, + }) + + minetest.register_craft({ + output = "elevator:motor", + recipe = { + {"default:diamond", "technic:control_logic_unit", "default:diamond"}, + {"default:steelblock", "technic:motor", "default:steelblock"}, + {"chains:chain", "default:diamond", "chains:chain"} + }, + }) +elseif technic_path and farming and farming.mod and farming.mod == "redo" then + -- add alternative recipe with hemp rope + minetest.register_craft({ + output = "elevator:elevator", + recipe = { + {"technic:cast_iron_ingot", "farming:hemp_rope", "technic:cast_iron_ingot"}, + {"technic:cast_iron_ingot", "default:mese_crystal", "technic:cast_iron_ingot"}, + {"technic:stainless_steel_ingot", "default:glass", "technic:stainless_steel_ingot"}, + }, + }) + + minetest.register_craft({ + output = "elevator:shaft", + recipe = { + {"technic:cast_iron_ingot", "default:glass"}, + {"default:glass", "farming:hemp_rope"}, + }, + }) + + minetest.register_craft({ + output = "elevator:motor", + recipe = { + {"default:diamond", "technic:control_logic_unit", "default:diamond"}, + {"default:steelblock", "technic:motor", "default:steelblock"}, + {"farming:hemp_rope", "default:diamond", "farming:hemp_rope"} + }, + }) + +-- Recipes without technic & chains required. +-- Recipes for default dependency fallback. +else + minetest.register_craft({ + output = "elevator:elevator", + recipe = { + {"default:steel_ingot", "farming:cotton", "default:steel_ingot"}, + {"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"}, + {"xpanes:pane_flat", "default:glass", "xpanes:pane_flat"}, + }, + }) + + minetest.register_craft({ + output = "elevator:shaft", + recipe = { + {"default:steel_ingot", "default:obsidian_glass"}, + {"default:obsidian_glass", "default:steel_ingot"}, + }, + }) + + minetest.register_craft({ + output = "elevator:motor", + recipe = { + {"default:diamond", "default:copper_ingot", "default:diamond"}, + {"default:steelblock", "default:furnace", "default:steelblock"}, + {"farming:cotton", "default:diamond", "farming:cotton"} + }, + }) +end diff --git a/storage.lua b/storage.lua new file mode 100644 index 0000000..5adbaf5 --- /dev/null +++ b/storage.lua @@ -0,0 +1,33 @@ + +local elevator_file = minetest.get_worldpath() .. "/elevator" + +local str = minetest.get_mod_storage and minetest.get_mod_storage() + +-- Central "network" table. +elevator.motors = {} + +local function load_elevator() + local data = nil + if str and ((str.contains and str:contains("data")) or (str:get_string("data") and str:get_string("data") ~= "")) then + data = minetest.deserialize(str:get_string("data")) + else + local file = io.open(elevator_file) + if file then + data = minetest.deserialize(file:read("*all")) or {} + file:close() + end + end + elevator.motors = data.motors and data.motors or {} +end + +local function save_elevator() + if str then + str:set_string("data", minetest.serialize({motors = elevator.motors})) + return + end + local f = io.open(elevator_file, "w") + f:write(minetest.serialize({motors = elevator.motors})) + f:close() +end + +load_elevator() -- cgit v1.2.3 From 469b50633862b4838e4304750ef01195fd9850e8 Mon Sep 17 00:00:00 2001 From: SX Date: Thu, 13 Feb 2020 22:23:06 +0200 Subject: Refactoring hooks, storage, register --- hooks.lua | 61 ++++++++++++++++ init.lua | 231 ++++++++++++----------------------------------------------- register.lua | 82 +++++++++++++++++++++ storage.lua | 4 +- 4 files changed, 189 insertions(+), 189 deletions(-) create mode 100644 hooks.lua diff --git a/hooks.lua b/hooks.lua new file mode 100644 index 0000000..ff6d4cb --- /dev/null +++ b/hooks.lua @@ -0,0 +1,61 @@ + +-- Globalstep timer. +local time = 0 + +minetest.register_globalstep(function(dtime) + -- Don't want to run this too often. + time = time + dtime + if time < 0.5 then + return + end + time = 0 + -- Only count riders who are still logged in. + local newriding = {} + for _,p in ipairs(minetest.get_connected_players()) do + local pos = p:getpos() + local name = p:get_player_name() + newriding[name] = elevator.riding[name] + -- If the player is indeed riding, update their position. + if newriding[name] then + newriding[name].pos = pos + end + end + elevator.riding = newriding + for name,r in pairs(elevator.riding) do + -- If the box is no longer loaded or existent, create another. + local ok = r.box and r.box.getpos and r.box:getpos() and r.box:get_luaentity() and r.box:get_luaentity().attached == name + if not ok then + minetest.log("action", "[elevator] "..minetest.pos_to_string(r.pos).." created due to lost rider.") + minetest.after(0, create_box, r.motor, r.pos, r.target, minetest.get_player_by_name(name)) + end + end + -- Ensure boxes are deleted after seconds if there are no players nearby. + for motor,obj in pairs(elevator.boxes) do + if type(obj) ~= "table" then + return + end + elevator.lastboxes[motor] = elevator.lastboxes[motor] and math.min(elevator.lastboxes[motor], PTIMEOUT) or PTIMEOUT + elevator.lastboxes[motor] = math.max(elevator.lastboxes[motor] - 1, 0) + local pos = obj:getpos() + if pos then + for _,object in ipairs(minetest.get_objects_inside_radius(pos, 5)) do + if object.is_player and object:is_player() then + elevator.lastboxes[motor] = PTIMEOUT + break + end + end + if elevator.lastboxes[motor] < 1 then + minetest.log("action", "[elevator] "..minetest.pos_to_string(pos).." broke due to lack of players.") + elevator.boxes[motor] = false + end + else + minetest.log("action", "[elevator] "..minetest.pos_to_string(pos).." broke due to lack of position during player check.") + elevator.boxes[motor] = false + end + end +end) + +minetest.register_on_leaveplayer(function(player) + -- We don't want players potentially logging into open elevators. + elevator.teleport_player_from_elevator(player) +end) diff --git a/init.lua b/init.lua index f0d7cac..905e5e3 100644 --- a/init.lua +++ b/init.lua @@ -12,22 +12,19 @@ local armor_path = minetest.get_modpath("3d_armor") -- global runtime storage for data and references -- contains .motors loaded from mod storage and api functions -elevator = {} +elevator = { + boxes = {}, -- Elevator boxes in action. + lastboxes = {}, -- Player near box timeout. + riding = {}, -- Players riding boxes. +} local MP = minetest.get_modpath(minetest.get_current_modname()) dofile(MP .. "/storage.lua") dofile(MP .. "/register.lua") +dofile(MP .. "/hooks.lua") --- Elevator boxes in action. -local boxes = {} -- Player formspecs. local formspecs = {} --- Player near box timeout. -local lastboxes = {} --- Players riding boxes. -local riding = {} --- Globalstep timer. -local time = 0 -- Helper function to read unloaded nodes. local function get_node(pos) @@ -64,8 +61,8 @@ local function create_box(motorhash, pos, target, sender) obj:setvelocity({x=0, y=SPEED*obj:get_luaentity().vmult, z=0}) obj:setacceleration({x=0, y=ACCEL*obj:get_luaentity().vmult, z=0}) -- Set the tables. - boxes[motorhash] = obj - riding[sender:get_player_name()] = { + elevator.boxes[motorhash] = obj + elevator.riding[sender:get_player_name()] = { motor = motorhash, pos = pos, target = target, @@ -75,7 +72,7 @@ local function create_box(motorhash, pos, target, sender) end -- Try to teleport player away from any closed (on) elevator node. -local function teleport_player_from_elevator(player) +elevator.teleport_player_from_elevator = function(player) local function solid(pos) if not minetest.registered_nodes[minetest.get_node(pos).name] then return true @@ -96,64 +93,6 @@ local function teleport_player_from_elevator(player) end end -minetest.register_globalstep(function(dtime) - -- Don't want to run this too often. - time = time + dtime - if time < 0.5 then - return - end - time = 0 - -- Only count riders who are still logged in. - local newriding = {} - for _,p in ipairs(minetest.get_connected_players()) do - local pos = p:getpos() - local name = p:get_player_name() - newriding[name] = riding[name] - -- If the player is indeed riding, update their position. - if newriding[name] then - newriding[name].pos = pos - end - end - riding = newriding - for name,r in pairs(riding) do - -- If the box is no longer loaded or existent, create another. - local ok = r.box and r.box.getpos and r.box:getpos() and r.box:get_luaentity() and r.box:get_luaentity().attached == name - if not ok then - minetest.log("action", "[elevator] "..minetest.pos_to_string(r.pos).." created due to lost rider.") - minetest.after(0, create_box, r.motor, r.pos, r.target, minetest.get_player_by_name(name)) - end - end - -- Ensure boxes are deleted after seconds if there are no players nearby. - for motor,obj in pairs(boxes) do - if type(obj) ~= "table" then - return - end - lastboxes[motor] = lastboxes[motor] and math.min(lastboxes[motor], PTIMEOUT) or PTIMEOUT - lastboxes[motor] = math.max(lastboxes[motor] - 1, 0) - local pos = obj:getpos() - if pos then - for _,object in ipairs(minetest.get_objects_inside_radius(pos, 5)) do - if object.is_player and object:is_player() then - lastboxes[motor] = PTIMEOUT - break - end - end - if lastboxes[motor] < 1 then - minetest.log("action", "[elevator] "..minetest.pos_to_string(pos).." broke due to lack of players.") - boxes[motor] = false - end - else - minetest.log("action", "[elevator] "..minetest.pos_to_string(pos).." broke due to lack of position during player check.") - boxes[motor] = false - end - end -end) - -minetest.register_on_leaveplayer(function(player) - -- We don't want players potentially logging into open elevators. - teleport_player_from_elevator(player) -end) - local function phash(pos) return minetest.pos_to_string(pos) end @@ -163,7 +102,7 @@ local function punhash(pos) end -- Starting from , locate a motor hash. -local function locate_motor(pos) +elevator.locate_motor = function(pos) local p = vector.new(pos) while true do local node = get_node(p) @@ -179,7 +118,7 @@ local function locate_motor(pos) end end -local function build_motor(hash) +elevator.build_motor = function(hash) local need_saving = false local motor = elevator.motors[hash] -- Just ignore motors that don't exist. @@ -221,7 +160,7 @@ local function build_motor(hash) local meta = minetest.get_meta(pos) meta:set_int("version", VERSION) if meta:get_string("motor") ~= hash then - build_motor(meta:get_string("motor")) + elevator.build_motor(meta:get_string("motor")) end motor.labels[i] = meta:get_string("label") meta:set_string("motor", hash) @@ -230,11 +169,11 @@ local function build_motor(hash) end end if need_saving then - save_elevator() + elevator.save_elevator() end end -local function unbuild(pos, add) +elevator.unbuild = function(pos, add) local need_saving = false local p = table.copy(pos) p.y = p.y - 1 @@ -261,15 +200,15 @@ local function unbuild(pos, add) return end p2.y = p2.y + add - local motorhash = locate_motor(p2) - build_motor(motorhash) + local motorhash = elevator.locate_motor(p2) + elevator.build_motor(motorhash) -- If there's a box below this point, break it. - if boxes[motorhash] and boxes[motorhash]:getpos() and p2.y >= boxes[motorhash]:getpos().y then - boxes[motorhash] = nil + if elevator.boxes[motorhash] and elevator.boxes[motorhash]:getpos() and p2.y >= elevator.boxes[motorhash]:getpos().y then + elevator.boxes[motorhash] = nil end -- If the box does not exist, just clear it. - if boxes[motorhash] and not boxes[motorhash]:getpos() then - boxes[motorhash] = nil + if elevator.boxes[motorhash] and not elevator.boxes[motorhash]:getpos() then + elevator.boxes[motorhash] = nil end end, table.copy(pos), add) end @@ -293,14 +232,14 @@ minetest.register_node("elevator:motor", { pnames = {}, labels = {}, } - save_elevator() - build_motor(phash(pos)) + elevator.save_elevator() + elevator.build_motor(phash(pos)) end, on_destruct = function(pos) -- Destroy everything related to this motor. - boxes[phash(pos)] = nil + elevator.boxes[phash(pos)] = nil elevator.motors[phash(pos)] = nil - save_elevator() + elevator.save_elevator() end, }) @@ -388,14 +327,14 @@ for _,mode in ipairs({"on", "off"}) do minetest.set_node(p, {name="elevator:placeholder", paramtype2="facedir", param2=p2}) -- Try to build a motor above. - local motor = locate_motor(pos) + local motor = elevator.locate_motor(pos) if motor then - build_motor(motor) + elevator.build_motor(motor) end end, after_dig_node = function(pos, node, meta, digger) - unbuild(pos, 2) + elevator.unbuild(pos, 2) end, on_place = function(itemstack, placer, pointed_thing) @@ -466,7 +405,7 @@ for _,mode in ipairs({"on", "off"}) do .."label[0,0;This elevator is inactive.]" end minetest.show_formspec(sender:get_player_name(), "elevator:elevator", formspec) - elseif boxes[meta:get_string("motor")] then + elseif elevator.boxes[meta:get_string("motor")] then if not minetest.is_protected(pos, sender:get_player_name()) then formspec = "size[4,2]" .."label[0,0;This elevator is in use.]" @@ -506,7 +445,7 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields) meta:set_string("infotext", fields.label) -- Rebuild the elevator shaft so the other elevators can read this label. local motorhash = meta:get_string("motor") - build_motor(elevator.motors[motorhash] and motorhash or locate_motor(pos)) + elevator.build_motor(elevator.motors[motorhash] and motorhash or elevator.locate_motor(pos)) return true end -- Double check if it's ok to go. @@ -526,11 +465,11 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields) local motorhash = meta:get_string("motor") local motor = elevator.motors[motorhash] if not motor then - motorhash = locate_motor(pos) + motorhash = elevator.locate_motor(pos) motor = elevator.motors[motorhash] if motor then meta:set_string("motor", "") - build_motor(motorhash) + elevator.build_motor(motorhash) minetest.chat_send_player(sender:get_player_name(), "Recalibrated to a new motor, please try again.") return true end @@ -553,7 +492,7 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields) -- Found the elevator? Then go! if target then -- Final check. - if boxes[motorhash] then + if elevator.boxes[motorhash] then minetest.chat_send_player(sender:get_player_name(), "This elevator is in use.") return true end @@ -564,7 +503,7 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields) for _,object in ipairs(minetest.get_objects_inside_radius(p, 0.6)) do if object.is_player and object:is_player() then if object:get_player_name() ~= obj:get_luaentity().attached then - teleport_player_from_elevator(object) + elevator.teleport_player_from_elevator(object) end end end @@ -585,7 +524,7 @@ minetest.register_alias("elevator:elevator", "elevator:elevator_off") local function upgrade_elevator(pos, meta) if meta:get_int("version") ~= VERSION then minetest.log("action", "[elevator] Updating elevator with old version at "..minetest.pos_to_string(pos)) - minetest.after(0, function(pos) build_motor(locate_motor(pos)) end, pos) + minetest.after(0, function(pos) elevator.build_motor(elevator.locate_motor(pos)) end, pos) meta:set_int("version", VERSION) meta:set_string("formspec", "") meta:set_string("infotext", meta:get_string("label")) @@ -596,7 +535,7 @@ end local offabm = function(pos, node) local meta = minetest.get_meta(pos) upgrade_elevator(pos, meta) - if not boxes[meta:get_string("motor")] and elevator.motors[meta:get_string("motor")] then + if not elevator.boxes[meta:get_string("motor")] and elevator.motors[meta:get_string("motor")] then node.name = "elevator:elevator_on" minetest.swap_node(pos, node) end @@ -618,7 +557,7 @@ minetest.register_abm({ action = function(pos, node) local meta = minetest.get_meta(pos) upgrade_elevator(pos, meta) - if boxes[meta:get_string("motor")] or not elevator.motors[meta:get_string("motor")] then + if elevator.boxes[meta:get_string("motor")] or not elevator.motors[meta:get_string("motor")] then node.name = "elevator:elevator_off" minetest.swap_node(pos, node) end @@ -626,88 +565,6 @@ minetest.register_abm({ label = "Elevator (On)", }) -minetest.register_node("elevator:shaft", { - description = "Elevator Shaft", - tiles = { "elevator_shaft.png" }, - drawtype = "nodebox", - paramtype = "light", - on_rotate = screwdriver.disallow, - sunlight_propagates = true, - groups = {cracky=2, oddly_breakable_by_hand=1}, - sounds = default.node_sound_stone_defaults(), - node_box = { - type = "fixed", - fixed = { - {-8/16,-8/16,-8/16,-7/16,8/16,8/16}, - {7/16,-8/16,-8/16,8/16,8/16,8/16}, - {-7/16,-8/16,-8/16,7/16,8/16,-7/16}, - {-7/16,-8/16,8/16,7/16,8/16,7/16}, - }, - }, - collisionbox = { - type = "fixed", - fixed = { - {-8/16,-8/16,-8/16,-7/16,8/16,8/16}, - {7/16,-8/16,-8/16,8/16,8/16,8/16}, - {-7/16,-8/16,-8/16,7/16,8/16,-7/16}, - {-7/16,-8/16,8/16,7/16,8/16,7/16}, - }, - }, - after_place_node = function(pos) - -- We might have connected a motor above to an elevator below. - build_motor(locate_motor(pos)) - end, - on_destruct = function(pos) - -- Remove boxes and deactivate elevators below us. - unbuild(pos, 1) - end, -}) - -local box = { - { 0.48, -0.5,-0.5, 0.5, 1.5, 0.5}, - {-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5}, - {-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5}, - {-0.5 , -0.5, -0.48, 0.5, 1.5, -0.5}, - { -0.5,-0.5,-0.5,0.5,-0.48, 0.5}, - { -0.5, 1.45,-0.5,0.5, 1.5, 0.5}, -} - --- Elevator box node. Not intended to be placeable. -minetest.register_node("elevator:elevator_box", { - description = "Elevator", - drawtype = "nodebox", - paramtype = 'light', - paramtype2 = "facedir", - wield_scale = {x=0.6, y=0.6, z=0.6}, - - selection_box = { - type = "fixed", - fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 } - }, - - collision_box = { - type = "fixed", - fixed = box, - }, - - node_box = { - type = "fixed", - fixed = box, - }, - - tiles = { - "default_steel_block.png", - "default_steel_block.png", - "elevator_box.png", - "elevator_box.png", - "elevator_box.png", - "elevator_box.png", - }, - groups = {not_in_creative_inventory = 1}, - - light_source = 4, -}) - -- Remove the player from self, and teleport them to pos if specified. local function detach(self, pos) local player = minetest.get_player_by_name(self.attached) @@ -727,7 +584,7 @@ local function detach(self, pos) pl:setpos(p) end, player, pos) end - riding[self.attached] = nil + elevator.riding[self.attached] = nil end local box_entity = { @@ -755,7 +612,7 @@ local box_entity = { local pos = self.object:getpos() -- First, check if this box needs removed. -- If the motor has a box and it isn't this box. - if boxes[self.motor] and boxes[self.motor] ~= self.object then + if elevator.boxes[self.motor] and elevator.boxes[self.motor] ~= self.object then minetest.log("action", "[elevator] "..minetest.pos_to_string(pos).." broke due to duplication.") self.object:remove() return @@ -764,22 +621,22 @@ local box_entity = { if not minetest.get_player_by_name(self.attached) then minetest.log("action", "[elevator] "..minetest.pos_to_string(pos).." broke due to lack of attachee logged in.") self.object:remove() - boxes[self.motor] = nil + elevator.boxes[self.motor] = nil return end -- If our attached player is no longer with us. if not minetest.get_player_by_name(self.attached):get_attach() or minetest.get_player_by_name(self.attached):get_attach():get_luaentity().uid ~= self.uid then minetest.log("action", "[elevator] "..minetest.pos_to_string(pos).." broke due to lack of attachee.") self.object:remove() - boxes[self.motor] = nil + elevator.boxes[self.motor] = nil return end -- If our motor's box is nil, we should self-destruct. - if not boxes[self.motor] then + if not elevator.boxes[self.motor] then minetest.log("action", "[elevator] "..minetest.pos_to_string(pos).." broke due to nil entry in boxes.") detach(self) self.object:remove() - boxes[self.motor] = nil + elevator.boxes[self.motor] = nil return end @@ -799,7 +656,7 @@ local box_entity = { minetest.log("action", "[elevator] "..minetest.pos_to_string(p).." broke due to arrival.") detach(self, vector.add(self.target, {x=0, y=-0.4, z=0})) self.object:remove() - boxes[self.motor] = nil + elevator.boxes[self.motor] = nil offabm(self.target, node) return end @@ -810,7 +667,7 @@ local box_entity = { if belownode.name ~= "elevator:elevator_on" and belownode.name ~= "elevator:elevator_off" then -- If we aren't, then break the box. minetest.log("action", "[elevator] "..minetest.pos_to_string(p).." broke on "..node.name) - boxes[self.motor] = nil + elevator.boxes[self.motor] = nil detach(self, p) self.object:remove() return diff --git a/register.lua b/register.lua index 6b60724..af8048b 100644 --- a/register.lua +++ b/register.lua @@ -117,3 +117,85 @@ else }, }) end + +minetest.register_node("elevator:shaft", { + description = "Elevator Shaft", + tiles = { "elevator_shaft.png" }, + drawtype = "nodebox", + paramtype = "light", + on_rotate = screwdriver.disallow, + sunlight_propagates = true, + groups = {cracky=2, oddly_breakable_by_hand=1}, + sounds = default.node_sound_stone_defaults(), + node_box = { + type = "fixed", + fixed = { + {-8/16,-8/16,-8/16,-7/16,8/16,8/16}, + {7/16,-8/16,-8/16,8/16,8/16,8/16}, + {-7/16,-8/16,-8/16,7/16,8/16,-7/16}, + {-7/16,-8/16,8/16,7/16,8/16,7/16}, + }, + }, + collisionbox = { + type = "fixed", + fixed = { + {-8/16,-8/16,-8/16,-7/16,8/16,8/16}, + {7/16,-8/16,-8/16,8/16,8/16,8/16}, + {-7/16,-8/16,-8/16,7/16,8/16,-7/16}, + {-7/16,-8/16,8/16,7/16,8/16,7/16}, + }, + }, + after_place_node = function(pos) + -- We might have connected a motor above to an elevator below. + elevator.build_motor(elevator.locate_motor(pos)) + end, + on_destruct = function(pos) + -- Remove boxes and deactivate elevators below us. + elevator.unbuild(pos, 1) + end, +}) + +local box = { + { 0.48, -0.5,-0.5, 0.5, 1.5, 0.5}, + {-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5}, + {-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5}, + {-0.5 , -0.5, -0.48, 0.5, 1.5, -0.5}, + { -0.5,-0.5,-0.5,0.5,-0.48, 0.5}, + { -0.5, 1.45,-0.5,0.5, 1.5, 0.5}, +} + +-- Elevator box node. Not intended to be placeable. +minetest.register_node("elevator:elevator_box", { + description = "Elevator", + drawtype = "nodebox", + paramtype = 'light', + paramtype2 = "facedir", + wield_scale = {x=0.6, y=0.6, z=0.6}, + + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 } + }, + + collision_box = { + type = "fixed", + fixed = box, + }, + + node_box = { + type = "fixed", + fixed = box, + }, + + tiles = { + "default_steel_block.png", + "default_steel_block.png", + "elevator_box.png", + "elevator_box.png", + "elevator_box.png", + "elevator_box.png", + }, + groups = {not_in_creative_inventory = 1}, + + light_source = 4, +}) diff --git a/storage.lua b/storage.lua index 5adbaf5..e923e5d 100644 --- a/storage.lua +++ b/storage.lua @@ -17,10 +17,10 @@ local function load_elevator() file:close() end end - elevator.motors = data.motors and data.motors or {} + elevator.motors = (data and data.motors) and data.motors or {} end -local function save_elevator() +elevator.save_elevator = function() if str then str:set_string("data", minetest.serialize({motors = elevator.motors})) return -- cgit v1.2.3 From a3966d1a029cbeaaf6778313ee44dd6ada9ed369 Mon Sep 17 00:00:00 2001 From: SX Date: Fri, 14 Feb 2020 02:07:10 +0200 Subject: Refactoring crafts formspecs components helpers --- components.lua | 334 ++++++++++++++++++++++++++++++++++++++++++++++++ crafts.lua | 87 +++++++++++++ formspecs.lua | 90 +++++++++++++ helpers.lua | 38 ++++++ hooks.lua | 6 +- init.lua | 390 ++++----------------------------------------------------- register.lua | 201 ----------------------------- 7 files changed, 575 insertions(+), 571 deletions(-) create mode 100644 components.lua create mode 100644 crafts.lua create mode 100644 formspecs.lua create mode 100644 helpers.lua delete mode 100644 register.lua diff --git a/components.lua b/components.lua new file mode 100644 index 0000000..d018ee0 --- /dev/null +++ b/components.lua @@ -0,0 +1,334 @@ + +local phash = elevator.phash +local get_node = elevator.get_node + +local homedecor_path = minetest.get_modpath("homedecor") + +-- Use homedecor's placeholder if possible. +if homedecor_path then + minetest.register_alias("elevator:placeholder", "homedecor:expansion_placeholder") +else + -- Placeholder node, in the style of homedecor. + minetest.register_node("elevator:placeholder", { + description = "Expansion Placeholder", + selection_box = { + type = "fixed", + fixed = {0, 0, 0, 0, 0, 0}, + }, + groups = { + not_in_creative_inventory=1 + }, + drawtype = "airlike", + paramtype = "light", + sunlight_propagates = true, + + walkable = false, + buildable_to = false, + is_ground_content = false, + + on_dig = function(pos, node, player) + minetest.remove_node(pos) + minetest.set_node(pos, {name="elevator:placeholder"}) + end + }) +end + +minetest.register_node("elevator:shaft", { + description = "Elevator Shaft", + tiles = { "elevator_shaft.png" }, + drawtype = "nodebox", + paramtype = "light", + on_rotate = screwdriver.disallow, + sunlight_propagates = true, + groups = {cracky=2, oddly_breakable_by_hand=1}, + sounds = default.node_sound_stone_defaults(), + node_box = { + type = "fixed", + fixed = { + {-8/16,-8/16,-8/16,-7/16,8/16,8/16}, + {7/16,-8/16,-8/16,8/16,8/16,8/16}, + {-7/16,-8/16,-8/16,7/16,8/16,-7/16}, + {-7/16,-8/16,8/16,7/16,8/16,7/16}, + }, + }, + collisionbox = { + type = "fixed", + fixed = { + {-8/16,-8/16,-8/16,-7/16,8/16,8/16}, + {7/16,-8/16,-8/16,8/16,8/16,8/16}, + {-7/16,-8/16,-8/16,7/16,8/16,-7/16}, + {-7/16,-8/16,8/16,7/16,8/16,7/16}, + }, + }, + after_place_node = function(pos) + -- We might have connected a motor above to an elevator below. + elevator.build_motor(elevator.locate_motor(pos)) + end, + on_destruct = function(pos) + -- Remove boxes and deactivate elevators below us. + elevator.unbuild(pos, 1) + end, +}) + +local box = { + { 0.48, -0.5,-0.5, 0.5, 1.5, 0.5}, + {-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5}, + {-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5}, + {-0.5 , -0.5, -0.48, 0.5, 1.5, -0.5}, + { -0.5,-0.5,-0.5,0.5,-0.48, 0.5}, + { -0.5, 1.45,-0.5,0.5, 1.5, 0.5}, +} + +-- Elevator box node. Not intended to be placeable. +minetest.register_node("elevator:elevator_box", { + description = "Elevator", + drawtype = "nodebox", + paramtype = 'light', + paramtype2 = "facedir", + wield_scale = {x=0.6, y=0.6, z=0.6}, + + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 } + }, + + collision_box = { + type = "fixed", + fixed = box, + }, + + node_box = { + type = "fixed", + fixed = box, + }, + + tiles = { + "default_steel_block.png", + "default_steel_block.png", + "elevator_box.png", + "elevator_box.png", + "elevator_box.png", + "elevator_box.png", + }, + groups = {not_in_creative_inventory = 1}, + + light_source = 4, +}) + +minetest.register_node("elevator:motor", { + description = "Elevator Motor", + tiles = { + "default_steel_block.png", + "default_steel_block.png", + "elevator_motor.png", + "elevator_motor.png", + "elevator_motor.png", + "elevator_motor.png", + }, + groups = {cracky=1}, + sounds = default.node_sound_stone_defaults(), + after_place_node = function(pos, placer, itemstack) + -- Set up the motor table. + elevator.motors[phash(pos)] = { + elevators = {}, + pnames = {}, + labels = {}, + } + elevator.save_elevator() + elevator.build_motor(phash(pos)) + end, + on_destruct = function(pos) + -- Destroy everything related to this motor. + elevator.boxes[phash(pos)] = nil + elevator.motors[phash(pos)] = nil + elevator.save_elevator() + end, +}) + +for _,mode in ipairs({"on", "off"}) do + local nodename = "elevator:elevator_"..mode + local on = (mode == "on") + local box + local cbox + if on then + -- Active elevators have a ceiling and floor. + box = { + + { 0.48, -0.5,-0.5, 0.5, 1.5, 0.5}, + {-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5}, + {-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5}, + + { -0.5,-0.5,-0.5,0.5,-0.48, 0.5}, + { -0.5, 1.45,-0.5,0.5, 1.5, 0.5}, + } + cbox = table.copy(box) + -- But you can enter them from the top. + cbox[5] = nil + else + -- Inactive elevators are almost like shafts. + box = { + + { 0.48, -0.5,-0.5, 0.5, 1.5, 0.5}, + {-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5}, + {-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5}, + {-0.5 , -0.5, -0.48, 0.5, 1.5, -0.5}, + } + cbox = box + end + minetest.register_node(nodename, { + description = "Elevator", + drawtype = "nodebox", + sunlight_propagates = false, + paramtype = "light", + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + + selection_box = { + type = "fixed", + fixed = box, + }, + + collision_box = { + type = "fixed", + fixed = cbox, + }, + + node_box = { + type = "fixed", + fixed = box, + }, + + tiles = on and { + "default_steel_block.png", + "default_steel_block.png", + "elevator_box.png", + "elevator_box.png", + "elevator_box.png", + "elevator_box.png", + } or { + "elevator_box.png", + "elevator_box.png", + "elevator_box.png", + "elevator_box.png", + "elevator_box.png", + "elevator_box.png", + }, + groups = {cracky=1, choppy=1, snappy=1}, + drop = "elevator:elevator_off", + + -- Emit a bit of light when active. + light_source = (on and 4 or nil), + + after_place_node = function(pos, placer, itemstack) + local meta = minetest.get_meta(pos) + meta:set_int("version", elevator.VERSION) + + -- Add a placeholder to avoid nodes being placed in the top. + local p = vector.add(pos, {x=0, y=1, z=0}) + local p2 = minetest.dir_to_facedir(placer:get_look_dir()) + minetest.set_node(p, {name="elevator:placeholder", paramtype2="facedir", param2=p2}) + + -- Try to build a motor above. + local motor = elevator.locate_motor(pos) + if motor then + elevator.build_motor(motor) + end + end, + + after_dig_node = function(pos, node, meta, digger) + elevator.unbuild(pos, 2) + end, + + on_place = function(itemstack, placer, pointed_thing) + local pos = pointed_thing.above + local node = minetest.get_node(vector.add(pos, {x=0, y=1, z=0})) + if (node ~= nil and node.name ~= "air" and node.name ~= "elevator:placeholder") then + return + end + return minetest.item_place(itemstack, placer, pointed_thing) + end, + + on_rightclick = function(pos, node, sender) + if not sender or not sender:is_player() then + return + end + local formspec + local meta = minetest.get_meta(pos) + elevator.formspecs[sender:get_player_name()] = {pos} + if on then + if vector.distance(sender:getpos(), pos) > 1 or minetest.get_node(sender:getpos()).name ~= nodename then + minetest.chat_send_player(sender:get_player_name(), "You are not inside the booth.") + return + end + -- Build the formspec from the motor table. + local tpnames = {} + local tpnames_l = {} + local motorhash = meta:get_string("motor") + local motor = elevator.motors[motorhash] + for ji,jv in ipairs(motor.pnames) do + if tonumber(jv) ~= pos.y then + table.insert(tpnames, jv) + table.insert(tpnames_l, (motor.labels[ji] and motor.labels[ji] ~= "") and (jv.." - "..minetest.formspec_escape(motor.labels[ji])) or jv) + end + end + elevator.formspecs[sender:get_player_name()] = {pos, tpnames} + if #tpnames > 0 then + if not minetest.is_protected(pos, sender:get_player_name()) then + formspec = "size[4,6]" + .."label[0,0;Click once to travel.]" + .."textlist[-0.1,0.5;4,4;target;"..table.concat(tpnames_l, ",").."]" + .."field[0.25,5.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]" + .."button_exit[-0.05,5.5;4,1;setlabel;Set label]" + else + formspec = "size[4,4.4]" + .."label[0,0;Click once to travel.]" + .."textlist[-0.1,0.5;4,4;target;"..table.concat(tpnames_l, ",").."]" + end + else + if not minetest.is_protected(pos, sender:get_player_name()) then + formspec = "size[4,2]" + .."label[0,0;No targets available.]" + .."field[0.25,1.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]" + .."button_exit[-0.05,1.5;4,1;setlabel;Set label]" + else + formspec = "size[4,0.4]" + .."label[0,0;No targets available.]" + end + end + minetest.show_formspec(sender:get_player_name(), "elevator:elevator", formspec) + elseif not elevator.motors[meta:get_string("motor")] then + if not minetest.is_protected(pos, sender:get_player_name()) then + formspec = "size[4,2]" + .."label[0,0;This elevator is inactive.]" + .."field[0.25,1.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]" + .."button_exit[-0.05,1.5;4,1;setlabel;Set label]" + else + formspec = "size[4,0.4]" + .."label[0,0;This elevator is inactive.]" + end + minetest.show_formspec(sender:get_player_name(), "elevator:elevator", formspec) + elseif elevator.boxes[meta:get_string("motor")] then + if not minetest.is_protected(pos, sender:get_player_name()) then + formspec = "size[4,2]" + .."label[0,0;This elevator is in use.]" + .."field[0.25,1.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]" + .."button_exit[-0.05,1.5;4,1;setlabel;Set label]" + else + formspec = "size[4,0.4]" + .."label[0,0;This elevator is in use.]" + end + minetest.show_formspec(sender:get_player_name(), "elevator:elevator", formspec) + end + end, + + on_destruct = function(pos) + local p = vector.add(pos, {x=0, y=1, z=0}) + if get_node(p).name == "elevator:placeholder" then + minetest.remove_node(p) + end + end, + }) +end + +-- Compatability with an older version. +minetest.register_alias("elevator:elevator", "elevator:elevator_off") diff --git a/crafts.lua b/crafts.lua new file mode 100644 index 0000000..5f5831a --- /dev/null +++ b/crafts.lua @@ -0,0 +1,87 @@ +-- Detect optional mods. +local technic_path = minetest.get_modpath("technic") +local chains_path = minetest.get_modpath("chains") + +if technic_path and chains_path then + minetest.register_craft({ + output = "elevator:elevator", + recipe = { + {"technic:cast_iron_ingot", "chains:chain", "technic:cast_iron_ingot"}, + {"technic:cast_iron_ingot", "default:mese_crystal", "technic:cast_iron_ingot"}, + {"technic:stainless_steel_ingot", "default:glass", "technic:stainless_steel_ingot"}, + }, + }) + + minetest.register_craft({ + output = "elevator:shaft", + recipe = { + {"technic:cast_iron_ingot", "default:glass"}, + {"default:glass", "glooptest:chainlink"}, + }, + }) + + minetest.register_craft({ + output = "elevator:motor", + recipe = { + {"default:diamond", "technic:control_logic_unit", "default:diamond"}, + {"default:steelblock", "technic:motor", "default:steelblock"}, + {"chains:chain", "default:diamond", "chains:chain"} + }, + }) +elseif technic_path and farming and farming.mod and farming.mod == "redo" then + -- add alternative recipe with hemp rope + minetest.register_craft({ + output = "elevator:elevator", + recipe = { + {"technic:cast_iron_ingot", "farming:hemp_rope", "technic:cast_iron_ingot"}, + {"technic:cast_iron_ingot", "default:mese_crystal", "technic:cast_iron_ingot"}, + {"technic:stainless_steel_ingot", "default:glass", "technic:stainless_steel_ingot"}, + }, + }) + + minetest.register_craft({ + output = "elevator:shaft", + recipe = { + {"technic:cast_iron_ingot", "default:glass"}, + {"default:glass", "farming:hemp_rope"}, + }, + }) + + minetest.register_craft({ + output = "elevator:motor", + recipe = { + {"default:diamond", "technic:control_logic_unit", "default:diamond"}, + {"default:steelblock", "technic:motor", "default:steelblock"}, + {"farming:hemp_rope", "default:diamond", "farming:hemp_rope"} + }, + }) + +-- Recipes without technic & chains required. +-- Recipes for default dependency fallback. +else + minetest.register_craft({ + output = "elevator:elevator", + recipe = { + {"default:steel_ingot", "farming:cotton", "default:steel_ingot"}, + {"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"}, + {"xpanes:pane_flat", "default:glass", "xpanes:pane_flat"}, + }, + }) + + minetest.register_craft({ + output = "elevator:shaft", + recipe = { + {"default:steel_ingot", "default:obsidian_glass"}, + {"default:obsidian_glass", "default:steel_ingot"}, + }, + }) + + minetest.register_craft({ + output = "elevator:motor", + recipe = { + {"default:diamond", "default:copper_ingot", "default:diamond"}, + {"default:steelblock", "default:furnace", "default:steelblock"}, + {"farming:cotton", "default:diamond", "farming:cotton"} + }, + }) +end diff --git a/formspecs.lua b/formspecs.lua new file mode 100644 index 0000000..64bd020 --- /dev/null +++ b/formspecs.lua @@ -0,0 +1,90 @@ + +local punhash = elevator.punhash + +minetest.register_on_player_receive_fields(function(sender, formname, fields) + if formname ~= "elevator:elevator" then + return + end + local pos = elevator.formspecs[sender:get_player_name()] and elevator.formspecs[sender:get_player_name()][1] or nil + if not pos then + return true + end + local meta = minetest.get_meta(pos) + if fields.setlabel then + if minetest.is_protected(pos, sender:get_player_name()) then + return true + end + meta:set_string("label", fields.label) + meta:set_string("infotext", fields.label) + -- Rebuild the elevator shaft so the other elevators can read this label. + local motorhash = meta:get_string("motor") + elevator.build_motor(elevator.motors[motorhash] and motorhash or elevator.locate_motor(pos)) + return true + end + -- Double check if it's ok to go. + if vector.distance(sender:getpos(), pos) > 1 then + return true + end + if fields.target then + local closeformspec = "" + -- HACK: With player information extensions enabled, we can check if closing formspecs are now allowed. This is specifically used on Survival in Ethereal. + local pi = minetest.get_player_information(sender:get_player_name()) + if (not (pi.major == 0 and pi.minor == 4 and pi.patch == 15)) and (pi.protocol_version or 29) < 29 then + closeformspec = "size[4,2] label[0,0;You are now using the elevator.\nUpgrade Minetest to avoid this dialog.] button_exit[0,1;4,1;close;Close]" + end + -- End hacky HACK. + minetest.after(0.2, minetest.show_formspec, sender:get_player_name(), "elevator:elevator", closeformspec) + -- Ensure we're connected to a motor. + local motorhash = meta:get_string("motor") + local motor = elevator.motors[motorhash] + if not motor then + motorhash = elevator.locate_motor(pos) + motor = elevator.motors[motorhash] + if motor then + meta:set_string("motor", "") + elevator.build_motor(motorhash) + minetest.chat_send_player(sender:get_player_name(), "Recalibrated to a new motor, please try again.") + return true + end + end + if not motor then + minetest.chat_send_player(sender:get_player_name(), "This elevator is not attached to a motor.") + return true + end + if not elevator.formspecs[sender:get_player_name()][2] or not elevator.formspecs[sender:get_player_name()][2][minetest.explode_textlist_event(fields.target).index] then + return true + end + -- Locate our target elevator. + local target = nil + local selected_target = elevator.formspecs[sender:get_player_name()][2][minetest.explode_textlist_event(fields.target).index] + for i,v in ipairs(motor.pnames) do + if v == selected_target then + target = punhash(motor.elevators[i]) + end + end + -- Found the elevator? Then go! + if target then + -- Final check. + if elevator.boxes[motorhash] then + minetest.chat_send_player(sender:get_player_name(), "This elevator is in use.") + return true + end + local obj = elevator.create_box(motorhash, pos, target, sender) + -- Teleport anyone standing within an on elevator out, or they'd fall through the off elevators. + for _,p in ipairs(motor.elevators) do + for _,object in ipairs(minetest.get_objects_inside_radius(punhash(p), 0.6)) do + if object.is_player and object:is_player() then + if object:get_player_name() ~= obj:get_luaentity().attached then + elevator.teleport_player_from_elevator(object) + end + end + end + end + else + minetest.chat_send_player(sender:get_player_name(), "This target is invalid.") + return true + end + return true + end + return true +end) diff --git a/helpers.lua b/helpers.lua new file mode 100644 index 0000000..ccd8ebb --- /dev/null +++ b/helpers.lua @@ -0,0 +1,38 @@ + +-- Try to teleport player away from any closed (on) elevator node. +elevator.teleport_player_from_elevator = function(player) + local function solid(pos) + if not minetest.registered_nodes[minetest.get_node(pos).name] then + return true + end + return minetest.registered_nodes[minetest.get_node(pos).name].walkable + end + local pos = vector.round(player:getpos()) + local node = minetest.get_node(pos) + -- elevator_off is like a shaft, so the player would already be falling. + if node.name == "elevator:elevator_on" then + local front = vector.subtract(pos, minetest.facedir_to_dir(node.param2)) + local front_above = vector.add(front, {x=0, y=1, z=0}) + local front_below = vector.subtract(front, {x=0, y=1, z=0}) + -- If the front isn't solid, it's ok to teleport the player. + if not solid(front) and not solid(front_above) then + player:setpos(front) + end + end +end + +elevator.phash = function(pos) + return minetest.pos_to_string(pos) +end + +elevator.punhash = function(pos) + return minetest.string_to_pos(pos) +end + +-- Helper function to read unloaded nodes. +elevator.get_node = function(pos) + local node = minetest.get_node_or_nil(pos) + if node then return node end + local _,_ = VoxelManip():read_from_map(pos, pos) + return minetest.get_node_or_nil(pos) +end diff --git a/hooks.lua b/hooks.lua index ff6d4cb..609f0e9 100644 --- a/hooks.lua +++ b/hooks.lua @@ -26,7 +26,7 @@ minetest.register_globalstep(function(dtime) local ok = r.box and r.box.getpos and r.box:getpos() and r.box:get_luaentity() and r.box:get_luaentity().attached == name if not ok then minetest.log("action", "[elevator] "..minetest.pos_to_string(r.pos).." created due to lost rider.") - minetest.after(0, create_box, r.motor, r.pos, r.target, minetest.get_player_by_name(name)) + minetest.after(0, elevator.create_box, r.motor, r.pos, r.target, minetest.get_player_by_name(name)) end end -- Ensure boxes are deleted after seconds if there are no players nearby. @@ -34,13 +34,13 @@ minetest.register_globalstep(function(dtime) if type(obj) ~= "table" then return end - elevator.lastboxes[motor] = elevator.lastboxes[motor] and math.min(elevator.lastboxes[motor], PTIMEOUT) or PTIMEOUT + elevator.lastboxes[motor] = elevator.lastboxes[motor] and math.min(elevator.lastboxes[motor], elevator.PTIMEOUT) or elevator.PTIMEOUT elevator.lastboxes[motor] = math.max(elevator.lastboxes[motor] - 1, 0) local pos = obj:getpos() if pos then for _,object in ipairs(minetest.get_objects_inside_radius(pos, 5)) do if object.is_player and object:is_player() then - elevator.lastboxes[motor] = PTIMEOUT + elevator.lastboxes[motor] = elevator.PTIMEOUT break end end diff --git a/init.lua b/init.lua index 905e5e3..b462b5b 100644 --- a/init.lua +++ b/init.lua @@ -1,43 +1,36 @@ --- Initial speed of a box. -local SPEED = 10 --- Acceleration of a box. -local ACCEL = 0.1 --- Elevator interface/database version. -local VERSION = 8 --- Maximum time a box can go without players nearby. -local PTIMEOUT = 120 - -- Detect optional mods. local armor_path = minetest.get_modpath("3d_armor") -- global runtime storage for data and references --- contains .motors loaded from mod storage and api functions +-- contains .motors loaded from mod storage +-- runtime variables and api functions elevator = { + SPEED = 10, -- Initial speed of a box. + ACCEL = 0.1, -- Acceleration of a box. + VISUAL_INCREASE = 1.75, + VERSION = 8, -- Elevator interface/database version. + PTIMEOUT = 120, -- Maximum time a box can go without players nearby. + boxes = {}, -- Elevator boxes in action. lastboxes = {}, -- Player near box timeout. riding = {}, -- Players riding boxes. + formspecs = {}, -- Player formspecs. } local MP = minetest.get_modpath(minetest.get_current_modname()) +dofile(MP .. "/helpers.lua") dofile(MP .. "/storage.lua") -dofile(MP .. "/register.lua") +dofile(MP .. "/crafts.lua") +dofile(MP .. "/components.lua") dofile(MP .. "/hooks.lua") +dofile(MP .. "/formspecs.lua") --- Player formspecs. -local formspecs = {} - --- Helper function to read unloaded nodes. -local function get_node(pos) - local node = minetest.get_node_or_nil(pos) - if node then return node end - local _,_ = VoxelManip():read_from_map(pos, pos) - return minetest.get_node_or_nil(pos) -end - -local VISUAL_INCREASE = 1.75 +local phash = elevator.phash +local punhash = elevator.punhash +local get_node = elevator.get_node -- Cause to ride beginning at and targetting . -local function create_box(motorhash, pos, target, sender) +elevator.create_box = function(motorhash, pos, target, sender) -- First create the box. local obj = minetest.add_entity(pos, "elevator:box") obj:setpos(pos) @@ -45,7 +38,7 @@ local function create_box(motorhash, pos, target, sender) sender:setpos(pos) sender:set_attach(obj, "", {x=0, y=9, z=0}, {x=0, y=0, z=0}) sender:set_eye_offset({x=0, y=-9, z=0},{x=0, y=-9, z=0}) - sender:set_properties({visual_size = {x=VISUAL_INCREASE, y=VISUAL_INCREASE}}) + sender:set_properties({visual_size = {x=elevator.VISUAL_INCREASE, y=elevator.VISUAL_INCREASE}}) if armor_path then armor:update_player_visuals(sender) end @@ -58,8 +51,8 @@ local function create_box(motorhash, pos, target, sender) obj:get_luaentity().halfway = {x=pos.x, y=(pos.y+target.y)/2, z=pos.z} obj:get_luaentity().vmult = (target.y < pos.y) and -1 or 1 -- Set the speed. - obj:setvelocity({x=0, y=SPEED*obj:get_luaentity().vmult, z=0}) - obj:setacceleration({x=0, y=ACCEL*obj:get_luaentity().vmult, z=0}) + obj:setvelocity({x=0, y=elevator.SPEED*obj:get_luaentity().vmult, z=0}) + obj:setacceleration({x=0, y=elevator.ACCEL*obj:get_luaentity().vmult, z=0}) -- Set the tables. elevator.boxes[motorhash] = obj elevator.riding[sender:get_player_name()] = { @@ -71,36 +64,6 @@ local function create_box(motorhash, pos, target, sender) return obj end --- Try to teleport player away from any closed (on) elevator node. -elevator.teleport_player_from_elevator = function(player) - local function solid(pos) - if not minetest.registered_nodes[minetest.get_node(pos).name] then - return true - end - return minetest.registered_nodes[minetest.get_node(pos).name].walkable - end - local pos = vector.round(player:getpos()) - local node = minetest.get_node(pos) - -- elevator_off is like a shaft, so the player would already be falling. - if node.name == "elevator:elevator_on" then - local front = vector.subtract(pos, minetest.facedir_to_dir(node.param2)) - local front_above = vector.add(front, {x=0, y=1, z=0}) - local front_below = vector.subtract(front, {x=0, y=1, z=0}) - -- If the front isn't solid, it's ok to teleport the player. - if not solid(front) and not solid(front_above) then - player:setpos(front) - end - end -end - -local function phash(pos) - return minetest.pos_to_string(pos) -end - -local function punhash(pos) - return minetest.string_to_pos(pos) -end - -- Starting from , locate a motor hash. elevator.locate_motor = function(pos) local p = vector.new(pos) @@ -158,7 +121,7 @@ elevator.build_motor = function(hash) for i,m in ipairs(motor.elevators) do local pos = punhash(m) local meta = minetest.get_meta(pos) - meta:set_int("version", VERSION) + meta:set_int("version", elevator.VERSION) if meta:get_string("motor") ~= hash then elevator.build_motor(meta:get_string("motor")) end @@ -213,319 +176,12 @@ elevator.unbuild = function(pos, add) end, table.copy(pos), add) end -minetest.register_node("elevator:motor", { - description = "Elevator Motor", - tiles = { - "default_steel_block.png", - "default_steel_block.png", - "elevator_motor.png", - "elevator_motor.png", - "elevator_motor.png", - "elevator_motor.png", - }, - groups = {cracky=1}, - sounds = default.node_sound_stone_defaults(), - after_place_node = function(pos, placer, itemstack) - -- Set up the motor table. - elevator.motors[phash(pos)] = { - elevators = {}, - pnames = {}, - labels = {}, - } - elevator.save_elevator() - elevator.build_motor(phash(pos)) - end, - on_destruct = function(pos) - -- Destroy everything related to this motor. - elevator.boxes[phash(pos)] = nil - elevator.motors[phash(pos)] = nil - elevator.save_elevator() - end, -}) - -for _,mode in ipairs({"on", "off"}) do - local nodename = "elevator:elevator_"..mode - local on = (mode == "on") - local box - local cbox - if on then - -- Active elevators have a ceiling and floor. - box = { - - { 0.48, -0.5,-0.5, 0.5, 1.5, 0.5}, - {-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5}, - {-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5}, - - { -0.5,-0.5,-0.5,0.5,-0.48, 0.5}, - { -0.5, 1.45,-0.5,0.5, 1.5, 0.5}, - } - cbox = table.copy(box) - -- But you can enter them from the top. - cbox[5] = nil - else - -- Inactive elevators are almost like shafts. - box = { - - { 0.48, -0.5,-0.5, 0.5, 1.5, 0.5}, - {-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5}, - {-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5}, - {-0.5 , -0.5, -0.48, 0.5, 1.5, -0.5}, - } - cbox = box - end - minetest.register_node(nodename, { - description = "Elevator", - drawtype = "nodebox", - sunlight_propagates = false, - paramtype = "light", - paramtype2 = "facedir", - on_rotate = screwdriver.disallow, - - selection_box = { - type = "fixed", - fixed = box, - }, - - collision_box = { - type = "fixed", - fixed = cbox, - }, - - node_box = { - type = "fixed", - fixed = box, - }, - - tiles = on and { - "default_steel_block.png", - "default_steel_block.png", - "elevator_box.png", - "elevator_box.png", - "elevator_box.png", - "elevator_box.png", - } or { - "elevator_box.png", - "elevator_box.png", - "elevator_box.png", - "elevator_box.png", - "elevator_box.png", - "elevator_box.png", - }, - groups = {cracky=1, choppy=1, snappy=1}, - drop = "elevator:elevator_off", - - -- Emit a bit of light when active. - light_source = (on and 4 or nil), - - after_place_node = function(pos, placer, itemstack) - local meta = minetest.get_meta(pos) - meta:set_int("version", VERSION) - - -- Add a placeholder to avoid nodes being placed in the top. - local p = vector.add(pos, {x=0, y=1, z=0}) - local p2 = minetest.dir_to_facedir(placer:get_look_dir()) - minetest.set_node(p, {name="elevator:placeholder", paramtype2="facedir", param2=p2}) - - -- Try to build a motor above. - local motor = elevator.locate_motor(pos) - if motor then - elevator.build_motor(motor) - end - end, - - after_dig_node = function(pos, node, meta, digger) - elevator.unbuild(pos, 2) - end, - - on_place = function(itemstack, placer, pointed_thing) - local pos = pointed_thing.above - local node = minetest.get_node(vector.add(pos, {x=0, y=1, z=0})) - if (node ~= nil and node.name ~= "air" and node.name ~= "elevator:placeholder") then - return - end - return minetest.item_place(itemstack, placer, pointed_thing) - end, - - on_rightclick = function(pos, node, sender) - if not sender or not sender:is_player() then - return - end - local formspec - local meta = minetest.get_meta(pos) - formspecs[sender:get_player_name()] = {pos} - if on then - if vector.distance(sender:getpos(), pos) > 1 or minetest.get_node(sender:getpos()).name ~= nodename then - minetest.chat_send_player(sender:get_player_name(), "You are not inside the booth.") - return - end - -- Build the formspec from the motor table. - local tpnames = {} - local tpnames_l = {} - local motorhash = meta:get_string("motor") - local motor = elevator.motors[motorhash] - for ji,jv in ipairs(motor.pnames) do - if tonumber(jv) ~= pos.y then - table.insert(tpnames, jv) - table.insert(tpnames_l, (motor.labels[ji] and motor.labels[ji] ~= "") and (jv.." - "..minetest.formspec_escape(motor.labels[ji])) or jv) - end - end - formspecs[sender:get_player_name()] = {pos, tpnames} - if #tpnames > 0 then - if not minetest.is_protected(pos, sender:get_player_name()) then - formspec = "size[4,6]" - .."label[0,0;Click once to travel.]" - .."textlist[-0.1,0.5;4,4;target;"..table.concat(tpnames_l, ",").."]" - .."field[0.25,5.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]" - .."button_exit[-0.05,5.5;4,1;setlabel;Set label]" - else - formspec = "size[4,4.4]" - .."label[0,0;Click once to travel.]" - .."textlist[-0.1,0.5;4,4;target;"..table.concat(tpnames_l, ",").."]" - end - else - if not minetest.is_protected(pos, sender:get_player_name()) then - formspec = "size[4,2]" - .."label[0,0;No targets available.]" - .."field[0.25,1.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]" - .."button_exit[-0.05,1.5;4,1;setlabel;Set label]" - else - formspec = "size[4,0.4]" - .."label[0,0;No targets available.]" - end - end - minetest.show_formspec(sender:get_player_name(), "elevator:elevator", formspec) - elseif not elevator.motors[meta:get_string("motor")] then - if not minetest.is_protected(pos, sender:get_player_name()) then - formspec = "size[4,2]" - .."label[0,0;This elevator is inactive.]" - .."field[0.25,1.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]" - .."button_exit[-0.05,1.5;4,1;setlabel;Set label]" - else - formspec = "size[4,0.4]" - .."label[0,0;This elevator is inactive.]" - end - minetest.show_formspec(sender:get_player_name(), "elevator:elevator", formspec) - elseif elevator.boxes[meta:get_string("motor")] then - if not minetest.is_protected(pos, sender:get_player_name()) then - formspec = "size[4,2]" - .."label[0,0;This elevator is in use.]" - .."field[0.25,1.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]" - .."button_exit[-0.05,1.5;4,1;setlabel;Set label]" - else - formspec = "size[4,0.4]" - .."label[0,0;This elevator is in use.]" - end - minetest.show_formspec(sender:get_player_name(), "elevator:elevator", formspec) - end - end, - - on_destruct = function(pos) - local p = vector.add(pos, {x=0, y=1, z=0}) - if get_node(p).name == "elevator:placeholder" then - minetest.remove_node(p) - end - end, - }) -end - -minetest.register_on_player_receive_fields(function(sender, formname, fields) - if formname ~= "elevator:elevator" then - return - end - local pos = formspecs[sender:get_player_name()] and formspecs[sender:get_player_name()][1] or nil - if not pos then - return true - end - local meta = minetest.get_meta(pos) - if fields.setlabel then - if minetest.is_protected(pos, sender:get_player_name()) then - return true - end - meta:set_string("label", fields.label) - meta:set_string("infotext", fields.label) - -- Rebuild the elevator shaft so the other elevators can read this label. - local motorhash = meta:get_string("motor") - elevator.build_motor(elevator.motors[motorhash] and motorhash or elevator.locate_motor(pos)) - return true - end - -- Double check if it's ok to go. - if vector.distance(sender:getpos(), pos) > 1 then - return true - end - if fields.target then - local closeformspec = "" - -- HACK: With player information extensions enabled, we can check if closing formspecs are now allowed. This is specifically used on Survival in Ethereal. - local pi = minetest.get_player_information(sender:get_player_name()) - if (not (pi.major == 0 and pi.minor == 4 and pi.patch == 15)) and (pi.protocol_version or 29) < 29 then - closeformspec = "size[4,2] label[0,0;You are now using the elevator.\nUpgrade Minetest to avoid this dialog.] button_exit[0,1;4,1;close;Close]" - end - -- End hacky HACK. - minetest.after(0.2, minetest.show_formspec, sender:get_player_name(), "elevator:elevator", closeformspec) - -- Ensure we're connected to a motor. - local motorhash = meta:get_string("motor") - local motor = elevator.motors[motorhash] - if not motor then - motorhash = elevator.locate_motor(pos) - motor = elevator.motors[motorhash] - if motor then - meta:set_string("motor", "") - elevator.build_motor(motorhash) - minetest.chat_send_player(sender:get_player_name(), "Recalibrated to a new motor, please try again.") - return true - end - end - if not motor then - minetest.chat_send_player(sender:get_player_name(), "This elevator is not attached to a motor.") - return true - end - if not formspecs[sender:get_player_name()][2] or not formspecs[sender:get_player_name()][2][minetest.explode_textlist_event(fields.target).index] then - return true - end - -- Locate our target elevator. - local target = nil - local selected_target = formspecs[sender:get_player_name()][2][minetest.explode_textlist_event(fields.target).index] - for i,v in ipairs(motor.pnames) do - if v == selected_target then - target = punhash(motor.elevators[i]) - end - end - -- Found the elevator? Then go! - if target then - -- Final check. - if elevator.boxes[motorhash] then - minetest.chat_send_player(sender:get_player_name(), "This elevator is in use.") - return true - end - local obj = create_box(motorhash, pos, target, sender) - -- Teleport anyone standing within an on elevator out, or they'd fall through the off elevators. - for _,p in ipairs(motor.elevators) do - local p = punhash(p) - for _,object in ipairs(minetest.get_objects_inside_radius(p, 0.6)) do - if object.is_player and object:is_player() then - if object:get_player_name() ~= obj:get_luaentity().attached then - elevator.teleport_player_from_elevator(object) - end - end - end - end - else - minetest.chat_send_player(sender:get_player_name(), "This target is invalid.") - return true - end - return true - end - return true -end) - --- Compatability with an older version. -minetest.register_alias("elevator:elevator", "elevator:elevator_off") - -- Ensure an elevator is up to the latest version. local function upgrade_elevator(pos, meta) - if meta:get_int("version") ~= VERSION then + if meta:get_int("version") ~= elevator.VERSION then minetest.log("action", "[elevator] Updating elevator with old version at "..minetest.pos_to_string(pos)) minetest.after(0, function(pos) elevator.build_motor(elevator.locate_motor(pos)) end, pos) - meta:set_int("version", VERSION) + meta:set_int("version", elevator.VERSION) meta:set_string("formspec", "") meta:set_string("infotext", meta:get_string("label")) end diff --git a/register.lua b/register.lua deleted file mode 100644 index af8048b..0000000 --- a/register.lua +++ /dev/null @@ -1,201 +0,0 @@ --- Detect optional mods. -local technic_path = minetest.get_modpath("technic") -local chains_path = minetest.get_modpath("chains") -local technic_path = minetest.get_modpath("technic") -local chains_path = minetest.get_modpath("chains") -local homedecor_path = minetest.get_modpath("homedecor") - --- Use homedecor's placeholder if possible. -if homedecor_path then - minetest.register_alias("elevator:placeholder", "homedecor:expansion_placeholder") -else - -- Placeholder node, in the style of homedecor. - minetest.register_node("elevator:placeholder", { - description = "Expansion Placeholder", - selection_box = { - type = "fixed", - fixed = {0, 0, 0, 0, 0, 0}, - }, - groups = { - not_in_creative_inventory=1 - }, - drawtype = "airlike", - paramtype = "light", - sunlight_propagates = true, - - walkable = false, - buildable_to = false, - is_ground_content = false, - - on_dig = function(pos, node, player) - minetest.remove_node(pos) - minetest.set_node(pos, {name="elevator:placeholder"}) - end - }) -end - -if technic_path and chains_path then - minetest.register_craft({ - output = "elevator:elevator", - recipe = { - {"technic:cast_iron_ingot", "chains:chain", "technic:cast_iron_ingot"}, - {"technic:cast_iron_ingot", "default:mese_crystal", "technic:cast_iron_ingot"}, - {"technic:stainless_steel_ingot", "default:glass", "technic:stainless_steel_ingot"}, - }, - }) - - minetest.register_craft({ - output = "elevator:shaft", - recipe = { - {"technic:cast_iron_ingot", "default:glass"}, - {"default:glass", "glooptest:chainlink"}, - }, - }) - - minetest.register_craft({ - output = "elevator:motor", - recipe = { - {"default:diamond", "technic:control_logic_unit", "default:diamond"}, - {"default:steelblock", "technic:motor", "default:steelblock"}, - {"chains:chain", "default:diamond", "chains:chain"} - }, - }) -elseif technic_path and farming and farming.mod and farming.mod == "redo" then - -- add alternative recipe with hemp rope - minetest.register_craft({ - output = "elevator:elevator", - recipe = { - {"technic:cast_iron_ingot", "farming:hemp_rope", "technic:cast_iron_ingot"}, - {"technic:cast_iron_ingot", "default:mese_crystal", "technic:cast_iron_ingot"}, - {"technic:stainless_steel_ingot", "default:glass", "technic:stainless_steel_ingot"}, - }, - }) - - minetest.register_craft({ - output = "elevator:shaft", - recipe = { - {"technic:cast_iron_ingot", "default:glass"}, - {"default:glass", "farming:hemp_rope"}, - }, - }) - - minetest.register_craft({ - output = "elevator:motor", - recipe = { - {"default:diamond", "technic:control_logic_unit", "default:diamond"}, - {"default:steelblock", "technic:motor", "default:steelblock"}, - {"farming:hemp_rope", "default:diamond", "farming:hemp_rope"} - }, - }) - --- Recipes without technic & chains required. --- Recipes for default dependency fallback. -else - minetest.register_craft({ - output = "elevator:elevator", - recipe = { - {"default:steel_ingot", "farming:cotton", "default:steel_ingot"}, - {"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"}, - {"xpanes:pane_flat", "default:glass", "xpanes:pane_flat"}, - }, - }) - - minetest.register_craft({ - output = "elevator:shaft", - recipe = { - {"default:steel_ingot", "default:obsidian_glass"}, - {"default:obsidian_glass", "default:steel_ingot"}, - }, - }) - - minetest.register_craft({ - output = "elevator:motor", - recipe = { - {"default:diamond", "default:copper_ingot", "default:diamond"}, - {"default:steelblock", "default:furnace", "default:steelblock"}, - {"farming:cotton", "default:diamond", "farming:cotton"} - }, - }) -end - -minetest.register_node("elevator:shaft", { - description = "Elevator Shaft", - tiles = { "elevator_shaft.png" }, - drawtype = "nodebox", - paramtype = "light", - on_rotate = screwdriver.disallow, - sunlight_propagates = true, - groups = {cracky=2, oddly_breakable_by_hand=1}, - sounds = default.node_sound_stone_defaults(), - node_box = { - type = "fixed", - fixed = { - {-8/16,-8/16,-8/16,-7/16,8/16,8/16}, - {7/16,-8/16,-8/16,8/16,8/16,8/16}, - {-7/16,-8/16,-8/16,7/16,8/16,-7/16}, - {-7/16,-8/16,8/16,7/16,8/16,7/16}, - }, - }, - collisionbox = { - type = "fixed", - fixed = { - {-8/16,-8/16,-8/16,-7/16,8/16,8/16}, - {7/16,-8/16,-8/16,8/16,8/16,8/16}, - {-7/16,-8/16,-8/16,7/16,8/16,-7/16}, - {-7/16,-8/16,8/16,7/16,8/16,7/16}, - }, - }, - after_place_node = function(pos) - -- We might have connected a motor above to an elevator below. - elevator.build_motor(elevator.locate_motor(pos)) - end, - on_destruct = function(pos) - -- Remove boxes and deactivate elevators below us. - elevator.unbuild(pos, 1) - end, -}) - -local box = { - { 0.48, -0.5,-0.5, 0.5, 1.5, 0.5}, - {-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5}, - {-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5}, - {-0.5 , -0.5, -0.48, 0.5, 1.5, -0.5}, - { -0.5,-0.5,-0.5,0.5,-0.48, 0.5}, - { -0.5, 1.45,-0.5,0.5, 1.5, 0.5}, -} - --- Elevator box node. Not intended to be placeable. -minetest.register_node("elevator:elevator_box", { - description = "Elevator", - drawtype = "nodebox", - paramtype = 'light', - paramtype2 = "facedir", - wield_scale = {x=0.6, y=0.6, z=0.6}, - - selection_box = { - type = "fixed", - fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 } - }, - - collision_box = { - type = "fixed", - fixed = box, - }, - - node_box = { - type = "fixed", - fixed = box, - }, - - tiles = { - "default_steel_block.png", - "default_steel_block.png", - "elevator_box.png", - "elevator_box.png", - "elevator_box.png", - "elevator_box.png", - }, - groups = {not_in_creative_inventory = 1}, - - light_source = 4, -}) -- cgit v1.2.3 From 13f7c692cbddb53618e904170c6ac1d6762cfa4f Mon Sep 17 00:00:00 2001 From: SX Date: Fri, 14 Feb 2020 02:30:20 +0200 Subject: Added linter --- .github/workflows/luacheck.yml | 17 +++++++++++++++++ .luacheckrc | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 .github/workflows/luacheck.yml create mode 100644 .luacheckrc diff --git a/.github/workflows/luacheck.yml b/.github/workflows/luacheck.yml new file mode 100644 index 0000000..a03fe92 --- /dev/null +++ b/.github/workflows/luacheck.yml @@ -0,0 +1,17 @@ +name: luacheck + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: apt + run: sudo apt-get install -y luarocks + - name: luacheck install + run: luarocks install --local luacheck + - name: luacheck run + run: $HOME/.luarocks/bin/luacheck ./ diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..db7f279 --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,24 @@ +unused_args = false + +ignore = { + "631", +} + +globals = { + "elevator", +} + +read_globals = { + -- Stdlib + string = {fields = {"split"}}, + table = {fields = {"copy", "getn"}}, + + -- Minetest + "minetest", + "vector", + "VoxelManip", + + -- deps + "default", "screwdriver", + "farming", "armor", +} -- cgit v1.2.3