aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSX <sx@minetest>2020-02-13 22:23:06 +0200
committerSX <sx@minetest>2020-02-13 22:23:06 +0200
commit469b50633862b4838e4304750ef01195fd9850e8 (patch)
tree7477a33b10cb3e1264b33d77ef85be8064852c1e
parent62d6d4d5aeced03397f88acaaccabc5e2a469735 (diff)
downloadelevator-469b50633862b4838e4304750ef01195fd9850e8.tar.gz
elevator-469b50633862b4838e4304750ef01195fd9850e8.tar.bz2
elevator-469b50633862b4838e4304750ef01195fd9850e8.zip
Refactoring hooks, storage, register
-rw-r--r--hooks.lua61
-rw-r--r--init.lua231
-rw-r--r--register.lua82
-rw-r--r--storage.lua4
4 files changed, 189 insertions, 189 deletions
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 <PTIMEOUT> 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 <PTIMEOUT> 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 <pos>, 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