summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.luacheckrc1
-rw-r--r--README54
-rw-r--r--callbuttons.lua32
-rw-r--r--car.lua753
-rw-r--r--car_glassback.lua416
-rw-r--r--car_metal.lua410
-rw-r--r--car_metalglass.lua416
-rw-r--r--car_standard.lua419
-rw-r--r--chatcommands.lua181
-rw-r--r--controller.lua15
-rw-r--r--controllerfw.lua150
-rw-r--r--crafts.lua316
-rw-r--r--decorations.lua2
-rw-r--r--digilines.lua12
-rw-r--r--dispatcher.lua6
-rw-r--r--dispatcherfw.lua23
-rw-r--r--docs/README2
-rw-r--r--docs/celevator_controller_manual.pdfbin2140061 -> 2192852 bytes
-rw-r--r--docs/file_sources4
-rw-r--r--doors.lua298
-rw-r--r--drive_entity.lua176
-rw-r--r--genericswitch.lua24
-rw-r--r--governor.lua131
-rw-r--r--init.lua6
-rw-r--r--laptop.lua24
-rw-r--r--mesecons.lua32
-rw-r--r--mod.conf2
-rw-r--r--pilantern.lua27
-rw-r--r--screenshot.pngbin0 -> 236634 bytes
-rw-r--r--textures/celevator_car_glass.pngbin0 -> 223 bytes
-rw-r--r--textures/celevator_car_glassback_inventory.pngbin0 -> 650 bytes
-rw-r--r--textures/celevator_car_glassback_wield.pngbin0 -> 515 bytes
-rw-r--r--textures/celevator_car_metal.pngbin0 -> 559 bytes
-rw-r--r--textures/celevator_car_metal_2x.pngbin0 -> 667 bytes
-rw-r--r--textures/celevator_car_metal_ceiling.pngbin0 -> 716 bytes
-rw-r--r--textures/celevator_car_metal_floor.pngbin0 -> 307 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_car_metal_inventory.pngbin0 -> 503 bytes
-rw-r--r--textures/celevator_car_metal_top.pngbin0 -> 584 bytes
-rw-r--r--textures/celevator_car_metal_wield.pngbin0 -> 390 bytes
-rw-r--r--textures/celevator_door_glass_inventory.pngbin573 -> 244 bytes
-rw-r--r--textures/celevator_door_metal.pngbin0 -> 561 bytes
-rw-r--r--textures/celevator_door_metal_inventory.pngbin0 -> 571 bytes
-rw-r--r--textures/celevator_governor_back.pngbin0 -> 2115 bytes
-rw-r--r--textures/celevator_governor_front.pngbin0 -> 2156 bytes
-rw-r--r--textures/celevator_governor_sheave_sides.pngbin0 -> 259 bytes
47 files changed, 3218 insertions, 714 deletions
diff --git a/.luacheckrc b/.luacheckrc
index 8ce3cc6..427b2d9 100644
--- a/.luacheckrc
+++ b/.luacheckrc
@@ -14,4 +14,5 @@ read_globals = {
"laptop",
"mesecon",
"digilines",
+ "xcompat",
}
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/callbuttons.lua b/callbuttons.lua
index 58cd40d..7e19de6 100644
--- a/callbuttons.lua
+++ b/callbuttons.lua
@@ -239,3 +239,35 @@ for _,state in ipairs(validstates) do
end,
})
end
+
+minetest.register_abm({
+ label = "Check call buttons for missing/replaced controllers",
+ nodenames = {"group:_celevator_callbutton",},
+ interval = 15,
+ chance = 1,
+ action = function(pos)
+ local meta = minetest.get_meta(pos)
+ local carid = meta:get_int("carid")
+ if not (carid and carid > 0) then return end --Not set up yet
+ local carinfo = minetest.deserialize(celevator.storage:get_string("car"..carid))
+ if not carinfo then
+ meta:set_string("infotext","Error reading car information!\nPlease remove and replace this node.")
+ return
+ end
+ local iscontroller = (carinfo.controllerpos and celevator.controller.iscontroller(carinfo.controllerpos))
+ local isdispatcher = (carinfo.dispatcherpos and celevator.dispatcher.isdispatcher(carinfo.dispatcherpos))
+ if not (iscontroller or isdispatcher) then
+ meta:set_string("infotext","Controller/dispatcher is missing!\nPlease remove and replace this node.")
+ return
+ end
+ local metacarid = 0
+ if iscontroller then
+ metacarid = celevator.get_meta(carinfo.controllerpos):get_int("carid")
+ elseif isdispatcher then
+ metacarid = celevator.get_meta(carinfo.dispatcherpos):get_int("carid")
+ end
+ if metacarid ~= carid then
+ meta:set_string("infotext","Controller/dispatcher found but with incorrect ID!\nPlease remove and replace this node.")
+ end
+ end,
+})
diff --git a/car.lua b/car.lua
index 26d0fdc..e8eca64 100644
--- a/car.lua
+++ b/car.lua
@@ -1,6 +1,6 @@
celevator.car = {}
-local function disambiguatebutton(pos,facedir,player)
+local function disambiguatecartopbutton(pos,facedir,player)
if player and not player.is_fake_player then
local eyepos = vector.add(player:get_pos(),vector.add(player:get_eye_offset(),vector.new(0,1.5,0)))
local lookdir = player:get_look_dir()
@@ -12,7 +12,8 @@ local function disambiguatebutton(pos,facedir,player)
pointed = ray:next()
if pointed and pointed.type == "node" then
local node = minetest.get_node(pointed.under)
- if node.name == "celevator:car_021" then
+ local ndef = minetest.registered_nodes[node.name] or {}
+ if ndef._cartopbox then
button = pointed.under
hitpos = vector.subtract(pointed.intersection_point,button)
end
@@ -68,507 +69,216 @@ minetest.register_globalstep(function()
end
end)
-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_floor.png^celevator_door_sill_single.png",
- "celevator_car_bottom.png",
- "celevator_car_wallpaper.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",
- },
- on_timer = function(pos)
- local carid = minetest.get_meta(pos):get_int("carid")
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
- if not (carinfo and carinfo.controllerpos) then return end
- local yaw = minetest.dir_to_yaw(minetest.fourdir_to_dir(minetest.get_node(pos).param2))
- local positions = {
- vector.new(-0.25,-0.1,-0.5),
- vector.new(0.25,-0.1,-0.5),
- vector.new(0.75,-0.1,-0.5),
- vector.new(1.25,-0.1,-0.5),
- }
- local playerseen = false
- for _,searchpos in ipairs(positions) do
- local rotatedpos = vector.rotate_around_axis(searchpos,vector.new(0,1,0),yaw)
- local erefs = minetest.get_objects_inside_radius(vector.add(pos,rotatedpos),0.5)
- for _,ref in pairs(erefs) do
- if ref:is_player() then
- playerseen = true
- break
- end
- end
- if playerseen then break end
- end
- if playerseen then
- celevator.controller.run(carinfo.controllerpos,{
- type = "lightcurtain",
- })
+celevator.car.types = {}
+
+function celevator.car.register(name,defs,size)
+ celevator.car.types[name] = {
+ size = size,
+ }
+ for _,def in ipairs(defs) do
+ def._celevator_car_type = name
+ def.groups = {
+ not_in_creative_inventory = 1,
+ _celevator_car = 1,
+ }
+ local xp = tonumber(string.sub(def._position,1,1))
+ local yp = tonumber(string.sub(def._position,2,2))
+ local zp = tonumber(string.sub(def._position,3,3))
+ if xp > 0 then
+ def.groups._connects_xm = 1
+ end
+ if xp < size.x-1 then
+ def.groups._connects_xp = 1
+ end
+ if yp > 0 then
+ def.groups._connects_ym = 1
+ end
+ if yp < size.y-1 then
+ def.groups._connects_yp = 1
+ end
+ if zp > 0 then
+ def.groups._connects_zm = 1
+ end
+ if zp < size.z-1 then
+ def.groups._connects_zp = 1
+ end
+ def.paramtype = "light"
+ def.paramtype2 = "4dir"
+ def.drawtype = "nodebox"
+ def.description = "Car "..def._position.." (you hacker you!)"
+ def.light_source = 9
+ def.drop = ""
+ if def._cop then
+ def.on_receive_fields = function(pos,_,fields,player)
+ local meta = minetest.get_meta(pos)
+ local carid = meta:get_int("carid")
+ if carid == 0 then return end
+ local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ if not carinfo then return end
+ local playername = player:get_player_name()
+ local protected = minetest.is_protected(pos,playername) and not minetest.check_player_privs(playername,{protection_bypass=true})
+ local event = {
+ type = "cop",
+ fields = fields,
+ player = playername,
+ protected = protected,
+ }
+ celevator.controller.run(carinfo.controllerpos,event)
end
- return true
- end,
- },
- {
- _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_floor.png",
- "celevator_car_bottom_center.png",
- "celevator_car_wallpaper.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},
- },
- },
- tiles = {
- "celevator_car_floor.png",
- "celevator_car_bottom.png",
- "celevator_car_wallpaper.png^celevator_car_wall_bottom.png",
- "celevator_cabinet_sides.png^celevator_car_side_overlay.png",
- "celevator_cabinet_sides.png",
- "celevator_car_wallpaper.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_floor.png^celevator_door_sill_double.png",
- "celevator_car_bottom.png",
- "celevator_cabinet_sides.png^celevator_car_side_overlay.png",
- "celevator_car_wallpaper.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_floor.png",
- "celevator_car_bottom_center.png^[transformFX",
- "celevator_cabinet_sides.png^celevator_car_side_center_overlay.png",
- "celevator_car_wallpaper.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},
- },
- },
- tiles = {
- "celevator_car_floor.png",
- "celevator_car_bottom.png",
- "celevator_cabinet_sides.png^celevator_car_side_overlay.png^[transformR90",
- "celevator_car_wallpaper.png^celevator_car_wall_bottom.png",
- "celevator_cabinet_sides.png",
- "celevator_car_wallpaper.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_wallpaper_2x.png^celevator_cop.png",
- "celevator_cabinet_sides.png",
- },
- },
- {
- _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_wallpaper.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},
- },
- },
- tiles = {
- "celevator_cabinet_sides.png",
- "celevator_cabinet_sides.png",
- "celevator_car_wallpaper.png^(celevator_car_handrail_end.png^[transformFX)",
- "celevator_cabinet_sides.png",
- "celevator_cabinet_sides.png",
- "celevator_car_wallpaper.png^celevator_car_handrail_end.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_wallpaper.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_wallpaper.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},
- },
- },
- tiles = {
- "celevator_cabinet_sides.png",
- "celevator_cabinet_sides.png",
- "celevator_cabinet_sides.png",
- "celevator_car_wallpaper.png^celevator_car_handrail_end.png",
- "celevator_cabinet_sides.png",
- "celevator_car_wallpaper.png^(celevator_car_handrail_end.png^[transformFX)",
- },
- },
- {
- _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_ceiling.png",
- "celevator_car_wallpaper.png",
- "celevator_cabinet_sides.png",
- "celevator_cabinet_sides.png",
- "celevator_dooroperator_left.png",
- },
- },
- {
- _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_ceiling.png",
- "celevator_car_wallpaper.png",
- "celevator_cabinet_sides.png^celevator_car_side_center_overlay.png",
- "celevator_cabinet_sides.png",
- },
- on_rightclick = function(pos,node,clicker)
- local name = clicker:get_player_name()
- for _,v in ipairs(held) do
- if name == v.name then return end
+ elseif def._keyswitches then
+ def.on_receive_fields = function(pos,_,fields,player)
+ if fields.quit then return end
+ local meta = minetest.get_meta(pos)
+ local carid = meta:get_int("carid")
+ if carid == 0 then return end
+ local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ if not carinfo then return end
+ local playername = player:get_player_name()
+ if minetest.is_protected(pos,playername) and not minetest.check_player_privs(playername,{protection_bypass=true}) then
+ minetest.chat_send_player(playername,"You don't have access to these switches.")
+ minetest.record_protection_violation(pos,playername)
+ return
+ end
+ local event = {
+ type = "copswitches",
+ fields = fields,
+ player = name,
+ }
+ celevator.controller.run(carinfo.controllerpos,event)
end
- local fdir = minetest.fourdir_to_dir(node.param2)
- local control = disambiguatebutton(pos,fdir,clicker)
- if not control then return end
- local meta = minetest.get_meta(pos)
- local carid = meta:get_int("carid")
- if carid == 0 then return end
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
- if not (carinfo and carinfo.controllerpos) then return end
- if control == "inspectswitch" then
- local boxpos = vector.add(pos,vector.new(0,1,0))
- local erefs = minetest.get_objects_inside_radius(boxpos,0.5)
- for _,ref in pairs(erefs) do
- if ref:get_luaentity() and ref:get_luaentity().name == "celevator:car_top_box" then
- local state = ref:get_properties().wield_item
- if state == "celevator:car_top_box_off" then
- state = "celevator:car_top_box_on"
- elseif state == "celevator:car_top_box_on" then
- state = "celevator:car_top_box_off"
+ end
+ if def._cartopbox then
+ def.groups._celevator_car_spawnstopbox = 1
+ def.on_rightclick = function(pos,node,clicker)
+ local playername = clicker:get_player_name()
+ for _,v in ipairs(held) do
+ if playername == v.name then return end
+ end
+ local fdir = minetest.fourdir_to_dir(node.param2)
+ local control = disambiguatecartopbutton(pos,fdir,clicker)
+ if not control then return end
+ local meta = minetest.get_meta(pos)
+ local carid = meta:get_int("carid")
+ if carid == 0 then return end
+ local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ if not (carinfo and carinfo.controllerpos) then return end
+ if control == "inspectswitch" then
+ local boxpos = vector.add(pos,vector.new(0,1,0))
+ local erefs = minetest.get_objects_inside_radius(boxpos,0.5)
+ for _,ref in pairs(erefs) do
+ if ref:get_luaentity() and ref:get_luaentity().name == "celevator:car_top_box" then
+ local state = ref:get_properties().wield_item
+ if state == "celevator:car_top_box_off" then
+ state = "celevator:car_top_box_on"
+ elseif state == "celevator:car_top_box_on" then
+ state = "celevator:car_top_box_off"
+ end
+ ref:set_properties({wield_item = state})
end
- ref:set_properties({wield_item = state})
end
end
+ celevator.controller.handlecartopbox(carinfo.controllerpos,control)
+ table.insert(held,{
+ pos = carinfo.controllerpos,
+ name = playername,
+ button = "place",
+ control = control,
+ })
end
- celevator.controller.handlecartopbox(carinfo.controllerpos,control)
- table.insert(held,{
- pos = carinfo.controllerpos,
- name = name,
- button = "place",
- control = control,
- })
- end,
- after_dig_node = function(pos)
- local toppos = vector.add(pos,vector.new(0,1.1,0))
- local entitiesnearby = minetest.get_objects_inside_radius(toppos,0.5)
- for _,i in pairs(entitiesnearby) do
- if i:get_luaentity() and i:get_luaentity().name == "celevator:car_top_box" then
- i:remove()
+ def.after_dig_node = function(pos)
+ local toppos = vector.add(pos,vector.new(0,1.1,0))
+ local entitiesnearby = minetest.get_objects_inside_radius(toppos,0.5)
+ for _,i in pairs(entitiesnearby) do
+ if i:get_luaentity() and i:get_luaentity().name == "celevator:car_top_box" then
+ i:remove()
+ end
end
end
- end,
- },
- {
- _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},
- },
- },
- tiles = {
- "celevator_cabinet_sides.png^celevator_car_top_hatch.png",
- "celevator_car_ceiling.png",
- "celevator_car_wallpaper.png",
- "celevator_cabinet_sides.png",
- "celevator_cabinet_sides.png",
- "celevator_car_wallpaper.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_ceiling.png",
- "celevator_cabinet_sides.png",
- "celevator_car_wallpaper.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_ceiling.png",
- "celevator_cabinet_sides.png^celevator_car_side_center_overlay.png",
- "celevator_car_wallpaper.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},
- },
- },
- tiles = {
- "celevator_cabinet_sides.png^celevator_car_top_misc.png",
- "celevator_car_ceiling.png",
- "celevator_cabinet_sides.png",
- "celevator_car_wallpaper.png",
- "celevator_cabinet_sides.png",
- "celevator_car_wallpaper.png",
- },
- },
-}
-
-for _,def in ipairs(pieces) do
- def.groups = {
- not_in_creative_inventory = 1,
- _celevator_car = 1,
- }
- local xp = tonumber(string.sub(def._position,1,1))
- local yp = tonumber(string.sub(def._position,2,2))
- local zp = tonumber(string.sub(def._position,3,3))
- if xp > 0 then
- def.groups._connects_xm = 1
- end
- if xp < 1 then
- def.groups._connects_xp = 1
- end
- if yp > 0 then
- def.groups._connects_ym = 1
- end
- if yp < 2 then
- def.groups._connects_yp = 1
- end
- if zp > 0 then
- def.groups._connects_zm = 1
- end
- if zp < 2 then
- def.groups._connects_zp = 1
- end
- def.paramtype = "light"
- def.paramtype2 = "4dir"
- def.drawtype = "nodebox"
- def.description = "Car "..def._position.." (you hacker you!)"
- def.light_source = 9
- def.drop = ""
- def.on_receive_fields = function(pos,_,fields,player)
- local meta = minetest.get_meta(pos)
- local carid = meta:get_int("carid")
- if carid == 0 then return end
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
- if not carinfo then return end
- local nname = minetest.get_node(pos).name
- if nname == "celevator:car_010" then
- local name = player:get_player_name()
- local protected = minetest.is_protected(pos,name) and not minetest.check_player_privs(name,{protection_bypass=true})
- local event = {
- type = "cop",
- fields = fields,
- player = player:get_player_name(),
- protected = protected,
- }
- celevator.controller.run(carinfo.controllerpos,event)
- elseif nname == "celevator:car_000" then
- if fields.quit then return end
- local name = player:get_player_name()
- if minetest.is_protected(pos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
- minetest.chat_send_player(name,"You don't have access to these switches.")
- minetest.record_protection_violation(pos,name)
- return
- end
- local event = {
- type = "copswitches",
- fields = fields,
- player = name,
- }
- celevator.controller.run(carinfo.controllerpos,event)
end
- end
- if def._position == "000" then
- def.on_construct = function(pos)
- minetest.get_meta(pos):set_string("doorstate","closed")
+ if def._pi then
+ def.groups._celevator_car_spawnspi = 1
end
- def.on_punch = function(pos,_,player)
- if player.is_fake_player then return end
- local name = player:get_player_name()
- local sneak = player:get_player_control().sneak
- if not sneak then return end
- if minetest.is_protected(pos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
- minetest.record_protection_violation(pos,name)
- return
+ if def._tapehead then
+ def.groups._celevator_car_spawnstapehead = 1
+ end
+ if def._position == "000" then
+ def.groups._celevator_car_root = 1
+ def._root = true
+ def.on_construct = function(pos)
+ minetest.get_meta(pos):set_string("doorstate","closed")
+ end
+ def.on_punch = function(pos,_,player)
+ if player.is_fake_player then return end
+ local playername = player:get_player_name()
+ local sneak = player:get_player_control().sneak
+ if not sneak then return end
+ if minetest.is_protected(pos,playername) and not minetest.check_player_privs(playername,{protection_bypass=true}) then
+ minetest.record_protection_violation(pos,playername)
+ return
+ end
+ local hash = minetest.hash_node_position(pos)
+ local fs = "formspec_version[7]size[6,4]"
+ fs = fs.."label[0.5,1;Really remove this car?]"
+ fs = fs.."button_exit[0.5,2;2,1;yes;Yes]"
+ fs = fs.."button_exit[3,2;2,1;no;No]"
+ minetest.show_formspec(playername,string.format("celevator:remove_car_%d",hash),fs)
+ end
+ def.on_timer = function(pos)
+ local carid = minetest.get_meta(pos):get_int("carid")
+ local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ if not (carinfo and carinfo.controllerpos) then return end
+ local yaw = minetest.dir_to_yaw(minetest.fourdir_to_dir(minetest.get_node(pos).param2))
+ local positions = {
+ vector.new(-0.25,-0.1,-0.5),
+ vector.new(0.25,-0.1,-0.5),
+ vector.new(0.75,-0.1,-0.5),
+ vector.new(1.25,-0.1,-0.5),
+ }
+ local playerseen = false
+ for _,searchpos in ipairs(positions) do
+ local rotatedpos = vector.rotate_around_axis(searchpos,vector.new(0,1,0),yaw)
+ local erefs = minetest.get_objects_inside_radius(vector.add(pos,rotatedpos),0.5)
+ for _,ref in pairs(erefs) do
+ if ref:is_player() then
+ playerseen = true
+ break
+ end
+ end
+ if playerseen then break end
+ end
+ if playerseen then
+ celevator.controller.run(carinfo.controllerpos,{
+ type = "lightcurtain",
+ })
+ end
+ return true
end
- local hash = minetest.hash_node_position(pos)
- local fs = "formspec_version[7]size[6,4]"
- fs = fs.."label[0.5,1;Really remove this car?]"
- fs = fs.."button_exit[0.5,2;2,1;yes;Yes]"
- fs = fs.."button_exit[3,2;2,1;no;No]"
- minetest.show_formspec(name,string.format("celevator:remove_car_%d",hash),fs)
end
+ minetest.register_node("celevator:car_"..name.."_"..def._position,def)
end
- minetest.register_node("celevator:car_"..def._position,def)
end
-function celevator.car.spawncar(origin,yaw,carid)
+function celevator.car.spawncar(origin,yaw,carid,name,doortype)
+ if (not name) or name == "" then name = "standard" end
+ local size = celevator.car.types[name].size
local right = vector.rotate_around_axis(vector.new(1,0,0),vector.new(0,1,0),yaw)
local back = vector.rotate_around_axis(vector.new(0,0,1),vector.new(0,1,0),yaw)
local up = vector.new(0,1,0)
- for x=0,1,1 do
- for y=0,2,1 do
- for z=0,2,1 do
+ for x=0,(size.x-1),1 do
+ for y=0,(size.y-1),1 do
+ for z=0,(size.z-1),1 do
local pos = vector.copy(origin)
pos = vector.add(pos,vector.multiply(right,x))
pos = vector.add(pos,vector.multiply(back,z))
pos = vector.add(pos,vector.multiply(up,y))
local node = {
- name = string.format("celevator:car_%d%d%d",x,y,z),
+ name = string.format("celevator:car_%s_%d%d%d",name,x,y,z),
param2 = minetest.dir_to_fourdir(minetest.yaw_to_dir(yaw)),
}
minetest.set_node(pos,node)
- if carid then minetest.get_meta(pos):set_int("carid",carid) end
+ local meta = minetest.get_meta(pos)
+ if carid then meta:set_int("carid",carid) end
+ meta:set_string("doortype",doortype or "glass")
end
end
end
@@ -576,7 +286,7 @@ end
minetest.register_abm({
label = "Respawn in-car PI displays",
- nodenames = {"celevator:car_020"},
+ nodenames = {"group:_celevator_car_spawnspi"},
interval = 1,
chance = 1,
action = function(pos)
@@ -650,97 +360,22 @@ minetest.register_entity("celevator:car_top_box",{
minetest.register_abm({
label = "Respawn car-top inspection boxes",
- nodenames = {"celevator:car_021"},
+ nodenames = {"group:_celevator_car_spawnstopbox"},
interval = 1,
chance = 1,
action = updatecartopbox,
})
-minetest.register_node("celevator:car",{
- description = "Elevator Car",
- paramtype2 = "4dir",
- buildable_to = true,
- inventory_image = "celevator_car_inventory.png",
- wield_image = "celevator_car_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_%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,
-})
-
minetest.register_on_player_receive_fields(function(_,formname,fields)
if string.sub(formname,1,21) ~= "celevator:remove_car_" then return false end
if not fields.yes then return true end
local hash = tonumber(string.sub(formname,22,-1))
if not hash then return true end
local rootpos = minetest.get_position_from_hash(hash)
- local rootdir = minetest.dir_to_yaw(minetest.fourdir_to_dir(minetest.get_node(rootpos).param2))
- 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_%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
+ local rootdef = minetest.registered_nodes[celevator.get_node(rootpos).name] or {}
+ local cartype = rootdef._celevator_car_type
+ if cartype and celevator.car.types[cartype] then
+ local rootdir = minetest.dir_to_yaw(minetest.fourdir_to_dir(minetest.get_node(rootpos).param2))
+ celevator.car.types[cartype].remove(rootpos,rootdir)
end
end)
diff --git a/car_glassback.lua b/car_glassback.lua
new file mode 100644
index 0000000..58d4c7a
--- /dev/null
+++ b/car_glassback.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_floor.png^celevator_door_sill_single.png",
+ "celevator_car_bottom.png",
+ "celevator_car_wallpaper.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_floor.png",
+ "celevator_car_bottom_center.png",
+ "celevator_car_wallpaper.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_floor.png",
+ "celevator_car_bottom.png",
+ "celevator_car_wallpaper.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_floor.png^celevator_door_sill_double.png",
+ "celevator_car_bottom.png",
+ "celevator_cabinet_sides.png^celevator_car_side_overlay.png",
+ "celevator_car_wallpaper.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_floor.png",
+ "celevator_car_bottom_center.png^[transformFX",
+ "celevator_cabinet_sides.png^celevator_car_side_center_overlay.png",
+ "celevator_car_wallpaper.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_floor.png",
+ "celevator_car_bottom.png",
+ "celevator_cabinet_sides.png^celevator_car_side_overlay.png^[transformR90",
+ "celevator_car_wallpaper.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_wallpaper_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_wallpaper.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_wallpaper.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_wallpaper.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_wallpaper.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_wallpaper.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_ceiling.png",
+ "celevator_car_wallpaper.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_ceiling.png",
+ "celevator_car_wallpaper.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_ceiling.png",
+ "celevator_car_wallpaper.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_ceiling.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_wallpaper.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_ceiling.png",
+ "celevator_cabinet_sides.png^celevator_car_side_center_overlay.png",
+ "celevator_car_wallpaper.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_ceiling.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_wallpaper.png",
+ "celevator_car_glass.png",
+ "celevator_car_glass.png",
+ },
+ _tapehead = true,
+ },
+}
+
+celevator.car.register("glassback",pieces,vector.new(2,3,3))
+
+
+minetest.register_node("celevator:car_glassback",{
+ description = "Glass-Back Elevator Car",
+ paramtype2 = "4dir",
+ buildable_to = true,
+ inventory_image = "celevator_car_glassback_inventory.png",
+ wield_image = "celevator_car_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_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.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_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/car_metal.lua b/car_metal.lua
new file mode 100644
index 0000000..1b18ced
--- /dev/null
+++ b/car_metal.lua
@@ -0,0 +1,410 @@
+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},
+ },
+ },
+ 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_cabinet_sides.png",
+ "celevator_car_metal.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},
+ },
+ },
+ 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_cabinet_sides.png",
+ "celevator_car_metal.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},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_metal.png^(celevator_car_handrail_end.png^[transformFX)",
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_metal.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},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_metal.png^celevator_car_handrail_end.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_metal.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},
+ },
+ },
+ 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_cabinet_sides.png",
+ "celevator_car_metal_top.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},
+ },
+ },
+ 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_cabinet_sides.png",
+ "celevator_car_metal_top.png",
+ },
+ _tapehead = true,
+ },
+}
+
+celevator.car.register("metal",pieces,vector.new(2,3,3))
+
+
+minetest.register_node("celevator:car_metal",{
+ description = "Metal Elevator Car",
+ paramtype2 = "4dir",
+ buildable_to = true,
+ inventory_image = "celevator_car_metal_inventory.png",
+ wield_image = "celevator_car_metal_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_%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.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_%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/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/car_standard.lua b/car_standard.lua
new file mode 100644
index 0000000..70cb91f
--- /dev/null
+++ b/car_standard.lua
@@ -0,0 +1,419 @@
+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_floor.png^celevator_door_sill_single.png",
+ "celevator_car_bottom.png",
+ "celevator_car_wallpaper.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_floor.png",
+ "celevator_car_bottom_center.png",
+ "celevator_car_wallpaper.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},
+ },
+ },
+ tiles = {
+ "celevator_car_floor.png",
+ "celevator_car_bottom.png",
+ "celevator_car_wallpaper.png^celevator_car_wall_bottom.png",
+ "celevator_cabinet_sides.png^celevator_car_side_overlay.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_wallpaper.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_floor.png^celevator_door_sill_double.png",
+ "celevator_car_bottom.png",
+ "celevator_cabinet_sides.png^celevator_car_side_overlay.png",
+ "celevator_car_wallpaper.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_floor.png",
+ "celevator_car_bottom_center.png^[transformFX",
+ "celevator_cabinet_sides.png^celevator_car_side_center_overlay.png",
+ "celevator_car_wallpaper.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},
+ },
+ },
+ tiles = {
+ "celevator_car_floor.png",
+ "celevator_car_bottom.png",
+ "celevator_cabinet_sides.png^celevator_car_side_overlay.png^[transformR90",
+ "celevator_car_wallpaper.png^celevator_car_wall_bottom.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_wallpaper.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_wallpaper_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_wallpaper.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},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_wallpaper.png^(celevator_car_handrail_end.png^[transformFX)",
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_wallpaper.png^celevator_car_handrail_end.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_wallpaper.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_wallpaper.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},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_wallpaper.png^celevator_car_handrail_end.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_wallpaper.png^(celevator_car_handrail_end.png^[transformFX)",
+ },
+ },
+ {
+ _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_ceiling.png",
+ "celevator_car_wallpaper.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_ceiling.png",
+ "celevator_car_wallpaper.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},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png^celevator_car_top_hatch.png",
+ "celevator_car_ceiling.png",
+ "celevator_car_wallpaper.png",
+ "celevator_cabinet_sides.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_wallpaper.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_ceiling.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_wallpaper.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_ceiling.png",
+ "celevator_cabinet_sides.png^celevator_car_side_center_overlay.png",
+ "celevator_car_wallpaper.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},
+ },
+ },
+ tiles = {
+ "celevator_cabinet_sides.png^celevator_car_top_misc.png",
+ "celevator_car_ceiling.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_wallpaper.png",
+ "celevator_cabinet_sides.png",
+ "celevator_car_wallpaper.png",
+ },
+ _tapehead = true,
+ },
+}
+
+celevator.car.register("standard",pieces,vector.new(2,3,3))
+
+for x=0,1,1 do
+ for y=0,2,1 do
+ for z=0,2,1 do
+ minetest.register_alias(string.format("celevator:car_%d%d%d",x,y,z),string.format("celevator:car_standard_%d%d%d",x,y,z))
+ end
+ end
+end
+
+minetest.register_node("celevator:car_standard",{
+ description = "Basic Elevator Car",
+ paramtype2 = "4dir",
+ buildable_to = true,
+ inventory_image = "celevator_car_inventory.png",
+ wield_image = "celevator_car_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_standard_%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,
+})
+
+minetest.register_alias("celevator:car","celevator:car_standard")
+
+celevator.car.types.standard.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_standard_%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/chatcommands.lua b/chatcommands.lua
new file mode 100644
index 0000000..bfd79c7
--- /dev/null
+++ b/chatcommands.lua
@@ -0,0 +1,181 @@
+minetest.register_chatcommand("carcall",{
+ description = "Places a car call at the specified landing on the specified elevator",
+ params = "<car ID> <landing number>",
+ func = function(name,param)
+ local carid,landing = string.match(param,"(%d+) (%d+)")
+ if not (carid and tonumber(carid)) then
+ return false,"Invalid car ID"
+ end
+ if not (landing and tonumber(landing)) then
+ return false,"Invalid landing number"
+ end
+ local carinfo = minetest.deserialize(celevator.storage:get_string("car"..carid))
+ if not (carinfo and carinfo.controllerpos) then
+ return false,"No such car or car info is missing"
+ end
+ if not celevator.controller.iscontroller(carinfo.controllerpos) then
+ return false,"Controller is missing"
+ end
+ if celevator.get_meta(carinfo.controllerpos):get_int("carid") ~= tonumber(carid) then
+ return false,"Controller found but with wrong ID"
+ end
+ if minetest.is_protected(carinfo.controllerpos,name) then
+ minetest.record_protection_violation(carinfo.controllerpos,name)
+ return false,"Controller is protected"
+ end
+ celevator.controller.run(carinfo.controllerpos,{
+ type = "remotemsg",
+ channel = "carcall",
+ msg = tonumber(landing),
+ })
+ return true,"Command sent"
+ end,
+})
+
+minetest.register_chatcommand("upcall",{
+ description = "Places an up hall call at the specified landing on the specified elevator or dispatcher",
+ params = "<car ID> <landing number>",
+ func = function(name,param)
+ local carid,landing = string.match(param,"(%d+) (%d+)")
+ if not (carid and tonumber(carid)) then
+ return false,"Invalid car ID"
+ end
+ if not (landing and tonumber(landing)) then
+ return false,"Invalid landing number"
+ end
+ local carinfo = minetest.deserialize(celevator.storage:get_string("car"..carid))
+ if not (carinfo and (carinfo.controllerpos or carinfo.dispatcherpos)) then
+ return false,"No such car or car info is missing"
+ end
+ if carinfo.controllerpos then
+ if not celevator.controller.iscontroller(carinfo.controllerpos) then
+ return false,"Controller is missing"
+ end
+ if celevator.get_meta(carinfo.controllerpos):get_int("carid") ~= tonumber(carid) then
+ return false,"Controller found but with wrong ID"
+ end
+ if minetest.is_protected(carinfo.controllerpos,name) then
+ minetest.record_protection_violation(carinfo.controllerpos,name)
+ return false,"Controller is protected"
+ end
+ --One of these will work depending on the mode, the other will be ignored
+ celevator.controller.run(carinfo.controllerpos,{
+ type = "remotemsg",
+ channel = "upcall",
+ msg = tonumber(landing),
+ })
+ celevator.controller.run(carinfo.controllerpos,{
+ type = "remotemsg",
+ channel = "swingupcall",
+ msg = tonumber(landing),
+ })
+ return true,"Command sent"
+ elseif carinfo.dispatcherpos then
+ if not celevator.dispatcher.isdispatcher(carinfo.dispatcherpos) then
+ return false,"Dispatcher is missing"
+ end
+ if celevator.get_meta(carinfo.dispatcherpos):get_int("carid") ~= tonumber(carid) then
+ return false,"Dispatcher found but with wrong ID"
+ end
+ if minetest.is_protected(carinfo.dispatcherpos,name) then
+ minetest.record_protection_violation(carinfo.dispatcherpos,name)
+ return false,"Dispatcher is protected"
+ end
+ celevator.dispatcher.run(carinfo.dispatcherpos,{
+ type = "remotemsg",
+ channel = "upcall",
+ msg = tonumber(landing),
+ })
+ return true,"Command sent"
+ end
+ end,
+})
+
+minetest.register_chatcommand("downcall",{
+ description = "Places a down hall call at the specified landing on the specified elevator or dispatcher",
+ params = "<car ID> <landing number>",
+ func = function(name,param)
+ local carid,landing = string.match(param,"(%d+) (%d+)")
+ if not (carid and tonumber(carid)) then
+ return false,"Invalid car ID"
+ end
+ if not (landing and tonumber(landing)) then
+ return false,"Invalid landing number"
+ end
+ local carinfo = minetest.deserialize(celevator.storage:get_string("car"..carid))
+ if not (carinfo and (carinfo.controllerpos or carinfo.dispatcherpos)) then
+ return false,"No such car or car info is missing"
+ end
+ if carinfo.controllerpos then
+ if not celevator.controller.iscontroller(carinfo.controllerpos) then
+ return false,"Controller is missing"
+ end
+ if celevator.get_meta(carinfo.controllerpos):get_int("carid") ~= tonumber(carid) then
+ return false,"Controller found but with wrong ID"
+ end
+ if minetest.is_protected(carinfo.controllerpos,name) then
+ minetest.record_protection_violation(carinfo.controllerpos,name)
+ return false,"Controller is protected"
+ end
+ --One of these will work depending on the mode, the other will be ignored
+ celevator.controller.run(carinfo.controllerpos,{
+ type = "remotemsg",
+ channel = "dncall",
+ msg = tonumber(landing),
+ })
+ celevator.controller.run(carinfo.controllerpos,{
+ type = "remotemsg",
+ channel = "swingdncall",
+ msg = tonumber(landing),
+ })
+ return true,"Command sent"
+ elseif carinfo.dispatcherpos then
+ if not celevator.dispatcher.isdispatcher(carinfo.dispatcherpos) then
+ return false,"Dispatcher is missing"
+ end
+ if celevator.get_meta(carinfo.dispatcherpos):get_int("carid") ~= tonumber(carid) then
+ return false,"Dispatcher found but with wrong ID"
+ end
+ if minetest.is_protected(carinfo.dispatcherpos,name) then
+ minetest.record_protection_violation(carinfo.dispatcherpos,name)
+ return false,"Dispatcher is protected"
+ end
+ celevator.dispatcher.run(carinfo.dispatcherpos,{
+ type = "remotemsg",
+ channel = "dncall",
+ msg = tonumber(landing),
+ })
+ return true,"Command sent"
+ end
+ end,
+})
+
+minetest.register_chatcommand("elevstatus",{
+ description = "View the status of the specified elevator",
+ params = "<car ID>",
+ func = function(_,param)
+ if not (param and tonumber(param)) then
+ return false,"Invalid car ID"
+ end
+ local carinfo = minetest.deserialize(celevator.storage:get_string("car"..param))
+ if not (carinfo and carinfo.controllerpos) then
+ return false,"No such car or car info is missing"
+ end
+ if not celevator.controller.iscontroller(carinfo.controllerpos) then
+ return false,"Controller is missing"
+ end
+ local controllermeta = celevator.get_meta(carinfo.controllerpos)
+ if controllermeta:get_int("carid") ~= tonumber(param) then
+ return false,"Controller found but with wrong ID"
+ end
+ local mem = minetest.deserialize(controllermeta:get_string("mem"))
+ if not mem then
+ return false,"Failed to load controller memory"
+ end
+ local infotext = controllermeta:get_string("infotext")
+ if mem.drive and mem.drive.status and mem.drive.status.vel and mem.drive.status.apos then
+ infotext = infotext..string.format(" - %0.02fm - %+0.02fm/s",mem.drive.status.apos,mem.drive.status.vel)
+ end
+ return true,infotext
+ end,
+})
diff --git a/controller.lua b/controller.lua
index 365cf73..2921f81 100644
--- a/controller.lua
+++ b/controller.lua
@@ -444,6 +444,9 @@ function celevator.controller.finish(pos,mem,changedinterrupts)
celevator.drives[drivetype].pibeep(drivepos)
end
end
+ if type(mem.drive.status) == "table" then
+ meta:set_string("vel",tostring(mem.drive.status.vel))
+ end
end
local node = celevator.get_node(pos)
local oldmem = minetest.deserialize(meta:get_string("mem")) or {}
@@ -451,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
@@ -636,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
@@ -646,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 eeb8814..1850a1e 100644
--- a/controllerfw.lua
+++ b/controllerfw.lua
@@ -48,13 +48,14 @@ local modenames = {
stop = "Emergency Stop",
mrinspect = "Machine Room Inspection",
carinspect = "Car Top Inspection",
- inspconflict = "Inspection Conflict",
+ inspconflict = "Inspection Conflict", --No longer used but some controllers may be in it at update time
fs1 = "Fire Service - Phase 1",
fs2 = "Fire Service - Phase 2",
fs2hold = "Fire Service - Phase 2 Hold",
indep = "Independent Service",
capture = "Captured",
test = "Test Mode",
+ swing = "Swing Operation",
}
local doorstates = {
@@ -74,6 +75,9 @@ local faultnames = {
drivebadorigin = "Drive Origin Invalid",
drivedoorinterlock = "Attempted to Move Doors With Car in Motion",
driveoutofbounds = "Target Position Out of Bounds",
+ drivenomachine = "Hoist Machine Missing",
+ drivemachinemismatch = "Drive<->Machine ID Mismatch",
+ drivecontrollermismatch = "Controller<->Drive ID Mismatch",
}
local function drivecmd(command)
@@ -93,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)
@@ -195,7 +199,7 @@ local function open()
interrupt(10,"opentimeout")
interrupt(nil,"closetimeout")
if mem.nudging then
- if mem.carstate == "normal" then
+ if (mem.carstate == "normal" or mem.carstate == "swing") then
interrupt(0,"nudge")
else
mem.nudging = false
@@ -228,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
@@ -275,6 +298,7 @@ if event.type == "program" then
inspectionspeed = 0.2,
indepunlock = {},
secoverrideusers = {},
+ swingcallwhennotswing = true,
}
end
elseif event.type == "ui" then
@@ -338,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)
@@ -428,16 +452,17 @@ elseif event.type == "ui" then
and (mem.carstate == "normal"
or mem.carstate == "test"
or mem.carstate == "capture"
- or mem.carstate == "indep")
+ or mem.carstate == "indep"
+ or mem.carstate == "swing")
then
mem.carcalls[i] = true
- elseif event.fields[string.format("upcall%d",i)] and mem.carstate == "normal" and not mem.capturesw then
+ elseif event.fields[string.format("upcall%d",i)] and (mem.carstate == "normal" or mem.carstate == "swing") and not mem.capturesw then
if mem.params.groupmode == "group" then
mem.swingupcalls[i] = true
else
mem.upcalls[i] = true
end
- elseif event.fields[string.format("downcall%d",i)] and mem.carstate == "normal" and not mem.capturesw then
+ elseif event.fields[string.format("downcall%d",i)] and (mem.carstate == "normal" or mem.carstate == "swing") and not mem.capturesw then
if mem.params.groupmode == "group" then
mem.swingdncalls[i] = true
else
@@ -503,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
@@ -556,7 +584,7 @@ elseif event.type == "ui" then
end
elseif event.iid == "opened" and mem.doorstate == "opening" then
mem.doorstate = "open"
- if mem.carstate == "normal" then
+ if (mem.carstate == "normal" or mem.carstate == "swing") then
interrupt(mem.params.doortimer,"close")
end
elseif event.iid == "close" and mem.doorstate == "open" then
@@ -578,9 +606,9 @@ elseif event.iid == "closed" and (mem.doorstate == "closing" or mem.doorstate ==
mem.carmotion = true
juststarted = true
end
-elseif event.type == "callbutton" and mem.carstate == "normal" then
+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
@@ -601,10 +629,15 @@ elseif event.type == "callbutton" and mem.carstate == "normal" then
elseif event.iid == "checkopen" then
if mem.drive.status.doorstate == "open" then
interrupt(0,"opened")
- if mem.carstate == "normal" or mem.carstate == "indep" or mem.carstate == "fs1" or mem.carstate == "fs2" or mem.carstate == "fs2hold" then
+ if mem.carstate == "normal"
+ or mem.carstate == "indep"
+ or mem.carstate == "fs1"
+ or mem.carstate == "fs2"
+ or mem.carstate == "fs2hold"
+ or mem.carstate == "swing" then
interrupt(nil,"opentimeout")
end
- if mem.carstate == "normal" and not mem.interrupts.nudge and mem.params.nudgetimer > 0 then
+ if (mem.carstate == "normal" or mem.carstate == "swing") and not mem.interrupts.nudge and mem.params.nudgetimer > 0 then
interrupt(mem.params.nudgetimer,"nudge")
end
else
@@ -625,7 +658,7 @@ elseif event.iid == "closetimeout" then
fault("closetimeout",true)
elseif event.type == "cop" then
local fields = event.fields
- if mem.carstate == "normal" or mem.carstate == "indep" or mem.carstate == "fs2" then
+ if mem.carstate == "normal" or mem.carstate == "indep" or mem.carstate == "fs2" or mem.carstate == "swing" then
for k,v in pairs(fields) do
if string.sub(k,1,7) == "carcall" then
local landing = tonumber(string.sub(k,8,-1))
@@ -649,7 +682,7 @@ elseif event.type == "cop" then
end
if v and landing and landing >= 1 and landing <= #mem.params.floorheights and secok then
if getpos() == landing then
- if mem.carstate == "normal" or mem.carstate == "indep" then
+ if mem.carstate == "normal" or mem.carstate == "indep" or mem.carstate == "swing" then
if mem.doorstate == "closing" and not mem.nudging then
open()
elseif mem.doorstate == "open" then
@@ -745,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
@@ -794,11 +833,11 @@ 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" then
+ elseif event.channel == "swingupcall" and swingstateok then
mem.swingupcalls[event.msg] = true
- elseif event.channel == "swingdncall" and mem.carstate == "normal" then
+ elseif event.channel == "swingdncall" and swingstateok then
mem.swingdncalls[event.msg] = true
- elseif event.channel == "carcall" and mem.carstate == "normal" then
+ elseif event.channel == "carcall" and (mem.carstate == "normal" or mem.carstate == "swing") then
mem.carcalls[event.msg] = true
send(event.source,"status",mem)
elseif event.channel == "fs1switch" then
@@ -810,38 +849,51 @@ 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" then
+ elseif event.channel == "swingupcall" and swingstateok then
mem.swingupcalls[event.msg] = true
- elseif event.channel == "swingdncall" and mem.carstate == "normal" then
+ elseif event.channel == "swingdncall" and swingstateok then
mem.swingdncalls[event.msg] = true
- elseif event.channel == "upcall" and mem.carstate == "normal" then
+ elseif event.channel == "upcall" and (mem.carstate == "normal" or mem.carstate == "swing") then
mem.upcalls[event.msg] = true
- elseif event.channel == "dncall" and mem.carstate == "normal" then
+ elseif event.channel == "dncall" and (mem.carstate == "normal" or mem.carstate == "swing") then
mem.dncalls[event.msg] = true
elseif event.channel == "groupupcancel" then
mem.groupupcalls[event.msg] = nil
elseif event.channel == "groupdncancel" then
mem.groupdncalls[event.msg] = nil
- elseif event.channel == "carcall" and mem.carstate == "normal" then
+ elseif event.channel == "carcall" and (mem.carstate == "normal" or mem.carstate == "swing") then
mem.carcalls[event.msg] = true
elseif event.channel == "security" and type(event.msg.floor) == "number" then
if mem.params.floornames[event.msg.floor] and event.msg.floor ~= (mem.params.mainlanding or 1) then
mem.params.carcallsecurity[event.msg.floor] = event.msg.mode
end
+ elseif event.channel == "swing" then
+ mem.swing = event.msg
+ if mem.carstate == "normal" and event.msg then
+ mem.carstate = "swing"
+ elseif mem.carstate == "swing" and not event.msg then
+ mem.carstate = "normal"
+ end
end
elseif event.type == "lightcurtain" and not mem.nudging then
- if mem.carstate == "normal" or mem.carstate == "indep" then
+ if mem.carstate == "normal" or mem.carstate == "indep" or mem.carstate == "swing" then
if mem.doorstate == "closing" then
open()
- elseif mem.doorstate == "open" and mem.carstate == "normal" then
+ elseif mem.doorstate == "open" and (mem.carstate == "normal" or mem.carstate == "swing") then
interrupt(mem.params.doortimer,"close")
end
end
-elseif event.iid == "nudge" and mem.carstate == "normal" then
+elseif event.iid == "nudge" and (mem.carstate == "normal" or mem.carstate == "swing") then
mem.nudging = true
if mem.doorstate == "open" then
close(true)
@@ -901,19 +953,6 @@ elseif mem.controllerstopsw or mem.screenstate == "floortable" or mem.screenstat
mem.direction = nil
interrupt(nil,"opentimeout")
interrupt(nil,"closetimeout")
-elseif mem.controllerinspectsw and mem.cartopinspectsw then
- mem.carstate = "inspconflict"
- mem.carcalls = {}
- mem.upcalls = {}
- mem.dncalls = {}
- mem.swingupcalls = {}
- mem.swingdncalls = {}
- mem.groupupcalls = {}
- mem.groupdncalls = {}
- mem.direction = nil
- drivecmd({command="estop"})
- interrupt(nil,"opentimeout")
- interrupt(nil,"closetimeout")
elseif mem.controllerinspectsw and not mem.cartopinspectsw then
mem.carstate = "mrinspect"
mem.carcalls = {}
@@ -927,7 +966,7 @@ elseif mem.controllerinspectsw and not mem.cartopinspectsw then
interrupt(nil,"opentimeout")
interrupt(nil,"closetimeout")
if oldstate ~= "mrinspect" then drivecmd({command="estop"}) end
-elseif mem.cartopinspectsw and not mem.controllerinspectsw then
+elseif mem.cartopinspectsw then
mem.carstate = "carinspect"
mem.carcalls = {}
mem.upcalls = {}
@@ -1022,9 +1061,9 @@ elseif mem.indsw then
if oldstate == "stop" or oldstate == "mrinspect" or oldstate == "fault" then
mem.carstate = "resync"
gotofloor(getpos())
- elseif oldstate == "normal" and (mem.doorstate == "closed" or mem.doorstate == "closing") and not (mem.carmotion or juststarted) then
+ elseif (oldstate == "normal" or oldstate == "swing") and (mem.doorstate == "closed" or mem.doorstate == "closing") and not (mem.carmotion or juststarted) then
open()
- elseif oldstate == "normal" and mem.doorstate == "open" then
+ elseif (oldstate == "normal" or oldstate == "swing") and mem.doorstate == "open" then
interrupt(nil,"close")
end
elseif mem.testsw then
@@ -1060,14 +1099,18 @@ else
if (oldstate == "fs1" or oldstate == "fs2" or oldstate == "fs2hold") and mem.doorstate == "open" then
interrupt(mem.params.doortimer,"close")
end
- mem.carstate = "normal"
+ mem.carstate = (mem.swing and "swing" or "normal")
elseif oldstate == "indep" then
- mem.carstate = "normal"
+ mem.carstate = (mem.swing and "swing" or "normal")
if mem.doorstate == "open" then interrupt(mem.params.doortimer,"close") end
end
end
-if mem.carstate == "normal" and oldstate ~= "normal" and mem.doorstate ~= "closed" and mem.params.nudgetimer > 0 and not mem.interrupts.nudge then
+if (mem.carstate == "normal" or mem.carstate == "swing")
+ and oldstate ~= "normal" and oldstate ~= "swing"
+ and mem.doorstate ~= "closed"
+ and mem.params.nudgetimer > 0
+ and not mem.interrupts.nudge then
interrupt(mem.params.nudgetimer,"nudge")
elseif mem.carstate ~= "normal" and oldstate == "normal" then
interrupt(nil,"nudge")
@@ -1079,7 +1122,7 @@ if mem.carmotion then
interrupt(0.1,"checkdrive")
else
local hallcall = mem.upcalls[getpos()] or mem.dncalls[getpos()]
- if mem.carstate == "normal" or mem.carstate == "indep" or mem.carstate == "fs1" or mem.carstate == "fs2" then
+ if mem.carstate == "normal" or mem.carstate == "indep" or mem.carstate == "fs1" or mem.carstate == "fs2" or mem.carstate == "swing" then
mem.carcalls[getpos()] = nil
if mem.direction == "up" then
mem.upcalls[getpos()] = nil
@@ -1141,7 +1184,7 @@ if mem.carmotion then
elseif mem.capturesw then
mem.carstate = "capture"
else
- mem.carstate = "normal"
+ mem.carstate = (mem.swing and "swing" or "normal")
end
end
end
@@ -1164,6 +1207,7 @@ local canprocesscalls = {
test = true,
indep = true,
fs2 = true,
+ swing = true,
}
if canprocesscalls[mem.carstate] and mem.doorstate == "closed" then
@@ -1212,14 +1256,14 @@ if canprocesscalls[mem.carstate] and mem.doorstate == "closed" then
gotofloor(gethighestdowncall())
end
end
- if mem.carstate == "normal" and mem.capturesw and not mem.direction then
+ if (mem.carstate == "normal" or mem.carstate == "swing") and mem.capturesw and not mem.direction then
mem.upcalls = {}
mem.dncalls = {}
mem.carstate = "capture"
elseif mem.carstate == "capture" and mem.direction then
- mem.carstate = "normal"
+ mem.carstate = (mem.swing and "swing" or "normal")
end
- elseif (mem.carstate == "normal" or mem.carstate == "capture" or mem.carstate == "test") and mem.carmotion then
+ elseif (mem.carstate == "normal" or mem.carstate == "capture" or mem.carstate == "test" or mem.carstate == "swing") and mem.carmotion then
if mem.drive.status.vel > 0 then
local nextup = getnextcallabove("up")
if nextup then
@@ -1471,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
@@ -1533,7 +1578,7 @@ local hidepi = {
}
if hidepi[mem.carstate] then mem.pifloor = "--" end
-if mem.pifloor ~= oldpifloor and mem.carstate == "normal" then
+if mem.pifloor ~= oldpifloor and (mem.carstate == "normal" or mem.carstate == "swing") then
drivecmd({command="pibeep"})
end
@@ -1544,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]
@@ -1553,9 +1599,9 @@ mem.flash_is = mem.carstate == "indep"
mem.flash_blank = mem.nudging
mem.lanterns = {}
-if mem.carstate == "normal" and (mem.doorstate == "open" or mem.doorstate == "opening") then
+if (mem.carstate == "normal" or mem.carstate == "swing") and (mem.doorstate == "open" or mem.doorstate == "opening") then
mem.lanterns[getpos()] = mem.direction
-elseif mem.carstate == "normal" and mem.doorstate == "closed" and mem.drive.status then
+elseif (mem.carstate == "normal" or mem.carstate == "swing") and mem.doorstate == "closed" and mem.drive.status then
local ring = false
if mem.drive.status.vel > 0 and mem.drive.status.neareststop > mem.drive.status.dpos then
ring = true
diff --git a/crafts.lua b/crafts.lua
index fd4390d..13a8b93 100644
--- a/crafts.lua
+++ b/crafts.lua
@@ -1,81 +1,235 @@
+local xcompat_available = minetest.global_exists("xcompat")
+local m = xcompat_available and table.copy(xcompat.materials) or {}
+
+-- provide required materials if xcompat is missing
+if not xcompat_available then
+ if minetest.get_modpath("default") then
+ m.empty_bucket = "bucket:bucket_empty"
+ m.iron_lump = "default:iron_lump"
+ m.steel_ingot = "default:steel_ingot"
+ m.glass = "default:glass"
+ m.sandstone = "default:sandstone"
+ m.copper_ingot = "default:copper_ingot"
+ m.copper_block = "default:copperblock"
+ m.gold_block = "default:goldblock"
+ m.tin_block = "default:tinblock"
+ m.mese = "default:mese"
+ m.pick_steel = "default:pick_steel"
+ m.torch = "default:torch"
+ elseif minetest.get_modpath("mcl_core") then
+ m.empty_bucket = "mcl_buckets:bucket_empty"
+ m.iron_lump = "mcl_raw_ores:raw_iron"
+ m.steel_ingot = "mcl_core:iron_ingot"
+ m.glass = "mcl_core:glass"
+ m.sandstone = "mcl_core:sandstone"
+ m.copper_ingot = "mcl_copper:copper_ingot"
+ m.copper_block = "mcl_copper:block"
+ m.gold_block = "mcl_core:goldblock"
+ m.tin_block = "mcl_core:ironblock"
+ 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"
+ m.dye_blue = "dye:blue"
+ m.dye_red = "dye:red"
+ m.dye_green = "dye:green"
+ elseif minetest.get_modpath("mcl_dyes") then
+ m.dye_black = "mcl_dyes:black"
+ m.dye_blue = "mcl_dyes:blue"
+ m.dye_red = "mcl_dyes:red"
+ m.dye_green = "mcl_dyes:green"
+ elseif minetest.get_modpath("mcl_dye") then
+ m.dye_black = "mcl_dye:black"
+ m.dye_blue = "mcl_dye:blue"
+ m.dye_red = "mcl_dye:red"
+ m.dye_green = "mcl_dye:green"
+ end
+end
+
+if minetest.get_modpath("basic_materials") then
+ m.steel_bar = "basic_materials:steel_bar"
+ m.steel_strip = "basic_materials:steel_strip"
+ m.steel_gear = "basic_materials:gear_steel"
+ m.plastic_sheet = "basic_materials:plastic_sheet"
+ m.silicon = "basic_materials:silicon"
+ m.copper_wire = "basic_materials:copper_wire"
+ m.ic = "basic_materials:ic"
+ m.motor = "basic_materials:motor"
+else
+ m.steel_bar = m.gold_block
+ m.steel_strip = m.gold_block
+ m.steel_gear = m.gold_block
+ m.plastic_sheet = m.tin_block
+ m.silicon = m.sandstone
+ m.copper_wire = m.copper_ingot
+ m.ic = m.copper_block
+ m.motor = m.pick_steel
+end
+
+-- vl mesecons has colored lightstone with different naming scheme
+local mc_lightstone = minetest.registered_nodes["mesecons_lightstone:lightstone_blue_off"]
+local vl_lightstone = minetest.registered_nodes["mesecons_lightstone:lightstone_off_blue"]
+if mc_lightstone then
+ -- real mesecons_lightstone
+ m.lightstone_blue = "mesecons_lightstone:lightstone_blue_off"
+ m.lightstone_green = "mesecons_lightstone:lightstone_green_off"
+ m.lightstone_red = "mesecons_lightstone:lightstone_red_off"
+ m.lightstone_white = "mesecons_lightstone:lightstone_white_off"
+ m.lightstone_extra = ""
+elseif vl_lightstone then
+ -- vl mesecons_lightstone
+ m.lightstone_blue = "mesecons_lightstone:lightstone_off_blue"
+ m.lightstone_green = "mesecons_lightstone:lightstone_off_green"
+ m.lightstone_red = "mesecons_lightstone:lightstone_off_red"
+ m.lightstone_white = "mesecons_lightstone:lightstone_off_white"
+ m.lightstone_extra = ""
+else
+ m.lightstone_blue = m.dye_blue
+ m.lightstone_green = m.dye_green
+ m.lightstone_red = m.dye_red
+ m.lightstone_white = m.torch
+ m.lightstone_extra = m.torch
+end
+
+local mesecons_button = minetest.registered_nodes["mesecons_button:button_off"]
+if mesecons_button then
+ -- real mesecons
+ m.button = mesecons_button.name
+elseif minetest.get_modpath("mcl_core") then
+ m.button = "group:button"
+else
+ m.button = m.mese
+end
+
+if minetest.get_modpath("mesecons_switch") then
+ -- real mesecons
+ m.switch = "mesecons_switch:mesecon_switch_off"
+elseif minetest.get_modpath("mcl_lever") then
+ -- mcla
+ m.switch = "mcl_lever:lever_off"
+elseif minetest.get_modpath("mesecons_walllever") then
+ -- other mcl
+ m.switch = "mesecons_walllever:wall_lever_off"
+else
+ m.switch = m.mese
+end
+
+if minetest.get_modpath("digilines") then
+ m.lcd = "digilines:lcd"
+else
+ m.lcd = m.mese
+end
+
minetest.register_craft({
output = "celevator:buffer_oil",
recipe = {
- {"","basic_materials:steel_bar",""},
- {"default:steel_ingot","bucket:bucket_empty","default:steel_ingot"},
- {"default:steel_ingot","default:steel_ingot","default:steel_ingot"},
+ {"",m.steel_bar,""},
+ {m.steel_ingot,m.empty_bucket,m.steel_ingot},
+ {m.steel_ingot,m.steel_ingot,m.steel_ingot},
},
})
minetest.register_craft({
output = "celevator:buffer_rubber",
recipe = {
- {"basic_materials:plastic_sheet","dye:black","basic_materials:plastic_sheet"},
- {"","default:steel_ingot",""},
- {"default:steel_ingot","default:steel_ingot","default:steel_ingot"},
+ {m.plastic_sheet,m.dye_black,m.plastic_sheet},
+ {"",m.steel_ingot,""},
+ {m.steel_ingot,m.steel_ingot,m.steel_ingot},
},
})
minetest.register_craft({
output = "celevator:callbutton_both",
recipe = {
- {"basic_materials:steel_strip","mesecons_lightstone:lightstone_blue_off","mesecons_button:button_off"},
- {"basic_materials:steel_strip","",""},
- {"basic_materials:steel_strip","mesecons_lightstone:lightstone_blue_off","mesecons_button:button_off"},
+ {m.steel_strip,m.lightstone_blue,m.button},
+ {m.steel_strip,m.lightstone_extra,""},
+ {m.steel_strip,m.lightstone_blue,m.button},
},
})
minetest.register_craft({
output = "celevator:callbutton_up",
recipe = {
- {"basic_materials:steel_strip","mesecons_lightstone:lightstone_blue_off","mesecons_button:button_off"},
- {"basic_materials:steel_strip","",""},
- {"basic_materials:steel_strip","",""},
+ {m.steel_strip,m.lightstone_blue,m.button},
+ {m.steel_strip,m.lightstone_extra,""},
+ {m.steel_strip,"",""},
},
})
minetest.register_craft({
output = "celevator:callbutton_down",
recipe = {
- {"basic_materials:steel_strip","",""},
- {"basic_materials:steel_strip","",""},
- {"basic_materials:steel_strip","mesecons_lightstone:lightstone_blue_off","mesecons_button:button_off"},
+ {m.steel_strip,"",""},
+ {m.steel_strip,m.lightstone_extra,""},
+ {m.steel_strip,m.lightstone_blue,m.button},
+ },
+})
+
+minetest.register_craft({
+ output = "celevator:car_standard",
+ recipe = {
+ {m.steel_ingot,m.steel_ingot,m.steel_ingot},
+ {m.button,"celevator:hwdoor_glass",m.steel_ingot},
+ {m.switch,m.steel_ingot,m.steel_ingot},
+ },
+})
+
+minetest.register_craft({
+ output = "celevator:car_glassback",
+ recipe = {
+ {m.steel_ingot,m.steel_ingot,m.steel_ingot},
+ {m.button,"celevator:hwdoor_glass",m.glass},
+ {m.switch,m.steel_ingot,m.steel_ingot},
+ },
+})
+
+minetest.register_craft({
+ output = "celevator:car_metal",
+ recipe = {
+ {"",m.steel_strip,""},
+ {m.steel_strip,"celevator:car_standard",m.steel_strip},
+ {"",m.steel_strip,""},
},
})
minetest.register_craft({
- output = "celevator:car",
+ output = "celevator:car_metal_glassback",
recipe = {
- {"default:steel_ingot","default:steel_ingot","default:steel_ingot"},
- {"mesecons_button:button_off","celevator:hwdoor_glass","default:steel_ingot"},
- {"mesecons_switch:mesecon_switch_off","default:steel_ingot","default:steel_ingot"},
+ {"",m.steel_strip,""},
+ {m.steel_strip,"celevator:car_glassback",m.steel_strip},
+ {"",m.steel_strip,""},
},
})
minetest.register_craft({
output = "celevator:controller",
recipe = {
- {"basic_materials:steel_strip","basic_materials:ic","basic_materials:steel_strip"},
- {"basic_materials:steel_strip","basic_materials:ic","basic_materials:steel_strip"},
- {"basic_materials:steel_strip","default:steel_ingot","basic_materials:steel_strip"},
+ {m.steel_strip,m.ic,m.steel_strip},
+ {m.steel_strip,m.ic,m.steel_strip},
+ {m.steel_strip,m.steel_ingot,m.steel_strip},
},
})
minetest.register_craft({
output = "celevator:dispatcher",
recipe = {
- {"basic_materials:steel_strip","basic_materials:ic","basic_materials:steel_strip"},
- {"basic_materials:steel_strip","basic_materials:ic","basic_materials:steel_strip"},
- {"basic_materials:steel_strip","basic_materials:steel_strip","basic_materials:steel_strip"},
+ {m.steel_strip,m.ic,m.steel_strip},
+ {m.steel_strip,m.ic,m.steel_strip},
+ {m.steel_strip,m.steel_strip,m.steel_strip},
},
})
minetest.register_craft({
output = "celevator:drive",
recipe = {
- {"basic_materials:silicon","basic_materials:steel_strip","basic_materials:silicon"},
- {"basic_materials:silicon","basic_materials:ic","basic_materials:silicon"},
- {"basic_materials:silicon","basic_materials:steel_strip","basic_materials:silicon"},
+ {m.silicon,m.steel_strip,m.silicon},
+ {m.silicon,m.ic,m.silicon},
+ {m.silicon,m.steel_strip,m.silicon},
},
})
@@ -83,8 +237,8 @@ minetest.register_craft({
output = "celevator:digilines_io",
recipe = {
{"","",""},
- {"","basic_materials:ic",""},
- {"digilines:wire_std_00000000","basic_materials:steel_strip","digilines:wire_std_00000000"},
+ {"",m.ic,""},
+ {"digilines:wire_std_00000000",m.steel_strip,"digilines:wire_std_00000000"},
},
})
@@ -92,8 +246,8 @@ minetest.register_craft({
output = "celevator:mesecons_input_off",
recipe = {
{"","",""},
- {"","basic_materials:ic",""},
- {"mesecons:wire_00000000_off","basic_materials:steel_strip","basic_materials:steel_strip"},
+ {"",m.ic,""},
+ {"mesecons:wire_00000000_off",m.steel_strip,m.steel_strip},
},
})
@@ -101,69 +255,78 @@ minetest.register_craft({
output = "celevator:mesecons_output_off",
recipe = {
{"","",""},
- {"","basic_materials:ic",""},
- {"basic_materials:steel_strip","basic_materials:steel_strip","mesecons:wire_00000000_off"},
+ {"",m.ic,""},
+ {m.steel_strip,m.steel_strip,"mesecons:wire_00000000_off"},
},
})
minetest.register_craft({
output = "celevator:fs1switch_off",
recipe = {
- {"basic_materials:steel_strip","mesecons_lightstone:lightstone_red_off",""},
- {"basic_materials:steel_strip","mesecons_switch:mesecon_switch_off","dye:red"},
- {"basic_materials:steel_strip","",""},
+ {m.steel_strip,m.lightstone_red,m.lightstone_extra},
+ {m.steel_strip,m.switch,m.dye_red},
+ {m.steel_strip,"",""},
},
})
minetest.register_craft({
output = "celevator:guide_rail 10",
recipe = {
- {"basic_materials:steel_strip","default:steel_ingot","basic_materials:steel_strip"},
- {"basic_materials:steel_strip","default:steel_ingot","basic_materials:steel_strip"},
- {"basic_materials:steel_strip","default:steel_ingot","basic_materials:steel_strip"},
+ {m.steel_strip,m.steel_ingot,m.steel_strip},
+ {m.steel_strip,m.steel_ingot,m.steel_strip},
+ {m.steel_strip,m.steel_ingot,m.steel_strip},
},
})
minetest.register_craft({
output = "celevator:guide_rail_bracket",
recipe = {
- {"basic_materials:steel_strip","celevator:guide_rail","basic_materials:steel_strip"},
+ {m.steel_strip,"celevator:guide_rail",m.steel_strip},
},
})
minetest.register_craft({
output = "celevator:hwdoor_glass",
recipe = {
- {"basic_materials:steel_bar","basic_materials:steel_bar","basic_materials:steel_bar"},
- {"default:glass","basic_materials:steel_bar","default:glass"},
- {"basic_materials:steel_bar","basic_materials:steel_bar","basic_materials:steel_bar"},
+ {m.steel_bar,m.steel_bar,m.steel_bar},
+ {m.glass,m.steel_bar,m.glass},
+ {m.steel_bar,m.steel_bar,m.steel_bar},
+ },
+})
+
+minetest.register_craft({
+ output = "celevator:hwdoor_steel",
+ recipe = {
+ {m.steel_bar,m.steel_bar,m.steel_bar},
+ {m.steel_strip,m.steel_bar,m.steel_strip},
+ {m.steel_bar,m.steel_bar,m.steel_bar},
},
})
minetest.register_craft({
output = "celevator:lantern_up",
recipe = {
- {"basic_materials:steel_strip",""},
- {"basic_materials:steel_strip","mesecons_lightstone:lightstone_green_off"},
- {"basic_materials:steel_strip",""},
+ {m.steel_strip,m.lightstone_green},
+ {m.steel_strip,m.lightstone_extra},
+ {m.steel_strip,""},
},
})
minetest.register_craft({
output = "celevator:lantern_down",
recipe = {
- {"basic_materials:steel_strip",""},
- {"basic_materials:steel_strip","mesecons_lightstone:lightstone_red_off"},
- {"basic_materials:steel_strip",""},
+ {m.steel_strip,""},
+ {m.steel_strip,m.lightstone_extra},
+ {m.steel_strip,m.lightstone_red},
},
})
minetest.register_craft({
output = "celevator:lantern_both",
recipe = {
- {"basic_materials:steel_strip","mesecons_lightstone:lightstone_green_off"},
- {"basic_materials:steel_strip",""},
- {"basic_materials:steel_strip","mesecons_lightstone:lightstone_red_off"},
+ {m.steel_strip,m.lightstone_green},
+ {m.steel_strip,m.lightstone_extra},
+ {m.steel_strip,m.lightstone_red},
},
})
@@ -218,18 +381,18 @@ minetest.register_craft({
minetest.register_craft({
output = "celevator:machine",
recipe = {
- {"basic_materials:gear_steel","basic_materials:copper_wire",""},
- {"basic_materials:steel_bar","basic_materials:steel_bar","basic_materials:motor"},
- {"default:steel_ingot","default:steel_ingot","default:steel_ingot"},
+ {m.steel_gear,m.copper_wire,""},
+ {m.steel_bar,m.steel_bar,m.motor},
+ {m.steel_ingot,m.steel_ingot,m.steel_ingot},
},
})
minetest.register_craft({
output = "celevator:pi",
recipe = {
- {"basic_materials:steel_strip",""},
- {"mesecons_lightstone:lightstone_red_off","digilines:lcd"},
- {"basic_materials:steel_strip",""},
+ {m.steel_strip,m.lightstone_extra},
+ {m.lightstone_red,m.lcd},
+ {m.steel_strip,m.lightstone_extra},
},
})
@@ -263,9 +426,9 @@ minetest.register_craft({
minetest.register_craft({
output = "celevator:tape 15",
recipe = {
- {"basic_materials:steel_strip","","basic_materials:steel_strip"},
- {"basic_materials:steel_strip","basic_materials:steel_strip","basic_materials:steel_strip"},
- {"basic_materials:steel_strip","","basic_materials:steel_strip"},
+ {m.steel_strip,"",m.steel_strip},
+ {m.steel_strip,m.steel_strip,m.steel_strip},
+ {m.steel_strip,"",m.steel_strip},
},
})
@@ -274,8 +437,8 @@ minetest.register_craft({
type = "shapeless",
recipe = {
"celevator:tape",
- "default:iron_lump",
- "basic_materials:plastic_sheet",
+ m.iron_lump,
+ m.plastic_sheet,
},
})
@@ -284,15 +447,32 @@ minetest.register_craft({
type = "shapeless",
recipe = {
"celevator:tape",
- "basic_materials:steel_strip",
+ m.steel_strip,
},
})
minetest.register_craft({
output = "celevator:dbdkiosk",
recipe = {
- {"basic_materials:steel_strip","basic_materials:ic","default:glass"},
- {"basic_materials:steel_strip","mesecons_lightstone:lightstone_white_off","default:glass"},
- {"basic_materials:steel_strip","","default:glass"},
+ {m.steel_strip,m.ic,m.glass},
+ {m.steel_strip,m.lightstone_white,m.glass},
+ {m.steel_strip,"",m.glass},
+ },
+})
+
+minetest.register_craft({
+ output = "celevator:genericswitch",
+ recipe = {
+ {m.steel_strip,"",""},
+ {m.steel_strip,m.switch,m.dye_black},
+ {m.steel_strip,"",""},
+ },
+})
+
+minetest.register_craft({
+ output = "celevator:governor",
+ recipe = {
+ {m.steel_strip,m.steel_bar,m.button},
+ {m.steel_strip,m.steel_gear,m.steel_strip},
},
})
diff --git a/decorations.lua b/decorations.lua
index 847c06a..7c408e4 100644
--- a/decorations.lua
+++ b/decorations.lua
@@ -304,7 +304,7 @@ end
minetest.register_abm({
label = "Spawn tapeheads",
- nodenames = {"celevator:car_122"},
+ nodenames = {"group:_celevator_car_spawnstapehead"},
neighbors = {"celevator:tape","celevator:tape_magnets","celevator:tape_bracket"},
interval = 1,
chance = 1,
diff --git a/digilines.lua b/digilines.lua
index 4b30345..8f5c220 100644
--- a/digilines.lua
+++ b/digilines.lua
@@ -158,6 +158,18 @@ local function handledigilines(pos,node,channel,msg)
celevator.controller.run(carinfo.controllerpos,{
type = "mrsmoke",
})
+ elseif msg.command == "swingon" then
+ celevator.controller.run(carinfo.controllerpos,{
+ type = "remotemsg",
+ channel = "swing",
+ msg = true,
+ })
+ elseif msg.command == "swingoff" then
+ celevator.controller.run(carinfo.controllerpos,{
+ type = "remotemsg",
+ channel = "swing",
+ msg = false,
+ })
end
end
end
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 2a1fec0..0bca94b 100644
--- a/docs/celevator_controller_manual.pdf
+++ b/docs/celevator_controller_manual.pdf
Binary files differ
diff --git a/docs/file_sources b/docs/file_sources
index 4bf263d..9de4fc7 100644
--- a/docs/file_sources
+++ b/docs/file_sources
@@ -1,4 +1,6 @@
-All code: Written by cheapie
+Code: Written by the following contributors:
+* cheapie
+* j-r (Jürgen Rühle)
All textures: Hand-drawn by cheapie using GIMP
diff --git a/doors.lua b/doors.lua
index 4443c5d..8528449 100644
--- a/doors.lua
+++ b/doors.lua
@@ -9,7 +9,7 @@ local function placesill(pos,node)
end
local yaw = minetest.dir_to_yaw(minetest.fourdir_to_dir(node.param2))
local entity = minetest.add_entity(pos,"celevator:door_sill")
- if node.name == "celevator:hwdoor_slow_glass_bottom" then
+ if node.name == "celevator:hwdoor_slow_glass_bottom" or node.name == "celevator:hwdoor_slow_steel_bottom" then
entity:set_properties({
wield_item = "celevator:door_sill_double",
})
@@ -199,6 +199,182 @@ minetest.register_node("celevator:hwdoor_slow_glass_top",{
},
})
+minetest.register_node("celevator:hwdoor_fast_steel_bottom",{
+ description = "Steel Hoistway Door (fast, bottom - you hacker you!)",
+ tiles = {
+ "celevator_transparent.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_metal.png",
+ "celevator_door_metal.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ _celevator_hwdoor_root = 1,
+ oddly_breakable_by_hand = 2,
+ },
+ drop = "celevator:hwdoor_steel",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.4,0.5,0.5,0.5},
+ },
+ },
+ after_dig_node = function(pos,node)
+ local erefs = minetest.get_objects_inside_radius(pos,1.5)
+ for _,ref in pairs(erefs) do
+ if ref:get_luaentity() and ref:get_luaentity().name == "celevator:door_sill" then ref:remove() end
+ end
+ local facedir = minetest.dir_to_yaw(minetest.fourdir_to_dir(node.param2))
+ local xnames = {
+ [0] = "fast",
+ [1] = "slow",
+ }
+ local ynames = {
+ [0] = "bottom",
+ [1] = "middle",
+ [2] = "top",
+ }
+ for x=0,1,1 do
+ for y=0,2,1 do
+ local piecename = string.format("celevator:hwdoor_%s_steel_%s",xnames[x],ynames[y])
+ local pieceoffset = vector.new(x,y,0)
+ local piecepos = vector.add(pos,vector.rotate_around_axis(pieceoffset,vector.new(0,1,0),facedir))
+ if minetest.get_node(piecepos).name == piecename then minetest.remove_node(piecepos) end
+ end
+ end
+ end,
+})
+
+minetest.register_node("celevator:hwdoor_fast_steel_middle",{
+ description = "Steel Hoistway Door (fast, middle - you hacker you!)",
+ tiles = {
+ "celevator_transparent.png",
+ "celevator_transparent.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_metal.png",
+ "celevator_door_metal.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.4,0.5,0.5,0.5},
+ },
+ },
+})
+
+minetest.register_node("celevator:hwdoor_fast_steel_top",{
+ description = "Steel Hoistway Door (fast, top - you hacker you!)",
+ tiles = {
+ "celevator_door_glass_edge.png",
+ "celevator_transparent.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_metal.png",
+ "celevator_door_metal.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.4,0.5,0.5,0.5},
+ },
+ },
+})
+
+minetest.register_node("celevator:hwdoor_slow_steel_bottom",{
+ description = "Steel Hoistway Door (slow, bottom - you hacker you!)",
+ tiles = {
+ "celevator_transparent.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_metal.png",
+ "celevator_door_metal.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.3,0.5,0.5,0.4},
+ },
+ },
+})
+
+minetest.register_node("celevator:hwdoor_slow_steel_middle",{
+ description = "Steel Hoistway Door (slow, middle - you hacker you!)",
+ tiles = {
+ "celevator_transparent.png",
+ "celevator_transparent.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_metal.png",
+ "celevator_door_metal.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.3,0.5,0.5,0.4},
+ },
+ },
+})
+
+minetest.register_node("celevator:hwdoor_slow_steel_top",{
+ description = "Steel Hoistway Door (slow, top - you hacker you!)",
+ tiles = {
+ "celevator_door_glass_edge.png",
+ "celevator_transparent.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_metal.png",
+ "celevator_door_metal.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.3,0.5,0.5,0.4},
+ },
+ },
+})
+
minetest.register_node("celevator:hwdoor_placeholder",{
description = "Hoistway Door Open-State Placeholder (you hacker you!)",
groups = {
@@ -255,6 +431,10 @@ function celevator.doors.hwopen(pos,drivepos)
oldnodes[i] = celevator.get_node(position)
end
local erefs = celevator.drives.entity.nodestoentities(positions,"celevator:hwdoor_moving")
+ local doortype = "glass"
+ if oldnodes[1].name == "celevator:hwdoor_slow_steel_bottom" then
+ doortype = "steel"
+ end
hwdoors_moving[hash] = {
direction = "open",
positions = positions,
@@ -263,6 +443,7 @@ function celevator.doors.hwopen(pos,drivepos)
opendir = vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2),
drivepos = drivepos,
param2 = param2,
+ doortype = doortype,
}
celevator.doors.erefs[hash] = erefs
celevator.storage:set_string("hwdoors_moving",minetest.serialize(hwdoors_moving))
@@ -270,8 +451,10 @@ function celevator.doors.hwopen(pos,drivepos)
local pmeta = celevator.get_meta(pos)
pmeta:set_string("data",minetest.serialize(hwdoors_moving[hash]))
pmeta:set_string("state","opening")
+ pmeta:set_string("doortype",doortype)
local carpos = vector.add(pos,fdir)
- if celevator.get_node(carpos).name == "celevator:car_000" then
+ local carndef = minetest.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
celevator.doors.caropen(carpos)
end
elseif hwdoors_moving[hash].direction == "close" then
@@ -280,7 +463,8 @@ function celevator.doors.hwopen(pos,drivepos)
celevator.storage:set_string("hwdoors_moving",minetest.serialize(hwdoors_moving))
local fdir = minetest.fourdir_to_dir(hwdoors_moving[hash].param2)
local carpos = vector.add(pos,fdir)
- if celevator.get_node(carpos).name == "celevator:car_000" then
+ local carndef = minetest.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
celevator.doors.caropen(carpos)
end
minetest.set_node(pos,{name="celevator:hwdoor_placeholder",param2=hwdoors_moving[hash].param2})
@@ -301,7 +485,8 @@ function celevator.doors.hwclose(pos,drivepos,nudge)
if state ~= "open" then return end
local fdir = minetest.fourdir_to_dir(celevator.get_node(pos).param2)
local carpos = vector.add(pos,fdir)
- if celevator.get_node(carpos).name == "celevator:car_000" then
+ local carndef = minetest.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
celevator.doors.carclose(carpos,nudge)
end
local data = minetest.deserialize(pmeta:get_string("data"))
@@ -493,7 +678,8 @@ minetest.register_entity("celevator:car_door",{
},
})
-function celevator.doors.spawncardoors(pos,dir)
+function celevator.doors.spawncardoors(pos,dir,doortype,replace)
+ if not doortype then doortype = "glass" end
local refs = {}
for x=2,1,-1 do
for y=1,3,1 do
@@ -501,7 +687,15 @@ function celevator.doors.spawncardoors(pos,dir)
local doorpos = vector.add(pos,vector.rotate_around_axis(vector.new(x-2,y-1,0),vector.new(0,1,0),yaw))
local xnames = {"slow","fast"}
local ynames = {"bottom","middle","top"}
- local nname = string.format("celevator:hwdoor_%s_glass_%s",xnames[x],ynames[y])
+ local nname = string.format("celevator:hwdoor_%s_%s_%s",xnames[x],doortype,ynames[y])
+ if replace then
+ local oldrefs = minetest.get_objects_inside_radius(doorpos,0.1)
+ for _,i in pairs(oldrefs) do
+ if i:get_luaentity() and i:get_luaentity().name == "celevator:car_door" then
+ i:remove()
+ end
+ end
+ end
local ref = minetest.add_entity(doorpos,"celevator:car_door")
ref:set_yaw(yaw)
ref:set_properties({
@@ -589,7 +783,9 @@ function celevator.doors.carclose(pos,nudge)
local dir = minetest.fourdir_to_dir(celevator.get_node(pos).param2)
data.direction = "close"
data.time = 0
- local erefs = celevator.doors.spawncardoors(pos,dir)
+ local doortype = meta:get_string("doortype")
+ if (not doortype) or doortype == "" then doortype = "glass" end
+ local erefs = celevator.doors.spawncardoors(pos,dir,doortype)
local soffset = data.opendir
local foffset = vector.multiply(soffset,2)
for i=1,3,1 do
@@ -619,7 +815,7 @@ end
minetest.register_abm({
label = "Respawn car doors",
- nodenames = {"celevator:car_000"},
+ nodenames = {"group:_celevator_car_root"},
interval = 1,
chance = 1,
action = function(pos)
@@ -631,7 +827,10 @@ minetest.register_abm({
end
end
local fdir = minetest.facedir_to_dir(minetest.get_node(pos).param2)
- celevator.doors.spawncardoors(pos,fdir)
+ local carmeta = minetest.get_meta(pos)
+ local doortype = carmeta:get_string("doortype")
+ if (not doortype) or doortype == "" then doortype = "glass" end
+ celevator.doors.spawncardoors(pos,fdir,doortype)
end,
})
@@ -667,12 +866,12 @@ minetest.register_node("celevator:hwdoor_glass",{
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.chat_send_player(name,string.format("Can't place door 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.chat_send_player(name,string.format("Can't place door here - position %s is protected!",offsetdesc))
minetest.record_protection_violation(placepos,name)
minetest.remove_node(pos)
return true
@@ -690,6 +889,76 @@ minetest.register_node("celevator:hwdoor_glass",{
end
end
end
+ local carpos = vector.add(pos,vector.rotate_around_axis(vector.new(0,0,1),vector.new(0,1,0),facedir))
+ local carndef = minetest.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.get_meta(carpos):set_string("doortype","glass")
+ celevator.doors.spawncardoors(carpos,minetest.fourdir_to_dir(newnode.param2),"glass",true)
+ end
+ end,
+})
+
+minetest.register_node("celevator:hwdoor_steel",{
+ description = "Steel Elevator Hoistway Door",
+ paramtype2 = "4dir",
+ buildable_to = true,
+ inventory_image = "celevator_door_metal_inventory.png",
+ wield_image = "celevator_door_metal_inventory.png",
+ wield_scale = vector.new(1,3,1),
+ 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))
+ local xnames = {
+ [0] = "fast",
+ [1] = "slow",
+ }
+ local ynames = {
+ [0] = "bottom",
+ [1] = "middle",
+ [2] = "top",
+ }
+ for x=0,1,1 do
+ for y=0,2,1 do
+ local offsetdesc = string.format("%dm to the right and %dm up",x,y)
+ local placeoffset = vector.new(x,y,0)
+ 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 door 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 door here - position %s is protected!",offsetdesc))
+ minetest.record_protection_violation(placepos,name)
+ minetest.remove_node(pos)
+ return true
+ end
+ end
+ end
+ for x=0,1,1 do
+ for y=0,2,1 do
+ local piecename = string.format("celevator:hwdoor_%s_steel_%s",xnames[x],ynames[y])
+ local placeoffset = vector.new(x,y,0)
+ 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})
+ if y==0 then
+ placesill(placepos,{name=piecename,param2=newnode.param2})
+ end
+ end
+ end
+ local carpos = vector.add(pos,vector.rotate_around_axis(vector.new(0,0,1),vector.new(0,1,0),facedir))
+ local carndef = minetest.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.get_meta(carpos):set_string("doortype","steel")
+ celevator.doors.spawncardoors(carpos,minetest.fourdir_to_dir(newnode.param2),"steel",true)
+ end
end,
})
@@ -747,7 +1016,12 @@ minetest.register_entity("celevator:door_sill",{
minetest.register_lbm({
label = "Respawn hoistway door sills",
name = "celevator:spawn_sill",
- nodenames = {"celevator:hwdoor_fast_glass_bottom","celevator:hwdoor_slow_glass_bottom"},
+ nodenames = {
+ "celevator:hwdoor_fast_glass_bottom",
+ "celevator:hwdoor_slow_glass_bottom",
+ "celevator:hwdoor_fast_steel_bottom",
+ "celevator:hwdoor_slow_steel_bottom",
+ },
run_at_every_load = true,
action = placesill,
})
diff --git a/drive_entity.lua b/drive_entity.lua
index ae72bca..0ddd4c4 100644
--- a/drive_entity.lua
+++ b/drive_entity.lua
@@ -11,6 +11,8 @@ celevator.drives.entity = {
sheaverefs = {},
}
+local playerposlimits = {}
+
local function update_ui(pos)
local meta = minetest.get_meta(pos)
local apos = tonumber(meta:get_string("apos")) or 0
@@ -231,6 +233,80 @@ minetest.register_entity("celevator:car_moving",{
},
})
+minetest.register_entity("celevator:player_holder",{
+ initial_properties = {
+ visual = "cube",
+ textures = {
+ "blank.png",
+ "blank.png",
+ "blank.png",
+ "blank.png",
+ "blank.png",
+ "blank.png",
+ },
+ --I have no idea where this magic number comes from, but it seems about right and that's good enough
+ visual_size = vector.new(3,3,3),
+ static_save = false,
+ pointable = false,
+ },
+ on_step = function(self,dtime)
+ local obj = self.object
+ local car,_,attachoffset = obj:get_attach()
+ if not car then
+ obj:remove()
+ return
+ end
+ local children = obj:get_children()
+ local player
+ for _,i in pairs(children) do
+ if i:is_player() then
+ player = i
+ end
+ end
+ if not player then return end
+ local caryaw = car:get_yaw()
+ local playeryaw = player:get_look_horizontal()
+ local attachrot = vector.new(0,(caryaw-playeryaw)*57.296,0)
+ local control = player:get_player_control()
+ if (control.up or control.down or control.left or control.right) then
+ local walkspeed = 120
+ local walkamount = walkspeed*dtime
+ local displacement = vector.new(0,0,0)
+ if control.up then
+ displacement = vector.add(displacement,vector.new(0,0,walkamount))
+ end
+ if control.down then
+ displacement = vector.add(displacement,vector.new(0,0,0-walkamount))
+ end
+ if control.left then
+ displacement = vector.add(displacement,vector.new(0-walkamount,0,0))
+ end
+ if control.right then
+ displacement = vector.add(displacement,vector.new(walkamount,0,0))
+ end
+ displacement = vector.rotate_around_axis(displacement,vector.new(0,1,0),playeryaw)
+ displacement = vector.rotate_around_axis(displacement,vector.new(0,-1,0),caryaw)
+ local oldattachoffset = vector.copy(attachoffset)
+ attachoffset = vector.add(attachoffset,displacement)
+ local realattachoffset = vector.rotate_around_axis(vector.multiply(attachoffset,1/30),vector.new(0,1,0),caryaw)
+ local newpos = vector.add(car:get_pos(),realattachoffset)
+ local limits = playerposlimits[player:get_player_name()] or {}
+ if limits.xmin and limits.xmax and limits.xmin < limits.xmax then
+ if newpos.x > limits.xmax or newpos.x < limits.xmin then
+ attachoffset = oldattachoffset
+ end
+ end
+ if limits.zmin and limits.zmax and limits.zmin < limits.zmax then
+ if newpos.z > limits.zmax or newpos.z < limits.zmin then
+ attachoffset = oldattachoffset
+ end
+ end
+ end
+ obj:set_attach(car,"",attachoffset,vector.new(0,0,0))
+ player:set_attach(obj,"",vector.new(0,0,0),attachrot)
+ end,
+})
+
function celevator.drives.entity.gathercar(pos,yaw,nodes)
if not nodes then nodes = {} end
local hash = minetest.hash_node_position(pos)
@@ -259,6 +335,16 @@ end
function celevator.drives.entity.nodestoentities(nodes,ename)
local refs = {}
+ local xmin = 32000
+ local xmax = -32000
+ local zmin = 32000
+ local zmax = -32000
+ for _,pos in ipairs(nodes) do
+ if pos.x < xmin then xmin = pos.x end
+ if pos.x > xmax then xmax = pos.x end
+ if pos.z < zmin then zmin = pos.z end
+ if pos.z > zmax then zmax = pos.z end
+ end
for _,pos in ipairs(nodes) do
local node = celevator.get_node(pos)
local attach = minetest.get_objects_inside_radius(pos,0.9)
@@ -268,7 +354,8 @@ function celevator.drives.entity.nodestoentities(nodes,ename)
})
eref:set_yaw(minetest.dir_to_yaw(minetest.fourdir_to_dir(node.param2)))
table.insert(refs,eref)
- if node.name == "celevator:car_021" or node.name == "celevator:car_122" then
+ local ndef = minetest.registered_nodes[node.name] or {}
+ if ndef._cartopbox or ndef._tapehead then
local toppos = vector.add(pos,vector.new(0,1,0))
local topattach = minetest.get_objects_inside_radius(toppos,0.75)
for _,ref in pairs(topattach) do
@@ -285,12 +372,27 @@ function celevator.drives.entity.nodestoentities(nodes,ename)
}
if attachref:get_luaentity() and included[attachref:get_luaentity().name] then
table.insert(refs,attachref)
+ elseif attachref:is_player() then
+ local attachpos = attachref:get_pos()
+ local basepos = eref:get_pos()
+ local attachoffset = vector.subtract(attachpos,basepos)
+ attachoffset = vector.rotate_around_axis(attachoffset,vector.new(0,-1,0),eref:get_yaw())
+ local holder = minetest.add_entity(attachpos,"celevator:player_holder")
+ holder:set_attach(eref,"",vector.multiply(attachoffset,30),vector.new(0,0,0))
+ attachref:set_attach(holder,"")
+ local extra = 0.25 --To allow getting closer to walls
+ playerposlimits[attachref:get_player_name()] = {
+ xmin = xmin-extra,
+ xmax = xmax+extra,
+ zmin = zmin-extra,
+ zmax = zmax+extra,
+ }
else
local attachpos = attachref:get_pos()
local basepos = eref:get_pos()
- local attachoffset = vector.multiply(vector.subtract(attachpos,basepos),30)
+ local attachoffset = vector.subtract(attachpos,basepos)
attachoffset = vector.rotate_around_axis(attachoffset,vector.new(0,-1,0),eref:get_yaw())
- attachref:set_attach(eref,"",attachoffset)
+ attachref:set_attach(eref,"",vector.multiply(attachoffset,30),vector.new(0,0,0))
end
end
end
@@ -333,10 +435,15 @@ function celevator.drives.entity.entitiestonodes(refs,carid)
i:set_velocity(vector.new(0,0,0))
if i:is_player() then
local ppos = i:get_pos()
- ppos.y=ppos.y-0.4
- if top then ppos.y = ppos.y+1.1 end
+ ppos.y=ppos.y-0.48
+ if top then ppos.y = ppos.y+1.02 end
i:set_pos(ppos)
- minetest.after(0.5,i.set_pos,i,ppos)
+ minetest.after(0.5,function()
+ if not i:is_player() then return end
+ local newpos = i:get_pos()
+ newpos.y = math.max(newpos.y,ppos.y)
+ i:set_pos(newpos)
+ end)
elseif i:get_luaentity() and rounded[i:get_luaentity().name] then
local epos = i:get_pos()
epos.y = math.floor(epos.y+0.5)
@@ -373,6 +480,7 @@ function celevator.drives.entity.step(dtime)
local dpos = tonumber(meta:get_string("dpos")) or 0
local maxvel = tonumber(meta:get_string("maxvel")) or 0.2
local startpos = tonumber(meta:get_string("startpos")) or 0
+ local oldvel = tonumber(meta:get_string("vel")) or 0
local inspection = meta:get_int("inspection") == 1
local origin = minetest.string_to_pos(meta:get_string("origin"))
if not origin then
@@ -402,7 +510,12 @@ function celevator.drives.entity.step(dtime)
end
end
local carparam2 = celevator.get_node(nodes[1]).param2
+ local cardef = minetest.registered_nodes[celevator.get_node(nodes[1]).name] or {}
+ local cartype = cardef._celevator_car_type or "standard"
+ local carmeta = celevator.get_meta(startv)
meta:set_int("carparam2",carparam2)
+ meta:set_string("cartype",cartype)
+ meta:set_string("doortype",carmeta:get_string("doortype"))
local handles = celevator.drives.entity.nodestoentities(nodes)
celevator.drives.entity.entityinfo[hash] = {
handles = handles,
@@ -432,20 +545,28 @@ function celevator.drives.entity.step(dtime)
local dremain = math.abs(dpos-apos)
local dmoved = math.abs(apos-startpos)
local vel
- if dremain < 0.01 then
+ local relevel = (dpos < apos and oldvel > 0) or (dpos > apos and oldvel < 0)
+ if dremain < 0.01 or (inspection and relevel) then
vel = 0
meta:set_string("state","stopped")
motorsound(pos,"idle")
celevator.drives.entity.sheavetonode(carid)
local ok = celevator.drives.entity.entitiestonodes(handles,carid)
+ local doortype = meta:get_string("doortype")
+ if (not doortype) or doortype == "" then doortype = "glass" end
+ local spawnpos = vector.round(vector.add(origin,vector.new(0,apos,0)))
if not ok then
local carparam2 = meta:get_int("carparam2")
- celevator.car.spawncar(vector.round(vector.add(origin,vector.new(0,apos,0))),minetest.dir_to_yaw(minetest.fourdir_to_dir(carparam2)),carid)
+ local cartype = meta:get_string("cartype")
+ celevator.car.spawncar(spawnpos,minetest.dir_to_yaw(minetest.fourdir_to_dir(carparam2)),carid,cartype,doortype)
+ else
+ celevator.get_meta(spawnpos):set_string("doortype",doortype)
end
apos = math.floor(apos+0.5)
minetest.after(0.25,celevator.drives.entity.updatecopformspec,pos)
- elseif dremain < 0.2 and not inspection then
- vel = 0.2
+ table.remove(entitydrives_running,i)
+ elseif dremain < 0.1 and not inspection then
+ vel = 0.1
elseif dremain < 2*maxvel and dremain < dmoved and not inspection then
vel = math.min(dremain,maxvel)
if celevator.drives.entity.movementsoundstate[hash] == "fast" or celevator.drives.entity.movementsoundstate[hash] == "accel" then
@@ -478,17 +599,23 @@ function celevator.drives.entity.step(dtime)
local dremain = math.abs(dpos-apos)
local dmoved = math.abs(apos-startpos)
local vel
- if dremain < 0.01 then
+ local relevel = (dpos < apos and oldvel > 0) or (dpos > apos and oldvel < 0)
+ if dremain < 0.01 or (relevel and inspection) then
vel = 0
meta:set_string("state","stopped")
motorsound(pos,"idle")
celevator.drives.entity.sheavetonode(carid)
local carparam2 = meta:get_int("carparam2")
- celevator.car.spawncar(vector.round(vector.add(origin,vector.new(0,apos,0))),minetest.dir_to_yaw(minetest.fourdir_to_dir(carparam2)),carid)
+ local cartype = meta:get_string("cartype")
+ local doortype = meta:get_string("doortype")
+ if (not doortype) or doortype == "" then doortype = "glass" end
+ local spawnpos = vector.round(vector.add(origin,vector.new(0,apos,0)))
+ celevator.car.spawncar(spawnpos,minetest.dir_to_yaw(minetest.fourdir_to_dir(carparam2)),carid,cartype,doortype)
apos = math.floor(apos+0.5)
minetest.after(0.25,celevator.drives.entity.updatecopformspec,pos)
- elseif dremain < 0.2 and not inspection then
- vel = 0.2
+ table.remove(entitydrives_running,i)
+ elseif dremain < 0.1 and not inspection then
+ vel = 0.1
elseif dremain < 2*maxvel and dremain < dmoved and not inspection then
vel = math.min(dremain,maxvel)
if celevator.drives.entity.movementsoundstate[hash] == "fast" or celevator.drives.entity.movementsoundstate[hash] == "accel" then
@@ -526,7 +653,21 @@ function celevator.drives.entity.moveto(pos,target,inspection)
meta:mark_as_private({"apos","dpos","vel","maxvel","state","startpos","doorstate"})
local carid = celevator.get_meta(pos):get_int("carid")
local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
- if not (carinfo and carinfo.machinepos) then return end
+ if not (carinfo and carinfo.machinepos and celevator.get_node(carinfo.machinepos).name == "celevator:machine") then
+ meta:set_string("fault","nomachine")
+ return
+ end
+ if not carinfo.controllerpos then return end
+ local controllermeta = celevator.get_meta(carinfo.controllerpos)
+ if controllermeta:get_int("carid") ~= carid then
+ meta:set_string("fault","controllermismatch")
+ return
+ end
+ local machinemeta = celevator.get_meta(carinfo.machinepos)
+ if machinemeta:get_int("carid") ~= carid then
+ meta:set_string("fault","machinemismatch")
+ return
+ end
local origin = minetest.string_to_pos(meta:get_string("origin"))
if not origin then
minetest.log("error","[celevator] [entity drive] Invalid origin for drive at "..minetest.pos_to_string(pos))
@@ -1025,9 +1166,10 @@ function celevator.drives.entity.updatecopformspec(drivepos)
for hash in pairs(carnodes) do
local piecepos = minetest.get_position_from_hash(hash)
local piece = celevator.get_node(piecepos)
- if piece.name == "celevator:car_010" then
+ local ndef = minetest.registered_nodes[piece.name] or {}
+ if ndef._cop then
celevator.get_meta(piecepos):set_string("formspec",copformspec)
- elseif piece.name == "celevator:car_000" then
+ elseif ndef._keyswitches then
celevator.get_meta(piecepos):set_string("formspec",switchformspec)
end
end
diff --git a/genericswitch.lua b/genericswitch.lua
index d52e9c9..9cdf31c 100644
--- a/genericswitch.lua
+++ b/genericswitch.lua
@@ -154,6 +154,30 @@ local inputoptions = {
end,
needsfloor = true,
},
+ {
+ id = "swingon",
+ desc = "Activate Swing Operation",
+ func_on = function(controllerpos)
+ celevator.controller.run(controllerpos,{
+ type = "remotemsg",
+ channel = "swing",
+ msg = true,
+ })
+ end,
+ needsfloor = false,
+ },
+ {
+ id = "swingoff",
+ desc = "Deactivate Swing Operation",
+ func_on = function(controllerpos)
+ celevator.controller.run(controllerpos,{
+ type = "remotemsg",
+ channel = "swing",
+ msg = false,
+ })
+ end,
+ needsfloor = false,
+ },
}
local dinputoptions = {
diff --git a/governor.lua b/governor.lua
new file mode 100644
index 0000000..4333c92
--- /dev/null
+++ b/governor.lua
@@ -0,0 +1,131 @@
+local function spawngovsheave(pos)
+ local entitiesnearby = minetest.get_objects_inside_radius(pos,0.5)
+ for _,i in pairs(entitiesnearby) do
+ if i:get_luaentity() and i:get_luaentity().name == "celevator:governor_sheave" then
+ return
+ end
+ end
+ local entity = minetest.add_entity(pos,"celevator:governor_sheave")
+ local fdir = minetest.fourdir_to_dir(minetest.get_node(pos).param2)
+ local yaw = minetest.dir_to_yaw(fdir)
+ local offset = vector.rotate_around_axis(vector.new(0,-0.05,-0.143),vector.new(0,1,0),yaw)
+ entity:set_yaw(yaw)
+ entity:set_pos(vector.add(pos,offset))
+end
+
+minetest.register_node("celevator:governor",{
+ description = "Elevator Governor",
+ groups = {
+ cracky = 1,
+ },
+ paramtype = "light",
+ paramtype2 = "4dir",
+ tiles = {
+ "celevator_machine_top.png",
+ "celevator_machine_top.png",
+ "celevator_machine_top.png",
+ "celevator_machine_top.png",
+ "celevator_governor_back.png",
+ "celevator_governor_front.png",
+ },
+ drawtype = "nodebox",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.2,-0.5,-0.1,0.2,0.1,-0.07},
+ {-0.2,-0.5,0.07,0.2,0.1,0.1},
+ {-0.2,-0.5,-0.25,0.2,-0.45,-0.1},
+ {-0.2,-0.5,0.1,0.2,-0.45,0.25},
+ },
+ },
+ on_construct = function(pos)
+ minetest.get_meta(pos):set_string("formspec","field[carid;Car ID;]")
+ spawngovsheave(pos)
+ end,
+ after_dig_node = function(pos)
+ local entitiesnearby = minetest.get_objects_inside_radius(pos,0.5)
+ for _,i in pairs(entitiesnearby) do
+ if i:get_luaentity() and i:get_luaentity().name == "celevator:governor_sheave" then
+ i:remove()
+ end
+ end
+ end,
+ on_receive_fields = function(pos,_,fields)
+ if not (fields.carid and tonumber(fields.carid)) then return end
+ local carid = tonumber(fields.carid)
+ local carinfo = minetest.deserialize(celevator.storage:get_string("car"..carid))
+ if not (carinfo and carinfo.controllerpos) then return end
+ if not celevator.controller.iscontroller(carinfo.controllerpos) then return end
+ local meta = minetest.get_meta(pos)
+ meta:set_string("controllerpos",minetest.pos_to_string(carinfo.controllerpos))
+ meta:set_string("formspec","")
+ end,
+})
+
+minetest.register_node("celevator:governor_sheave",{
+ description = "Governor Sheave (you hacker you!)",
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ tiles = {
+ "celevator_governor_sheave_sides.png^[transformR90",
+ "celevator_governor_sheave_sides.png^[transformR270",
+ "celevator_governor_sheave_sides.png",
+ "celevator_governor_sheave_sides.png^[transformR180",
+ "celevator_sheave_front_centered.png",
+ "celevator_sheave_front_centered.png",
+ },
+ drawtype = "nodebox",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.3,-0.3,0.2,0.3,0.3,0.5},
+ {-0.4,-0.2,0.2,-0.3,0.2,0.5},
+ {0.3,-0.2,0.2,0.4,0.2,0.5},
+ {-0.2,0.3,0.2,0.2,0.4,0.5},
+ {-0.2,-0.4,0.2,0.2,-0.3,0.5},
+ },
+ },
+ selection_box = {
+ type = "fixed",
+ fixed = {},
+ },
+})
+
+minetest.register_entity("celevator:governor_sheave",{
+ initial_properties = {
+ visual = "wielditem",
+ visual_size = vector.new(0.4,0.4,0.27),
+ wield_item = "celevator:governor_sheave",
+ static_save = false,
+ pointable = false,
+ },
+ on_step = function(self)
+ local sheave = self.object
+ if not sheave then return end
+ local governorpos = vector.round(sheave:get_pos())
+ local governormeta = celevator.get_meta(governorpos)
+ local controllerpos = minetest.string_to_pos(governormeta:get_string("controllerpos"))
+ if not controllerpos then return end
+ local controllermeta = celevator.get_meta(controllerpos)
+ local vel = tonumber(controllermeta:get_string("vel")) or 0
+ if vel == 0 then return end
+ local drivepos = celevator.controller.finddrive(controllerpos)
+ local drivemeta = celevator.get_meta(drivepos)
+ local apos = tonumber(drivemeta:get_string("apos")) or 0
+ local rotation = sheave:get_rotation()
+ rotation.z = apos*2*math.pi
+ sheave:set_rotation(rotation)
+ end,
+})
+
+minetest.register_lbm({
+ name = "celevator:spawngovsheave",
+ label = "Spawn governor sheaves",
+ nodenames = {"celevator:governor"},
+ run_at_every_load = true,
+ action = spawngovsheave,
+})
diff --git a/init.lua b/init.lua
index f771586..e718c8e 100644
--- a/init.lua
+++ b/init.lua
@@ -1,6 +1,10 @@
local components = {
"framework",
"car",
+ "car_standard",
+ "car_glassback",
+ "car_metal",
+ "car_metalglass",
"doors",
"drive_null",
"drive_entity",
@@ -12,7 +16,9 @@ local components = {
"dbdkiosk",
"genericswitch",
"decorations",
+ "governor",
"crafts",
+ "chatcommands",
}
local integrations = {
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/mesecons.lua b/mesecons.lua
index 7064821..f505649 100644
--- a/mesecons.lua
+++ b/mesecons.lua
@@ -83,6 +83,14 @@ local outputoptions = {
needsfloor = false,
},
{
+ id = "swing",
+ desc = "Swing Operation",
+ func = function(mem)
+ return (mem.carstate == "swing")
+ end,
+ needsfloor = false,
+ },
+ {
id = "opening",
desc = "Doors Opening",
func = function(mem)
@@ -393,6 +401,30 @@ local inputoptions = {
end,
needsfloor = true,
},
+ {
+ id = "swingon",
+ desc = "Activate Swing Operation",
+ func_on = function(controllerpos)
+ celevator.controller.run(controllerpos,{
+ type = "remotemsg",
+ channel = "swing",
+ msg = true,
+ })
+ end,
+ needsfloor = false,
+ },
+ {
+ id = "swingoff",
+ desc = "Deactivate Swing Operation",
+ func_on = function(controllerpos)
+ celevator.controller.run(controllerpos,{
+ type = "remotemsg",
+ channel = "swing",
+ msg = false,
+ })
+ end,
+ needsfloor = false,
+ },
}
local dinputoptions = {
diff --git a/mod.conf b/mod.conf
index 731d6c5..552f37b 100644
--- a/mod.conf
+++ b/mod.conf
@@ -1,5 +1,5 @@
name = celevator
description = Realistic Elevators
-optional_depends = laptop,mesecons,digilines
+optional_depends = laptop,mesecons,digilines,xcompat,mesecons_lightstone,mesecons_button
author = cheapie
min_minetest_version = 5.7
diff --git a/pilantern.lua b/pilantern.lua
index 7dda0a5..29f3cf7 100644
--- a/pilantern.lua
+++ b/pilantern.lua
@@ -578,3 +578,30 @@ minetest.register_abm({
celevator.pi.updatedisplay(pos)
end,
})
+
+minetest.register_abm({
+ label = "Check PIs/lanterns for missing/replaced controllers",
+ nodenames = {"group:_celevator_pi","group:_celevator_lantern"},
+ interval = 15,
+ chance = 1,
+ action = function(pos)
+ local meta = minetest.get_meta(pos)
+ local carid = meta:get_int("carid")
+ if not (carid and carid > 0) then return end --Not set up yet
+ local carinfo = minetest.deserialize(celevator.storage:get_string("car"..carid))
+ if not carinfo then
+ celevator.pi.settext(pos," --")
+ meta:set_string("infotext","Error reading car information!\nPlease remove and replace this node.")
+ return
+ end
+ if not (carinfo.controllerpos and celevator.controller.iscontroller(carinfo.controllerpos)) then
+ celevator.pi.settext(pos," --")
+ meta:set_string("infotext","Controller is missing!\nPlease remove and replace this node.")
+ return
+ end
+ if celevator.get_meta(carinfo.controllerpos):get_int("carid") ~= carid then
+ celevator.pi.settext(pos," --")
+ meta:set_string("infotext","Controller found but with incorrect ID!\nPlease remove and replace this node.")
+ end
+ end,
+})
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_glass.png b/textures/celevator_car_glass.png
new file mode 100644
index 0000000..025c1ec
--- /dev/null
+++ b/textures/celevator_car_glass.png
Binary files differ
diff --git a/textures/celevator_car_glassback_inventory.png b/textures/celevator_car_glassback_inventory.png
new file mode 100644
index 0000000..77dc082
--- /dev/null
+++ b/textures/celevator_car_glassback_inventory.png
Binary files differ
diff --git a/textures/celevator_car_glassback_wield.png b/textures/celevator_car_glassback_wield.png
new file mode 100644
index 0000000..152bbcf
--- /dev/null
+++ b/textures/celevator_car_glassback_wield.png
Binary files differ
diff --git a/textures/celevator_car_metal.png b/textures/celevator_car_metal.png
new file mode 100644
index 0000000..f9fdee6
--- /dev/null
+++ b/textures/celevator_car_metal.png
Binary files differ
diff --git a/textures/celevator_car_metal_2x.png b/textures/celevator_car_metal_2x.png
new file mode 100644
index 0000000..fdbb229
--- /dev/null
+++ b/textures/celevator_car_metal_2x.png
Binary files differ
diff --git a/textures/celevator_car_metal_ceiling.png b/textures/celevator_car_metal_ceiling.png
new file mode 100644
index 0000000..5023c7e
--- /dev/null
+++ b/textures/celevator_car_metal_ceiling.png
Binary files differ
diff --git a/textures/celevator_car_metal_floor.png b/textures/celevator_car_metal_floor.png
new file mode 100644
index 0000000..d944936
--- /dev/null
+++ b/textures/celevator_car_metal_floor.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_car_metal_inventory.png b/textures/celevator_car_metal_inventory.png
new file mode 100644
index 0000000..e969f08
--- /dev/null
+++ b/textures/celevator_car_metal_inventory.png
Binary files differ
diff --git a/textures/celevator_car_metal_top.png b/textures/celevator_car_metal_top.png
new file mode 100644
index 0000000..c9d400a
--- /dev/null
+++ b/textures/celevator_car_metal_top.png
Binary files differ
diff --git a/textures/celevator_car_metal_wield.png b/textures/celevator_car_metal_wield.png
new file mode 100644
index 0000000..2c76aa4
--- /dev/null
+++ b/textures/celevator_car_metal_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
diff --git a/textures/celevator_door_metal.png b/textures/celevator_door_metal.png
new file mode 100644
index 0000000..b14be20
--- /dev/null
+++ b/textures/celevator_door_metal.png
Binary files differ
diff --git a/textures/celevator_door_metal_inventory.png b/textures/celevator_door_metal_inventory.png
new file mode 100644
index 0000000..d5f858a
--- /dev/null
+++ b/textures/celevator_door_metal_inventory.png
Binary files differ
diff --git a/textures/celevator_governor_back.png b/textures/celevator_governor_back.png
new file mode 100644
index 0000000..3bf1cc6
--- /dev/null
+++ b/textures/celevator_governor_back.png
Binary files differ
diff --git a/textures/celevator_governor_front.png b/textures/celevator_governor_front.png
new file mode 100644
index 0000000..52a4c23
--- /dev/null
+++ b/textures/celevator_governor_front.png
Binary files differ
diff --git a/textures/celevator_governor_sheave_sides.png b/textures/celevator_governor_sheave_sides.png
new file mode 100644
index 0000000..43e3a12
--- /dev/null
+++ b/textures/celevator_governor_sheave_sides.png
Binary files differ