summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README54
-rw-r--r--car_metalglass.lua416
-rw-r--r--controller.lua12
-rw-r--r--controllerfw.lua51
-rw-r--r--crafts.lua12
-rw-r--r--dispatcher.lua6
-rw-r--r--dispatcherfw.lua23
-rw-r--r--docs/README2
-rw-r--r--docs/celevator_controller_manual.pdfbin2193128 -> 2192852 bytes
-rw-r--r--init.lua1
-rw-r--r--laptop.lua24
-rw-r--r--screenshot.pngbin0 -> 236634 bytes
-rw-r--r--textures/celevator_car_metal_glassback_inventory.pngbin0 -> 535 bytes
-rw-r--r--textures/celevator_car_metal_glassback_wield.pngbin0 -> 423 bytes
-rw-r--r--textures/celevator_door_glass_inventory.pngbin573 -> 244 bytes
15 files changed, 591 insertions, 10 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..a4a8104
--- /dev/null
+++ b/README
@@ -0,0 +1,54 @@
+celevator
+Fully functional realistic elevators for Luanti/Minetest (5.7+)
+===============================================================
+
+Description
+-----------
+
+Adds fully functional, realistic elevators capable of moving players between multiple floors in a building.
+
+Features include:
+
+ 2 to 100 floors with customizable names
+ Travel speed adjustable for each elevator independently, up to 20m/s (more than 7.5m/s not recommended in multiplayer)
+ Can travel through loaded or unloaded mapblocks
+ Full selective-collective operation
+ Group dispatching with up to 16 cars in a group and true ETA dispatching
+ Optional destination-based dispatching
+ Swing car operation
+ Animated doors, hoist machine, and tapehead
+ Controller interface with diagnostic LEDs, display, and GUI configuration
+ Optional car call security settings (require area access to place a car call, or disallow car calls to a specific floor entirely)
+ Functional independent service and fire service phase I and II (approximately following ASME A17.1 codes) modes
+ Car top and machine room inspection operation with adjustable speed
+ Adjustable door dwell and nudging timers
+ mView remote monitoring software (optional, available if "laptop" mod is installed)
+ Mesecons input and output modules (optional, available if "mesecons" mod is installed)
+ Communication with Luacontrollers via digilines input/output modules (optional, available if "digilines" mod is installed)
+
+Documentation
+-------------
+
+Documentation is located in the "docs" subdirectory.
+See "docs/celevator_controller_manual.pdf" for full installation and setup instructions.
+
+Contributing
+------------
+
+If you would like to contribute code, the easiest way is to publish your changes somewhere and request that I pull them.
+I can be reached on Libera.Chat in #luanti as "cheapie", or you can contact me via ContentDB or the Luanti forums (same username).
+If you don't have anywhere to publish your changes, I can also accept patches.
+
+Reporting Issues
+----------------
+
+See the previous "Contributing" section for contact information.
+You are encouraged to report any issues you have to me using any of those contact methods.
+If you just have a question or you're not sure if something is a bug, IRC is probably the easiest method.
+
+License
+-------
+
+This software is offered under The Unlicense.
+See the LICENSE file for the full license text.
+If you do use this code for something I'd love to hear what it is, but you're not required to tell me.
diff --git a/car_metalglass.lua b/car_metalglass.lua
new file mode 100644
index 0000000..432babf
--- /dev/null
+++ b/car_metalglass.lua
@@ -0,0 +1,416 @@
+local pieces = {
+ {
+ _position = "000",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.6,-0.5,0.5,-0.5,0.5},
+ {-0.5,-0.5,-0.5,-0.45,0.5,0.5},
+ {-0.5,-1.5,-0.5,0.5,-0.6,-0.45},
+ },
+ },
+ tiles = {
+ "celevator_car_metal_floor.png^celevator_door_sill_single.png",
+ "celevator_car_bottom.png",
+ "celevator_car_metal.png^celevator_car_wall_bottom.png^celevator_car_switch_panel.png",
+ "celevator_cabinet_sides.png^celevator_car_side_overlay.png^[transformR90",
+ "celevator_cabinet_sides.png",
+ },
+ _keyswitches = true,
+ },
+ {
+ _position = "001",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.6,-0.5,0.5,-0.5,0.5},
+ {-0.5,-0.5,-0.5,-0.45,0.5,0.5},
+ },
+ },
+ tiles = {
+ "celevator_car_metal_floor.png",
+ "celevator_car_bottom_center.png",
+ "celevator_car_metal.png^celevator_car_wall_bottom.png^celevator_car_wall_vent.png",
+ "celevator_cabinet_sides.png^celevator_car_side_center_overlay.png",
+ "celevator_cabinet_sides.png",
+ },
+ },
+ {
+ _position = "002",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.6,-0.5,0.5,-0.5,0.5},
+ {-0.5,-0.5,-0.5,-0.45,0.5,0.5},
+ {-0.45,-0.5,0.45,0.5,0.5,0.5},
+ },
+ },
+ use_texture_alpha = "clip",
+ tiles = {
+ "celevator_car_metal_floor.png",
+ "celevator_car_bottom.png",
+ "celevator_car_metal.png^celevator_car_wall_bottom.png",
+ "celevator_cabinet_sides.png^celevator_car_side_overlay.png",
+ "celevator_car_glass.png",
+ "celevator_car_glass.png^celevator_car_wall_bottom.png",
+ },
+ },
+ {
+ _position = "100",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.6,-0.5,0.5,-0.5,0.5},
+ {0.45,-0.5,-0.5,0.5,0.5,0.5},
+ {-0.5,-1.5,-0.5,0.5,-0.6,-0.45},
+ },
+ },
+ tiles = {
+ "celevator_car_metal_floor.png^celevator_door_sill_double.png",
+ "celevator_car_bottom.png",
+ "celevator_cabinet_sides.png^celevator_car_side_overlay.png",
+ "celevator_car_metal.png^celevator_car_wall_bottom.png",
+ "celevator_cabinet_sides.png",
+ },
+ },
+ {
+ _position = "101",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.6,-0.5,0.5,-0.5,0.5},
+ {0.45,-0.5,-0.5,0.5,0.5,0.5},
+ },
+ },
+ tiles = {
+ "celevator_car_metal_floor.png",
+ "celevator_car_bottom_center.png^[transformFX",
+ "celevator_cabinet_sides.png^celevator_car_side_center_overlay.png",
+ "celevator_car_metal.png^celevator_car_wall_bottom.png^celevator_car_wall_vent.png",
+ "celevator_cabinet_sides.png",
+ },
+ },
+ {
+ _position = "102",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.6,-0.5,0.5,-0.5,0.5},
+ {0.45,-0.5,-0.5,0.5,0.5,0.5},
+ {-0.5,-0.5,0.45,0.45,0.5,0.5},
+ },
+ },
+ use_texture_alpha = "clip",
+ tiles = {
+ "celevator_car_metal_floor.png",
+ "celevator_car_bottom.png",
+ "celevator_cabinet_sides.png^celevator_car_side_overlay.png^[transformR90",
+ "celevator_car_metal.png^celevator_car_wall_bottom.png",
+ "celevator_car_glass.png",
+ "celevator_car_glass.png^celevator_car_wall_bottom.png",
+ },
+ },
+ {
+ _position = "010",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,-0.5,-0.45,0.5,0.5},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_metal_2x.png^celevator_cop.png",
+ "celevator_cabinet_sides.png",
+ },
+ _cop = true,
+ },
+ {
+ _position = "011",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,-0.5,-0.45,0.5,0.5},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_metal.png^celevator_car_handrail_end.png",
+ "celevator_cabinet_sides.png^celevator_car_side_center2_overlay.png",
+ "celevator_cabinet_sides.png",
+ },
+ },
+ {
+ _position = "012",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,-0.5,-0.45,0.5,0.5},
+ {-0.45,-0.5,0.45,0.5,0.5,0.5},
+ },
+ },
+ use_texture_alpha = "clip",
+ tiles = {
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_metal.png^(celevator_car_handrail_end.png^[transformFX)",
+ "celevator_cabinet_sides.png",
+ "celevator_car_glass.png",
+ "celevator_car_glass.png",
+ },
+ },
+ {
+ _position = "110",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {0.45,-0.5,-0.5,0.5,0.5,0.5},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_metal.png^(celevator_car_handrail_end.png^[transformFX)",
+ "celevator_cabinet_sides.png",
+ },
+ },
+ {
+ _position = "111",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {0.45,-0.5,-0.5,0.5,0.5,0.5},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png^celevator_car_side_center2_overlay.png",
+ "celevator_car_metal.png^celevator_car_handrail_center.png",
+ "celevator_cabinet_sides.png",
+ },
+ },
+ {
+ _position = "112",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {0.45,-0.5,-0.5,0.5,0.5,0.5},
+ {-0.5,-0.5,0.45,0.45,0.5,0.5},
+ },
+ },
+ use_texture_alpha = "clip",
+ tiles = {
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_metal.png^celevator_car_handrail_end.png",
+ "celevator_car_glass.png",
+ "celevator_car_glass.png",
+ },
+ },
+ {
+ _position = "020",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,0.5,-0.5,0.5,0.6,0.5},
+ {-0.5,-0.5,-0.5,-0.45,0.5,0.5},
+ {-0.5,0.6,-0.4,0.5,1,-0.1},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png",
+ "celevator_car_metal_ceiling.png",
+ "celevator_car_metal_top.png",
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_dooroperator_left.png",
+ },
+ _pi = true,
+ },
+ {
+ _position = "021",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,0.5,-0.5,0.5,0.6,0.5},
+ {-0.5,-0.5,-0.5,-0.45,0.5,0.5},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png^celevator_car_top_center_overlay.png",
+ "celevator_car_metal_ceiling.png",
+ "celevator_car_metal_top.png",
+ "celevator_cabinet_sides.png^celevator_car_side_center_overlay.png",
+ "celevator_cabinet_sides.png",
+ },
+ _cartopbox = true,
+ },
+ {
+ _position = "022",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,0.5,-0.5,0.5,0.6,0.5},
+ {-0.5,-0.5,-0.5,-0.45,0.5,0.5},
+ {-0.45,-0.5,0.45,0.5,0.5,0.5},
+ },
+ },
+ use_texture_alpha = "clip",
+ tiles = {
+ "celevator_cabinet_sides.png^celevator_car_top_hatch.png",
+ "celevator_car_metal_ceiling.png",
+ "celevator_car_metal_top.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_glass.png",
+ "celevator_car_glass.png",
+ },
+ },
+ {
+ _position = "120",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,0.5,-0.5,0.5,0.6,0.5},
+ {0.45,-0.5,-0.5,0.5,0.5,0.5},
+ {-0.5,0.6,-0.4,0.5,1,-0.1},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png",
+ "celevator_car_metal_ceiling.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_metal_top.png",
+ "celevator_cabinet_sides.png",
+ "celevator_dooroperator_right.png",
+ },
+ },
+ {
+ _position = "121",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,0.5,-0.5,0.5,0.6,0.5},
+ {0.45,-0.5,-0.5,0.5,0.5,0.5},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png^celevator_car_top_center_overlay.png^[transformFX",
+ "celevator_car_metal_ceiling.png",
+ "celevator_cabinet_sides.png^celevator_car_side_center_overlay.png",
+ "celevator_car_metal_top.png",
+ "celevator_cabinet_sides.png",
+ },
+ },
+ {
+ _position = "122",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,0.5,-0.5,0.5,0.6,0.5},
+ {0.45,-0.5,-0.5,0.5,0.5,0.5},
+ {-0.5,-0.5,0.45,0.45,0.5,0.5},
+ },
+ },
+ use_texture_alpha = "clip",
+ tiles = {
+ "celevator_cabinet_sides.png^celevator_car_top_misc.png",
+ "celevator_car_metal_ceiling.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_metal_top.png",
+ "celevator_car_glass.png",
+ "celevator_car_glass.png",
+ },
+ _tapehead = true,
+ },
+}
+
+celevator.car.register("metal_glassback",pieces,vector.new(2,3,3))
+
+
+minetest.register_node("celevator:car_metal_glassback",{
+ description = "Metal Glass-Back Elevator Car",
+ paramtype2 = "4dir",
+ buildable_to = true,
+ inventory_image = "celevator_car_metal_glassback_inventory.png",
+ wield_image = "celevator_car_metal_glassback_wield.png",
+ wield_scale = vector.new(1,1,10),
+ tiles = {"celevator_transparent.png"},
+ after_place_node = function(pos,player)
+ if not player:is_player() then
+ minetest.remove_node(pos)
+ return true
+ end
+ local name = player:get_player_name()
+ local newnode = minetest.get_node(pos)
+ local facedir = minetest.dir_to_yaw(minetest.fourdir_to_dir(newnode.param2))
+ for x=0,1,1 do
+ for y=0,2,1 do
+ for z=0,2,1 do
+ local offsetdesc = string.format("%dm to the right, %dm up, and %dm back",x,y,z)
+ local placeoffset = vector.new(x,y,z)
+ local placepos = vector.add(pos,vector.rotate_around_axis(placeoffset,vector.new(0,1,0),facedir))
+ local replaces = minetest.get_node(placepos).name
+ if not (minetest.registered_nodes[replaces] and minetest.registered_nodes[replaces].buildable_to) then
+ minetest.chat_send_player(name,string.format("Can't place car here - position %s is blocked!",offsetdesc))
+ minetest.remove_node(pos)
+ return true
+ end
+ if minetest.is_protected(placepos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
+ minetest.chat_send_player(name,string.format("Can't place car here - position %s is protected!",offsetdesc))
+ minetest.record_protection_violation(placepos,name)
+ minetest.remove_node(pos)
+ return true
+ end
+ end
+ end
+ end
+ for x=0,1,1 do
+ for y=0,2,1 do
+ for z=0,2,1 do
+ local piecename = string.format("celevator:car_metal_glassback_%d%d%d",x,y,z)
+ local placeoffset = vector.new(x,y,z)
+ local placepos = vector.add(pos,vector.rotate_around_axis(placeoffset,vector.new(0,1,0),facedir))
+ minetest.set_node(placepos,{name=piecename,param2=newnode.param2})
+ end
+ end
+ end
+ end,
+})
+
+celevator.car.types.metal_glassback.remove = function(rootpos,rootdir)
+ local toberemoved = {
+ ["celevator:car_top_box"] = true,
+ ["celevator:incar_pi_entity"] = true,
+ ["celevator:car_door"] = true,
+ }
+ for x=0,1,1 do
+ for y=0,2,1 do
+ for z=0,2,1 do
+ local piecename = string.format("celevator:car_metal_glassback_%d%d%d",x,y,z)
+ local pieceoffset = vector.new(x,y,z)
+ local piecepos = vector.add(rootpos,vector.rotate_around_axis(pieceoffset,vector.new(0,1,0),rootdir))
+ if minetest.get_node(piecepos).name == piecename then
+ minetest.remove_node(piecepos)
+ local erefs = minetest.get_objects_inside_radius(piecepos,0.5)
+ for _,ref in pairs(erefs) do
+ if ref:get_luaentity() and toberemoved[ref:get_luaentity().name] then
+ ref:remove()
+ end
+ end
+ end
+ end
+ end
+ end
+ local cartopboxpos = vector.add(rootpos,vector.rotate_around_axis(vector.new(0,3,1),vector.new(0,1,0),rootdir))
+ local erefs = minetest.get_objects_inside_radius(cartopboxpos,0.5)
+ for _,ref in pairs(erefs) do
+ if ref:get_luaentity() and toberemoved[ref:get_luaentity().name] then
+ ref:remove()
+ end
+ end
+end
diff --git a/controller.lua b/controller.lua
index cbe9ab3..2921f81 100644
--- a/controller.lua
+++ b/controller.lua
@@ -454,6 +454,12 @@ function celevator.controller.finish(pos,mem,changedinterrupts)
local olddownbuttonlights = oldmem.dncalls or {}
local newupbuttonlights = mem.upcalls or {}
local newdownbuttonlights = mem.dncalls or {}
+ if mem.params and mem.params.groupmode == "group" then
+ oldupbuttonlights = oldmem.swingupcalls
+ olddownbuttonlights = oldmem.swingdncalls
+ newupbuttonlights = mem.swingupcalls
+ newdownbuttonlights = mem.swingdncalls
+ end
local callbuttons = carinfo.callbuttons
for _,button in pairs(callbuttons) do
if oldupbuttonlights[button.landing] ~= newupbuttonlights[button.landing] then
@@ -639,7 +645,9 @@ end
function celevator.controller.checkiqueue(dtime)
for hash,iqueue in pairs(celevator.controller.iqueue) do
local pos = minetest.get_position_from_hash(hash)
+ local noneleft = true
for iid,time in pairs(iqueue) do
+ noneleft = false
iqueue[iid] = time-dtime
if iqueue[iid] < 0 then
iqueue[iid] = nil
@@ -649,6 +657,10 @@ function celevator.controller.checkiqueue(dtime)
celevator.controller.run(pos,event)
end
end
+ if noneleft then
+ celevator.controller.iqueue[hash] = nil
+ celevator.storage:set_string("controller_iqueue",minetest.serialize(celevator.controller.iqueue))
+ end
end
end
diff --git a/controllerfw.lua b/controllerfw.lua
index 5abb165..1850a1e 100644
--- a/controllerfw.lua
+++ b/controllerfw.lua
@@ -97,7 +97,7 @@ local function getpos(pioffset)
ret = ret+v
if ret > searchpos then return k end
end
- return mem.params.floorheights[#mem.params.floorheights]
+ return #mem.params.floorheights
end
local function gettarget(floor)
@@ -232,8 +232,27 @@ if mem.params and not mem.recallto then mem.recallto = mem.params.mainlanding or
if mem.params and not mem.params.inspectionspeed then mem.params.inspectionspeed = 0.2 end
if mem.params and not mem.params.indepunlock then mem.params.indepunlock = {} end
if mem.params and not mem.params.secoverrideusers then mem.params.secoverrideusers = {} end
+if mem.params and mem.params.swingcallwhennotswing == nil then mem.params.swingcallwhennotswing = true end
if not mem.editinguser then mem.editinguser = 1 end
+if mem.params and #mem.params.floornames < 2 then
+ mem.params.floornames = {"1","2","3"}
+ mem.params.floorheights = {5,5,5}
+ mem.carstate = "bfdemand"
+ if mem.doorstate == "closed" then
+ drivecmd({
+ command = "setmaxvel",
+ maxvel = mem.params.contractspeed,
+ })
+ drivecmd({command = "resetpos"})
+ interrupt(0.1,"checkdrive")
+ mem.carmotion = true
+ juststarted = true
+ else
+ close()
+ end
+end
+
if event.type == "program" then
mem.carstate = "uninit"
mem.editingfloor = 1
@@ -279,6 +298,7 @@ if event.type == "program" then
inspectionspeed = 0.2,
indepunlock = {},
secoverrideusers = {},
+ swingcallwhennotswing = true,
}
end
elseif event.type == "ui" then
@@ -342,7 +362,7 @@ elseif event.type == "ui" then
elseif event.fields.add then
table.insert(mem.params.floorheights,5)
table.insert(mem.params.floornames,tostring(#mem.params.floornames+1))
- elseif event.fields.remove then
+ elseif event.fields.remove and #mem.params.floornames > 2 then
table.remove(mem.params.floorheights,mem.editingfloor)
table.remove(mem.params.floornames,mem.editingfloor)
mem.editingfloor = math.max(1,mem.editingfloor-1)
@@ -508,6 +528,9 @@ elseif event.type == "ui" then
if event.fields.indepunlock then
mem.params.indepunlock[mem.editingfloor] = (event.fields.indepunlock == "true")
end
+ if event.fields.swingcallwhennotswing then
+ mem.params.swingcallwhennotswing = (event.fields.swingcallwhennotswing == "true")
+ end
if event.fields.save then
mem.screenstate = "parameters"
elseif event.fields.floor then
@@ -585,7 +608,7 @@ elseif event.iid == "closed" and (mem.doorstate == "closing" or mem.doorstate ==
end
elseif event.type == "callbutton" and (mem.carstate == "normal" or mem.carstate == "swing") then
if mem.doorstate == "closed" or mem.direction ~= event.dir or getpos() ~= event.landing then
- if mem.params.groupmode == "group" then
+ if mem.params.groupmode == "group" and not (mem.carstate == "normal" and not mem.params.swingcallwhennotswing) then
if event.dir == "up" and event.landing >= 1 and event.landing < #mem.params.floornames then
mem.swingupcalls[event.landing] = true
elseif event.dir == "down" and event.landing > 1 and event.landing <= #mem.params.floornames then
@@ -755,6 +778,12 @@ elseif event.type == "cartopbox" then
})
end
elseif event.type == "dispatchermsg" then
+ local swingstateok = false
+ if mem.carstate == "normal" then
+ swingstateok = mem.params.swingcallwhennotswing
+ elseif mem.carstate == "swing" then
+ swingstateok = true
+ end
if event.channel == "pairrequest" and mem.screenstate == "oobe_dispatcherconnect" then
mem.params.floornames = event.msg.floornames
mem.params.floorheights = event.msg.floorheights
@@ -804,9 +833,9 @@ elseif event.type == "dispatchermsg" then
mem.groupupcalls[event.msg] = nil
elseif event.channel == "groupdncancel" then
mem.groupdncalls[event.msg] = nil
- elseif event.channel == "swingupcall" and (mem.carstate == "normal" or mem.carstate == "swing") then
+ elseif event.channel == "swingupcall" and swingstateok then
mem.swingupcalls[event.msg] = true
- elseif event.channel == "swingdncall" and (mem.carstate == "normal" or mem.carstate == "swing") then
+ elseif event.channel == "swingdncall" and swingstateok then
mem.swingdncalls[event.msg] = true
elseif event.channel == "carcall" and (mem.carstate == "normal" or mem.carstate == "swing") then
mem.carcalls[event.msg] = true
@@ -820,13 +849,19 @@ elseif event.type == "dispatchermsg" then
if not event.msg then mem.flashfirehat = false end
end
elseif event.type == "remotemsg" then
+ local swingstateok = false
+ if mem.carstate == "normal" then
+ swingstateok = mem.params.swingcallwhennotswing
+ elseif mem.carstate == "swing" then
+ swingstateok = true
+ end
if event.channel == "groupupcall" and mem.carstate == "normal" then
mem.groupupcalls[event.msg] = true
elseif event.channel == "groupdncall" and mem.carstate == "normal" then
mem.groupdncalls[event.msg] = true
- elseif event.channel == "swingupcall" and (mem.carstate == "normal" or mem.carstate == "swing") then
+ elseif event.channel == "swingupcall" and swingstateok then
mem.swingupcalls[event.msg] = true
- elseif event.channel == "swingdncall" and (mem.carstate == "normal" or mem.carstate == "swing") then
+ elseif event.channel == "swingdncall" and swingstateok then
mem.swingdncalls[event.msg] = true
elseif event.channel == "upcall" and (mem.carstate == "normal" or mem.carstate == "swing") then
mem.upcalls[event.msg] = true
@@ -1480,6 +1515,7 @@ elseif mem.screenstate == "carcallsecurity" then
fs(minetest.formspec_escape(string.format("%s - %s",mem.params.floornames[i],secmode))..(i==1 and "" or ","))
end
fs(";"..tostring(#mem.params.floornames-mem.editingfloor+1)..";false]")
+ fs("checkbox[1,9.5;swingcallwhennotswing;Allow Swing Calls When Not In Swing Operation;"..tostring(mem.params.swingcallwhennotswing).."]")
if mem.editingfloor ~= (mem.params.mainlanding or 1) then
fs("dropdown[8,2;4,1;secmode;Security Disabled,Authorized Users Only,Locked;")
if mem.params.carcallsecurity[mem.editingfloor] == "auth" then
@@ -1553,6 +1589,7 @@ local arrowenabled = {
indep = true,
capture = true,
test = true,
+ swing = true,
}
mem.piuparrow = mem.drive.status.vel > 0 and arrowenabled[mem.carstate]
mem.pidownarrow = mem.drive.status.vel < 0 and arrowenabled[mem.carstate]
diff --git a/crafts.lua b/crafts.lua
index 05303c6..13a8b93 100644
--- a/crafts.lua
+++ b/crafts.lua
@@ -29,6 +29,9 @@ if not xcompat_available then
m.mese = "mesecons_torch:redstoneblock" -- mcla still carries this as an alias
m.pick_steel = "mcl_core:pick_steel"
m.torch = "mcl_torches:torch"
+ else
+ minetest.log("warning","[celevator] Unsupported game and xcompat not found, not registering craft recipes")
+ return
end
if minetest.get_modpath("dye") then
m.dye_black = "dye:black"
@@ -195,6 +198,15 @@ minetest.register_craft({
})
minetest.register_craft({
+ output = "celevator:car_metal_glassback",
+ recipe = {
+ {"",m.steel_strip,""},
+ {m.steel_strip,"celevator:car_glassback",m.steel_strip},
+ {"",m.steel_strip,""},
+ },
+})
+
+minetest.register_craft({
output = "celevator:controller",
recipe = {
{m.steel_strip,m.ic,m.steel_strip},
diff --git a/dispatcher.lua b/dispatcher.lua
index a8bcf1c..02533ff 100644
--- a/dispatcher.lua
+++ b/dispatcher.lua
@@ -422,7 +422,9 @@ end
function celevator.dispatcher.checkiqueue(dtime)
for hash,iqueue in pairs(celevator.dispatcher.iqueue) do
local pos = minetest.get_position_from_hash(hash)
+ local noneleft = true
for iid,time in pairs(iqueue) do
+ noneleft = false
iqueue[iid] = time-dtime
if iqueue[iid] < 0 then
iqueue[iid] = nil
@@ -432,6 +434,10 @@ function celevator.dispatcher.checkiqueue(dtime)
celevator.dispatcher.run(pos,event)
end
end
+ if noneleft then
+ celevator.dispatcher.iqueue[hash] = nil
+ celevator.storage:set_string("dispatcher_iqueue",minetest.serialize(celevator.dispatcher.iqueue))
+ end
end
end
diff --git a/dispatcherfw.lua b/dispatcherfw.lua
index 25ad4f8..9b0a23b 100644
--- a/dispatcherfw.lua
+++ b/dispatcherfw.lua
@@ -300,6 +300,27 @@ local function fs(element)
mem.formspec = mem.formspec..element
end
+if mem.params and #mem.params.floornames < 2 then
+ mem.params.floorheights = {5,5,5}
+ mem.params.floornames = {"1","2","3"}
+ for _,carid in ipairs(mem.params.carids) do
+ local floornames = {}
+ local floorheights = {}
+ for i=1,#mem.params.floornames,1 do
+ if mem.params.floorsserved[carid][i] then
+ table.insert(floornames,mem.params.floornames[i])
+ table.insert(floorheights,mem.params.floorheights[i])
+ elseif #floornames > 0 then
+ floorheights[#floorheights] = floorheights[#floorheights]+mem.params.floorheights[i]
+ end
+ end
+ send(carid,"newfloortable",{
+ floornames = floornames,
+ floorheights = floorheights,
+ })
+ end
+end
+
if event.type == "program" then
mem.carstatus = {}
mem.screenstate = "oobe_welcome"
@@ -367,7 +388,7 @@ elseif event.type == "ui" then
elseif event.fields.add then
table.insert(mem.params.floorheights,5)
table.insert(mem.params.floornames,tostring(#mem.params.floornames+1))
- elseif event.fields.remove then
+ elseif event.fields.remove and #mem.params.floornames > 2 then
table.remove(mem.params.floorheights,mem.editingfloor)
table.remove(mem.params.floornames,mem.editingfloor)
mem.editingfloor = math.max(1,mem.editingfloor-1)
diff --git a/docs/README b/docs/README
index 4928bef..a53637c 100644
--- a/docs/README
+++ b/docs/README
@@ -1,2 +1,4 @@
Source for celevator_controller_manual.pdf is not included in this repository due to its large size.
If desired, the file can be downloaded from: https://cheapiesystems.com/media/celevator_controller_manual.odt
+
+This isn't the README for the whole project, go up one folder for that.
diff --git a/docs/celevator_controller_manual.pdf b/docs/celevator_controller_manual.pdf
index 2da5ca1..0bca94b 100644
--- a/docs/celevator_controller_manual.pdf
+++ b/docs/celevator_controller_manual.pdf
Binary files differ
diff --git a/init.lua b/init.lua
index c38c1ff..e718c8e 100644
--- a/init.lua
+++ b/init.lua
@@ -4,6 +4,7 @@ local components = {
"car_standard",
"car_glassback",
"car_metal",
+ "car_metalglass",
"doors",
"drive_null",
"drive_entity",
diff --git a/laptop.lua b/laptop.lua
index a65739c..bbfe0a5 100644
--- a/laptop.lua
+++ b/laptop.lua
@@ -61,6 +61,10 @@ laptop.register_app("celevator",{
fs = fs..mtos.theme:get_label("0.5,1","Could not find a controller or dispatcher with the given ID.")
fs = fs..mtos.theme:get_label("0.5,1.3","Please check the ID number and try again.")
fs = fs..mtos.theme:get_button("0.5,3;2,1","major","ok","OK")
+ elseif ram.screenstate == "protected" then
+ fs = fs..mtos.theme:get_label("0.5,0.5","Error")
+ fs = fs..mtos.theme:get_label("0.5,1","Controller or dispatcher is protected.")
+ fs = fs..mtos.theme:get_button("0.5,3;2,1","major","ok","OK")
elseif ram.screenstate == "dispatcherstatus" then
local connection = mem.connections[mem.selectedconnection]
local pos = connection.pos
@@ -201,6 +205,7 @@ laptop.register_app("celevator",{
indep = "Independent Service",
capture = "Captured",
test = "Test Mode",
+ swing = "Swing Operation",
}
local doorstates = {
open = "Open",
@@ -331,10 +336,16 @@ laptop.register_app("celevator",{
mem.screenpage = 1
if exp.type == "DCL" then mem.selectedconnection = #mem.connections-exp.index+1 end
local connection = mem.connections[mem.selectedconnection]
- if connection.itemtype == "controller" and celevator.controller.iscontroller(connection.pos) then
+ local cpos = connection.pos
+ if minetest.is_protected(cpos,mtos.sysram.current_player) and not minetest.check_player_privs(mtos.sysram.current_player,{protection_bypass=true}) then
+ minetest.record_protection_violation(cpos,mtos.sysram.current_player)
+ ram.screenstate = "protected"
+ return
+ end
+ if connection.itemtype == "controller" and celevator.controller.iscontroller(cpos) then
ram.screenstate = "controllerstatus"
app:get_timer():start(0.2)
- elseif connection.itemtype == "dispatcher" and celevator.dispatcher.isdispatcher(connection.pos) then
+ elseif connection.itemtype == "dispatcher" and celevator.dispatcher.isdispatcher(cpos) then
ram.screenstate = "dispatcherstatus"
app:get_timer():start(0.2)
else
@@ -365,6 +376,11 @@ laptop.register_app("celevator",{
ram.screenstate = "notfound"
return
end
+ if minetest.is_protected(pos,mtos.sysram.current_player) and not minetest.check_player_privs(mtos.sysram.current_player,{protection_bypass=true}) then
+ minetest.record_protection_violation(pos,mtos.sysram.current_player)
+ ram.screenstate = "protected"
+ return
+ end
local connection = {
name = fields.name,
carid = carid,
@@ -381,6 +397,10 @@ laptop.register_app("celevator",{
if fields.ok then
ram.screenstate = "newconnection"
end
+ elseif ram.screenstate == "protected" then
+ if fields.ok then
+ ram.screenstate = #mem.connections > 0 and "connections" or "newconnection"
+ end
elseif ram.screenstate == "dispatcherstatus" then
if fields.disconnect then
ram.screenstate = "connections"
diff --git a/screenshot.png b/screenshot.png
new file mode 100644
index 0000000..907df06
--- /dev/null
+++ b/screenshot.png
Binary files differ
diff --git a/textures/celevator_car_metal_glassback_inventory.png b/textures/celevator_car_metal_glassback_inventory.png
new file mode 100644
index 0000000..5c7cc22
--- /dev/null
+++ b/textures/celevator_car_metal_glassback_inventory.png
Binary files differ
diff --git a/textures/celevator_car_metal_glassback_wield.png b/textures/celevator_car_metal_glassback_wield.png
new file mode 100644
index 0000000..a072b41
--- /dev/null
+++ b/textures/celevator_car_metal_glassback_wield.png
Binary files differ
diff --git a/textures/celevator_door_glass_inventory.png b/textures/celevator_door_glass_inventory.png
index 4ebf6f9..2538465 100644
--- a/textures/celevator_door_glass_inventory.png
+++ b/textures/celevator_door_glass_inventory.png
Binary files differ