summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--.luacheckrc5
-rw-r--r--README54
-rw-r--r--callbuttons.lua219
-rw-r--r--car.lua796
-rw-r--r--car_fullglass.lua425
-rw-r--r--car_glassback.lua419
-rw-r--r--car_metal.lua413
-rw-r--r--car_metalglass.lua419
-rw-r--r--car_standard.lua422
-rw-r--r--chatcommands.lua183
-rw-r--r--controller.lua221
-rw-r--r--controllerfw.lua646
-rw-r--r--crafts.lua411
-rw-r--r--dbdkiosk.lua70
-rw-r--r--decorations.lua136
-rw-r--r--digilines.lua82
-rw-r--r--digistuff.lua27
-rw-r--r--dispatcher.lua178
-rw-r--r--dispatcherfw.lua220
-rw-r--r--docs/README2
-rw-r--r--docs/celevator_controller_manual.pdfbin2140061 -> 2219488 bytes
-rw-r--r--docs/file_sources20
-rw-r--r--door_2speedglass.lua641
-rw-r--r--door_2speedmetal.lua635
-rw-r--r--door_centerglass.lua641
-rw-r--r--door_centermetal.lua636
-rw-r--r--doors.lua716
-rw-r--r--drive_entity.lua671
-rw-r--r--drive_null.lua91
-rw-r--r--framework.lua12
-rw-r--r--fs1switch.lua71
-rw-r--r--genericswitch.lua178
-rw-r--r--governor.lua137
-rw-r--r--init.lua16
-rw-r--r--laptop.lua223
-rw-r--r--locale/celevator.es.tr377
-rw-r--r--locale/template.txt377
-rw-r--r--mesecons.lua254
-rw-r--r--mod.conf4
-rw-r--r--pilantern.lua282
-rw-r--r--screenshot.pngbin0 -> 236634 bytes
-rw-r--r--settingtypes.txt32
-rw-r--r--sounds/celevator_alarm.oggbin0 -> 62361 bytes
-rw-r--r--sounds/celevator_chime2_down.oggbin0 -> 40001 bytes
-rw-r--r--sounds/celevator_chime2_up.oggbin0 -> 26042 bytes
-rw-r--r--sounds/celevator_phone.oggbin0 -> 29051 bytes
-rw-r--r--textures/celevator_car_fullglass_inventory.pngbin0 -> 496 bytes
-rw-r--r--textures/celevator_car_fullglass_wield.pngbin0 -> 388 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_copbutton_alarm.pngbin0 -> 229 bytes
-rw-r--r--textures/celevator_copbutton_phone.pngbin0 -> 213 bytes
-rw-r--r--textures/celevator_door_centerglass_inventory.pngbin0 -> 285 bytes
-rw-r--r--textures/celevator_door_centermetal_inventory.pngbin0 -> 653 bytes
-rw-r--r--textures/celevator_door_glass_inventory.pngbin573 -> 281 bytes
-rw-r--r--textures/celevator_door_metal.pngbin0 -> 561 bytes
-rw-r--r--textures/celevator_door_metal_inventory.pngbin0 -> 654 bytes
-rw-r--r--textures/celevator_door_sill.pngbin0 -> 229 bytes
-rw-r--r--textures/celevator_door_sill_double.pngbin4542 -> 0 bytes
-rw-r--r--textures/celevator_door_sill_single.pngbin4544 -> 0 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
-rw-r--r--textures/celevator_menu_small_arrow.pngbin0 -> 231 bytes
75 files changed, 8693 insertions, 2671 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ffc8a2e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+i18n.py
+locale/*.old
diff --git a/.luacheckrc b/.luacheckrc
index 8ce3cc6..0a45878 100644
--- a/.luacheckrc
+++ b/.luacheckrc
@@ -5,13 +5,14 @@ globals = {
}
read_globals = {
- "DIR_DELIM",
"vector",
"screwdriver",
- "minetest",
+ "core",
"table.copy",
"VoxelManip",
"laptop",
"mesecon",
"digilines",
+ "xcompat",
+ "digistuff",
}
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..432ef19 100644
--- a/callbuttons.lua
+++ b/callbuttons.lua
@@ -1,5 +1,54 @@
celevator.callbutton = {}
+local fscontext = {}
+
+local S = core.get_translator("celevator")
+
+local function showfs(pos,name)
+ local nname = celevator.get_node(pos).name
+ fscontext[name] = pos
+
+ local fs = "formspec_version[10]size[4,6]"
+ fs = fs.."background[0,0;4,6;celevator_callbutton_panel.png;true]"
+
+ local uplit = core.get_item_group(nname,"_celevator_callbutton_up_lit") == 1
+ local uptex = "celevator_callbutton_up.png"
+ local uplittex = "[combine:17x9:0,0="..uptex..":9,1=celevator_callbutton_light.png"
+ if uplit then uptex = uplittex end
+ fs = fs.."image_button[0.75,1;2.5,1.25;"..uptex..";up;;false;false;"..uplittex.."]"
+
+ local downlit = core.get_item_group(nname,"_celevator_callbutton_down_lit") == 1
+ local downtex = "celevator_callbutton_down.png"
+ local downlittex = "[combine:17x9:0,0="..downtex..":9,1=celevator_callbutton_light.png"
+ if downlit then downtex = downlittex end
+ fs = fs.."image_button[0.75,3.5;2.5,1.25;"..downtex..";down;;false;false;"..downlittex.."]"
+
+ core.show_formspec(name,"celevator:call_button",fs)
+end
+
+core.register_on_player_receive_fields(function(player,formname,fields)
+ if formname ~= "celevator:call_button" then
+ return false
+ end
+ local name = player:get_player_name()
+ local pos = fscontext[name]
+ if not pos then return true end
+ if fields.quit then
+ fscontext[name] = nil
+ elseif fields.up then
+ local nname = celevator.get_node(pos).name
+ if core.get_item_group(nname,"_celevator_callbutton_has_up") == 1 then
+ core.registered_nodes["celevator:callbutton_up"].on_rightclick(pos)
+ end
+ elseif fields.down then
+ local nname = celevator.get_node(pos).name
+ if core.get_item_group(nname,"_celevator_callbutton_has_down") == 1 then
+ core.registered_nodes["celevator:callbutton_down"].on_rightclick(pos)
+ end
+ end
+ return true
+end)
+
local function makebuttontex(dir,upon,downon,inventory)
local tex = "[combine:64x64"..
":0,0=celevator_cabinet_sides.png"..
@@ -42,77 +91,93 @@ local function makebuttontex(dir,upon,downon,inventory)
return(tex)
end
+local upname = S("Elevator Up Call Button")
+local dnname = S("Elevator Down Call Button")
+local bothname = S("Elevator Up and Down Call Buttons")
+local onname = S("Elevator Call Button (on state - you hacker you!)")
+
local validstates = {
- {"up",false,false,"Up"},
- {"up",true,false,"Up"},
- {"down",false,false,"Down"},
- {"down",false,true,"Down"},
- {"both",false,false,"Up and Down"},
- {"both",true,false,"Up and Down"},
- {"both",false,true,"Up and Down"},
- {"both",true,true,"Up and Down"},
+ {"up",false,false,upname},
+ {"up",true,false,onname},
+ {"down",false,false,dnname},
+ {"down",false,true,onname},
+ {"both",false,false,bothname},
+ {"both",true,false,onname},
+ {"both",false,true,onname},
+ {"both",true,true,onname},
}
function celevator.callbutton.setlight(pos,dir,newstate)
local node = celevator.get_node(pos)
- if minetest.get_item_group(node.name,"_celevator_callbutton") ~= 1 then return end
+ if core.get_item_group(node.name,"_celevator_callbutton") ~= 1 then return end
if dir == "up" then
- if minetest.get_item_group(node.name,"_celevator_callbutton_has_up") ~= 1 then return end
- local lit = minetest.get_item_group(node.name,"_celevator_callbutton_up_lit") == 1
+ if core.get_item_group(node.name,"_celevator_callbutton_has_up") ~= 1 then return end
+ local lit = core.get_item_group(node.name,"_celevator_callbutton_up_lit") == 1
if lit == newstate then return end
local newname = "celevator:callbutton_"
- if minetest.get_item_group(node.name,"_celevator_callbutton_has_down") == 1 then
+ if core.get_item_group(node.name,"_celevator_callbutton_has_down") == 1 then
newname = newname.."both"
else
newname = newname.."up"
end
if newstate then newname = newname.."_upon" end
- if minetest.get_item_group(node.name,"_celevator_callbutton_down_lit") == 1 then
+ if core.get_item_group(node.name,"_celevator_callbutton_down_lit") == 1 then
newname = newname.."_downon"
end
node.name = newname
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
elseif dir == "down" then
- if minetest.get_item_group(node.name,"_celevator_callbutton_has_down") ~= 1 then return end
- local lit = minetest.get_item_group(node.name,"_celevator_callbutton_down_lit") == 1
+ if core.get_item_group(node.name,"_celevator_callbutton_has_down") ~= 1 then return end
+ local lit = core.get_item_group(node.name,"_celevator_callbutton_down_lit") == 1
if lit == newstate then return end
local newname = "celevator:callbutton_"
- if minetest.get_item_group(node.name,"_celevator_callbutton_has_up") == 1 then
+ if core.get_item_group(node.name,"_celevator_callbutton_has_up") == 1 then
newname = newname.."both"
else
newname = newname.."down"
end
- if minetest.get_item_group(node.name,"_celevator_callbutton_up_lit") == 1 then
+ if core.get_item_group(node.name,"_celevator_callbutton_up_lit") == 1 then
newname = newname.."_upon"
end
if newstate then newname = newname.."_downon" end
node.name = newname
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
+ end
+ for name,contextpos in pairs(fscontext) do
+ if vector.equals(pos,contextpos) then
+ showfs(pos,name)
+ end
end
end
local function disambiguatedir(pos,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()
- local distance = vector.distance(eyepos,pos)
- local endpos = vector.add(eyepos,vector.multiply(lookdir,distance+1))
- local ray = minetest.raycast(eyepos,endpos,true,false)
- local pointed,button,hitpos
- repeat
- pointed = ray:next()
- if pointed and pointed.type == "node" then
- local node = minetest.get_node(pointed.under)
- if node.name and (minetest.get_item_group(node.name,"_celevator_callbutton") == 1) then
- button = pointed.under
- hitpos = vector.subtract(pointed.intersection_point,button)
+ local name = player:get_player_name()
+ local windowinfo = core.get_player_window_information(name)
+ if windowinfo and windowinfo.touch_controls then
+ showfs(pos,name)
+ else
+ 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()
+ local distance = vector.distance(eyepos,pos)
+ local endpos = vector.add(eyepos,vector.multiply(lookdir,distance+1))
+ local ray = core.raycast(eyepos,endpos,true,false)
+ local pointed,button,hitpos
+ repeat
+ pointed = ray:next()
+ if pointed and pointed.type == "node" then
+ local node = core.get_node(pointed.under)
+ if node.name and (core.get_item_group(node.name,"_celevator_callbutton") == 1) then
+ button = pointed.under
+ hitpos = vector.subtract(pointed.intersection_point,button)
+ end
end
- end
- until button or not pointed
- if not hitpos then return end
- hitpos.y = -1*hitpos.y
- hitpos.y = math.floor((hitpos.y+0.5)*64+0.5)+1
- return hitpos.y >= 40 and "down" or "up"
+ until button or not pointed
+ if not hitpos then return end
+ hitpos.y = -1*hitpos.y
+ hitpos.y = math.floor((hitpos.y+0.5)*64+0.5)+1
+ return hitpos.y >= 40 and "down" or "up"
+ end
end
end
@@ -134,8 +199,8 @@ for _,state in ipairs(validstates) do
light = light + 5
end
local idle = not (state[2] or state[3])
- local description = string.format("Elevator %s Call Button%s%s",state[4],(state[1] == "both" and "s" or ""),(idle and "" or " (on state, you hacker you!)"))
- minetest.register_node(nname,{
+ local description = state[4]
+ core.register_node(nname,{
description = description,
groups = {
dig_immediate = 2,
@@ -167,45 +232,63 @@ for _,state in ipairs(validstates) do
},
},
after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("formspec","formspec_version[7]size[8,5]field[0.5,0.5;7,1;carid;Car ID;]field[0.5,2;7,1;landing;Landing Number;]button[3,3.5;2,1;save;Save]")
+ local meta = core.get_meta(pos)
+ local idmsg = S("Car ID")
+ local landingmsg = S("Landing Number")
+ local savemsg = S("Save")
+ local fs = "formspec_version[7]size[8,5]"
+ fs = fs.."field[0.5,0.5;7,1;carid;"..idmsg..";]"
+ fs = fs.."field[0.5,2;7,1;landing;"..landingmsg..";]"
+ fs = fs.."button[3,3.5;2,1;save;"..savemsg.."]"
+ meta:set_string("formspec",fs)
end,
- on_receive_fields = function(pos,_,fields)
+ on_receive_fields = function(pos,_,fields,player)
if tonumber(fields.carid) and tonumber(fields.landing) then
local carid = tonumber(fields.carid)
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then return end
+ local controllerpos = carinfo.controllerpos or carinfo.dispatcherpos
+ local playername = player and player:get_player_name() or ""
+ if core.is_protected(controllerpos,playername) and not core.check_player_privs(playername,{protection_bypass=true}) then
+ core.record_protection_violation(controllerpos,playername)
+ if carinfo.controllerpos then
+ core.chat_send_player(playername,S("Can't connect to a controller you don't have access to."))
+ else
+ core.chat_send_player(playername,S("Can't connect to a dispatcher you don't have access to."))
+ end
+ return
+ end
table.insert(carinfo.callbuttons,{pos=pos,landing=tonumber(fields.landing)})
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
- local meta = minetest.get_meta(pos)
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
+ local meta = core.get_meta(pos)
meta:set_int("carid",carid)
meta:set_int("landing",tonumber(fields.landing))
meta:set_string("formspec","")
end
end,
on_destruct = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.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)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then return end
for i,button in pairs(carinfo.callbuttons) do
if vector.equals(pos,button.pos) then
table.remove(carinfo.callbuttons,i)
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
end
end
end,
on_rightclick = function(pos,_,clicker)
- local meta = minetest.get_meta(pos)
+ local meta = core.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)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then return end
local controllerpos = carinfo.controllerpos or carinfo.dispatcherpos
local isdispatcher = carinfo.dispatcherpos
if not controllerpos then return end
- local controllermeta = minetest.get_meta(controllerpos)
+ local controllermeta = core.get_meta(controllerpos)
if controllermeta:get_int("carid") ~= carid then return end
local landing = meta:get_int("landing")
if state[1] == "up" then
@@ -239,3 +322,35 @@ for _,state in ipairs(validstates) do
end,
})
end
+
+core.register_abm({
+ label = "Check call buttons for missing/replaced controllers",
+ nodenames = {"group:_celevator_callbutton",},
+ interval = 15,
+ chance = 1,
+ action = function(pos)
+ local meta = core.get_meta(pos)
+ local carid = meta:get_int("carid")
+ if not (carid and carid > 0) then return end --Not set up yet
+ local carinfo = core.deserialize(celevator.storage:get_string("car"..carid))
+ if not carinfo then
+ meta:set_string("infotext",S("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",S("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",S("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..c50f962 100644
--- a/car.lua
+++ b/car.lua
@@ -1,25 +1,35 @@
celevator.car = {}
-local function disambiguatebutton(pos,facedir,player)
+local S = core.get_translator("celevator")
+
+local function disambiguatecartopbutton(pos,facedir,player)
if player and not player.is_fake_player then
+ local playername = player:get_player_name()
+ if core.settings:get_bool("celevator.cartop_protected",false) then
+ if core.is_protected(pos,playername) and not core.check_player_privs(playername,{protection_bypass=true}) then
+ core.record_protection_violation(pos,playername)
+ return
+ end
+ end
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()
local distance = vector.distance(eyepos,pos)
local endpos = vector.add(eyepos,vector.multiply(lookdir,distance+1))
- local ray = minetest.raycast(eyepos,endpos,true,false)
+ local ray = core.raycast(eyepos,endpos,true,false)
local pointed,button,hitpos
repeat
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 node = core.get_node(pointed.under)
+ local ndef = core.registered_nodes[node.name] or {}
+ if ndef._cartopbox then
button = pointed.under
hitpos = vector.subtract(pointed.intersection_point,button)
end
end
until button or not pointed
if not hitpos then return end
- hitpos = vector.rotate_around_axis(hitpos,vector.new(0,-1,0),minetest.dir_to_yaw(facedir)+(math.pi/2))
+ hitpos = vector.rotate_around_axis(hitpos,vector.new(0,-1,0),core.dir_to_yaw(facedir)+(math.pi/2))
if hitpos.y < 0.55 then return end
if hitpos.z > 0.36 or hitpos.z < 0.09 then return end
if hitpos.x >= -0.36 and hitpos.x <= -0.16 then
@@ -34,33 +44,33 @@ end
local function updatecartopbox(pos)
local toppos = vector.add(pos,vector.new(0,1.1,0))
- local entitiesnearby = minetest.get_objects_inside_radius(toppos,0.5)
+ local entitiesnearby = core.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
- local carmeta = minetest.get_meta(pos)
+ local carmeta = core.get_meta(pos)
local carid = carmeta:get_int("carid")
if carid == 0 then return end
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then return end
- local entity = minetest.add_entity(pos,"celevator:car_top_box")
+ local entity = core.add_entity(pos,"celevator:car_top_box")
local inspon = carinfo.cartopinspect
entity:set_properties({
wield_item = inspon and "celevator:car_top_box_on" or "celevator:car_top_box_off",
})
- local fdir = minetest.fourdir_to_dir(minetest.get_node(pos).param2)
+ local fdir = core.fourdir_to_dir(core.get_node(pos).param2)
fdir = vector.rotate_around_axis(fdir,vector.new(0,1,0),math.pi/2)
- entity:set_yaw(minetest.dir_to_yaw(fdir))
+ entity:set_yaw(core.dir_to_yaw(fdir))
entity:set_pos(toppos)
end
local held = {}
-minetest.register_globalstep(function()
+core.register_globalstep(function()
for k,v in ipairs(held) do
- local player = minetest.get_player_by_name(v.name)
+ local player = core.get_player_by_name(v.name)
if not (player and player:get_player_control()[v.button]) then
table.remove(held,k)
celevator.controller.handlecartopbox(v.pos,v.control.."_release")
@@ -68,539 +78,226 @@ 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 = S("Car (part @1 - you hacker you!)",def._position)
+ def.light_source = 9
+ def.drop = ""
+ if def._cop then
+ def.groups._has_cop = 1
+ def.on_rightclick = function(pos,_,player)
+ local meta = core.get_meta(pos)
+ local carid = meta:get_int("carid")
+ if carid ~= 0 then celevator.drives.entity.coprightclick(carid,player,pos) end
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.groups._has_keyswitches = 1
+ def.on_rightclick = function(pos,_,player)
+ local meta = core.get_meta(pos)
+ local carid = meta:get_int("carid")
+ if carid ~= 0 then celevator.drives.entity.keyswitchrightclick(carid,player,pos) end
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 = core.fourdir_to_dir(node.param2)
+ local control = disambiguatecartopbutton(pos,fdir,clicker)
+ if not control then return end
+ local meta = core.get_meta(pos)
+ local carid = meta:get_int("carid")
+ if carid == 0 then return end
+ local carinfo = core.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 = core.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 = core.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)
+ core.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 core.is_protected(pos,playername) and not core.check_player_privs(playername,{protection_bypass=true}) then
+ core.record_protection_violation(pos,playername)
+ return
+ end
+ local hash = core.hash_node_position(pos)
+ local fs = "formspec_version[7]size[6,4]"
+ fs = fs.."label[0.5,1;"..S("Really remove this car?").."]"
+ fs = fs.."button_exit[0.5,2;2,1;yes;"..S("Yes").."]"
+ fs = fs.."button_exit[3,2;2,1;no;"..S("No").."]"
+ core.show_formspec(playername,string.format("celevator:remove_car_%d",hash),fs)
+ end
+ def.on_timer = function(pos)
+ local carid = core.get_meta(pos):get_int("carid")
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ if not (carinfo and carinfo.controllerpos) then return end
+ local yaw = core.dir_to_yaw(core.fourdir_to_dir(core.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 = core.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
+ core.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),
- param2 = minetest.dir_to_fourdir(minetest.yaw_to_dir(yaw)),
+ name = string.format("celevator:car_%s_%d%d%d",name,x,y,z),
+ param2 = core.dir_to_fourdir(core.yaw_to_dir(yaw)),
}
- minetest.set_node(pos,node)
- if carid then minetest.get_meta(pos):set_int("carid",carid) end
+ core.set_node(pos,node)
+ local meta = core.get_meta(pos)
+ if carid then meta:set_int("carid",carid) end
+ meta:set_string("doortype",doortype or "glass")
end
end
end
end
-minetest.register_abm({
+core.register_abm({
label = "Respawn in-car PI displays",
- nodenames = {"celevator:car_020"},
+ nodenames = {"group:_celevator_car_spawnspi"},
interval = 1,
chance = 1,
action = function(pos)
- local entitiesnearby = minetest.get_objects_inside_radius(pos,0.5)
+ local entitiesnearby = core.get_objects_inside_radius(pos,0.5)
for _,i in pairs(entitiesnearby) do
if i:get_luaentity() and i:get_luaentity().name == "celevator:incar_pi_entity" then
return
end
end
- local entity = minetest.add_entity(pos,"celevator:incar_pi_entity")
- local fdir = vector.rotate_around_axis(minetest.facedir_to_dir(minetest.get_node(pos).param2),vector.new(0,1,0),math.pi/2)
+ local entity = core.add_entity(pos,"celevator:incar_pi_entity")
+ local fdir = vector.rotate_around_axis(core.facedir_to_dir(core.get_node(pos).param2),vector.new(0,1,0),math.pi/2)
local etex = celevator.pi.generatetexture(" --",false,false,false,true)
entity:set_properties({
textures = {etex},
})
- entity:set_yaw(minetest.dir_to_yaw(fdir))
+ entity:set_yaw(core.dir_to_yaw(fdir))
entity:set_pos(vector.add(pos,vector.multiply(fdir,0.44)))
end,
})
-minetest.register_node("celevator:car_top_box_off",{
- description = "Car-top Inspection Box, Off State (you hacker you!)",
+core.register_node("celevator:car_top_box_off",{
+ description = S("Car-top Inspection Box, Off State (you hacker you!)"),
drop = "",
groups = {
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
paramtype = "light",
@@ -617,10 +314,12 @@ minetest.register_node("celevator:car_top_box_off",{
},
})
-minetest.register_node("celevator:car_top_box_on",{
- description = "Car-top Inspection Box, On State (you hacker you!)",
+core.register_node("celevator:car_top_box_on",{
+ description = S("Car-top Inspection Box, On State (you hacker you!)"),
drop = "",
groups = {
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
paramtype = "light",
@@ -637,110 +336,35 @@ minetest.register_node("celevator:car_top_box_on",{
},
})
-minetest.register_entity("celevator:car_top_box",{
+core.register_entity("celevator:car_top_box",{
initial_properties = {
visual = "wielditem",
visual_size = vector.new(0.667,0.667,0.667),
wield_item = "celevator:car_top_box_off",
static_save = false,
pointable = false,
- glow = minetest.LIGHT_MAX,
+ glow = core.LIGHT_MAX,
},
})
-minetest.register_abm({
+core.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)
+core.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 rootpos = core.get_position_from_hash(hash)
+ local rootdef = core.registered_nodes[celevator.get_node(rootpos).name] or {}
+ local cartype = rootdef._celevator_car_type
+ if cartype and celevator.car.types[cartype] then
+ local rootdir = core.dir_to_yaw(core.fourdir_to_dir(core.get_node(rootpos).param2))
+ celevator.car.types[cartype].remove(rootpos,rootdir)
end
end)
diff --git a/car_fullglass.lua b/car_fullglass.lua
new file mode 100644
index 0000000..f934007
--- /dev/null
+++ b/car_fullglass.lua
@@ -0,0 +1,425 @@
+local S = core.get_translator("celevator")
+
+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.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},
+ },
+ },
+ use_texture_alpha = "clip",
+ tiles = {
+ "celevator_car_metal_floor.png",
+ "celevator_car_bottom_center.png",
+ "celevator_car_side_center_overlay.png^celevator_car_glass.png^celevator_car_wall_bottom.png^celevator_car_wall_vent.png",
+ "celevator_car_wall_bottom.png^celevator_car_wall_vent.png^celevator_car_glass.png^celevator_car_side_center_overlay.png",
+ "celevator_car_glass.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_side_overlay.png^[transformFX^celevator_car_glass.png^celevator_car_wall_bottom.png",
+ "celevator_car_wall_bottom.png^celevator_car_glass.png^celevator_car_side_overlay.png",
+ "celevator_car_wall_bottom.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.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},
+ },
+ },
+ use_texture_alpha = "clip",
+ tiles = {
+ "celevator_car_metal_floor.png",
+ "celevator_car_bottom_center.png^[transformFX",
+ "celevator_car_wall_bottom.png^celevator_car_wall_vent.png^celevator_car_glass.png^celevator_car_side_center_overlay.png",
+ "celevator_car_side_center_overlay.png^celevator_car_glass.png^celevator_car_wall_bottom.png^celevator_car_wall_vent.png",
+ "celevator_car_glass.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_car_wall_bottom.png^[transformR270^celevator_car_glass.png^celevator_car_side_overlay.png^[transformR90",
+ "celevator_car_side_overlay.png^celevator_car_glass.png^celevator_car_wall_bottom.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},
+ },
+ },
+ use_texture_alpha = "clip",
+ tiles = {
+ "celevator_car_glass.png",
+ "celevator_car_glass.png",
+ "celevator_car_side_center2_overlay.png^celevator_car_glass.png^celevator_car_handrail_end.png",
+ "celevator_car_handrail_end.png^[transformFX^celevator_car_glass.png^celevator_car_side_center2_overlay.png",
+ "celevator_car_glass.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_car_glass.png",
+ "celevator_car_glass.png",
+ "celevator_car_glass.png^(celevator_car_handrail_end.png^[transformFX)",
+ "celevator_car_handrail_end.png^celevator_car_glass.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},
+ },
+ },
+ use_texture_alpha = "clip",
+ tiles = {
+ "celevator_car_glass.png",
+ "celevator_car_glass.png",
+ "celevator_car_handrail_center.png^celevator_car_glass.png^celevator_car_side_center2_overlay.png",
+ "celevator_car_side_center2_overlay.png^celevator_car_glass.png^celevator_car_handrail_center.png",
+ "celevator_car_glass.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_car_glass.png",
+ "celevator_car_glass.png",
+ "celevator_car_handrail_end.png^[transformFX^celevator_car_glass.png",
+ "celevator_car_glass.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},
+ },
+ },
+ use_texture_alpha = "clip",
+ tiles = {
+ "celevator_cabinet_sides.png^celevator_car_top_center_overlay.png",
+ "celevator_car_metal_ceiling.png",
+ "celevator_car_side_center_overlay.png^celevator_car_glass.png",
+ "celevator_car_glass.png^celevator_car_side_center_overlay.png",
+ "celevator_car_glass.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_glass.png",
+ "celevator_car_glass.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},
+ },
+ },
+ use_texture_alpha = "clip",
+ tiles = {
+ "celevator_cabinet_sides.png^celevator_car_top_center_overlay.png^[transformFX",
+ "celevator_car_metal_ceiling.png",
+ "celevator_car_glass.png^celevator_car_side_center_overlay.png",
+ "celevator_car_side_center_overlay.png^celevator_car_glass.png",
+ "celevator_car_glass.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_car_glass.png",
+ "celevator_car_glass.png",
+ "celevator_car_glass.png",
+ "celevator_car_glass.png",
+ },
+ _tapehead = true,
+ },
+}
+
+celevator.car.register("fullglass",pieces,vector.new(2,3,3))
+
+
+core.register_node("celevator:car_fullglass",{
+ description = S("Full-Glass Elevator Car"),
+ paramtype2 = "4dir",
+ buildable_to = true,
+ inventory_image = "celevator_car_fullglass_inventory.png",
+ wield_image = "celevator_car_fullglass_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
+ core.remove_node(pos)
+ return true
+ end
+ local name = player:get_player_name()
+ local newnode = core.get_node(pos)
+ local facedir = core.dir_to_yaw(core.fourdir_to_dir(newnode.param2))
+ for x=0,1,1 do
+ for y=0,2,1 do
+ for z=0,2,1 do
+ 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 = core.get_node(placepos).name
+ if not (core.registered_nodes[replaces] and core.registered_nodes[replaces].buildable_to) then
+ local message = S("Can't place car here - position @1m to the right, @2m up, and @3m back is blocked!",x,y,z)
+ core.chat_send_player(name,message)
+ core.remove_node(pos)
+ return true
+ end
+ if core.is_protected(placepos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ local message = S("Can't place car here - position @1m to the right, @2m up, and @3m back is protected!",x,y,z)
+ core.chat_send_player(name,message)
+ core.record_protection_violation(placepos,name)
+ core.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_fullglass_%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))
+ core.set_node(placepos,{name=piecename,param2=newnode.param2})
+ end
+ end
+ end
+ end,
+})
+
+celevator.car.types.fullglass.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_fullglass_%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 core.get_node(piecepos).name == piecename then
+ core.remove_node(piecepos)
+ local erefs = core.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 = core.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_glassback.lua b/car_glassback.lua
new file mode 100644
index 0000000..1c7163e
--- /dev/null
+++ b/car_glassback.lua
@@ -0,0 +1,419 @@
+local S = core.get_translator("celevator")
+
+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.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.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))
+
+
+core.register_node("celevator:car_glassback",{
+ description = S("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
+ core.remove_node(pos)
+ return true
+ end
+ local name = player:get_player_name()
+ local newnode = core.get_node(pos)
+ local facedir = core.dir_to_yaw(core.fourdir_to_dir(newnode.param2))
+ for x=0,1,1 do
+ for y=0,2,1 do
+ for z=0,2,1 do
+ 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 = core.get_node(placepos).name
+ if not (core.registered_nodes[replaces] and core.registered_nodes[replaces].buildable_to) then
+ local message = S("Can't place car here - position @1m to the right, @2m up, and @3m back is blocked!",x,y,z)
+ core.chat_send_player(name,message)
+ core.remove_node(pos)
+ return true
+ end
+ if core.is_protected(placepos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ local message = S("Can't place car here - position @1m to the right, @2m up, and @3m back is protected!",x,y,z)
+ core.chat_send_player(name,message)
+ core.record_protection_violation(placepos,name)
+ core.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))
+ core.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 core.get_node(piecepos).name == piecename then
+ core.remove_node(piecepos)
+ local erefs = core.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 = core.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..c3d1a44
--- /dev/null
+++ b/car_metal.lua
@@ -0,0 +1,413 @@
+local S = core.get_translator("celevator")
+
+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.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.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))
+
+
+core.register_node("celevator:car_metal",{
+ description = S("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
+ core.remove_node(pos)
+ return true
+ end
+ local name = player:get_player_name()
+ local newnode = core.get_node(pos)
+ local facedir = core.dir_to_yaw(core.fourdir_to_dir(newnode.param2))
+ for x=0,1,1 do
+ for y=0,2,1 do
+ for z=0,2,1 do
+ 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 = core.get_node(placepos).name
+ if not (core.registered_nodes[replaces] and core.registered_nodes[replaces].buildable_to) then
+ local message = S("Can't place car here - position @1m to the right, @2m up, and @3m back is blocked!",x,y,z)
+ core.chat_send_player(name,message)
+ core.remove_node(pos)
+ return true
+ end
+ if core.is_protected(placepos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ local message = S("Can't place car here - position @1m to the right, @2m up, and @3m back is protected!",x,y,z)
+ core.chat_send_player(name,message)
+ core.record_protection_violation(placepos,name)
+ core.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))
+ core.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 core.get_node(piecepos).name == piecename then
+ core.remove_node(piecepos)
+ local erefs = core.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 = core.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..7ca944e
--- /dev/null
+++ b/car_metalglass.lua
@@ -0,0 +1,419 @@
+local S = core.get_translator("celevator")
+
+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.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.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))
+
+
+core.register_node("celevator:car_metal_glassback",{
+ description = S("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
+ core.remove_node(pos)
+ return true
+ end
+ local name = player:get_player_name()
+ local newnode = core.get_node(pos)
+ local facedir = core.dir_to_yaw(core.fourdir_to_dir(newnode.param2))
+ for x=0,1,1 do
+ for y=0,2,1 do
+ for z=0,2,1 do
+ 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 = core.get_node(placepos).name
+ if not (core.registered_nodes[replaces] and core.registered_nodes[replaces].buildable_to) then
+ local message = S("Can't place car here - position @1m to the right, @2m up, and @3m back is blocked!",x,y,z)
+ core.chat_send_player(name,message)
+ core.remove_node(pos)
+ return true
+ end
+ if core.is_protected(placepos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ local message = S("Can't place car here - position @1m to the right, @2m up, and @3m back is protected!",x,y,z)
+ core.chat_send_player(name,message)
+ core.record_protection_violation(placepos,name)
+ core.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))
+ core.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 core.get_node(piecepos).name == piecename then
+ core.remove_node(piecepos)
+ local erefs = core.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 = core.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..44f74bb
--- /dev/null
+++ b/car_standard.lua
@@ -0,0 +1,422 @@
+local S = core.get_translator("celevator")
+
+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.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.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
+ core.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
+
+core.register_node("celevator:car_standard",{
+ description = S("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
+ core.remove_node(pos)
+ return true
+ end
+ local name = player:get_player_name()
+ local newnode = core.get_node(pos)
+ local facedir = core.dir_to_yaw(core.fourdir_to_dir(newnode.param2))
+ for x=0,1,1 do
+ for y=0,2,1 do
+ for z=0,2,1 do
+ 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 = core.get_node(placepos).name
+ if not (core.registered_nodes[replaces] and core.registered_nodes[replaces].buildable_to) then
+ local message = S("Can't place car here - position @1m to the right, @2m up, and @3m back is blocked!",x,y,z)
+ core.chat_send_player(name,message)
+ core.remove_node(pos)
+ return true
+ end
+ if core.is_protected(placepos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ local message = S("Can't place car here - position @1m to the right, @2m up, and @3m back is protected!",x,y,z)
+ core.chat_send_player(name,message)
+ core.record_protection_violation(placepos,name)
+ core.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))
+ core.set_node(placepos,{name=piecename,param2=newnode.param2})
+ end
+ end
+ end
+ end,
+})
+
+core.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 core.get_node(piecepos).name == piecename then
+ core.remove_node(piecepos)
+ local erefs = core.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 = core.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..eacb4f0
--- /dev/null
+++ b/chatcommands.lua
@@ -0,0 +1,183 @@
+local S = core.get_translator("celevator")
+
+core.register_chatcommand("carcall",{
+ description = S("Places a car call at the specified landing on the specified elevator"),
+ params = S("<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,S("Invalid car ID")
+ end
+ if not (landing and tonumber(landing)) then
+ return false,S("Invalid landing number")
+ end
+ local carinfo = core.deserialize(celevator.storage:get_string("car"..carid))
+ if not (carinfo and carinfo.controllerpos) then
+ return false,S("No such car or car info is missing")
+ end
+ if not celevator.controller.iscontroller(carinfo.controllerpos) then
+ return false,S("Controller is missing")
+ end
+ if celevator.get_meta(carinfo.controllerpos):get_int("carid") ~= tonumber(carid) then
+ return false,S("Controller found but with wrong ID")
+ end
+ if core.is_protected(carinfo.controllerpos,name) then
+ core.record_protection_violation(carinfo.controllerpos,name)
+ return false,S("Controller is protected")
+ end
+ celevator.controller.run(carinfo.controllerpos,{
+ type = "remotemsg",
+ channel = "carcall",
+ msg = tonumber(landing),
+ })
+ return true,S("Command sent")
+ end,
+})
+
+core.register_chatcommand("upcall",{
+ description = S("Places an up hall call at the specified landing on the specified elevator or dispatcher"),
+ params = S("<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,S("Invalid car ID")
+ end
+ if not (landing and tonumber(landing)) then
+ return false,S("Invalid landing number")
+ end
+ local carinfo = core.deserialize(celevator.storage:get_string("car"..carid))
+ if not (carinfo and (carinfo.controllerpos or carinfo.dispatcherpos)) then
+ return false,S("No such car or car info is missing")
+ end
+ if carinfo.controllerpos then
+ if not celevator.controller.iscontroller(carinfo.controllerpos) then
+ return false,S("Controller is missing")
+ end
+ if celevator.get_meta(carinfo.controllerpos):get_int("carid") ~= tonumber(carid) then
+ return false,S("Controller found but with wrong ID")
+ end
+ if core.is_protected(carinfo.controllerpos,name) then
+ core.record_protection_violation(carinfo.controllerpos,name)
+ return false,S("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,S("Command sent")
+ elseif carinfo.dispatcherpos then
+ if not celevator.dispatcher.isdispatcher(carinfo.dispatcherpos) then
+ return false,S("Dispatcher is missing")
+ end
+ if celevator.get_meta(carinfo.dispatcherpos):get_int("carid") ~= tonumber(carid) then
+ return false,S("Dispatcher found but with wrong ID")
+ end
+ if core.is_protected(carinfo.dispatcherpos,name) then
+ core.record_protection_violation(carinfo.dispatcherpos,name)
+ return false,S("Dispatcher is protected")
+ end
+ celevator.dispatcher.run(carinfo.dispatcherpos,{
+ type = "remotemsg",
+ channel = "upcall",
+ msg = tonumber(landing),
+ })
+ return true,S("Command sent")
+ end
+ end,
+})
+
+core.register_chatcommand("downcall",{
+ description = S("Places a down hall call at the specified landing on the specified elevator or dispatcher"),
+ params = S("<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,S("Invalid car ID")
+ end
+ if not (landing and tonumber(landing)) then
+ return false,S("Invalid landing number")
+ end
+ local carinfo = core.deserialize(celevator.storage:get_string("car"..carid))
+ if not (carinfo and (carinfo.controllerpos or carinfo.dispatcherpos)) then
+ return false,S("No such car or car info is missing")
+ end
+ if carinfo.controllerpos then
+ if not celevator.controller.iscontroller(carinfo.controllerpos) then
+ return false,S("Controller is missing")
+ end
+ if celevator.get_meta(carinfo.controllerpos):get_int("carid") ~= tonumber(carid) then
+ return false,S("Controller found but with wrong ID")
+ end
+ if core.is_protected(carinfo.controllerpos,name) then
+ core.record_protection_violation(carinfo.controllerpos,name)
+ return false,S("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,S("Command sent")
+ elseif carinfo.dispatcherpos then
+ if not celevator.dispatcher.isdispatcher(carinfo.dispatcherpos) then
+ return false,S("Dispatcher is missing")
+ end
+ if celevator.get_meta(carinfo.dispatcherpos):get_int("carid") ~= tonumber(carid) then
+ return false,S("Dispatcher found but with wrong ID")
+ end
+ if core.is_protected(carinfo.dispatcherpos,name) then
+ core.record_protection_violation(carinfo.dispatcherpos,name)
+ return false,S("Dispatcher is protected")
+ end
+ celevator.dispatcher.run(carinfo.dispatcherpos,{
+ type = "remotemsg",
+ channel = "dncall",
+ msg = tonumber(landing),
+ })
+ return true,S("Command sent")
+ end
+ end,
+})
+
+core.register_chatcommand("elevstatus",{
+ description = S("View the status of the specified elevator"),
+ params = S("<car ID>"),
+ func = function(_,param)
+ if not (param and tonumber(param)) then
+ return false,S("Invalid car ID")
+ end
+ local carinfo = core.deserialize(celevator.storage:get_string("car"..param))
+ if not (carinfo and carinfo.controllerpos) then
+ return false,S("No such car or car info is missing")
+ end
+ if not celevator.controller.iscontroller(carinfo.controllerpos) then
+ return false,S("Controller is missing")
+ end
+ local controllermeta = celevator.get_meta(carinfo.controllerpos)
+ if controllermeta:get_int("carid") ~= tonumber(param) then
+ return false,S("Controller found but with wrong ID")
+ end
+ local mem = core.deserialize(controllermeta:get_string("mem"))
+ if not mem then
+ return false,S("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..d6c4ee9 100644
--- a/controller.lua
+++ b/controller.lua
@@ -1,23 +1,25 @@
celevator.controller = {}
-celevator.controller.iqueue = minetest.deserialize(celevator.storage:get_string("controller_iqueue")) or {}
+local S = core.get_translator("celevator")
-celevator.controller.equeue = minetest.deserialize(celevator.storage:get_string("controller_equeue")) or {}
+celevator.controller.iqueue = core.deserialize(celevator.storage:get_string("controller_iqueue")) or {}
+
+celevator.controller.equeue = core.deserialize(celevator.storage:get_string("controller_equeue")) or {}
celevator.controller.running = {}
-local fw,err = loadfile(minetest.get_modpath("celevator")..DIR_DELIM.."controllerfw.lua")
+local fw,err = loadfile(core.get_modpath("celevator").."/controllerfw.lua")
if not fw then error(err) end
-minetest.register_chatcommand("celevator_reloadcontroller",{
+core.register_chatcommand("celevator_reloadcontroller",{
params = "",
- description = "Reload celevator controller firmware from disk",
+ description = S("Reload celevator controller firmware from disk"),
privs = {server = true},
func = function()
- local newfw,loaderr = loadfile(minetest.get_modpath("celevator")..DIR_DELIM.."controllerfw.lua")
+ local newfw,loaderr = loadfile(core.get_modpath("celevator").."/controllerfw.lua")
if newfw then
fw = newfw
- return true,"Firmware reloaded successfully"
+ return true,S("Firmware reloaded successfully")
else
return false,loaderr
end
@@ -25,32 +27,32 @@ minetest.register_chatcommand("celevator_reloadcontroller",{
})
local function after_place(pos,placer)
- local node = minetest.get_node(pos)
+ local node = core.get_node(pos)
local toppos = {x=pos.x,y=pos.y + 1,z=pos.z}
- local topnode = minetest.get_node(toppos)
+ local topnode = core.get_node(toppos)
local placername = placer:get_player_name()
if topnode.name ~= "air" then
if placer:is_player() then
- minetest.chat_send_player(placername,"Can't place cabinet - no room for the top half!")
+ core.chat_send_player(placername,S("Can't place cabinet - no room for the top half!"))
end
- minetest.set_node(pos,{name="air"})
+ core.set_node(pos,{name="air"})
return true
end
- if minetest.is_protected(toppos,placername) and not minetest.check_player_privs(placername,{protection_bypass=true}) then
+ if core.is_protected(toppos,placername) and not core.check_player_privs(placername,{protection_bypass=true}) then
if placer:is_player() then
- minetest.chat_send_player(placername,"Can't place cabinet - top half is protected!")
- minetest.record_protection_violation(toppos,placername)
+ core.chat_send_player(placername,S("Can't place cabinet - top half is protected!"))
+ core.record_protection_violation(toppos,placername)
end
- minetest.set_node(pos,{name="air"})
+ core.set_node(pos,{name="air"})
return true
end
node.name = "celevator:controller_top"
- minetest.set_node(toppos,node)
+ core.set_node(toppos,node)
end
local function ondestruct(pos)
pos.y = pos.y + 1
- local topnode = minetest.get_node(pos)
+ local topnode = core.get_node(pos)
local controllertops = {
["celevator:controller_top"] = true,
["celevator:controller_top_running"] = true,
@@ -58,32 +60,38 @@ local function ondestruct(pos)
["celevator:controller_top_open_running"] = true,
}
if controllertops[topnode.name] then
- minetest.set_node(pos,{name="air"})
+ core.set_node(pos,{name="air"})
end
- celevator.controller.equeue[minetest.hash_node_position(pos)] = nil
- celevator.storage:set_string("controller_equeue",minetest.serialize(celevator.controller.equeue))
- local carid = minetest.get_meta(pos):get_int("carid")
+ celevator.controller.equeue[core.hash_node_position(pos)] = nil
+ celevator.storage:set_string("controller_equeue",core.serialize(celevator.controller.equeue))
+ local carid = core.get_meta(pos):get_int("carid")
if carid ~= 0 then celevator.storage:set_string(string.format("car%d",carid),"") end
end
local function onrotate(controllerpos,node,user,mode,new_param2)
- if not minetest.global_exists("screwdriver") then
+ if not core.global_exists("screwdriver") then
return false
end
local ret = screwdriver.rotate_simple(controllerpos,node,user,mode,new_param2)
- minetest.after(0,function(pos)
- local newnode = minetest.get_node(pos)
+ core.after(0,function(pos)
+ local newnode = core.get_node(pos)
local param2 = newnode.param2
pos.y = pos.y + 1
- local topnode = minetest.get_node(pos)
+ local topnode = core.get_node(pos)
topnode.param2 = param2
- minetest.set_node(pos,topnode)
+ core.set_node(pos,topnode)
end,controllerpos)
return ret
end
local function handlefields(pos,_,fields,sender)
local playername = sender and sender:get_player_name() or ""
+ if core.settings:get_bool("celevator.controller_screen_protected",false) then
+ if core.is_protected(pos,playername) and not core.check_player_privs(playername,{protection_bypass=true}) then
+ core.record_protection_violation(pos,playername)
+ return
+ end
+ end
local event = {}
event.type = "ui"
event.fields = fields
@@ -99,20 +107,20 @@ local function controllerleds(pos,running)
}
if node.name == "celevator:controller_top_open" and running then
node.name = "celevator:controller_top_open_running"
- minetest.swap_node(toppos,node)
- minetest.sound_play("celevator_controller_start",sparams,true)
+ core.swap_node(toppos,node)
+ core.sound_play("celevator_controller_start",sparams,true)
elseif node.name == "celevator:controller_top" and running then
node.name = "celevator:controller_top_running"
- minetest.swap_node(toppos,node)
- minetest.sound_play("celevator_controller_start",sparams,true)
+ core.swap_node(toppos,node)
+ core.sound_play("celevator_controller_start",sparams,true)
elseif node.name == "celevator:controller_top_open_running" and not running then
node.name = "celevator:controller_top_open"
- minetest.swap_node(toppos,node)
- minetest.sound_play("celevator_controller_stop",sparams,true)
+ core.swap_node(toppos,node)
+ core.sound_play("celevator_controller_stop",sparams,true)
elseif node.name == "celevator:controller_top_running" and not running then
node.name = "celevator:controller_top"
- minetest.swap_node(toppos,node)
- minetest.sound_play("celevator_controller_stop",sparams,true)
+ core.swap_node(toppos,node)
+ core.sound_play("celevator_controller_stop",sparams,true)
end
end
@@ -121,15 +129,16 @@ local function candig(_,player)
if controls.sneak then
return true
else
- minetest.chat_send_player(player:get_player_name(),"Hold the sneak button while digging to remove.")
+ core.chat_send_player(player:get_player_name(),S("Hold the sneak button while digging to remove."))
return false
end
end
-minetest.register_node("celevator:controller",{
- description = "Elevator Controller",
+core.register_node("celevator:controller",{
+ description = S("Elevator Controller"),
groups = {
- cracky = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
paramtype = "light",
paramtype2 = "facedir",
@@ -160,15 +169,15 @@ minetest.register_node("celevator:controller",{
on_receive_fields = handlefields,
can_dig = candig,
on_construct = function(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("mem",minetest.serialize({}))
+ local meta = core.get_meta(pos)
+ meta:set_string("mem",core.serialize({}))
meta:mark_as_private("mem")
local event = {}
event.type = "program"
local carid = celevator.storage:get_int("maxcarid")+1
meta:set_int("carid",carid)
celevator.storage:set_int("maxcarid",carid)
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize({controllerpos=pos,pis={},lanterns={},callbuttons={},fs1switches={}}))
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize({controllerpos=pos,pis={},lanterns={},callbuttons={},fs1switches={}}))
celevator.controller.run(pos,event)
end,
on_punch = function(pos,node,puncher)
@@ -176,24 +185,26 @@ minetest.register_node("celevator:controller",{
return
end
local name = puncher: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,"Can't open cabinet - cabinet is locked.")
- minetest.record_protection_violation(pos,name)
- return
+ if core.settings:get_bool("celevator.controller_cabinet_protected",true) then
+ if core.is_protected(pos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ core.chat_send_player(name,S("Can't open cabinet - cabinet is locked."))
+ core.record_protection_violation(pos,name)
+ return
+ end
end
node.name = "celevator:controller_open"
- minetest.swap_node(pos,node)
- local meta = minetest.get_meta(pos)
+ core.swap_node(pos,node)
+ local meta = core.get_meta(pos)
meta:set_string("formspec",meta:get_string("formspec_hidden"))
pos.y = pos.y + 1
- node = minetest.get_node(pos)
+ node = core.get_node(pos)
if node.name == "celevator:controller_top_running" then
node.name = "celevator:controller_top_open_running"
else
node.name = "celevator:controller_top_open"
end
- minetest.swap_node(pos,node)
- minetest.sound_play("celevator_cabinet_open",{
+ core.swap_node(pos,node)
+ core.sound_play("celevator_cabinet_open",{
pos = pos,
gain = 0.5,
max_hear_distance = 10
@@ -201,10 +212,11 @@ minetest.register_node("celevator:controller",{
end,
})
-minetest.register_node("celevator:controller_open",{
- description = "Controller (door open - you hacker you!)",
+core.register_node("celevator:controller_open",{
+ description = S("Controller (door open - you hacker you!)"),
groups = {
- cracky = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
paramtype = "light",
@@ -243,18 +255,18 @@ minetest.register_node("celevator:controller_open",{
return
end
node.name = "celevator:controller"
- minetest.swap_node(pos,node)
- local meta = minetest.get_meta(pos)
+ core.swap_node(pos,node)
+ local meta = core.get_meta(pos)
meta:set_string("formspec","")
pos.y = pos.y + 1
- node = minetest.get_node(pos)
+ node = core.get_node(pos)
if node.name == "celevator:controller_top_open_running" then
node.name = "celevator:controller_top_running"
else
node.name = "celevator:controller_top"
end
- minetest.swap_node(pos,node)
- minetest.sound_play("celevator_cabinet_close",{
+ core.swap_node(pos,node)
+ core.sound_play("celevator_cabinet_close",{
pos = pos,
gain = 0.5,
max_hear_distance = 10
@@ -262,9 +274,11 @@ minetest.register_node("celevator:controller_open",{
end,
})
-minetest.register_node("celevator:controller_top",{
- description = "Controller (top section - you hacker you!)",
+core.register_node("celevator:controller_top",{
+ description = S("Controller (top section - you hacker you!)"),
groups = {
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
drop = "",
@@ -293,9 +307,11 @@ minetest.register_node("celevator:controller_top",{
},
})
-minetest.register_node("celevator:controller_top_running",{
- description = "Controller (top section, car in motion - you hacker you!)",
+core.register_node("celevator:controller_top_running",{
+ description = S("Controller (top section, car in motion - you hacker you!)"),
groups = {
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
drop = "",
@@ -324,9 +340,11 @@ minetest.register_node("celevator:controller_top_running",{
},
})
-minetest.register_node("celevator:controller_top_open",{
- description = "Controller (top section, open - you hacker you!)",
+core.register_node("celevator:controller_top_open",{
+ description = S("Controller (top section, open - you hacker you!)"),
groups = {
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
drop = "",
@@ -360,9 +378,11 @@ minetest.register_node("celevator:controller_top_open",{
},
})
-minetest.register_node("celevator:controller_top_open_running",{
- description = "Controller (top section, open, car in motion - you hacker you!)",
+core.register_node("celevator:controller_top_open_running",{
+ description = S("Controller (top section, open, car in motion - you hacker you!)"),
groups = {
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
drop = "",
@@ -403,24 +423,24 @@ end
function celevator.controller.finddrive(pos)
local node = celevator.get_node(pos)
- local dir = minetest.facedir_to_dir(node.param2)
+ local dir = core.facedir_to_dir(node.param2)
local drivepos = vector.add(pos,vector.new(0,1,0))
drivepos = vector.add(drivepos,vector.rotate_around_axis(dir,vector.new(0,-1,0),math.pi/2))
drivepos = vector.round(drivepos)
local drivename = celevator.get_node(drivepos).name
- return drivepos,minetest.registered_nodes[drivename]._celevator_drive_type
+ return drivepos,core.registered_nodes[drivename]._celevator_drive_type
end
function celevator.controller.finish(pos,mem,changedinterrupts)
if not celevator.controller.iscontroller(pos) then
return
else
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local carid = meta:get_int("carid")
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
local carinfodirty = false
if not carinfo then
- minetest.log("error","[celevator] [controller] Bad car info for controller at "..minetest.pos_to_string(pos))
+ core.log("error",string.format("[celevator] [controller] Bad car info for controller at %s",core.pos_to_string(pos)))
return
end
local drivepos,drivetype = celevator.controller.finddrive(pos)
@@ -435,7 +455,7 @@ function celevator.controller.finish(pos,mem,changedinterrupts)
elseif command.command == "estop" then
celevator.drives[drivetype].estop(drivepos)
elseif command.command == "open" then
- minetest.after(0.25,celevator.drives[drivetype].movedoors,drivepos,"open")
+ core.after(0.25,celevator.drives[drivetype].movedoors,drivepos,"open")
elseif command.command == "close" then
celevator.drives[drivetype].movedoors(drivepos,"close",command.nudge)
elseif command.command == "resetfault" then
@@ -444,13 +464,22 @@ 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 {}
+ local oldmem = core.deserialize(meta:get_string("mem")) or {}
local oldupbuttonlights = oldmem.upcalls or {}
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
@@ -533,10 +562,10 @@ function celevator.controller.finish(pos,mem,changedinterrupts)
meta:set_string("copformspec",mem.copformspec)
meta:set_string("switchformspec",mem.switchformspec)
if (mem.copformspec ~= oldmem.copformspec or mem.switchformspec ~= oldmem.switchformspec) and drivetype then
- minetest.after(0.25,celevator.drives[drivetype].updatecopformspec,drivepos)
+ core.after(0.25,celevator.drives[drivetype].updatecopformspec,drivepos)
end
for _,message in ipairs(mem.messages) do
- local destinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",message.carid)))
+ local destinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",message.carid)))
if destinfo and destinfo.dispatcherpos then
celevator.dispatcher.run(destinfo.dispatcherpos,{
type = "controllermsg",
@@ -546,26 +575,26 @@ function celevator.controller.finish(pos,mem,changedinterrupts)
})
end
end
- meta:set_string("mem",minetest.serialize(mem))
+ meta:set_string("mem",core.serialize(mem))
if node.name == "celevator:controller_open" then meta:set_string("formspec",mem.formspec or "") end
meta:set_string("formspec_hidden",mem.formspec or "")
meta:set_string("infotext",mem.infotext or "")
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
if not celevator.controller.iqueue[hash] then celevator.controller.iqueue[hash] = mem.interrupts end
for iid in pairs(changedinterrupts) do
celevator.controller.iqueue[hash][iid] = mem.interrupts[iid]
end
- celevator.storage:set_string("controller_iqueue",minetest.serialize(celevator.controller.iqueue))
+ celevator.storage:set_string("controller_iqueue",core.serialize(celevator.controller.iqueue))
controllerleds(pos,mem.showrunning)
celevator.controller.running[hash] = nil
if #celevator.controller.equeue[hash] > 0 then
local event = celevator.controller.equeue[hash][1]
table.remove(celevator.controller.equeue[hash],1)
- celevator.storage:set_string("controller_equeue",minetest.serialize(celevator.controller.equeue))
+ celevator.storage:set_string("controller_equeue",core.serialize(celevator.controller.equeue))
celevator.controller.run(pos,event)
end
if carinfodirty then
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
end
end
end
@@ -574,25 +603,27 @@ function celevator.controller.run(pos,event)
if not celevator.controller.iscontroller(pos) then
return
else
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
if not celevator.controller.equeue[hash] then
celevator.controller.equeue[hash] = {}
- celevator.storage:set_string("controller_equeue",minetest.serialize(celevator.controller.equeue))
+ celevator.storage:set_string("controller_equeue",core.serialize(celevator.controller.equeue))
end
if celevator.controller.running[hash] then
table.insert(celevator.controller.equeue[hash],event)
- celevator.storage:set_string("controller_equeue",minetest.serialize(celevator.controller.equeue))
+ celevator.storage:set_string("controller_equeue",core.serialize(celevator.controller.equeue))
if #celevator.controller.equeue[hash] > 5 then
- local message = "[celevator] [controller] Async process for controller at %s is falling behind, %d events in queue"
- minetest.log("warning",string.format(message,minetest.pos_to_string(pos),#celevator.controller.equeue[hash]))
+ local pstring = core.pos_to_string(pos)
+ local queuelen = #celevator.controller.equeue[hash]
+ local message = string.format("[celevator] [controller] Async process for controller at %s is falling behind, %d events in queue",pstring,queuelen)
+ core.log("warning",message)
end
return
end
celevator.controller.running[hash] = true
- local meta = minetest.get_meta(pos)
- local mem = minetest.deserialize(meta:get_string("mem"))
+ local meta = core.get_meta(pos)
+ local mem = core.deserialize(meta:get_string("mem"))
if not mem then
- minetest.log("error","[celevator] [controller] Failed to load controller memory at "..minetest.pos_to_string(pos))
+ core.log("error",string.format("[celevator] [controller] Failed to load controller memory at %s",core.pos_to_string(pos)))
return
end
mem.drive = {}
@@ -602,9 +633,9 @@ function celevator.controller.run(pos,event)
mem.drive.type = drivetype
mem.drive.status = celevator.drives[drivetype].getstatus(drivepos)
end
- mem.interrupts = celevator.controller.iqueue[minetest.hash_node_position(pos)] or {}
+ mem.interrupts = celevator.controller.iqueue[core.hash_node_position(pos)] or {}
mem.carid = meta:get_int("carid")
- minetest.handle_async(fw,celevator.controller.finish,pos,event,mem)
+ core.handle_async(fw,celevator.controller.finish,pos,event,mem)
end
end
@@ -635,8 +666,10 @@ end
function celevator.controller.checkiqueue(dtime)
for hash,iqueue in pairs(celevator.controller.iqueue) do
- local pos = minetest.get_position_from_hash(hash)
+ local pos = core.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,7 +679,11 @@ 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",core.serialize(celevator.controller.iqueue))
+ end
end
end
-minetest.register_globalstep(celevator.controller.checkiqueue)
+core.register_globalstep(celevator.controller.checkiqueue)
diff --git a/controllerfw.lua b/controllerfw.lua
index eeb8814..fe23066 100644
--- a/controllerfw.lua
+++ b/controllerfw.lua
@@ -1,5 +1,7 @@
local pos,event,mem = ...
+local S = core.get_translator("celevator")
+
local changedinterrupts = {}
mem.messages = {}
@@ -40,40 +42,44 @@ end
local juststarted = false
local modenames = {
- normal = "Normal Operation",
- uninit = "Uninitialized",
- resync = "Position Sync - Floor",
- bfdemand = "Position Sync - Terminal",
- fault = "Fault",
- stop = "Emergency Stop",
- mrinspect = "Machine Room Inspection",
- carinspect = "Car Top Inspection",
- inspconflict = "Inspection Conflict",
- fs1 = "Fire Service - Phase 1",
- fs2 = "Fire Service - Phase 2",
- fs2hold = "Fire Service - Phase 2 Hold",
- indep = "Independent Service",
- capture = "Captured",
- test = "Test Mode",
+ normal = S("Normal Operation"),
+ uninit = S("Uninitialized"),
+ resync = S("Position Sync - Floor"),
+ bfdemand = S("Position Sync - Terminal"),
+ fault = S("Fault"),
+ stop = S("Emergency Stop"),
+ mrinspect = S("Machine Room Inspection"),
+ carinspect = S("Car Top Inspection"),
+ inspconflict = "Inspection Conflict", --No longer used but some controllers may be in it at update time
+ fs1 = S("Fire Service - Phase 1"),
+ fs2 = S("Fire Service - Phase 2"),
+ fs2hold = S("Fire Service - Phase 2 Hold"),
+ indep = S("Independent Service"),
+ capture = S("Captured"),
+ test = S("Test Mode"),
+ swing = S("Swing Operation"),
}
local doorstates = {
- open = "Open",
- opening = "Opening",
- closing = "Closing",
- closed = "Closed",
- testtiming = "Closed",
+ open = S("Doors Open"),
+ opening = S("Doors Opening"),
+ closing = S("Doors Closing"),
+ closed = S("Doors Closed"),
+ testtiming = S("Doors Closed"),
}
local faultnames = {
- opentimeout = "Door Open Timeout",
- closetimeout = "Door Close Timeout",
- drivecomm = "Lost Communication With Drive",
- driveuninit = "Drive Not Configured",
- drivemetaload = "Drive Metadata Load Failure",
- drivebadorigin = "Drive Origin Invalid",
- drivedoorinterlock = "Attempted to Move Doors With Car in Motion",
- driveoutofbounds = "Target Position Out of Bounds",
+ opentimeout = S("Door Open Timeout"),
+ closetimeout = S("Door Close Timeout"),
+ drivecomm = S("Lost Communication With Drive"),
+ driveuninit = S("Drive Not Configured"),
+ drivemetaload = S("Drive Metadata Load Failure"),
+ drivebadorigin = S("Drive Origin Invalid"),
+ drivedoorinterlock = S("Attempted to Move Doors With Car in Motion"),
+ driveoutofbounds = S("Target Position Out of Bounds"),
+ drivenomachine = S("Hoist Machine Missing"),
+ drivemachinemismatch = S("Drive<->Machine ID Mismatch"),
+ drivecontrollermismatch = S("Controller<->Drive ID Mismatch"),
}
local function drivecmd(command)
@@ -93,7 +99,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 +201,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 +234,30 @@ 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 mem.params and not mem.params.suppressbeep then mem.params.suppressbeep = {} end
+if mem.params and not mem.params.hiddenbuttons then mem.params.hiddenbuttons = {} end
+if mem.params and not mem.params.alwayshiddenbuttons then mem.params.alwayshiddenbuttons = {} 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 +303,10 @@ if event.type == "program" then
inspectionspeed = 0.2,
indepunlock = {},
secoverrideusers = {},
+ swingcallwhennotswing = true,
+ suppressbeep = {},
+ hiddenbuttons = {},
+ alwayshiddenbuttons = {},
}
end
elseif event.type == "ui" then
@@ -303,7 +335,8 @@ elseif event.type == "ui" then
mem.screenstate = "oobe_groupmode"
end
elseif mem.screenstate == "oobe_floortable" or mem.screenstate == "floortable" then
- local exp = event.fields.floor and minetest.explode_textlist_event(event.fields.floor) or {}
+ local exp = event.fields.floor and core.explode_textlist_event(event.fields.floor) or {}
+ local maxfloors = tonumber(core.settings:get("celevator.max_landings")) or 100
if event.fields.back then
mem.screenstate = "oobe_groupmode"
elseif event.fields.next then
@@ -335,14 +368,15 @@ elseif event.type == "ui" then
mem.screenstate = (mem.screenstate == "oobe_floortable" and "oobe_floortable_edit" or "floortable_edit")
elseif event.fields.edit then
mem.screenstate = (mem.screenstate == "oobe_floortable" and "oobe_floortable_edit" or "floortable_edit")
- 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.add and #mem.params.floornames < maxfloors then
+ table.insert(mem.params.floorheights,mem.params.floorheights[#mem.params.floorheights] or 5)
+ local previous = tonumber(mem.params.floornames[#mem.params.floornames]) or #mem.params.floornames
+ table.insert(mem.params.floornames,tostring(math.floor(previous)+1))
+ 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)
- elseif event.fields.moveup then
+ elseif event.fields.moveup and mem.editingfloor < #mem.params.floornames then
local height = mem.params.floorheights[mem.editingfloor]
local name = mem.params.floornames[mem.editingfloor]
table.remove(mem.params.floorheights,mem.editingfloor)
@@ -350,7 +384,7 @@ elseif event.type == "ui" then
table.insert(mem.params.floorheights,mem.editingfloor+1,height)
table.insert(mem.params.floornames,mem.editingfloor+1,name)
mem.editingfloor = mem.editingfloor + 1
- elseif event.fields.movedown then
+ elseif event.fields.movedown and mem.editingfloor > 1 then
local height = mem.params.floorheights[mem.editingfloor]
local name = mem.params.floornames[mem.editingfloor]
table.remove(mem.params.floorheights,mem.editingfloor)
@@ -363,7 +397,7 @@ elseif event.type == "ui" then
if event.fields.back or event.fields.save then
mem.screenstate = (mem.screenstate == "oobe_floortable_edit" and "oobe_floortable" or "floortable")
local height = tonumber(event.fields.height)
- if height then
+ if height and height < (tonumber(core.settings:get("celevator.max_height")) or 100) then
height = math.floor(height+0.5)
mem.params.floorheights[mem.editingfloor] = math.max(1,height)
end
@@ -377,7 +411,8 @@ elseif event.type == "ui" then
mem.params.doortimer = doortimer
end
local contractspeed = tonumber(event.fields.contractspeed)
- if contractspeed and contractspeed >= 0.1 and contractspeed <= 20 then
+ local maxspeed = tonumber(core.settings:get("celevator.max_speed")) or 20
+ if contractspeed and contractspeed >= 0.1 and contractspeed <= maxspeed then
mem.params.contractspeed = contractspeed
end
local nudgetimer = tonumber(event.fields.nudgetimer)
@@ -428,16 +463,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
@@ -445,10 +481,10 @@ elseif event.type == "ui" then
end
end
end
- if event.fields.scrollup then
+ if event.fields.scrollup and (mem.screenpage-1)*10+1 < #mem.params.floornames then
mem.screenpage = mem.screenpage + 1
mem.scrollfollowscar = false
- elseif event.fields.scrolldown then
+ elseif event.fields.scrolldown and mem.screenpage > 1 then
mem.screenpage = mem.screenpage - 1
mem.scrollfollowscar = false
elseif event.fields.scrollfollowscar then
@@ -494,19 +530,47 @@ elseif event.type == "ui" then
if event.fields.back then
mem.screenstate = "status"
elseif event.fields.clear then
+ local wasfatalfaulted = mem.fatalfault
mem.faultlog = {}
mem.activefaults = {}
mem.fatalfault = false
drivecmd({command = "resetfault"})
+ if wasfatalfaulted then
+ 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
end
elseif mem.screenstate == "carcallsecurity" then
if event.fields.indepunlock then
mem.params.indepunlock[mem.editingfloor] = (event.fields.indepunlock == "true")
end
+ if event.fields.suppressbeep then
+ mem.params.suppressbeep[mem.editingfloor] = (event.fields.suppressbeep == "true")
+ end
+ if event.fields.hidebutton then
+ mem.params.hiddenbuttons[mem.editingfloor] = (event.fields.hidebutton == "true")
+ end
+ if event.fields.alwayshidebutton then
+ mem.params.alwayshiddenbuttons[mem.editingfloor] = (event.fields.alwayshidebutton == "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
- local exp = minetest.explode_textlist_event(event.fields.floor) or {}
+ local exp = core.explode_textlist_event(event.fields.floor) or {}
if exp.type == "CHG" then
mem.editingfloor = #mem.params.floornames-exp.index+1
elseif exp.type == "DCL" then
@@ -533,7 +597,7 @@ elseif event.type == "ui" then
if not mem.params.secoverrideusers[mem.editingfloor] then
mem.params.secoverrideusers[mem.editingfloor] = {}
end
- local exp = minetest.explode_textlist_event(event.fields.user) or {}
+ local exp = core.explode_textlist_event(event.fields.user) or {}
if exp.type == "CHG" then
mem.editinguser = exp.index
elseif exp.type == "DCL" then
@@ -556,7 +620,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 +642,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 +665,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 +694,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 +718,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
@@ -670,6 +739,24 @@ elseif event.type == "cop" then
open()
elseif fields.callcancel and (mem.carstate == "indep" or mem.carstate == "fs2") then
mem.carcalls = {}
+ if mem.drive.status.vel > 0 then
+ for i=getpos(),#mem.params.floornames,1 do
+ if mem.drive.status.neareststop < gettarget(i) and mem.drive.status.dpos > gettarget(i) then
+ gotofloor(i)
+ break
+ end
+ end
+ elseif mem.drive.status.vel < 0 then
+ for i=getpos(),1,-1 do
+ if mem.drive.status.neareststop > gettarget(i) and mem.drive.status.dpos < gettarget(i) then
+ gotofloor(i)
+ break
+ end
+ end
+ end
+ elseif fields.phone then
+ mem.phoneactive = true
+ interrupt(15,"phonedone")
end
end
elseif event.type == "copswitches" then
@@ -745,6 +832,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
@@ -786,19 +879,19 @@ elseif event.type == "dispatchermsg" then
end
elseif event.channel == "getstatus" then
send(event.source,"status",mem)
- elseif event.channel == "groupupcall" and mem.carstate == "normal" then
+ elseif event.channel == "groupupcall" and mem.carstate == "normal" and event.msg then
mem.groupupcalls[event.msg] = true
- elseif event.channel == "groupdncall" and mem.carstate == "normal" then
+ elseif event.channel == "groupdncall" and mem.carstate == "normal" and event.msg then
mem.groupdncalls[event.msg] = true
- elseif event.channel == "groupupcancel" then
+ elseif event.channel == "groupupcancel" and event.msg then
mem.groupupcalls[event.msg] = nil
- elseif event.channel == "groupdncancel" then
+ elseif event.channel == "groupdncancel" and event.msg then
mem.groupdncalls[event.msg] = nil
- elseif event.channel == "swingupcall" and mem.carstate == "normal" then
+ elseif event.channel == "swingupcall" and swingstateok and event.msg then
mem.swingupcalls[event.msg] = true
- elseif event.channel == "swingdncall" and mem.carstate == "normal" then
+ elseif event.channel == "swingdncall" and swingstateok and event.msg 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") and event.msg then
mem.carcalls[event.msg] = true
send(event.source,"status",mem)
elseif event.channel == "fs1switch" then
@@ -810,38 +903,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)
@@ -871,6 +977,8 @@ elseif event.type == "mrsmoke" then
end
if not mem.recallto then mem.recallto = getpos() end
end
+elseif event.iid == "phonedone" then
+ mem.phoneactive = false
end
local oldstate = mem.carstate
@@ -901,19 +1009,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 +1022,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 +1117,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 +1155,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,8 +1178,9 @@ 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.carstate == "fs2" then mem.carcalls = {} end
if mem.direction == "up" then
mem.upcalls[getpos()] = nil
mem.swingupcalls[getpos()] = nil
@@ -1141,7 +1241,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 +1264,7 @@ local canprocesscalls = {
test = true,
indep = true,
fs2 = true,
+ swing = true,
}
if canprocesscalls[mem.carstate] and mem.doorstate == "closed" then
@@ -1212,14 +1313,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
@@ -1252,75 +1353,101 @@ fs("no_prepend[]")
fs("background9[0,0;16,12;celevator_fs_bg.png;true;3]")
if mem.screenstate == "oobe_welcome" then
fs("image[6,1;4,2;celevator_logo.png]")
- fs("label[1,4;Welcome to your new MTronic XT elevator controller!]")
- fs("label[1,4.5;This setup wizard is designed to get your elevator up and running as quickly as possible.]")
- fs("label[1,5.5;Press Next to begin.]")
- fs("button[1,10;2,1;license;License Info]")
- fs("button[13,10;2,1;next;Next >]")
+ local welcomemsg = S("Welcome to your new MTronic XT elevator controller!")
+ local wizardmsg = S("This setup wizard is designed to get your elevator up and running as quickly as possible.")
+ local pressnextmsg = S("Press Next to begin.")
+ local licensemsg = S("License Info")
+ local nextbuttonmsg = S("Next >")
+ fs("label[1,4;"..welcomemsg.."]")
+ fs("label[1,4.5;"..wizardmsg.."]")
+ fs("label[1,5.5;"..pressnextmsg.."]")
+ fs("button[1,10;3,1;license;"..licensemsg.."]")
+ fs("button[13,10;2,1;next;"..nextbuttonmsg.."]")
elseif mem.screenstate == "oobe_license" then
- local licensefile = io.open(minetest.get_modpath("celevator")..DIR_DELIM.."LICENSE")
- local license = minetest.formspec_escape(licensefile:read("*all"))
+ local licensefile = io.open(core.get_modpath("celevator").."/LICENSE")
+ local license = core.formspec_escape(licensefile:read("*all"))
licensefile:close()
- fs("textarea[1,1;14,8;license;This applies to the whole celevator mod\\, not just this controller:;"..license.."]")
- fs("button[7,10.5;2,1;back;OK]")
+ local licenseinfo = core.formspec_escape(S("This applies to the whole celevator mod, not just this controller:"))
+ fs("textarea[1,1;14,8;license;"..licenseinfo..";"..license.."]")
+ local okmsg = S("OK")
+ fs("button[7,10.5;2,1;back;"..okmsg.."]")
elseif mem.screenstate == "oobe_groupmode" then
- fs("button[1,10;2,1;back;< Back]")
- fs("label[1,1;Select a group operation mode:]")
- fs("button[1,3;2,1;simplex;Simplex]")
- fs("label[1,4.5;This will be the only elevator in the group. Hall calls will be handled by this controller.]")
- fs("button[1,6;2,1;group;Group]")
- fs("label[1,7.5;This elevator will participate in a group with others. Hall calls will be handled by a dispatcher.]")
+ local backmsg = S("< Back")
+ fs("button[1,10;2,1;back;"..backmsg.."]")
+ local modeselectmsg = S("Select a group operation mode:")
+ fs("label[1,1;"..modeselectmsg.."]")
+ local simplexmsg = S("Simplex")
+ fs("button[1,3;2,1;simplex;"..simplexmsg.."]")
+ local simplexlongmsg = S("This will be the only elevator in the group. Hall calls will be handled by this controller.")
+ fs("label[1,4.5;"..simplexlongmsg.."]")
+ local groupmsg = S("Group")
+ fs("button[1,6;2,1;group;"..groupmsg.."]")
+ local grouplongmsg = S("This elevator will participate in a group with others. Hall calls will be handled by a dispatcher.")
+ fs("label[1,7.5;"..grouplongmsg.."]")
elseif mem.screenstate == "oobe_dispatcherconnect" then
- fs("button[1,10;2,1;back;< Cancel]")
- fs("label[1,1;Waiting for connection from dispatcher...]")
- fs(string.format("label[1,1.5;This controller's car ID is: %d]",mem.carid))
+ local cancelmsg = S("Cancel")
+ fs("button[1,10;2,1;back;"..cancelmsg.."]")
+ local waitingmsg = S("Waiting for connection from dispatcher...")
+ fs("label[1,1;"..waitingmsg.."]")
+ local idmsg = S("This controller's car ID is: @1",mem.carid)
+ fs("label[1,1.5;"..idmsg.."]")
elseif mem.screenstate == "oobe_floortable" or mem.screenstate == "floortable" then
if mem.screenstate == "oobe_floortable" then
- fs("label[1,1;Enter details of all floors this elevator will serve, then press Done.]")
- fs("button[1,10;2,1;back;< Back]")
- fs("button[13,10;2,1;next;Done >]")
+ local helpmsg = S("Enter details of all floors this elevator will serve, then press Done.")
+ fs("label[1,1;"..helpmsg.."]")
+ local backmsg = S("< Back")
+ fs("button[1,10;2,1;back;"..backmsg.."]")
+ local donemsg = S("Done")
+ fs("button[13,10;2,1;next;"..donemsg.."]")
else
- fs("label[1,1;EDIT FLOOR TABLE]")
- fs("button[1,10;2,1;next;Done]")
+ local titlemsg = S("EDIT FLOOR TABLE")
+ fs("label[1,1;"..titlemsg.."]")
+ local donemsg = S("Done")
+ fs("button[1,10;2,1;next;"..donemsg.."]")
end
fs("textlist[1,2;6,7;floor;")
for i=#mem.params.floornames,1,-1 do
- fs(minetest.formspec_escape(string.format("%d - Height: %d - PI: %s",i,mem.params.floorheights[i],mem.params.floornames[i]))..(i==1 and "" or ","))
+ local floortext = S("@1 - Height: @2 - PI: @3",i,mem.params.floorheights[i],mem.params.floornames[i])
+ fs(core.formspec_escape(floortext)..(i==1 and "" or ","))
end
fs(";"..tostring(#mem.params.floornames-mem.editingfloor+1)..";false]")
- if #mem.params.floornames < 100 then fs("button[8,2;2,1;add;New Floor]") end
- fs("button[8,3.5;2,1;edit;Edit Floor]")
- if #mem.params.floornames > 2 then fs("button[8,5;2,1;remove;Remove Floor]") end
- if mem.editingfloor < #mem.params.floornames then fs("button[8,6.5;2,1;moveup;Move Up]") end
- if mem.editingfloor > 1 then fs("button[8,8;2,1;movedown;Move Down") end
+ local maxfloors = tonumber(core.settings:get("celevator.max_landings")) or 100
+ if #mem.params.floornames < maxfloors then fs("button[8,2;2,1;add;"..S("New Floor").."]") end
+ fs("button[8,3.5;2,1;edit;"..S("Edit Floor").."]")
+ if #mem.params.floornames > 2 then fs("button[8,5;2,1;remove;"..S("Remove Floor").."]") end
+ if mem.editingfloor < #mem.params.floornames then fs("button[8,6.5;2,1;moveup;"..S("Move Up").."]") end
+ if mem.editingfloor > 1 then fs("button[8,8;2,1;movedown;"..S("Move Down").."]") end
elseif mem.screenstate == "oobe_floortable_edit" or mem.screenstate == "floortable_edit" then
if mem.screenstate == "oobe_floortable_edit" then
- fs("button[7,10.5;2,1;back;OK]")
- fs("label[1,5;The Floor Height is the distance (in meters/nodes) from the floor level of this floor to the floor level of the next floor.]")
- fs("label[1,5.5;(not used at the highest floor)]")
- fs("label[1,6.5;The Floor Name is how the floor will be displayed on the position indicators.]")
+ fs("button[7,10.5;2,1;back;"..S("OK").."]")
+ local help1 = S("The Floor Height is the distance (in meters/nodes) from the floor level of this floor to the floor level of the next floor.")
+ local help2 = S("(not used at the highest floor)")
+ local help3 = S("The Floor Name is how the floor will be displayed on the position indicators.")
+ fs("label[1,5;"..help1.."]")
+ fs("label[1,5.5;"..help2.."]")
+ fs("label[1,6.5;"..help3.."]")
else
- fs("button[7,10.5;2,1;save;Save]")
+ fs("button[7,10.5;2,1;save;"..S("Save").."]")
end
- fs("label[1,1;Editing floor "..tostring(mem.editingfloor).."]")
- fs("field[1,3;3,1;height;Floor Height;"..tostring(mem.params.floorheights[mem.editingfloor]).."]")
- fs("field[5,3;3,1;name;Floor Name;"..minetest.formspec_escape(mem.params.floornames[mem.editingfloor]).."]")
+ fs("label[1,1;"..S("Editing Floor @1",tostring(mem.editingfloor)).."]")
+ fs("field[1,3;3,1;height;"..S("Floor Height")..";"..tostring(mem.params.floorheights[mem.editingfloor]).."]")
+ fs("field[5,3;3,1;name;"..S("Floor Name")..";"..core.formspec_escape(mem.params.floornames[mem.editingfloor]).."]")
elseif mem.screenstate == "status" then
fs("style_type[image_button;font=mono;font_size=*0.75]")
fs("box[12,2.5;0.1,9;#AAAAAAFF]")
fs("box[13.12,2.5;0.05,9;#AAAAAAFF]")
fs("box[14.12,2.5;0.05,9;#AAAAAAFF]")
fs("box[15.25,2.5;0.1,9;#AAAAAAFF]")
- fs("label[12.5,2;UP]")
- fs("label[13.38,2;CAR]")
- fs("label[14.25,2;DOWN]")
+ fs("image[12.5,1.9;0.2,0.4;celevator_menu_small_arrow.png]")
+ fs("label[13.38,2;"..S("CAR").."]")
+ fs("image[14.6,1.9;0.2,0.4;celevator_menu_small_arrow.png^[transformFY]")
local maxfloor = #mem.params.floornames
local bottom = (mem.screenpage-1)*10+1
for i=0,9,1 do
local ypos = 11-(i*0.9)
local floornum = bottom+i
if floornum > maxfloor then break end
- fs(string.format("label[11.25,%f;%s]",ypos,minetest.formspec_escape(mem.params.floornames[floornum])))
+ fs(string.format("label[11.25,%f;%s]",ypos,core.formspec_escape(mem.params.floornames[floornum])))
local ccdot = mem.carcalls[floornum] and "*" or ""
if getpos() == floornum then
local cargraphics = {
@@ -1332,31 +1459,31 @@ elseif mem.screenstate == "status" then
}
ccdot = cargraphics[mem.doorstate]
if mem.direction == "up" then
- ccdot = minetest.colorize("#55FF55",ccdot)
+ ccdot = core.colorize("#55FF55",ccdot)
elseif mem.direction == "down" then
- ccdot = minetest.colorize("#FF5555",ccdot)
+ ccdot = core.colorize("#FF5555",ccdot)
end
end
fs(string.format("image_button[13.25,%f;0.75,0.75;celevator_fs_bg.png;carcall%d;%s]",ypos-0.25,floornum,ccdot))
if floornum < maxfloor then
- local arrow = mem.upcalls[floornum] and minetest.colorize("#55FF55","^") or ""
+ local arrow = mem.upcalls[floornum] and core.colorize("#55FF55","^") or ""
if mem.params.groupmode == "group" then
- arrow = mem.groupupcalls[floornum] and minetest.colorize("#55FF55","^") or ""
- arrow = (mem.swingupcalls[floornum] and minetest.colorize("#FFFF55","^") or "")..arrow
+ arrow = mem.groupupcalls[floornum] and core.colorize("#55FF55","^") or ""
+ arrow = (mem.swingupcalls[floornum] and core.colorize("#FFFF55","^") or "")..arrow
end
fs(string.format("image_button[12.25,%f;0.75,0.75;celevator_fs_bg.png;upcall%d;%s]",ypos-0.25,floornum,arrow))
end
if floornum > 1 then
- local arrow = mem.dncalls[floornum] and minetest.colorize("#FF5555","v") or ""
+ local arrow = mem.dncalls[floornum] and core.colorize("#FF5555","v") or ""
if mem.params.groupmode == "group" then
- arrow = mem.swingdncalls[floornum] and minetest.colorize("#FFFF55","v") or ""
- arrow = (mem.groupdncalls[floornum] and minetest.colorize("#FF5555","v") or "")..arrow
+ arrow = mem.swingdncalls[floornum] and core.colorize("#FFFF55","v") or ""
+ arrow = (mem.groupdncalls[floornum] and core.colorize("#FF5555","v") or "")..arrow
end
fs(string.format("image_button[14.25,%f;0.75,0.75;celevator_fs_bg.png;downcall%d;%s]",ypos-0.25,floornum,arrow))
end
end
if maxfloor > 10 then
- fs(string.format("checkbox[13,1.25;scrollfollowscar;Follow Car;%s]",tostring(mem.scrollfollowscar)))
+ fs(string.format("checkbox[13,1.25;scrollfollowscar;"..S("Follow Car")..";%s]",tostring(mem.scrollfollowscar)))
if bottom+9 < maxfloor then
fs("image_button[12.75,0.25;0.75,0.75;celevator_menu_arrow.png;scrollup;;false;false;celevator_menu_arrow.png]")
end
@@ -1364,18 +1491,21 @@ elseif mem.screenstate == "status" then
fs("image_button[13.87,0.25;0.75,0.75;celevator_menu_arrow.png^\\[transformFY;scrolldown;;false;false;celevator_menu_arrow.png^\\[transformFY]")
end
end
- fs("label[1,1;CAR STATUS]")
+ fs("label[1,1;"..S("CAR STATUS").."]")
fs(string.format("label[1,2;%s]",modenames[mem.carstate]))
- fs(string.format("label[1,2.5;Doors %s]",doorstates[mem.doorstate]))
- local currentfloor = minetest.formspec_escape(mem.params.floornames[getpos()])
- fs(string.format("label[1,3;Position: %0.02fm Speed: %+0.02fm/s PI: %s]",mem.drive.status.apos,mem.drive.status.vel,currentfloor))
+ fs(string.format("label[1,2.5;%s]",doorstates[mem.doorstate]))
+ local currentfloor = core.formspec_escape(mem.params.floornames[getpos()])
+ local posfmt = string.format("%0.02f",mem.drive.status.apos)
+ local speedfmt = string.format("%+0.02f",mem.drive.status.vel)
+ local posmsg = S("Position: @1m Speed: @2m/s PI: @3",posfmt,speedfmt,currentfloor)
+ fs("label[1,3;"..posmsg.."]")
if #mem.faultlog > 0 then
- fs("label[1,3.5;Fault(s) Active]")
+ fs("label[1,3.5;"..S("Fault(s) Active").."]")
else
- fs("label[1,3.5;No Current Faults]")
+ fs("label[1,3.5;"..S("No Current Faults").."]")
end
- fs("button[1,10;3,1;faults;Fault History]")
- fs("button[4.5,10;3,1;parameters;Edit Parameters]")
+ fs("button[1,10;3,1;faults;"..S("Fault History").."]")
+ fs("button[4.5,10;3,1;parameters;"..S("Edit Parameters").."]")
local redon = "celevator_led_red_on.png"
local redoff = "celevator_led_red_off.png"
local yellowon = "celevator_led_yellow_on.png"
@@ -1383,64 +1513,64 @@ elseif mem.screenstate == "status" then
local greenon = "celevator_led_green_on.png"
local greenoff = "celevator_led_green_off.png"
fs(string.format("image[7,1;0.7,0.7;%s]",mem.carstate == "fault" and redon or redoff))
- fs("label[8,1.35;FAULT]")
+ fs("label[8,1.35;"..S("FAULT").."]")
local inspectionstates = {
mrinspect = true,
carinspect = true,
inspconflict = true,
}
fs(string.format("image[7,1.9;0.7,0.7;%s]",inspectionstates[mem.carstate] and yellowon or yellowoff))
- fs("label[8,2.25;INSP/ACCESS]")
+ fs("label[8,2.25;"..S("INSP/ACCESS").."]")
fs(string.format("image[7,2.8;0.7,0.7;%s]",mem.carstate == "normal" and greenon or greenoff))
- fs("label[8,3.15;NORMAL OPERATION]")
+ fs("label[8,3.15;"..S("NORMAL OPERATION").."]")
fs(string.format("image[7,3.7;0.7,0.7;%s]",mem.drive.status.vel > 0.01 and yellowon or yellowoff))
- fs("label[8,4.05;UP]")
+ fs("label[8,4.05;"..S("UP").."]")
fs(string.format("image[7,4.6;0.7,0.7;%s]",math.abs(mem.drive.status.vel) > 0.01 and yellowon or yellowoff))
- fs("label[8,4.95;DRIVE CMD]")
+ fs("label[8,4.95;"..S("DRIVE CMD").."]")
fs(string.format("image[7,5.5;0.7,0.7;%s]",mem.drive.status.vel < -0.01 and yellowon or yellowoff))
- fs("label[8,5.85;DOWN]")
+ fs("label[8,5.85;"..S("DOWN").."]")
fs(string.format("image[7,6.4;0.7,0.7;%s]",math.abs(mem.drive.status.vel) > math.min(0.4,mem.params.contractspeed/2) and yellowon or yellowoff))
- fs("label[8,6.75;HIGH SPEED]")
+ fs("label[8,6.75;"..S("HIGH SPEED").."]")
fs(string.format("image[7,7.3;0.7,0.7;%s]",math.abs(gettarget(getpos(true))-mem.drive.status.apos) < 0.5 and greenon or greenoff))
- fs("label[8,7.65;DOOR ZONE]")
+ fs("label[8,7.65;"..S("DOOR ZONE").."]")
fs(string.format("image[7,8.2;0.7,0.7;%s]",mem.doorstate == "closed" and greenon or greenoff))
- fs("label[8,8.55;DOORS LOCKED]")
+ fs("label[8,8.55;"..S("DOORS LOCKED").."]")
fs("style[*;font=mono]")
local stopswimg = "celevator_toggle_switch.png"..(mem.controllerstopsw and "^\\[transformFY" or "")
fs(string.format("image_button[1,5;1,1.33;%s;stopsw;;false;false;%s]",stopswimg,stopswimg))
- fs("label[1.3,4.75;RUN]")
- fs("label[1.2,6.6;STOP]")
+ fs("label[1.3,4.75;"..S("RUN").."]")
+ fs("label[1.2,6.6;"..S("STOP").."]")
local captureswimg = "celevator_toggle_switch.png"..(mem.capturesw and "" or "^\\[transformFY")
fs(string.format("image_button[3,5;1,1.33;%s;capturesw;;false;false;%s]",captureswimg,captureswimg))
- fs("label[3,4.75;CAPTURE]")
+ fs("label[3,4.75;"..S("CAPTURE").."]")
local testswimg = "celevator_toggle_switch.png"..(mem.testsw and "" or "^\\[transformFY")
fs(string.format("image_button[5,5;1,1.33;%s;testsw;;false;false;%s]",testswimg,testswimg))
- fs("label[5.23,4.75;TEST]")
+ fs("label[5.23,4.75;"..S("TEST").."]")
local inspectswimg = "celevator_toggle_switch.png"..(mem.controllerinspectsw and "" or "^\\[transformFY")
fs(string.format("image_button[1,8;1,1.33;%s;inspectsw;;false;false;%s]",inspectswimg,inspectswimg))
- fs("label[1.05,7.75;INSPECT]")
- fs("label[1.1,9.6;NORMAL]")
+ fs("label[1.05,7.75;"..S("INSPECT").."]")
+ fs("label[1.1,9.6;"..S("NORMAL").."]")
fs(string.format("image_button[3,8.25;1,1;%s;inspectup;;false;false;%s]","celevator_button_black.png","celevator_button_black.png"))
- fs("label[3.4,7.75;UP]")
+ fs("label[3.4,7.75;"..S("UP ").."]")
fs(string.format("image_button[5,8.25;1,1;%s;inspectdown;;false;false;%s]","celevator_button_black.png","celevator_button_black.png"))
- fs("label[5.25,7.75;DOWN]")
+ fs("label[5.25,7.75;"..S("DOWN ").."]")
elseif mem.screenstate == "parameters" then
- fs("label[1,1;EDIT PARAMETERS]")
- fs("button[1,10;3,1;save;Save]")
- fs("button[4.5,10;3,1;cancel;Cancel]")
- if mem.params.groupmode == "simplex" then fs("button[8,10;3,1;floortable;Edit Floor Table]") end
- fs(string.format("field[1,3;3,1;doortimer;Door Dwell Timer;%0.1f]",mem.params.doortimer))
- fs(string.format("field[1,5;3,1;contractspeed;Contract Speed (m/s);%0.1f]",mem.params.contractspeed))
- fs(string.format("field[4.5,5;3,1;inspectionspeed;Inspection Speed (m/s);%0.1f]",mem.params.inspectionspeed))
- fs(string.format("field[1,7;3,1;mainlanding;Main Egress Landing;%d]",mem.params.mainlanding or 1))
- fs(string.format("field[4.5,3;3,1;nudgetimer;Nudging Timer (0 = None);%0.1f]",mem.params.nudgetimer))
- fs(string.format("field[4.5,7;3,1;altrecalllanding;Alternate Recall Landing;%d]",mem.params.altrecalllanding))
+ fs("label[1,1;"..S("EDIT PARAMETERS").."]")
+ fs("button[1,10;3,1;save;"..S("Save").."]")
+ fs("button[4.5,10;3,1;cancel;"..S("Cancel").."]")
+ if mem.params.groupmode == "simplex" then fs("button[8,10;3,1;floortable;"..S("Edit Floor Table").."]") end
+ fs(string.format("field[1,3;3,1;doortimer;"..S("Door Dwell Timer")..";%0.1f]",mem.params.doortimer))
+ fs(string.format("field[1,5;3,1;contractspeed;"..S("Contract Speed (m/s)")..";%0.1f]",mem.params.contractspeed))
+ fs(string.format("field[4.5,5;3,1;inspectionspeed;"..S("Inspection Speed (m/s)")..";%0.1f]",mem.params.inspectionspeed))
+ fs(string.format("field[1,7;3,1;mainlanding;"..S("Main Egress Landing")..";%d]",mem.params.mainlanding or 1))
+ fs(string.format("field[4.5,3;3,1;nudgetimer;"..S("Nudging Timer")..";%0.1f]",mem.params.nudgetimer))
+ fs(string.format("field[4.5,7;3,1;altrecalllanding;"..S("Alternate Recall Landing")..";%d]",mem.params.altrecalllanding))
fs("style[resetdoors,resetcontroller;bgcolor=#DD3333]")
- fs("button[12,1;3,1;resetdoors;Reset Doors]")
- fs("button[12,2.5;3,1;resetcontroller;Reset Controller]")
- fs("button[1,8.5;3,1;carcallsecurity;Car Call Security]")
+ fs("button[12,1;3,1;resetdoors;"..S("Reset Doors").."]")
+ fs("button[12,2.5;3,1;resetcontroller;"..S("Reset Controller").."]")
+ fs("button[1,8.5;3,1;carcallsecurity;"..S("Car Call Security").."]")
elseif mem.screenstate == "faults" then
- fs("label[1,1;FAULT HISTORY]")
+ fs("label[1,1;"..S("FAULT HISTORY").."]")
if #mem.faultlog > 0 then
for i=0,9,1 do
if #mem.faultlog-i >= 1 then
@@ -1451,28 +1581,30 @@ elseif mem.screenstate == "faults" then
end
end
else
- fs("label[1,2;No Current Faults]")
+ fs("label[1,2;"..S("No Current Faults").."]")
end
- fs("button[1,10;3,1;back;Back]")
- fs("button[4.5,10;3,1;clear;Clear]")
+ fs("button[1,10;3,1;back;"..S("Back").."]")
+ fs("button[4.5,10;3,1;clear;"..S("Clear").."]")
elseif mem.screenstate == "carcallsecurity" then
- fs("label[1,1;CAR CALL SECURITY]")
- fs("button[1,10;3,1;save;Done]")
+ fs("label[1,1;"..S("CAR CALL SECURITY").."]")
+ fs("button[1,10;3,1;save;"..S("Done").."]")
fs("textlist[1,2;6,7;floor;")
for i=#mem.params.floornames,1,-1 do
local secmode = mem.params.carcallsecurity[i]
if secmode == "auth" then
- secmode = "Authorized Users Only"
+ secmode = S("Authorized Users Only")
elseif secmode == "deny" then
- secmode = "Locked"
+ secmode = S("Locked")
else
- secmode = "Security Disabled"
+ secmode = S("Security Disabled")
end
- fs(minetest.formspec_escape(string.format("%s - %s",mem.params.floornames[i],secmode))..(i==1 and "" or ","))
+ fs(core.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]")
+ local swingmsg = S("Allow Swing Calls When Not In Swing Operation")
+ fs("checkbox[1,9.5;swingcallwhennotswing;"..swingmsg..";"..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;")
+ fs("dropdown[8,2;4,1;secmode;"..S("Security Disabled")..","..S("Authorized Users Only")..","..S("Locked")..";")
if mem.params.carcallsecurity[mem.editingfloor] == "auth" then
fs("2;true]")
elseif mem.params.carcallsecurity[mem.editingfloor] == "deny" then
@@ -1481,25 +1613,33 @@ elseif mem.screenstate == "carcallsecurity" then
fs("1;true]")
end
if mem.params.carcallsecurity[mem.editingfloor] then
- fs(string.format("checkbox[8,3.5;indepunlock;Unlock in Independent;%s]",(mem.params.indepunlock[mem.editingfloor] and "true" or "false")))
- fs("label[8,4.7;Extra Allowed Users]")
+ fs(string.format("checkbox[8,5;indepunlock;"..S("Unlock in Independent")..";%s]",(mem.params.indepunlock[mem.editingfloor] and "true" or "false")))
+ fs("label[8,5.7;"..S("Extra Allowed Users").."]")
if not mem.params.secoverrideusers[mem.editingfloor] then mem.params.secoverrideusers[mem.editingfloor] = {} end
if #mem.params.secoverrideusers[mem.editingfloor] > 0 then
- fs("textlist[8,6;4,2;user;")
+ fs("textlist[8,7;4,2;user;")
for i=1,#mem.params.secoverrideusers[mem.editingfloor],1 do
- fs(minetest.formspec_escape(mem.params.secoverrideusers[mem.editingfloor][i])..(i==#mem.params.secoverrideusers[mem.editingfloor] and "" or ","))
+ fs(core.formspec_escape(mem.params.secoverrideusers[mem.editingfloor][i])..(i==#mem.params.secoverrideusers[mem.editingfloor] and "" or ","))
end
fs(";"..tostring(mem.editinguser)..";false]")
else
- fs("label[8,6.25;(none)]")
+ fs("label[8,7.25;"..S("(none)").."]")
end
- fs("field[8,5;3,1;username;;]")
- fs("button[11.25,5;0.5,1;adduser;+]")
- fs("button[12,5;0.5,1;deluser;-]")
+ fs("field[8,6;3,1;username;;]")
+ fs("button[11.25,6;0.5,1;adduser;+]")
+ fs("button[12,6;0.5,1;deluser;-]")
end
else
- fs("label[8,2;Main landing cannot be locked]")
+ fs("label[8,2;"..S("Main landing cannot be locked").."]")
end
+ local hidden = mem.params.hiddenbuttons[mem.editingfloor] and "true" or "false"
+ fs("checkbox[8,4;hidebutton;"..S("Hide Button")..";"..hidden.."]")
+ if hidden == "true" then
+ local veryhidden = mem.params.alwayshiddenbuttons[mem.editingfloor] and "true" or "false"
+ fs("checkbox[8,4.5;alwayshidebutton;"..S("Also Hide in Fire/Independent Service")..";"..veryhidden.."]")
+ end
+ local suppressed = mem.params.suppressbeep[mem.editingfloor] and "true" or "false"
+ fs("checkbox[8,3.5;suppressbeep;"..S("Suppress Beep Sound")..";"..suppressed.."]")
end
local arrow = " "
@@ -1511,7 +1651,7 @@ end
local floorname = mem.params.floornames[getpos()]
local modename = modenames[mem.carstate]
local doorstate = doorstates[mem.doorstate]
-mem.infotext = string.format("ID %d: Floor %s %s - %s - Doors %s",mem.carid,floorname,arrow,modename,doorstate)
+mem.infotext = S("ID @1: Floor @2 - @3 - @4",mem.carid,(floorname.." "..arrow),modename,doorstate)
if mem.drive.type then
mem.showrunning = mem.drive.status.vel ~= 0
@@ -1533,8 +1673,10 @@ local hidepi = {
}
if hidepi[mem.carstate] then mem.pifloor = "--" end
-if mem.pifloor ~= oldpifloor and mem.carstate == "normal" then
- drivecmd({command="pibeep"})
+if mem.pifloor ~= oldpifloor and (mem.carstate == "normal" or mem.carstate == "swing") then
+ if not mem.params.suppressbeep[getpos(true)] then
+ drivecmd({command="pibeep"})
+ end
end
local arrowenabled = {
@@ -1544,6 +1686,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 +1696,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
@@ -1576,27 +1719,45 @@ elseif mem.carstate == "normal" and mem.doorstate == "closed" and mem.drive.stat
end
mem.copformspec = "formspec_version[7]"
-local floorcount = #mem.params.floornames
-local copcols = math.floor((floorcount-1)/10)+1
-local coprows = math.floor((floorcount-1)/copcols)+1
+local displayedfloors = {}
+local realfloors = {}
+if mem.carstate == "fs2" or mem.carstate == "fs2hold" or mem.carstate == "indep" then
+ for k,v in pairs(mem.params.floornames) do
+ if not (mem.params.hiddenbuttons[k] and mem.params.alwayshiddenbuttons[k]) then
+ table.insert(displayedfloors,v)
+ realfloors[#displayedfloors] = k
+ end
+ end
+else
+ for k,v in pairs(mem.params.floornames) do
+ if not mem.params.hiddenbuttons[k] then
+ table.insert(displayedfloors,v)
+ realfloors[#displayedfloors] = k
+ end
+ end
+end
+local floorcount = #displayedfloors
+local copcols = math.max(1,math.floor((floorcount-1)/10)+1)
+local coprows = math.max(1,math.floor((floorcount-1)/copcols)+1)
local litimg = "celevator_copbutton_lit.png"
local unlitimg = "celevator_copbutton_unlit.png"
-mem.copformspec = mem.copformspec..string.format("size[%f,%f]",copcols*1.25+2.5,coprows*1.25+5)
+mem.copformspec = mem.copformspec..string.format("size[%f,%f]",copcols*1.25+2.5,coprows*1.25+6)
mem.copformspec = mem.copformspec.."no_prepend[]"
mem.copformspec = mem.copformspec.."background9[0,0;16,12;celevator_fs_bg.png;true;3]"
for i=1,floorcount,1 do
+ local landing = realfloors[i]
local row = math.floor((i-1)/copcols)+1
local col = ((i-1)%copcols)+1
local yp = (coprows-row+1)*1.25+1
local xp = col*1.25
- local tex = mem.carcalls[i] and litimg or unlitimg
- local star = (i == (mem.params.mainlanding or 1) and "*" or "")
- local label = minetest.formspec_escape(star..mem.params.floornames[i])
- mem.copformspec = mem.copformspec..string.format("image_button[%f,%f;1.2,1.2;%s;carcall%d;%s;false;false;%s]",xp,yp,tex,i,label,litimg)
+ local tex = mem.carcalls[landing] and litimg or unlitimg
+ local star = (landing == (mem.params.mainlanding or 1) and "*" or "")
+ local label = core.formspec_escape(star..displayedfloors[i])
+ mem.copformspec = mem.copformspec..string.format("image_button[%f,%f;1.2,1.2;%s;carcall%d;%s;false;false;%s]",xp,yp,tex,landing,label,litimg)
end
local doxp = (copcols == 1) and 0.5 or 1.25
-local openlabel = minetest.formspec_escape("<|>")
+local openlabel = core.formspec_escape("<|>")
mem.copformspec = mem.copformspec..string.format("image_button[%f,%f;1.2,1.2;%s;open;%s;false;false;%s]",doxp,coprows*1.25+2.5,unlitimg,openlabel,litimg)
local dcxp = 3.75
@@ -1605,43 +1766,66 @@ if copcols == 1 then
elseif copcols == 2 then
dcxp = 2.5
end
-local closelabel = minetest.formspec_escape(">|<")
+local closelabel = core.formspec_escape(">|<")
mem.copformspec = mem.copformspec..string.format("image_button[%f,%f;1.2,1.2;%s;close;%s;false;false;%s]",dcxp,coprows*1.25+2.5,unlitimg,closelabel,litimg)
-mem.copformspec = mem.copformspec..string.format("image_button[0.4,0.5;1.4,1.4;%s;callcancel;Call\nCancel;false;false;%s]",unlitimg,litimg)
+local alarmunlitimg = unlitimg.."^celevator_copbutton_alarm.png"
+local alarmlitimg = litimg.."^celevator_copbutton_alarm.png"
+mem.copformspec = mem.copformspec..string.format("image_button[%f,%f;1.2,1.2;%s;alarm;;false;false;%s]",doxp,coprows*1.25+4,alarmunlitimg,alarmlitimg)
+
+local phoneunlitimg = unlitimg.."^celevator_copbutton_phone.png"
+local phonelitimg = litimg.."^celevator_copbutton_phone.png"
+if mem.phoneactive then
+ mem.copformspec = mem.copformspec..string.format("image[%f,%f;1.2,1.2;%s]",dcxp,coprows*1.25+4,phonelitimg)
+else
+ mem.copformspec = mem.copformspec..string.format("image_button[%f,%f;1.2,1.2;%s;phone;;false;false;%s]",dcxp,coprows*1.25+4,phoneunlitimg,phonelitimg)
+end
+
+local hatxp = 1.2
+
+if floorcount > 0 then
+ --If all floors are hidden, this is probably a DBD setup and all of the car call buttons are in a cabinet that is not currently open.
+ --Call cancel would be in there too, so hide it in that case
+ local callcancellabel = S("Call\nCancel")
+ mem.copformspec = mem.copformspec..string.format("image_button[0.4,0.5;1.4,1.4;%s;callcancel;"..callcancellabel..";false;false;%s]",unlitimg,litimg)
+ --Also center the hat in that case (un-center it here if there are buttons)
+ hatxp = 2.2
+end
if mem.flashfirehat then
- mem.copformspec = mem.copformspec.."animated_image[2.2,0.5;1.4,1.4;firehat;celevator_fire_hat_flashing.png;2;750]"
+ mem.copformspec = mem.copformspec..string.format("animated_image[%f,0.5;1.4,1.4;firehat;celevator_fire_hat_flashing.png;2;750]",hatxp)
else
local firehat = mem.flash_fs and "celevator_fire_hat_lit.png" or "celevator_fire_hat_unlit.png"
- mem.copformspec = mem.copformspec..string.format("image[2.2,0.5;1.4,1.4;%s]",firehat)
+ mem.copformspec = mem.copformspec..string.format("image[%f,0.5;1.4,1.4;%s]",hatxp,firehat)
end
+local switchboilerplate = ";false;false;celevator_button_rect_active.png"
+
mem.switchformspec = "formspec_version[7]size[8,10]no_prepend[]background9[0,0;16,12;celevator_fs_bg.png;true;3]"
local fs2ontex = (mem.fs2sw == "on") and "celevator_button_rect_active.png" or "celevator_button_rect.png"
local fs2holdtex = (mem.fs2sw == "hold") and "celevator_button_rect_active.png" or "celevator_button_rect.png"
local fs2offtex = (mem.fs2sw == "off" or not mem.fs2sw) and "celevator_button_rect_active.png" or "celevator_button_rect.png"
-mem.switchformspec = mem.switchformspec..string.format("image_button[1.5,1.5;1.5,1;%s;fs2on;ON;false;false;celevator_button_rect_active.png]",fs2ontex)
-mem.switchformspec = mem.switchformspec..string.format("image_button[1.5,2.5;1.5,1;%s;fs2hold;HOLD;false;false;celevator_button_rect_active.png]",fs2holdtex)
-mem.switchformspec = mem.switchformspec..string.format("image_button[1.5,3.5;1.5,1;%s;fs2off;OFF;false;false;celevator_button_rect_active.png]",fs2offtex)
-mem.switchformspec = mem.switchformspec.."label[1.6,4.75;FIRE SVC]"
+mem.switchformspec = mem.switchformspec..string.format("image_button[1.5,1.5;1.5,1;%s;fs2on;"..S("ON")..switchboilerplate.."]",fs2ontex)
+mem.switchformspec = mem.switchformspec..string.format("image_button[1.5,2.5;1.5,1;%s;fs2hold;"..S("HOLD")..switchboilerplate.."]",fs2holdtex)
+mem.switchformspec = mem.switchformspec..string.format("image_button[1.5,3.5;1.5,1;%s;fs2off;"..S("OFF")..switchboilerplate.."]",fs2offtex)
+mem.switchformspec = mem.switchformspec.."label[1.6,4.75;"..S("FIRE SVC").."]"
local indontex = mem.indsw and "celevator_button_rect_active.png" or "celevator_button_rect.png"
local indofftex = (not mem.indsw) and "celevator_button_rect_active.png" or "celevator_button_rect.png"
-mem.switchformspec = mem.switchformspec..string.format("image_button[4.5,1.5;1.5,1;%s;indon;ON;false;false;celevator_button_rect_active.png]",indontex)
-mem.switchformspec = mem.switchformspec..string.format("image_button[4.5,3.5;1.5,1;%s;indoff;OFF;false;false;celevator_button_rect_active.png]",indofftex)
-mem.switchformspec = mem.switchformspec.."label[4.6,4.75;IND SVC]"
+mem.switchformspec = mem.switchformspec..string.format("image_button[4.5,1.5;1.5,1;%s;indon;"..S("ON")..switchboilerplate.."]",indontex)
+mem.switchformspec = mem.switchformspec..string.format("image_button[4.5,3.5;1.5,1;%s;indoff;"..S("OFF")..switchboilerplate.."]",indofftex)
+mem.switchformspec = mem.switchformspec.."label[4.6,4.75;"..S("IND SVC").."]"
local lightontex = mem.lightsw and "celevator_button_rect_active.png" or "celevator_button_rect.png"
local lightofftex = (not mem.lightsw) and "celevator_button_rect_active.png" or "celevator_button_rect.png"
-mem.switchformspec = mem.switchformspec..string.format("image_button[1.5,5.5;1.5,1;%s;lighton;ON;false;false;celevator_button_rect_active.png]",lightontex)
-mem.switchformspec = mem.switchformspec..string.format("image_button[1.5,7.5;1.5,1;%s;lightoff;OFF;false;false;celevator_button_rect_active.png]",lightofftex)
-mem.switchformspec = mem.switchformspec.."label[1.6,8.75;CAR LIGHT]"
+mem.switchformspec = mem.switchformspec..string.format("image_button[1.5,5.5;1.5,1;%s;lighton;"..S("ON")..switchboilerplate.."]",lightontex)
+mem.switchformspec = mem.switchformspec..string.format("image_button[1.5,7.5;1.5,1;%s;lightoff;"..S("OFF")..switchboilerplate.."]",lightofftex)
+mem.switchformspec = mem.switchformspec.."label[1.6,8.75;"..S("CAR LIGHT").."]"
local fanontex = mem.fansw and "celevator_button_rect_active.png" or "celevator_button_rect.png"
local fanofftex = (not mem.fansw) and "celevator_button_rect_active.png" or "celevator_button_rect.png"
-mem.switchformspec = mem.switchformspec..string.format("image_button[4.5,5.5;1.5,1;%s;fanon;ON;false;false;celevator_button_rect_active.png]",fanontex)
-mem.switchformspec = mem.switchformspec..string.format("image_button[4.5,7.5;1.5,1;%s;fanoff;OFF;false;false;celevator_button_rect_active.png]",fanofftex)
-mem.switchformspec = mem.switchformspec.."label[4.6,8.75;CAR FAN]"
+mem.switchformspec = mem.switchformspec..string.format("image_button[4.5,5.5;1.5,1;%s;fanon;"..S("ON")..switchboilerplate.."]",fanontex)
+mem.switchformspec = mem.switchformspec..string.format("image_button[4.5,7.5;1.5,1;%s;fanoff;"..S("OFF")..switchboilerplate.."]",fanofftex)
+mem.switchformspec = mem.switchformspec.."label[4.6,8.75;"..S("CAR FAN").."]"
return pos,mem,changedinterrupts
diff --git a/crafts.lua b/crafts.lua
index fd4390d..241346f 100644
--- a/crafts.lua
+++ b/crafts.lua
@@ -1,173 +1,363 @@
-minetest.register_craft({
+local xcompat_available = core.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 core.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 core.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
+ core.log("warning","[celevator] Unsupported game and xcompat not found, not registering craft recipes")
+ return
+ end
+ if core.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 core.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 core.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 core.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 = core.registered_nodes["mesecons_lightstone:lightstone_blue_off"]
+local vl_lightstone = core.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 = core.registered_nodes["mesecons_button:button_off"]
+if mesecons_button then
+ -- real mesecons
+ m.button = mesecons_button.name
+elseif core.get_modpath("mcl_core") then
+ m.button = "group:button"
+else
+ m.button = m.mese
+end
+
+if core.get_modpath("mesecons_switch") then
+ -- real mesecons
+ m.switch = "mesecons_switch:mesecon_switch_off"
+elseif core.get_modpath("mcl_lever") then
+ -- mcla
+ m.switch = "mcl_lever:lever_off"
+elseif core.get_modpath("mesecons_walllever") then
+ -- other mcl
+ m.switch = "mesecons_walllever:wall_lever_off"
+else
+ m.switch = m.mese
+end
+
+if core.get_modpath("digilines") then
+ m.lcd = "digilines:lcd"
+else
+ m.lcd = m.mese
+end
+
+core.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({
+core.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({
+core.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({
+core.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({
+core.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",
+core.register_craft({
+ output = "celevator:car_standard",
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_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({
+core.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},
+ },
+})
+
+core.register_craft({
+ output = "celevator:car_fullglass",
+ recipe = {
+ {m.glass,m.glass,m.glass},
+ {m.button,"celevator:hwdoor_glass",m.glass},
+ {m.switch,m.steel_ingot,m.steel_ingot},
+ },
+})
+
+core.register_craft({
+ output = "celevator:car_metal",
+ recipe = {
+ {"",m.steel_strip,""},
+ {m.steel_strip,"celevator:car_standard",m.steel_strip},
+ {"",m.steel_strip,""},
+ },
+})
+
+core.register_craft({
+ output = "celevator:car_metal_glassback",
+ recipe = {
+ {"",m.steel_strip,""},
+ {m.steel_strip,"celevator:car_glassback",m.steel_strip},
+ {"",m.steel_strip,""},
+ },
+})
+
+core.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({
+core.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({
+core.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},
},
})
-minetest.register_craft({
+core.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"},
},
})
-minetest.register_craft({
+core.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},
},
})
-minetest.register_craft({
+core.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({
+core.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({
+core.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({
+core.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({
+core.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},
+ },
+})
+
+core.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},
+ },
+})
+
+core.register_craft({
+ output = "celevator:hwdoor_centerglass",
+ recipe = {
+ {m.steel_bar,"",m.steel_bar},
+ {m.glass,m.steel_bar,m.glass},
+ {m.steel_bar,m.steel_bar,m.steel_bar},
+ },
+})
+
+core.register_craft({
+ output = "celevator:hwdoor_centersteel",
+ recipe = {
+ {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({
+core.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({
+core.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({
+core.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},
},
})
-minetest.register_craft({
+core.register_craft({
output = "celevator:lantern_vertical_up",
type = "shapeless",
recipe = {
@@ -175,7 +365,7 @@ minetest.register_craft({
},
})
-minetest.register_craft({
+core.register_craft({
output = "celevator:lantern_vertical_down",
type = "shapeless",
recipe = {
@@ -183,7 +373,7 @@ minetest.register_craft({
},
})
-minetest.register_craft({
+core.register_craft({
output = "celevator:lantern_vertical_both",
type = "shapeless",
recipe = {
@@ -191,7 +381,7 @@ minetest.register_craft({
},
})
-minetest.register_craft({
+core.register_craft({
output = "celevator:lantern_up",
type = "shapeless",
recipe = {
@@ -199,7 +389,7 @@ minetest.register_craft({
},
})
-minetest.register_craft({
+core.register_craft({
output = "celevator:lantern_down",
type = "shapeless",
recipe = {
@@ -207,7 +397,7 @@ minetest.register_craft({
},
})
-minetest.register_craft({
+core.register_craft({
output = "celevator:lantern_both",
type = "shapeless",
recipe = {
@@ -215,25 +405,25 @@ minetest.register_craft({
},
})
-minetest.register_craft({
+core.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({
+core.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},
},
})
-minetest.register_craft({
+core.register_craft({
output = "celevator:pilantern_up",
type = "shapeless",
recipe = {
@@ -242,7 +432,7 @@ minetest.register_craft({
},
})
-minetest.register_craft({
+core.register_craft({
output = "celevator:pilantern_down",
type = "shapeless",
recipe = {
@@ -251,7 +441,7 @@ minetest.register_craft({
},
})
-minetest.register_craft({
+core.register_craft({
output = "celevator:pilantern_both",
type = "shapeless",
recipe = {
@@ -260,39 +450,56 @@ minetest.register_craft({
},
})
-minetest.register_craft({
+core.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},
},
})
-minetest.register_craft({
+core.register_craft({
output = "celevator:tape_magnets",
type = "shapeless",
recipe = {
"celevator:tape",
- "default:iron_lump",
- "basic_materials:plastic_sheet",
+ m.iron_lump,
+ m.plastic_sheet,
},
})
-minetest.register_craft({
+core.register_craft({
output = "celevator:tape_bracket",
type = "shapeless",
recipe = {
"celevator:tape",
- "basic_materials:steel_strip",
+ m.steel_strip,
},
})
-minetest.register_craft({
+core.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},
+ },
+})
+
+core.register_craft({
+ output = "celevator:genericswitch",
+ recipe = {
+ {m.steel_strip,"",""},
+ {m.steel_strip,m.switch,m.dye_black},
+ {m.steel_strip,"",""},
+ },
+})
+
+core.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/dbdkiosk.lua b/dbdkiosk.lua
index 1250685..1f55b3c 100644
--- a/dbdkiosk.lua
+++ b/dbdkiosk.lua
@@ -1,32 +1,33 @@
celevator.dbdkiosk = {}
+local S = core.get_translator("celevator")
+
function celevator.dbdkiosk.checkprot(pos,name)
- if minetest.is_protected(pos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
- minetest.chat_send_player(name,"Can't open cabinet - cabinet is locked.")
- minetest.record_protection_violation(pos,name)
+ if core.is_protected(pos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ core.record_protection_violation(pos,name)
return false
end
return true
end
function celevator.dbdkiosk.updatefields(pos)
- if minetest.get_node(pos).name ~= "celevator:dbdkiosk" then return end
- local meta = minetest.get_meta(pos)
+ if core.get_node(pos).name ~= "celevator:dbdkiosk" then return end
+ local meta = core.get_meta(pos)
local screenstate = meta:get_string("screenstate")
if screenstate == "connect" then
meta:set_string("formspec","formspec_version[7]"..
"size[8,5]"..
- "field[0.5,0.5;7,1;carid;Dispatcher ID;]"..
- "field[0.5,2;7,1;landing;Landing Number;]"..
- "button[3,3.5;2,1;save;Save]"
+ "field[0.5,0.5;7,1;carid;"..S("Dispatcher ID")..";]"..
+ "field[0.5,2;7,1;landing;"..S("Landing Number")..";]"..
+ "button[3,3.5;2,1;save;"..S("Save").."]"
)
elseif screenstate == "main" then
local landing = meta:get_int("landing")
local fs = "formspec_version[7]"
fs = fs.."size[8,14]"
- fs = fs.."label[3,0.5;Please select a floor\\:]"
- local floornames = minetest.deserialize(meta:get_string("floornames"))
- local floorsavailable = minetest.deserialize(meta:get_string("floorsavailable"))
+ fs = fs.."label[3,0.5;"..core.formspec_escape(S("Please select a floor:")).."]"
+ local floornames = core.deserialize(meta:get_string("floornames"))
+ local floorsavailable = core.deserialize(meta:get_string("floorsavailable"))
local showfloors = {}
for i=1,#floornames,1 do
if floorsavailable[i] then
@@ -38,7 +39,7 @@ function celevator.dbdkiosk.updatefields(pos)
local floornum = showfloors[startfloor+i-1]
local floorname = floornum and floornames[floornum]
if floorname and floornum ~= landing then
- fs = fs..string.format("button[2,%f;4,1;floor%d;%s]",12-i,floornum,minetest.formspec_escape(floorname))
+ fs = fs..string.format("button[2,%f;4,1;floor%d;%s]",12-i,floornum,core.formspec_escape(floorname))
end
end
if startfloor > 1 then
@@ -51,39 +52,45 @@ function celevator.dbdkiosk.updatefields(pos)
elseif screenstate == "assignment" then
local fs = "formspec_version[7]"
fs = fs.."size[8,14]"
- fs = fs.."label[3,3;Please use elevator]"
+ fs = fs.."label[3,3;"..S("Please use elevator").."]"
fs = fs.."style_type[label;font_size=*4]"
fs = fs.."label[3.5,5;"..meta:get_string("assignedcar").."]"
meta:set_string("formspec",fs)
elseif screenstate == "error" then
local fs = "formspec_version[7]"
fs = fs.."size[8,14]"
- fs = fs.."label[3.5,0.5;ERROR]"
- fs = fs.."label[2.5,3;Could not find a suitable elevator]"
- fs = fs.."label[2.5,3.5;Please try again later]"
+ fs = fs.."label[3.5,0.5;"..S("ERROR").."]"
+ fs = fs.."label[2.5,3;"..S("Could not find a suitable elevator").."]"
+ fs = fs.."label[2.5,3.5;"..S("Please try again later").."]"
meta:set_string("formspec",fs)
end
end
function celevator.dbdkiosk.handlefields(pos,_,fields,player)
local name = player:get_player_name()
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local screenstate = meta:get_string("screenstate")
if screenstate == "connect" then
if not (fields.save and celevator.dbdkiosk.checkprot(pos,name)) then return end
if not (tonumber(fields.carid) and tonumber(fields.landing)) then return end
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",fields.carid)))
+ if tonumber(fields.landing) ~= math.floor(tonumber(fields.landing)) then return end
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",fields.carid)))
if not carinfo then return end
if not (carinfo.dispatcherpos and celevator.dispatcher.isdispatcher(carinfo.dispatcherpos)) then return end
- local dmem = minetest.deserialize(minetest.get_meta(carinfo.dispatcherpos):get_string("mem"))
+ if core.is_protected(carinfo.dispatcherpos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ core.record_protection_violation(carinfo.dispatcherpos,name)
+ core.chat_send_player(name,S("Can't connect to a dispatcher you don't have access to."))
+ return
+ end
+ local dmem = core.deserialize(core.get_meta(carinfo.dispatcherpos):get_string("mem"))
if not dmem then return end
local floornames = dmem.params.floornames
local floorsavailable = {}
for i=1,#floornames,1 do
floorsavailable[i] = true
end
- meta:set_string("floornames",minetest.serialize(floornames))
- meta:set_string("floorsavailable",minetest.serialize(floorsavailable))
+ meta:set_string("floornames",core.serialize(floornames))
+ meta:set_string("floorsavailable",core.serialize(floorsavailable))
meta:set_int("screenpage",1)
meta:set_string("screenstate","main")
meta:set_int("carid",tonumber(fields.carid))
@@ -95,17 +102,17 @@ function celevator.dbdkiosk.handlefields(pos,_,fields,player)
local floor = tonumber(string.sub(k,6,-1))
if not floor then return end
local carid = meta:get_int("carid")
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then return end
if not (carinfo.dispatcherpos and celevator.dispatcher.isdispatcher(carinfo.dispatcherpos)) then return end
- local dmem = minetest.deserialize(minetest.get_meta(carinfo.dispatcherpos):get_string("mem"))
+ local dmem = core.deserialize(core.get_meta(carinfo.dispatcherpos):get_string("mem"))
if dmem then
local floornames = dmem.params.floornames
- meta:set_string("floornames",minetest.serialize(floornames))
+ meta:set_string("floornames",core.serialize(floornames))
end
local event = {
type = "dbdkiosk",
- source = minetest.hash_node_position(pos),
+ source = core.hash_node_position(pos),
player = name,
srcfloor = meta:get_int("landing"),
destfloor = floor,
@@ -128,7 +135,7 @@ function celevator.dbdkiosk.handlefields(pos,_,fields,player)
end
function celevator.dbdkiosk.showassignment(pos,assignment)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
if meta:get_string("screenstate") == "main" then
local carnames = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P"}
if carnames[assignment] then
@@ -138,20 +145,21 @@ function celevator.dbdkiosk.showassignment(pos,assignment)
meta:set_string("screenstate","error")
end
celevator.dbdkiosk.updatefields(pos)
- minetest.after(5,function()
+ core.after(5,function()
meta:set_string("screenstate","main")
celevator.dbdkiosk.updatefields(pos)
end)
end
end
-minetest.register_node("celevator:dbdkiosk",{
- description = "Elevator Destination Entry Kiosk",
+core.register_node("celevator:dbdkiosk",{
+ description = S("Elevator Destination Entry Kiosk"),
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "4dir",
groups = {
- cracky = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
node_box = {
type = "fixed",
@@ -168,7 +176,7 @@ minetest.register_node("celevator:dbdkiosk",{
"celevator_cabinet_sides.png^celevator_dbdkiosk.png",
},
on_construct = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
meta:set_string("screenstate","connect")
celevator.dbdkiosk.updatefields(pos)
end,
diff --git a/decorations.lua b/decorations.lua
index 847c06a..2822e0d 100644
--- a/decorations.lua
+++ b/decorations.lua
@@ -1,7 +1,10 @@
-minetest.register_node("celevator:buffer_rubber",{
- description = "Elevator Elastomeric Buffer",
+local S = core.get_translator("celevator")
+
+core.register_node("celevator:buffer_rubber",{
+ description = S("Elevator Elastomeric Buffer"),
groups = {
- choppy = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
bouncy = 60,
},
paramtype = "light",
@@ -39,10 +42,11 @@ minetest.register_node("celevator:buffer_rubber",{
},
})
-minetest.register_node("celevator:buffer_oil",{
- description = "Elevator Oil-Filled Buffer",
+core.register_node("celevator:buffer_oil",{
+ description = S("Elevator Oil-Filled Buffer"),
groups = {
- choppy = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
paramtype = "light",
tiles = {
@@ -65,41 +69,42 @@ minetest.register_node("celevator:buffer_oil",{
},
},
after_place_node = function(pos,placer)
- local node = minetest.get_node(pos)
+ local node = core.get_node(pos)
local toppos = {x=pos.x,y=pos.y + 1,z=pos.z}
- local topnode = minetest.get_node(toppos)
+ local topnode = core.get_node(toppos)
local placername = placer:get_player_name()
if topnode.name ~= "air" then
if placer:is_player() then
- minetest.chat_send_player(placername,"Can't place buffer - no room for the top half!")
+ core.chat_send_player(placername,"Can't place buffer - no room for the top half!")
end
- minetest.set_node(pos,{name="air"})
+ core.set_node(pos,{name="air"})
return true
end
- if minetest.is_protected(toppos,placername) and not minetest.check_player_privs(placername,{protection_bypass=true}) then
+ if core.is_protected(toppos,placername) and not core.check_player_privs(placername,{protection_bypass=true}) then
if placer:is_player() then
- minetest.chat_send_player(placername,"Can't place buffer - top half is protected!")
- minetest.record_protection_violation(toppos,placername)
+ core.chat_send_player(placername,"Can't place buffer - top half is protected!")
+ core.record_protection_violation(toppos,placername)
end
- minetest.set_node(pos,{name="air"})
+ core.set_node(pos,{name="air"})
return true
end
node.name = "celevator:buffer_oil_top"
- minetest.set_node(toppos,node)
+ core.set_node(toppos,node)
end,
on_destruct = function(pos)
pos.y = pos.y + 1
- local topnode = minetest.get_node(pos)
+ local topnode = core.get_node(pos)
if topnode.name == "celevator:buffer_oil_top" then
- minetest.set_node(pos,{name="air"})
+ core.set_node(pos,{name="air"})
end
end,
})
-minetest.register_node("celevator:buffer_oil_top",{
- description = "Elevator Oil-Filled Buffer (top half - you hacker you!)",
+core.register_node("celevator:buffer_oil_top",{
+ description = S("Elevator Oil-Filled Buffer (top half - you hacker you!)"),
groups = {
- choppy = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
drop = "",
@@ -116,10 +121,11 @@ minetest.register_node("celevator:buffer_oil_top",{
},
})
-minetest.register_node("celevator:guide_rail",{
- description = "Elevator Guide Rail",
+core.register_node("celevator:guide_rail",{
+ description = S("Elevator Guide Rail"),
groups = {
- choppy = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
paramtype = "light",
paramtype2 = "4dir",
@@ -140,10 +146,11 @@ minetest.register_node("celevator:guide_rail",{
},
})
-minetest.register_node("celevator:guide_rail_bracket",{
- description = "Elevator Guide Rail with Bracket",
+core.register_node("celevator:guide_rail_bracket",{
+ description = S("Elevator Guide Rail with Bracket"),
groups = {
- choppy = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
paramtype = "light",
paramtype2 = "4dir",
@@ -169,10 +176,11 @@ minetest.register_node("celevator:guide_rail_bracket",{
},
})
-minetest.register_node("celevator:tape",{
- description = "Elevator Positioning System Tape",
+core.register_node("celevator:tape",{
+ description = S("Elevator Positioning System Tape"),
groups = {
- choppy = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
paramtype = "light",
paramtype2 = "4dir",
@@ -194,10 +202,11 @@ minetest.register_node("celevator:tape",{
},
})
-minetest.register_node("celevator:tape_magnets",{
- description = "Elevator Positioning System Tape with Magnets",
+core.register_node("celevator:tape_magnets",{
+ description = S("Elevator Positioning System Tape with Magnets"),
groups = {
- choppy = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
paramtype = "light",
paramtype2 = "4dir",
@@ -219,10 +228,11 @@ minetest.register_node("celevator:tape_magnets",{
},
})
-minetest.register_node("celevator:tape_bracket",{
- description = "Elevator Positioning System Tape with Bracket",
+core.register_node("celevator:tape_bracket",{
+ description = S("Elevator Positioning System Tape with Bracket"),
groups = {
- choppy = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
paramtype = "light",
paramtype2 = "4dir",
@@ -246,14 +256,14 @@ minetest.register_node("celevator:tape_bracket",{
},
})
-minetest.register_entity("celevator:tapehead",{
+core.register_entity("celevator:tapehead",{
initial_properties = {
visual = "wielditem",
visual_size = vector.new(0.667,0.667,0.667),
wield_item = "celevator:tapehead",
static_save = false,
pointable = false,
- glow = minetest.LIGHT_MAX,
+ glow = core.LIGHT_MAX,
},
on_step = function(self)
local obj = self.object
@@ -261,9 +271,9 @@ minetest.register_entity("celevator:tapehead",{
local pos = obj:get_pos()
if not pos then return end
local roundpos = vector.round(pos)
- local backdir = minetest.yaw_to_dir(obj:get_yaw())
+ local backdir = core.yaw_to_dir(obj:get_yaw())
local tapepos = vector.add(roundpos,backdir)
- local tapename = minetest.get_node(tapepos).name
+ local tapename = core.get_node(tapepos).name
if tapename ~= "celevator:tape" and tapename ~= "celevator:tape_magnets" and tapename ~= "celevator:tape_bracket" then
obj:remove()
return
@@ -289,32 +299,34 @@ minetest.register_entity("celevator:tapehead",{
local function spawntapehead(pos)
local toppos = vector.add(pos,vector.new(0,1,0))
- local entitiesnearby = minetest.get_objects_inside_radius(toppos,0.5)
+ local entitiesnearby = core.get_objects_inside_radius(toppos,0.5)
for _,i in pairs(entitiesnearby) do
if i:get_luaentity() and i:get_luaentity().name == "celevator:tapehead" then
return
end
end
- local entity = minetest.add_entity(pos,"celevator:tapehead")
- local fdir = minetest.fourdir_to_dir(minetest.get_node(pos).param2)
+ local entity = core.add_entity(pos,"celevator:tapehead")
+ local fdir = core.fourdir_to_dir(core.get_node(pos).param2)
fdir = vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2)
- entity:set_yaw(minetest.dir_to_yaw(fdir))
+ entity:set_yaw(core.dir_to_yaw(fdir))
entity:set_pos(toppos)
end
-minetest.register_abm({
+core.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,
action = spawntapehead,
})
-minetest.register_node("celevator:tapehead",{
- description = "Elevator Positioning System Tapehead (off, you hacker you!)",
+core.register_node("celevator:tapehead",{
+ description = S("Elevator Positioning System Tapehead (off, you hacker you!)"),
groups = {
not_in_creative_inventory = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
drop = "",
paramtype = "light",
@@ -338,10 +350,12 @@ minetest.register_node("celevator:tapehead",{
},
})
-minetest.register_node("celevator:tapehead_ulm",{
- description = "Elevator Positioning System Tapehead (ULM on, you hacker you!)",
+core.register_node("celevator:tapehead_ulm",{
+ description = S("Elevator Positioning System Tapehead (ULM on, you hacker you!)"),
groups = {
not_in_creative_inventory = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
drop = "",
paramtype = "light",
@@ -365,10 +379,12 @@ minetest.register_node("celevator:tapehead_ulm",{
},
})
-minetest.register_node("celevator:tapehead_ulm_dz",{
- description = "Elevator Positioning System Tapehead (ULM and DZ on, you hacker you!)",
+core.register_node("celevator:tapehead_ulm_dz",{
+ description = S("Elevator Positioning System Tapehead (ULM and DZ on, you hacker you!)"),
groups = {
not_in_creative_inventory = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
drop = "",
paramtype = "light",
@@ -392,10 +408,12 @@ minetest.register_node("celevator:tapehead_ulm_dz",{
},
})
-minetest.register_node("celevator:tapehead_ulm_dlm_dz",{
- description = "Elevator Positioning System Tapehead (ULM, DLM, and DZ on, you hacker you!)",
+core.register_node("celevator:tapehead_ulm_dlm_dz",{
+ description = S("Elevator Positioning System Tapehead (ULM, DLM, and DZ on, you hacker you!)"),
groups = {
not_in_creative_inventory = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
drop = "",
paramtype = "light",
@@ -419,10 +437,12 @@ minetest.register_node("celevator:tapehead_ulm_dlm_dz",{
},
})
-minetest.register_node("celevator:tapehead_dlm_dz",{
- description = "Elevator Positioning System Tapehead (DLM and DZ on, you hacker you!)",
+core.register_node("celevator:tapehead_dlm_dz",{
+ description = S("Elevator Positioning System Tapehead (DLM and DZ on, you hacker you!)"),
groups = {
not_in_creative_inventory = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
drop = "",
paramtype = "light",
@@ -446,10 +466,12 @@ minetest.register_node("celevator:tapehead_dlm_dz",{
},
})
-minetest.register_node("celevator:tapehead_dlm",{
- description = "Elevator Positioning System Tapehead (DLM on, you hacker you!)",
+core.register_node("celevator:tapehead_dlm",{
+ description = S("Elevator Positioning System Tapehead (DLM on, you hacker you!)"),
groups = {
not_in_creative_inventory = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
drop = "",
paramtype = "light",
diff --git a/digilines.lua b/digilines.lua
index 4b30345..60fa469 100644
--- a/digilines.lua
+++ b/digilines.lua
@@ -1,15 +1,17 @@
+local S = core.get_translator("celevator")
+
local function handledigilines(pos,node,channel,msg)
local multi = node.name == "celevator:digilines_multi_io"
if msg == "GET" then msg = {command = "GET"} end
if type(msg) ~= "table" or type(msg.command) ~= "string" then return end
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local setchannel = meta:get_string("channel")
if setchannel ~= channel then return end
if multi and type(msg.carid) ~= "number" then return end
local carid = multi and msg.carid or meta:get_int("carid")
if carid == 0 then return end
local dmode = meta:get_int("dispatcher") == 1
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {}
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {}
if multi then
dmode = carinfo.dispatcherpos
end
@@ -18,7 +20,7 @@ local function handledigilines(pos,node,channel,msg)
if not carinfo.dispatcherpos then return end
if not celevator.dispatcher.isdispatcher(carinfo.dispatcherpos) then return end
if msg.command == "get" then
- local mem = minetest.deserialize(minetest.get_meta(carinfo.dispatcherpos):get_string("mem"))
+ local mem = core.deserialize(core.get_meta(carinfo.dispatcherpos):get_string("mem"))
if not mem then return end
local ret = {
upcalls = {},
@@ -67,7 +69,7 @@ local function handledigilines(pos,node,channel,msg)
if not carinfo.controllerpos then return end
if not celevator.controller.iscontroller(carinfo.controllerpos) then return end
if msg.command == "get" then
- local mem = minetest.deserialize(minetest.get_meta(carinfo.controllerpos):get_string("mem"))
+ local mem = core.deserialize(core.get_meta(carinfo.controllerpos):get_string("mem"))
if not mem then return end
local ret = {
carstate = mem.carstate,
@@ -158,12 +160,24 @@ 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
-minetest.register_node("celevator:digilines_io",{
- description = "Elevator Digilines Input/Output",
+core.register_node("celevator:digilines_io",{
+ description = S("Elevator Digilines Input/Output"),
tiles = {
"celevator_digilinesio_top.png",
"celevator_cabinet_sides.png",
@@ -187,27 +201,27 @@ minetest.register_node("celevator:digilines_io",{
},
},
after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local fs = "formspec_version[7]size[8,4.5]"
- fs = fs.."field[0.5,0.5;3,1;channel;Channel;${channel}]"
- fs = fs.."field[4.5,0.5;3,1;carid;Car ID;${carid}]"
- fs = fs.."button_exit[2.5,2;3,1;save;Save]"
+ fs = fs.."field[0.5,0.5;3,1;channel;"..S("Channel")..";${channel}]"
+ fs = fs.."field[4.5,0.5;3,1;carid;"..S("Car ID")..";${carid}]"
+ fs = fs.."button_exit[2.5,2;3,1;save;"..S("Save").."]"
meta:set_string("formspec",fs)
end,
on_receive_fields = function(pos,_,fields,player)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
if not fields.save 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
+ if core.is_protected(pos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
if player:is_player() then
- minetest.record_protection_violation(pos,name)
+ core.record_protection_violation(pos,name)
end
return
end
if not tonumber(fields.carid) then return end
meta:set_int("carid",fields.carid)
local carid = tonumber(fields.carid)
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {}
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {}
if not (carinfo.controllerpos or carinfo.dispatcherpos) then return end
local dmode = false
if carinfo.dispatcherpos then
@@ -217,31 +231,31 @@ minetest.register_node("celevator:digilines_io",{
if not celevator.controller.iscontroller(carinfo.controllerpos) then return end
end
if dmode then
- if minetest.is_protected(carinfo.dispatcherpos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
+ if core.is_protected(carinfo.dispatcherpos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
if player:is_player() then
- minetest.chat_send_player(name,"Can't connect to a dispatcher you don't have access to.")
- minetest.record_protection_violation(carinfo.dispatcherpos,name)
+ core.chat_send_player(name,S("Can't connect to a dispatcher you don't have access to."))
+ core.record_protection_violation(carinfo.dispatcherpos,name)
end
return
end
else
- if minetest.is_protected(carinfo.controllerpos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
+ if core.is_protected(carinfo.controllerpos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
if player:is_player() then
- minetest.chat_send_player(name,"Can't connect to a controller you don't have access to.")
- minetest.record_protection_violation(carinfo.controllerpos,name)
+ core.chat_send_player(name,S("Can't connect to a controller you don't have access to."))
+ core.record_protection_violation(carinfo.controllerpos,name)
end
return
end
end
meta:set_int("dispatcher",dmode and 1 or 0)
meta:set_string("channel",fields.channel)
- local infotext = "Car: "..carid
+ local infotext = S("ID: @1",carid)
meta:set_string("infotext",infotext)
end,
})
-minetest.register_node("celevator:digilines_multi_io",{
- description = "Elevator Digilines Multi-Car Input/Output",
+core.register_node("celevator:digilines_multi_io",{
+ description = S("Elevator Digilines Multi-Car Input/Output"),
tiles = {
"celevator_digilinesio_multi_top.png",
"celevator_cabinet_sides.png",
@@ -267,28 +281,28 @@ minetest.register_node("celevator:digilines_multi_io",{
},
after_place_node = function(pos,player)
local name = player:get_player_name()
- if not (minetest.check_player_privs(name,{protection_bypass=true}) or minetest.check_player_privs(name,{server=true})) then
+ if not (core.check_player_privs(name,{protection_bypass=true}) or core.check_player_privs(name,{server=true})) then
if player:is_player() then
- minetest.chat_send_player(name,"You need either the 'protection_bypass' or 'server' privilege to use this.")
- minetest.record_protection_violation(pos,name)
+ core.chat_send_player(name,S("You need either the 'protection_bypass' or 'server' privilege to use this."))
+ core.record_protection_violation(pos,name)
end
- minetest.remove_node(pos)
+ core.remove_node(pos)
return
end
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local fs = "formspec_version[7]size[8,4.5]"
- fs = fs.."field[0.5,0.5;7,1;channel;Channel;${channel}]"
- fs = fs.."button_exit[2.5,2;3,1;save;Save]"
+ fs = fs.."field[0.5,0.5;7,1;channel;"..S("Channel")..";${channel}]"
+ fs = fs.."button_exit[2.5,2;3,1;save;"..S("Save").."]"
meta:set_string("formspec",fs)
end,
on_receive_fields = function(pos,_,fields,player)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
if not fields.save then return end
local name = player:get_player_name()
- if not (minetest.check_player_privs(name,{protection_bypass=true}) or minetest.check_player_privs(name,{server=true})) then
+ if not (core.check_player_privs(name,{protection_bypass=true}) or core.check_player_privs(name,{server=true})) then
if player:is_player() then
- minetest.chat_send_player(name,"You need either the 'protection_bypass' or 'server' privilege to use this.")
- minetest.record_protection_violation(pos,name)
+ core.chat_send_player(name,S("You need either the 'protection_bypass' or 'server' privilege to use this."))
+ core.record_protection_violation(pos,name)
end
return
end
diff --git a/digistuff.lua b/digistuff.lua
new file mode 100644
index 0000000..c1382e8
--- /dev/null
+++ b/digistuff.lua
@@ -0,0 +1,27 @@
+local nbsounds = {
+ --At the moment this is everything except the nudging buzzer
+ "celevator_brake_apply",
+ "celevator_brake_release",
+ "celevator_cabinet_close",
+ "celevator_cabinet_open",
+ "celevator_car_run",
+ "celevator_car_start",
+ "celevator_car_stop",
+ "celevator_chime_down",
+ "celevator_chime_up",
+ "celevator_controller_start",
+ "celevator_controller_stop",
+ "celevator_door_close",
+ "celevator_door_open",
+ "celevator_door_reverse",
+ "celevator_drive_run",
+ "celevator_motor_accel",
+ "celevator_motor_decel",
+ "celevator_motor_fast",
+ "celevator_motor_slow",
+ "celevator_pi_beep",
+ "celevator_chime2_up",
+ "celevator_chime2_down",
+}
+
+for _,i in ipairs(nbsounds) do digistuff.register_nb_sound(i,i) end
diff --git a/dispatcher.lua b/dispatcher.lua
index a8bcf1c..cd091bb 100644
--- a/dispatcher.lua
+++ b/dispatcher.lua
@@ -1,23 +1,25 @@
celevator.dispatcher = {}
-celevator.dispatcher.iqueue = minetest.deserialize(celevator.storage:get_string("dispatcher_iqueue")) or {}
+local S = core.get_translator("celevator")
-celevator.dispatcher.equeue = minetest.deserialize(celevator.storage:get_string("dispatcher_equeue")) or {}
+celevator.dispatcher.iqueue = core.deserialize(celevator.storage:get_string("dispatcher_iqueue")) or {}
+
+celevator.dispatcher.equeue = core.deserialize(celevator.storage:get_string("dispatcher_equeue")) or {}
celevator.dispatcher.running = {}
-local fw,err = loadfile(minetest.get_modpath("celevator")..DIR_DELIM.."dispatcherfw.lua")
+local fw,err = loadfile(core.get_modpath("celevator").."/dispatcherfw.lua")
if not fw then error(err) end
-minetest.register_chatcommand("celevator_reloaddispatcher",{
+core.register_chatcommand("celevator_reloaddispatcher",{
params = "",
description = "Reload celevator dispatcher firmware from disk",
privs = {server = true},
func = function()
- local newfw,loaderr = loadfile(minetest.get_modpath("celevator")..DIR_DELIM.."dispatcherfw.lua")
+ local newfw,loaderr = loadfile(core.get_modpath("celevator").."/dispatcherfw.lua")
if newfw then
fw = newfw
- return true,"Firmware reloaded successfully"
+ return true,S("Firmware reloaded successfully")
else
return false,loaderr
end
@@ -25,63 +27,69 @@ minetest.register_chatcommand("celevator_reloaddispatcher",{
})
local function after_place(pos,placer)
- local node = minetest.get_node(pos)
+ local node = core.get_node(pos)
local toppos = {x=pos.x,y=pos.y + 1,z=pos.z}
- local topnode = minetest.get_node(toppos)
+ local topnode = core.get_node(toppos)
local placername = placer:get_player_name()
if topnode.name ~= "air" then
if placer:is_player() then
- minetest.chat_send_player(placername,"Can't place cabinet - no room for the top half!")
+ core.chat_send_player(placername,S("Can't place cabinet - no room for the top half!"))
end
- minetest.set_node(pos,{name="air"})
+ core.set_node(pos,{name="air"})
return true
end
- if minetest.is_protected(toppos,placername) and not minetest.check_player_privs(placername,{protection_bypass=true}) then
+ if core.is_protected(toppos,placername) and not core.check_player_privs(placername,{protection_bypass=true}) then
if placer:is_player() then
- minetest.chat_send_player(placername,"Can't place cabinet - top half is protected!")
- minetest.record_protection_violation(toppos,placername)
+ core.chat_send_player(placername,S("Can't place cabinet - top half is protected!"))
+ core.record_protection_violation(toppos,placername)
end
- minetest.set_node(pos,{name="air"})
+ core.set_node(pos,{name="air"})
return true
end
node.name = "celevator:dispatcher_top"
- minetest.set_node(toppos,node)
+ core.set_node(toppos,node)
end
local function ondestruct(pos)
pos.y = pos.y + 1
- local topnode = minetest.get_node(pos)
+ local topnode = core.get_node(pos)
local dispatchertops = {
["celevator:dispatcher_top"] = true,
["celevator:dispatcher_top_open"] = true,
}
if dispatchertops[topnode.name] then
- minetest.set_node(pos,{name="air"})
+ core.set_node(pos,{name="air"})
end
- celevator.dispatcher.equeue[minetest.hash_node_position(pos)] = nil
- celevator.storage:set_string("dispatcher_equeue",minetest.serialize(celevator.dispatcher.equeue))
- local carid = minetest.get_meta(pos):get_int("carid")
+ celevator.dispatcher.equeue[core.hash_node_position(pos)] = nil
+ celevator.storage:set_string("dispatcher_equeue",core.serialize(celevator.dispatcher.equeue))
+ local carid = core.get_meta(pos):get_int("carid")
if carid ~= 0 then celevator.storage:set_string(string.format("car%d",carid),"") end
end
local function onrotate(controllerpos,node,user,mode,new_param2)
- if not minetest.global_exists("screwdriver") then
+ if not core.global_exists("screwdriver") then
return false
end
local ret = screwdriver.rotate_simple(controllerpos,node,user,mode,new_param2)
- minetest.after(0,function(pos)
- local newnode = minetest.get_node(pos)
+ core.after(0,function(pos)
+ local newnode = core.get_node(pos)
local param2 = newnode.param2
pos.y = pos.y + 1
- local topnode = minetest.get_node(pos)
+ local topnode = core.get_node(pos)
topnode.param2 = param2
- minetest.set_node(pos,topnode)
+ core.set_node(pos,topnode)
end,controllerpos)
return ret
end
local function handlefields(pos,_,fields,sender)
local playername = sender and sender:get_player_name() or ""
+ if core.settings:get_bool("celevator.controller_screen_protected",false) then
+ if core.is_protected(pos,playername) and not core.check_player_privs(playername,{protection_bypass=true}) then
+ core.record_protection_violation(pos,playername)
+ return
+ end
+ end
local event = {}
event.type = "ui"
event.fields = fields
@@ -94,15 +102,16 @@ local function candig(_,player)
if controls.sneak then
return true
else
- minetest.chat_send_player(player:get_player_name(),"Hold the sneak button while digging to remove.")
+ core.chat_send_player(player:get_player_name(),S("Hold the sneak button while digging to remove."))
return false
end
end
-minetest.register_node("celevator:dispatcher",{
- description = "Elevator Dispatcher",
+core.register_node("celevator:dispatcher",{
+ description = S("Elevator Dispatcher"),
groups = {
- cracky = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
},
paramtype = "light",
paramtype2 = "facedir",
@@ -133,15 +142,15 @@ minetest.register_node("celevator:dispatcher",{
on_receive_fields = handlefields,
can_dig = candig,
on_construct = function(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("mem",minetest.serialize({}))
+ local meta = core.get_meta(pos)
+ meta:set_string("mem",core.serialize({}))
meta:mark_as_private("mem")
local event = {}
event.type = "program"
local carid = celevator.storage:get_int("maxcarid")+1
meta:set_int("carid",carid)
celevator.storage:set_int("maxcarid",carid)
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize({dispatcherpos=pos,callbuttons={},fs1switches={}}))
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize({dispatcherpos=pos,callbuttons={},fs1switches={}}))
celevator.dispatcher.run(pos,event)
end,
on_punch = function(pos,node,puncher)
@@ -149,20 +158,22 @@ minetest.register_node("celevator:dispatcher",{
return
end
local name = puncher: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,"Can't open cabinet - cabinet is locked.")
- minetest.record_protection_violation(pos,name)
- return
+ if core.settings:get_bool("celevator.controller_cabinet_protected",true) then
+ if core.is_protected(pos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ core.chat_send_player(name,S("Can't open cabinet - cabinet is locked."))
+ core.record_protection_violation(pos,name)
+ return
+ end
end
node.name = "celevator:dispatcher_open"
- minetest.swap_node(pos,node)
- local meta = minetest.get_meta(pos)
+ core.swap_node(pos,node)
+ local meta = core.get_meta(pos)
meta:set_string("formspec",meta:get_string("formspec_hidden"))
pos.y = pos.y + 1
- node = minetest.get_node(pos)
+ node = core.get_node(pos)
node.name = "celevator:dispatcher_top_open"
- minetest.swap_node(pos,node)
- minetest.sound_play("celevator_cabinet_open",{
+ core.swap_node(pos,node)
+ core.sound_play("celevator_cabinet_open",{
pos = pos,
gain = 0.5,
max_hear_distance = 10
@@ -170,10 +181,11 @@ minetest.register_node("celevator:dispatcher",{
end,
})
-minetest.register_node("celevator:dispatcher_open",{
- description = "Dispatcher (door open - you hacker you!)",
+core.register_node("celevator:dispatcher_open",{
+ description = S("Dispatcher (door open - you hacker you!)"),
groups = {
- cracky = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
paramtype = "light",
@@ -215,14 +227,14 @@ minetest.register_node("celevator:dispatcher_open",{
return
end
node.name = "celevator:dispatcher"
- minetest.swap_node(pos,node)
- local meta = minetest.get_meta(pos)
+ core.swap_node(pos,node)
+ local meta = core.get_meta(pos)
meta:set_string("formspec","")
pos.y = pos.y + 1
- node = minetest.get_node(pos)
+ node = core.get_node(pos)
node.name = "celevator:dispatcher_top"
- minetest.swap_node(pos,node)
- minetest.sound_play("celevator_cabinet_close",{
+ core.swap_node(pos,node)
+ core.sound_play("celevator_cabinet_close",{
pos = pos,
gain = 0.5,
max_hear_distance = 10
@@ -230,9 +242,11 @@ minetest.register_node("celevator:dispatcher_open",{
end,
})
-minetest.register_node("celevator:dispatcher_top",{
- description = "Dispatcher (top section - you hacker you!)",
+core.register_node("celevator:dispatcher_top",{
+ description = S("Dispatcher (top section - you hacker you!)"),
groups = {
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
drop = "",
@@ -261,9 +275,11 @@ minetest.register_node("celevator:dispatcher_top",{
},
})
-minetest.register_node("celevator:dispatcher_top_open",{
- description = "Dispatcher (top section, open - you hacker you!)",
+core.register_node("celevator:dispatcher_top_open",{
+ description = S("Dispatcher (top section, open - you hacker you!)"),
groups = {
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
drop = "",
@@ -303,16 +319,16 @@ function celevator.dispatcher.finish(pos,mem,changedinterrupts)
if not celevator.dispatcher.isdispatcher(pos) then
return
else
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local carid = meta:get_int("carid")
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
local carinfodirty = false
if not carinfo then
- minetest.log("error","[celevator] [controller] Bad car info for dispatcher at "..minetest.pos_to_string(pos))
+ core.log("error",string.format("[celevator] [dispatcher] Bad car info for dispatcher at %s",core.pos_to_string(pos)))
return
end
local node = celevator.get_node(pos)
- local oldmem = minetest.deserialize(meta:get_string("mem")) or {}
+ local oldmem = core.deserialize(meta:get_string("mem")) or {}
local oldupbuttonlights = oldmem.upcalls or {}
local olddownbuttonlights = oldmem.dncalls or {}
local newupbuttonlights = mem.upcalls or {}
@@ -335,7 +351,7 @@ function celevator.dispatcher.finish(pos,mem,changedinterrupts)
end
end
for _,message in ipairs(mem.messages) do
- local destinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",message.carid)))
+ local destinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",message.carid)))
if destinfo and destinfo.controllerpos then
celevator.controller.run(destinfo.controllerpos,{
type = "dispatchermsg",
@@ -346,27 +362,27 @@ function celevator.dispatcher.finish(pos,mem,changedinterrupts)
end
end
for _,message in ipairs(mem.kioskmessages) do
- celevator.dbdkiosk.showassignment(minetest.get_position_from_hash(message.pos),message.car)
+ celevator.dbdkiosk.showassignment(core.get_position_from_hash(message.pos),message.car)
end
- meta:set_string("mem",minetest.serialize(mem))
+ meta:set_string("mem",core.serialize(mem))
if node.name == "celevator:dispatcher_open" then meta:set_string("formspec",mem.formspec or "") end
meta:set_string("formspec_hidden",mem.formspec or "")
meta:set_string("infotext",mem.infotext or "")
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
if not celevator.dispatcher.iqueue[hash] then celevator.dispatcher.iqueue[hash] = mem.interrupts end
for iid in pairs(changedinterrupts) do
celevator.dispatcher.iqueue[hash][iid] = mem.interrupts[iid]
end
- celevator.storage:set_string("dispatcher_iqueue",minetest.serialize(celevator.dispatcher.iqueue))
+ celevator.storage:set_string("dispatcher_iqueue",core.serialize(celevator.dispatcher.iqueue))
celevator.dispatcher.running[hash] = nil
if #celevator.dispatcher.equeue[hash] > 0 then
local event = celevator.dispatcher.equeue[hash][1]
table.remove(celevator.dispatcher.equeue[hash],1)
- celevator.storage:set_string("dispatcher_equeue",minetest.serialize(celevator.dispatcher.equeue))
+ celevator.storage:set_string("dispatcher_equeue",core.serialize(celevator.dispatcher.equeue))
celevator.dispatcher.run(pos,event)
end
if carinfodirty then
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
end
end
end
@@ -375,30 +391,32 @@ function celevator.dispatcher.run(pos,event)
if not celevator.dispatcher.isdispatcher(pos) then
return
else
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
if not celevator.dispatcher.equeue[hash] then
celevator.dispatcher.equeue[hash] = {}
- celevator.storage:set_string("dispatcher_equeue",minetest.serialize(celevator.dispatcher.equeue))
+ celevator.storage:set_string("dispatcher_equeue",core.serialize(celevator.dispatcher.equeue))
end
if celevator.dispatcher.running[hash] then
table.insert(celevator.dispatcher.equeue[hash],event)
- celevator.storage:set_string("dispatcher_equeue",minetest.serialize(celevator.dispatcher.equeue))
+ celevator.storage:set_string("dispatcher_equeue",core.serialize(celevator.dispatcher.equeue))
if #celevator.dispatcher.equeue[hash] > 20 then
- local message = "[celevator] [dispatcher] Async process for dispatcher at %s is falling behind, %d events in queue"
- minetest.log("warning",string.format(message,minetest.pos_to_string(pos),#celevator.dispatcher.equeue[hash]))
+ local pstring = core.pos_to_string(pos)
+ local queuelen = #celevator.dispatcher.equeue[hash]
+ local message = string.format("[celevator] [dispatcher] Async process for dispatcher at %s is falling behind, %d events in queue",pstring,queuelen)
+ core.log("warning",message)
end
return
end
celevator.dispatcher.running[hash] = true
- local meta = minetest.get_meta(pos)
- local mem = minetest.deserialize(meta:get_string("mem"))
+ local meta = core.get_meta(pos)
+ local mem = core.deserialize(meta:get_string("mem"))
if not mem then
- minetest.log("error","[celevator] [controller] Failed to load dispatcher memory at "..minetest.pos_to_string(pos))
+ core.log("error",string.format("[celevator] [dispatcher] Failed to load dispatcher memory at %s",core.pos_to_string(pos)))
return
end
- mem.interrupts = celevator.dispatcher.iqueue[minetest.hash_node_position(pos)] or {}
+ mem.interrupts = celevator.dispatcher.iqueue[core.hash_node_position(pos)] or {}
mem.carid = meta:get_int("carid")
- minetest.handle_async(fw,celevator.dispatcher.finish,pos,event,mem)
+ core.handle_async(fw,celevator.dispatcher.finish,pos,event,mem)
end
end
@@ -421,8 +439,10 @@ end
function celevator.dispatcher.checkiqueue(dtime)
for hash,iqueue in pairs(celevator.dispatcher.iqueue) do
- local pos = minetest.get_position_from_hash(hash)
+ local pos = core.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,12 +452,16 @@ 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",core.serialize(celevator.dispatcher.iqueue))
+ end
end
end
-minetest.register_globalstep(celevator.dispatcher.checkiqueue)
+core.register_globalstep(celevator.dispatcher.checkiqueue)
-minetest.register_abm({
+core.register_abm({
label = "Run otherwise idle dispatchers if a user is nearby",
nodenames = {"celevator:dispatcher","celevator:dispatcher_open"},
interval = 1,
diff --git a/dispatcherfw.lua b/dispatcherfw.lua
index 25ad4f8..7793091 100644
--- a/dispatcherfw.lua
+++ b/dispatcherfw.lua
@@ -1,5 +1,7 @@
local pos,event,mem = ...
+local S = core.get_translator("celevator")
+
local changedinterrupts = {}
local function interrupt(time,iid)
@@ -240,6 +242,7 @@ local function estimatetraveltime(carid,src,dest)
end
local function buildstopsequence(carid,startfloor,direction,target,targetdir,leaving)
+ if not startfloor then return {} end
local carcalls = cartorealfloor(carid,mem.carstatus[carid].carcalls)
local upcalls = cartorealfloor(carid,mem.carstatus[carid].upcalls)
local dncalls = cartorealfloor(carid,mem.carstatus[carid].dncalls)
@@ -258,7 +261,9 @@ local function buildstopsequence(carid,startfloor,direction,target,targetdir,lea
end
repeat
local src = carpos
+ if not src then return sequence end
carpos,direction = predictnextstop(carid,carpos,direction,carcalls,upcalls,dncalls,leaving)
+ if not carpos then return sequence end
carcalls[carpos] = nil
if direction == "up" then
upcalls[carpos] = nil
@@ -300,6 +305,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"
@@ -335,7 +361,8 @@ elseif event.type == "ui" then
mem.screenstate = "oobe_welcome"
end
elseif mem.screenstate == "oobe_floortable" or mem.screenstate == "floortable" then
- local exp = event.fields.floor and minetest.explode_textlist_event(event.fields.floor) or {}
+ local exp = event.fields.floor and core.explode_textlist_event(event.fields.floor) or {}
+ local maxfloors = tonumber(core.settings:get("celevator.max_landings")) or 100
if event.fields.back then
mem.screenstate = "oobe_welcome"
elseif event.fields.next then
@@ -364,14 +391,15 @@ elseif event.type == "ui" then
mem.screenstate = (mem.screenstate == "oobe_floortable" and "oobe_floortable_edit" or "floortable_edit")
elseif event.fields.edit then
mem.screenstate = (mem.screenstate == "oobe_floortable" and "oobe_floortable_edit" or "floortable_edit")
- 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.add and #mem.params.floornames < maxfloors then
+ table.insert(mem.params.floorheights,mem.params.floorheights[#mem.params.floorheights] or 5)
+ local previous = tonumber(mem.params.floornames[#mem.params.floornames]) or #mem.params.floornames
+ table.insert(mem.params.floornames,tostring(math.floor(previous)+1))
+ 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)
- elseif event.fields.moveup then
+ elseif event.fields.moveup and mem.editingfloor < #mem.params.floornames then
local height = mem.params.floorheights[mem.editingfloor]
local name = mem.params.floornames[mem.editingfloor]
table.remove(mem.params.floorheights,mem.editingfloor)
@@ -379,7 +407,7 @@ elseif event.type == "ui" then
table.insert(mem.params.floorheights,mem.editingfloor+1,height)
table.insert(mem.params.floornames,mem.editingfloor+1,name)
mem.editingfloor = mem.editingfloor + 1
- elseif event.fields.movedown then
+ elseif event.fields.movedown and mem.editingfloor > 1 then
local height = mem.params.floorheights[mem.editingfloor]
local name = mem.params.floornames[mem.editingfloor]
table.remove(mem.params.floorheights,mem.editingfloor)
@@ -392,14 +420,15 @@ elseif event.type == "ui" then
if event.fields.back or event.fields.save then
mem.screenstate = (mem.screenstate == "oobe_floortable_edit" and "oobe_floortable" or "floortable")
local height = tonumber(event.fields.height)
- if height then
+ if height and height < (tonumber(core.settings:get("celevator.max_height")) or 100) then
height = math.floor(height+0.5)
mem.params.floorheights[mem.editingfloor] = math.max(1,height)
end
mem.params.floornames[mem.editingfloor] = string.sub(event.fields.name,1,256)
end
elseif mem.screenstate == "oobe_connections" or mem.screenstate == "connections" then
- local exp = event.fields.connection and minetest.explode_textlist_event(event.fields.connection) or {}
+ local exp = event.fields.connection and core.explode_textlist_event(event.fields.connection) or {}
+ local maxcars = tonumber(core.settings:get("celevator.max_group")) or 16
if event.fields.back then
mem.screenstate = "oobe_floortable"
elseif event.fields.next and #mem.params.carids > 0 then
@@ -410,10 +439,11 @@ elseif event.type == "ui" then
elseif exp.type == "DCL" then
mem.editingconnection = #mem.params.carids-exp.index+1
mem.screenstate = (mem.screenstate == "oobe_connections" and "oobe_connection" or "connection")
+ mem.newconnfloors = mem.params.floorsserved[mem.params.carids[mem.editingconnection]]
elseif event.fields.edit then
mem.screenstate = (mem.screenstate == "oobe_connections" and "oobe_connection" or "connection")
mem.newconnfloors = mem.params.floorsserved[mem.params.carids[mem.editingconnection]]
- elseif event.fields.add then
+ elseif event.fields.add and #mem.params.carids < maxcars then
mem.newconnfloors = {}
for i in ipairs(mem.params.floornames) do
mem.newconnfloors[i] = true
@@ -425,7 +455,7 @@ elseif event.type == "ui" then
mem.editingconnection = math.max(1,mem.editingconnection-1)
end
elseif mem.screenstate == "oobe_newconnection" or mem.screenstate == "newconnection" then
- local exp = event.fields.floors and minetest.explode_textlist_event(event.fields.floors) or {}
+ local exp = event.fields.floors and core.explode_textlist_event(event.fields.floors) or {}
if event.fields.back then
mem.screenstate = (mem.screenstate == "oobe_newconnection" and "oobe_connections" or "connections")
elseif event.fields.connect and fields.carid and tonumber(fields.carid) then
@@ -450,7 +480,7 @@ elseif event.type == "ui" then
mem.newconnfloors[floor] = not mem.newconnfloors[floor]
end
elseif mem.screenstate == "oobe_connection" or mem.screenstate == "connection" then
- local exp = event.fields.floors and minetest.explode_textlist_event(event.fields.floors) or {}
+ local exp = event.fields.floors and core.explode_textlist_event(event.fields.floors) or {}
if event.fields.back then
mem.screenstate = (mem.screenstate == "oobe_connection" and "oobe_connections" or "connections")
elseif event.fields.save then
@@ -906,134 +936,140 @@ fs("background9[0,0;16,12;celevator_fs_bg.png;true;3]")
if mem.screenstate == "oobe_welcome" then
fs("image[6,1;4,2;celevator_logo.png]")
- fs("label[1,4;Welcome to your new MTronic XT elevator dispatcher!]")
- fs("label[1,4.5;Before continuing, make sure you have at least two controllers in group operation mode and ready to connect.]")
- fs("label[1,5.5;Press Next to begin.]")
- fs("button[1,10;2,1;license;License Info]")
- fs("button[13,10;2,1;next;Next >]")
+ fs("label[1,4;"..S("Welcome to your new MTronic XT elevator dispatcher!").."]")
+ fs("label[1,4.5;"..S("Before continuing, make sure you have at least two controllers in group operation mode and ready to connect.").."]")
+ fs("label[1,5.5;"..S("Press Next to begin.").."]")
+ fs("button[1,10;3,1;license;"..S("License Info").."]")
+ fs("button[13,10;2,1;next;"..S("Next >").."]")
elseif mem.screenstate == "oobe_license" then
- local licensefile = io.open(minetest.get_modpath("celevator")..DIR_DELIM.."LICENSE")
- local license = minetest.formspec_escape(licensefile:read("*all"))
+ local licensefile = io.open(core.get_modpath("celevator").."/LICENSE")
+ local license = core.formspec_escape(licensefile:read("*all"))
licensefile:close()
- fs("textarea[1,1;14,8;license;This applies to the whole celevator mod\\, not just this dispatcher:;"..license.."]")
+ fs("textarea[1,1;14,8;license;"..core.formspec_escape(S("This applies to the whole celevator mod, not just this dispatcher:"))..";"..license.."]")
fs("button[7,10.5;2,1;back;OK]")
elseif mem.screenstate == "oobe_floortable" or mem.screenstate == "floortable" then
if mem.screenstate == "oobe_floortable" then
- fs("label[1,1;Enter details of all floors this group will serve, then press Next.]")
- fs("label[1,1.3;Include all floors served by any car in the group, even if not served by all cars.]")
- fs("button[1,10;2,1;back;< Back]")
- fs("button[13,10;2,1;next;Next >]")
+ fs("label[1,1;"..S("Enter details of all floors this group will serve, then press Next.").."]")
+ fs("label[1,1.3;"..S("Include all floors served by any car in the group, even if not served by all cars.").."]")
+ fs("button[1,10;2,1;back;"..S("< Back").."]")
+ fs("button[13,10;2,1;next;"..S("Next >").."]")
else
- fs("label[1,1;EDIT FLOOR TABLE]")
- fs("button[1,10;2,1;next;Done]")
+ fs("label[1,1;"..S("EDIT FLOOR TABLE").."]")
+ fs("button[1,10;2,1;next;"..S("Done").."]")
end
fs("textlist[1,2;6,7;floor;")
for i=#mem.params.floornames,1,-1 do
- fs(minetest.formspec_escape(string.format("%d - Height: %d - PI: %s",i,mem.params.floorheights[i],mem.params.floornames[i]))..(i==1 and "" or ","))
+ local floortext = S("@1 - Height: @2 - PI: @3",i,mem.params.floorheights[i] or "??",mem.params.floornames[i] or "??")
+ fs(core.formspec_escape(floortext)..(i==1 and "" or ","))
end
fs(";"..tostring(#mem.params.floornames-mem.editingfloor+1)..";false]")
- if #mem.params.floornames < 100 then fs("button[8,2;2,1;add;New Floor]") end
- fs("button[8,3.5;2,1;edit;Edit Floor]")
- if #mem.params.floornames > 2 then fs("button[8,5;2,1;remove;Remove Floor]") end
- if mem.editingfloor < #mem.params.floornames then fs("button[8,6.5;2,1;moveup;Move Up]") end
- if mem.editingfloor > 1 then fs("button[8,8;2,1;movedown;Move Down") end
+ local maxfloors = tonumber(core.settings:get("celevator.max_landings")) or 100
+ if #mem.params.floornames < maxfloors then fs("button[8,2;2,1;add;"..S("New Floor").."]") end
+ fs("button[8,3.5;2,1;edit;"..S("Edit Floor").."]")
+ if #mem.params.floornames > 2 then fs("button[8,5;2,1;remove;"..S("Remove Floor").."]") end
+ if mem.editingfloor < #mem.params.floornames then fs("button[8,6.5;2,1;moveup;"..S("Move Up").."]") end
+ if mem.editingfloor > 1 then fs("button[8,8;2,1;movedown;"..S("Move Down").."]") end
elseif mem.screenstate == "oobe_floortable_edit" or mem.screenstate == "floortable_edit" then
if mem.screenstate == "oobe_floortable_edit" then
- fs("button[7,10.5;2,1;back;OK]")
- fs("label[1,5;The Floor Height is the distance (in meters/nodes) from the floor level of this floor to the floor level of the next floor.]")
- fs("label[1,5.5;(not used at the highest floor)]")
- fs("label[1,6.5;The Floor Name is how the floor will be displayed on the position indicators.]")
+ fs("button[7,10.5;2,1;back;"..S("OK").."]")
+ local help1 = S("The Floor Height is the distance (in meters/nodes) from the floor level of this floor to the floor level of the next floor.")
+ local help2 = S("(not used at the highest floor)")
+ local help3 = S("The Floor Name is how the floor will be displayed on the position indicators.")
+ fs("label[1,5;"..help1.."]")
+ fs("label[1,5.5;"..help2.."]")
+ fs("label[1,6.5;"..help3.."]")
else
- fs("button[7,10.5;2,1;save;Save]")
+ fs("button[7,10.5;2,1;save;"..S("Save").."]")
end
- fs("label[1,1;Editing floor "..tostring(mem.editingfloor).."]")
- fs("field[1,3;3,1;height;Floor Height;"..tostring(mem.params.floorheights[mem.editingfloor]).."]")
- fs("field[5,3;3,1;name;Floor Name;"..minetest.formspec_escape(mem.params.floornames[mem.editingfloor]).."]")
+ fs("label[1,1;"..S("Editing Floor @1",tostring(mem.editingfloor)).."]")
+ fs("field[1,3;3,1;height;"..S("Floor Height")..";"..tostring(mem.params.floorheights[mem.editingfloor]).."]")
+ fs("field[5,3;3,1;name;"..S("Floor Name")..";"..core.formspec_escape(mem.params.floornames[mem.editingfloor]).."]")
elseif mem.screenstate == "oobe_connections" or mem.screenstate == "connections" then
if mem.screenstate == "oobe_connections" then
- fs("label[1,1;Connect to each car in the group, then click Done.]")
- fs("button[1,10;2,1;back;< Back]")
- if #mem.params.carids > 0 then fs("button[13,10;2,1;next;Done >]") end
+ fs("label[1,1;"..S("Connect to each car in the group, then click Done.").."]")
+ fs("button[1,10;2,1;back;"..S("< Back").."]")
+ if #mem.params.carids > 0 then fs("button[13,10;2,1;next;"..S("Done").."]") end
else
- fs("label[1,1;EDIT CONNECTIONS]")
- if #mem.params.carids > 0 then fs("button[1,10;2,1;next;Done]") end
+ fs("label[1,1;"..S("EDIT CONNECTIONS").."]")
+ if #mem.params.carids > 0 then fs("button[1,10;2,1;next;"..S("Done").."]") end
end
if #mem.params.carids > 0 then
fs("textlist[1,2;6,7;connection;")
for i=#mem.params.carids,1,-1 do
- fs(string.format("Car %d - ID #%d",i,mem.params.carids[i])..(i==1 and "" or ","))
+ local connectiontext = S("Car @1 - ID #@2",i,mem.params.carids[i])
+ fs(connectiontext..(i==1 and "" or ","))
end
fs(";"..tostring(#mem.params.carids-mem.editingconnection+1)..";false]")
else
- fs("label[1,2;No Connections]")
+ fs("label[1,2;"..S("No Connections").."]")
end
- if #mem.params.carids < 16 then fs("button[8,2;3,1;add;New Connection]") end
- if #mem.params.carids > 0 then fs("button[8,3.5;3,1;edit;Edit Connection]") end
- if #mem.params.carids > 0 then fs("button[8,5;3,1;remove;Remove Connection]") end
+ local maxcars = tonumber(core.settings:get("celevator.max_group")) or 16
+ if #mem.params.carids < maxcars then fs("button[8,2;3,1;add;"..S("New Connection").."]") end
+ if #mem.params.carids > 0 then fs("button[8,3.5;3,1;edit;"..S("Edit Connection").."]") end
+ if #mem.params.carids > 0 then fs("button[8,5;3,1;remove;"..S("Remove Connection").."]") end
elseif mem.screenstate == "oobe_newconnection" or mem.screenstate == "newconnection" then
local numfloors = 0
for _,v in ipairs(mem.newconnfloors) do
if v then numfloors = numfloors + 1 end
end
if mem.screenstate == "oobe_newconnection" then
- fs("label[1,1;Enter the car ID and select the floors served (click them to toggle), then click Connect.]")
- fs("label[1,1.3;You must select at least two floors.]")
- fs("button[1,10;2,1;back;< Back]")
- if numfloors >= 2 then fs("button[13,10;2,1;connect;Connect >]") end
+ fs("label[1,1;"..S("Enter the car ID and select the floors served (click them to toggle), then click Connect.").."]")
+ fs("label[1,1.3;"..S("You must select at least two floors.").."]")
+ fs("button[1,10;2,1;back;"..S("< Back").."]")
+ if numfloors >= 2 then fs("button[13,10;2,1;connect;"..S("Connect").."]") end
else
- fs("label[1,1;NEW CONNECTION]")
- fs("button[1,10;2,1;back;Back]")
- if numfloors >= 2 then fs("button[13,10;2,1;connect;Connect]") end
+ fs("label[1,1;"..S("NEW CONNECTION").."]")
+ fs("button[1,10;2,1;back;"..S("Back").."]")
+ if numfloors >= 2 then fs("button[13,10;2,1;connect;"..S("Connect").."]") end
end
fs("textlist[8,2;6,7;floors;")
for i=#mem.params.floornames,1,-1 do
- fs(string.format("%s - %s",minetest.formspec_escape(mem.params.floornames[i]),mem.newconnfloors[i] and "YES" or "NO")..(i==1 and "" or ","))
+ fs(string.format("%s - %s",core.formspec_escape(mem.params.floornames[i]),mem.newconnfloors[i] and S("YES") or S("NO"))..(i==1 and "" or ","))
end
fs(";0;false]")
- fs("field[2,3;4,1;carid;Car ID;]")
+ fs("field[2,3;4,1;carid;"..S("Car ID")..";]")
elseif mem.screenstate == "oobe_connection" or mem.screenstate == "connection" then
local numfloors = 0
for _,v in ipairs(mem.newconnfloors) do
if v then numfloors = numfloors + 1 end
end
if mem.screenstate == "oobe_newconnection" then
- fs("label[1,1;Enter the car ID and select the floors served (click them to toggle), then click Connect.]")
- fs("label[1,1.3;You must select at least two floors.]")
- fs("button[1,10;2,1;back;< Back]")
- if numfloors >= 2 then fs("button[13,10;2,1;save;Save >]") end
+ fs("label[1,1;"..S("Enter the car ID and select the floors served (click them to toggle), then click Connect.").."]")
+ fs("label[1,1.3;"..S("You must select at least two floors.").."]")
+ fs("button[1,10;2,1;back;"..S("< Back").."]")
+ if numfloors >= 2 then fs("button[13,10;2,1;save;"..S("Save").."]") end
else
- fs("label[1,1;EDIT CONNECTION]")
- fs("button[1,10;2,1;back;< Back]")
- if numfloors >= 2 then fs("button[13,10;2,1;save;Save >]") end
+ fs("label[1,1;"..S("EDIT CONNECTION").."]")
+ fs("button[1,10;2,1;back;"..S("< Back").."]")
+ if numfloors >= 2 then fs("button[13,10;2,1;save;"..S("Save").."]") end
end
fs("textlist[8,2;6,7;floors;")
for i=#mem.params.floornames,1,-1 do
- fs(string.format("%s - %s",minetest.formspec_escape(mem.params.floornames[i]),mem.newconnfloors[i] and "YES" or "NO")..(i==1 and "" or ","))
+ fs(string.format("%s - %s",core.formspec_escape(mem.params.floornames[i]),mem.newconnfloors[i] and S("YES") or S("NO"))..(i==1 and "" or ","))
end
fs(";0;false]")
- fs("label[2,3;Car ID: "..mem.params.carids[mem.editingconnection].."]")
+ fs("label[2,3;"..S("Car ID: @1",mem.params.carids[mem.editingconnection]).."]")
elseif mem.screenstate == "oobe_connecting" or mem.screenstate == "connecting" then
- fs("label[1,1;Connecting to controller...]")
+ fs("label[1,1;"..S("Connecting to controller...").."]")
elseif mem.screenstate == "oobe_connectionfailed" or mem.screenstate == "connectionfailed" then
- fs("label[4,4;Connection timed out!]")
- fs("label[4,5;Make sure the car ID is correct and]")
- fs("label[4,5.5;that the controller is ready to pair.]")
- fs("button[1,10;2,1;back;< Back]")
+ fs("label[4,4;"..S("Connection timed out!").."]")
+ fs("label[4,5;"..S("Make sure the car ID is correct and\nthat the controller is ready to connect.").."]")
+ fs("button[1,10;2,1;back;"..S("< Back").."]")
elseif mem.screenstate == "status" then
if not mem.screenpage then mem.screenpage = 1 end
- fs("label[1,1;GROUP DISPLAY]")
+ fs("label[1,1;"..S("GROUP DISPLAY").."]")
fs("box[1.5,1.5;0.1,10;#AAAAAAFF]")
fs("box[18.5,1.5;0.1,10;#AAAAAAFF]")
- fs("label[0.55,11.5;UP]")
- fs("label[18.85,11.5;DOWN]")
- fs("button[15,0.5;2,1;menu;Menu]")
+ fs("image[0.45,11;0.2,0.4;celevator_menu_small_arrow.png]")
+ fs("image[19.4,11;0.2,0.4;celevator_menu_small_arrow.png^[transformFY]")
+ fs("button[15,0.5;2,1;menu;"..S("Menu").."]")
fs("style_type[image_button;font=mono;font_size=*0.75]")
for car=1,#mem.params.carids,1 do
local xp = 1.7+(car-1)
local carid = mem.params.carids[car]
local carstate = mem.carstatus[carid].state
- fs(string.format("label[%f,11;CAR %d]",xp,car))
- fs(string.format("label[%f,11.35;%s]",xp+0.1,minetest.colorize("#ff5555",(carstate == "normal" and " IN" or "OUT"))))
+ fs(string.format("label[%f,11;%s]",xp,S("CAR @1",car)))
+ fs(string.format("label[%f,11.35;%s]",xp+0.1,core.colorize("#ff5555",(carstate == "normal" and S(" IN") or S("OUT")))))
end
local lowestfloor = (mem.screenpage-1)*10+1
for i=1,math.min(10,#mem.params.floornames-lowestfloor+1),1 do
@@ -1041,11 +1077,11 @@ elseif mem.screenstate == "status" then
local floor = i+lowestfloor-1
fs(string.format("label[0.9,%f;%s]",yp+0.35,mem.params.floornames[floor]))
local uplabel = ""
- if mem.upcalls[floor] then uplabel = minetest.colorize("#55FF55",math.floor(mem.upeta[floor] or 0)) end
+ if mem.upcalls[floor] then uplabel = core.colorize("#55FF55",math.floor(mem.upeta[floor] or 0)) end
if floor < #mem.params.floornames then fs(string.format("image_button[0.15,%f;0.75,0.75;celevator_fs_bg.png;upcall%d;%s]",yp,floor,uplabel)) end
fs(string.format("label[18.65,%f;%s]",yp+0.35,mem.params.floornames[floor]))
local dnlabel = ""
- if mem.dncalls[floor] then dnlabel = minetest.colorize("#FF5555",math.floor(mem.dneta[floor] or 0)) end
+ if mem.dncalls[floor] then dnlabel = core.colorize("#FF5555",math.floor(mem.dneta[floor] or 0)) end
if floor > 1 then fs(string.format("image_button[19.1,%f;0.75,0.75;celevator_fs_bg.png;dncall%d;%s]",yp,floor,dnlabel)) end
for car=1,#mem.params.carids,1 do
local xp = 1.7+(car-1)
@@ -1053,10 +1089,10 @@ elseif mem.screenstate == "status" then
local carfloor = realtocarfloor(carid,floor)
if carfloor then
local ccdot = mem.carstatus[carid].carcalls[carfloor] and "*" or ""
- local groupup = mem.carstatus[carid].groupupcalls[carfloor] and minetest.colorize("#55FF55","^") or ""
- local swingup = mem.carstatus[carid].swingupcalls[carfloor] and minetest.colorize("#FFFF55","^") or ""
- local swingdn = mem.carstatus[carid].swingdncalls[carfloor] and minetest.colorize("#FFFF55","v") or ""
- local groupdn = mem.carstatus[carid].groupdncalls[carfloor] and minetest.colorize("#FF5555","v") or ""
+ local groupup = mem.carstatus[carid].groupupcalls[carfloor] and core.colorize("#55FF55","^") or ""
+ local swingup = mem.carstatus[carid].swingupcalls[carfloor] and core.colorize("#FFFF55","^") or ""
+ local swingdn = mem.carstatus[carid].swingdncalls[carfloor] and core.colorize("#FFFF55","v") or ""
+ local groupdn = mem.carstatus[carid].groupdncalls[carfloor] and core.colorize("#FF5555","v") or ""
ccdot = groupup..swingup..ccdot..swingdn..groupdn
if getpos(carid) == floor then
local cargraphics = {
@@ -1068,9 +1104,9 @@ elseif mem.screenstate == "status" then
}
ccdot = cargraphics[mem.carstatus[carid].doorstate]
if mem.carstatus[carid].direction == "up" then
- ccdot = minetest.colorize("#55FF55",ccdot)
+ ccdot = core.colorize("#55FF55",ccdot)
elseif mem.carstatus[carid].direction == "down" then
- ccdot = minetest.colorize("#FF5555",ccdot)
+ ccdot = core.colorize("#FF5555",ccdot)
end
end
fs(string.format("image_button[%f,%f;0.75,0.75;celevator_fs_bg.png;carcall%02d%d;%s]",xp,yp,car,floor,ccdot))
@@ -1084,12 +1120,12 @@ elseif mem.screenstate == "status" then
fs("image_button[5,0.5;0.75,0.75;celevator_menu_arrow.png;scrollup;;false;false;celevator_menu_arrow.png]")
end
elseif mem.screenstate == "menu" then
- fs("label[1,1;MAIN MENU]")
- fs("button[1,3;3,1;floortable;Edit Floor Table]")
- fs("button[1,4.5;3,1;connections;Edit Connections]")
- fs("button[1,10;3,1;back;< Back]")
+ fs("label[1,1;"..S("MAIN MENU").."]")
+ fs("button[1,3;3,1;floortable;"..S("Edit Floor Table").."]")
+ fs("button[1,4.5;3,1;connections;"..S("Edit Connections").."]")
+ fs("button[1,10;3,1;back;"..S("< Back").."]")
end
-mem.infotext = string.format("ID: %d",mem.carid)
+mem.infotext = S("ID: @1",mem.carid)
return pos,mem,changedinterrupts
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..ac707d8 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..3e2b464 100644
--- a/docs/file_sources
+++ b/docs/file_sources
@@ -1,4 +1,10 @@
-All code: Written by cheapie
+Code: Written by the following contributors:
+* cheapie
+* j-r (Jürgen Rühle)
+
+Locales: Translated by the following contributors:
+* cheapie (es)
+* pgimeno (es)
All textures: Hand-drawn by cheapie using GIMP
@@ -25,6 +31,10 @@ Originally from "elevator bell dings closeup nice.flac" by kyles on Freesound, o
https://freesound.org/people/kyles/sounds/453980/
Edited by cheapie.
+* celevator_chime2_up.ogg and celevator_chime2_down.ogg
+Synthesized in Faust Music Creator by cheapie.
+Edited by cheapie.
+
* celevator_door_close.ogg, celevator_door_open.ogg, and celevator_door_reverse.ogg
Originally from "elevator doors open close.wav" by omsomaque on Freesound, originally licensed under CC0.
https://freesound.org/people/omsomaque/sounds/584911/
@@ -44,3 +54,11 @@ Edited by cheapie.
Originally from "Fujitec Traction Elevator Machine Room" by ElevDSM on YouTube, explicit permission has been obtained from the author to use these sounds here and distribute them under mod's license.
https://www.youtube.com/watch?v=0rPZrkEreAo
Edited by cheapie.
+
+* celevator_alarm.ogg
+Originally from "School bell.wav" by deleted_user_7020630 on Freesound, originally licensed under CC0.
+https://freesound.org/people/deleted_user_7020630/sounds/378394/
+Edited by cheapie.
+
+* celevator_phone.ogg
+Synthesized in Audacity by cheapie.
diff --git a/door_2speedglass.lua b/door_2speedglass.lua
new file mode 100644
index 0000000..22eafab
--- /dev/null
+++ b/door_2speedglass.lua
@@ -0,0 +1,641 @@
+celevator.doors.twospeedglass = {}
+
+local S = core.get_translator("celevator")
+
+core.register_node("celevator:hwdoor_fast_glass_bottom",{
+ description = S("Glass 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_glass_topbottom.png^[transformFY",
+ "celevator_door_glass_topbottom.png^[transformFY",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ _celevator_hwdoor_root = 1,
+ oddly_breakable_by_hand = 2,
+ },
+ drop = "celevator:hwdoor_glass",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ use_texture_alpha = "clip",
+ 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 = core.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 = core.dir_to_yaw(core.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_glass_%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 core.get_node(piecepos).name == piecename then core.remove_node(piecepos) end
+ end
+ end
+ end,
+ _celevator_doortype = "twospeedglass",
+})
+
+core.register_node("celevator:hwdoor_fast_glass_middle",{
+ description = S("Glass 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_glass_middle.png",
+ "celevator_door_glass_middle.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ use_texture_alpha = "clip",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.4,0.5,0.5,0.5},
+ },
+ },
+ _celevator_doortype = "twospeedglass",
+})
+
+core.register_node("celevator:hwdoor_fast_glass_top",{
+ description = S("Glass 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_glass_topbottom.png",
+ "celevator_door_glass_topbottom.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ use_texture_alpha = "clip",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.4,0.5,0.5,0.5},
+ },
+ },
+ _celevator_doortype = "twospeedglass",
+})
+
+core.register_node("celevator:hwdoor_slow_glass_bottom",{
+ description = S("Glass 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_glass_topbottom.png^[transformFY",
+ "celevator_door_glass_topbottom.png^[transformFY",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ use_texture_alpha = "clip",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.3,0.5,0.5,0.4},
+ },
+ },
+ _celevator_doortype = "twospeedglass",
+})
+
+core.register_node("celevator:hwdoor_slow_glass_middle",{
+ description = S("Glass 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_glass_middle.png",
+ "celevator_door_glass_middle.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ use_texture_alpha = "clip",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.3,0.5,0.5,0.4},
+ },
+ },
+ _celevator_doortype = "twospeedglass",
+})
+
+core.register_node("celevator:hwdoor_slow_glass_top",{
+ description = S("Glass 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_glass_topbottom.png",
+ "celevator_door_glass_topbottom.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ use_texture_alpha = "clip",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.3,0.5,0.5,0.4},
+ },
+ },
+ _celevator_doortype = "twospeedglass",
+})
+
+core.register_node("celevator:hwdoor_glass",{
+ description = S("Glass Elevator Hoistway Door"),
+ paramtype2 = "4dir",
+ buildable_to = true,
+ inventory_image = "celevator_door_glass_inventory.png",
+ wield_image = "celevator_door_glass_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
+ core.remove_node(pos)
+ return true
+ end
+ local name = player:get_player_name()
+ local newnode = core.get_node(pos)
+ local facedir = core.dir_to_yaw(core.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 placeoffset = vector.new(x,y,0)
+ local placepos = vector.add(pos,vector.rotate_around_axis(placeoffset,vector.new(0,1,0),facedir))
+ local replaces = core.get_node(placepos).name
+ if not (core.registered_nodes[replaces] and core.registered_nodes[replaces].buildable_to) then
+ local errormsg = S("Can't place door here - position @1m to the right and @2m up is blocked!",x,y)
+ core.chat_send_player(name,errormsg)
+ core.remove_node(pos)
+ return true
+ end
+ if core.is_protected(placepos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ local errormsg = S("Can't place door here - position @1m to the right and @2m up is protected!",x,y)
+ core.chat_send_player(name,errormsg)
+ core.record_protection_violation(placepos,name)
+ core.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_glass_%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))
+ core.set_node(placepos,{name=piecename,param2=newnode.param2})
+ if y==0 then
+ celevator.doors.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 = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.get_meta(carpos):set_string("doortype","glass")
+ celevator.doors.spawncardoors(carpos,core.fourdir_to_dir(newnode.param2),"glass",true)
+ end
+ end,
+})
+
+core.register_lbm({
+ label = "Respawn hoistway door sills (2-speed glass)",
+ name = "celevator:spawn_sill_twospeedglass",
+ nodenames = {
+ "celevator:hwdoor_fast_glass_bottom",
+ "celevator:hwdoor_slow_glass_bottom",
+ },
+ run_at_every_load = true,
+ action = celevator.doors.placesill,
+})
+
+celevator.doors.twospeedglass.spawncardoors = function(pos,dir,replace)
+ local refs = {}
+ for x=2,1,-1 do
+ for y=1,3,1 do
+ local yaw = core.dir_to_yaw(dir)+math.pi
+ 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])
+ if replace then
+ local oldrefs = core.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 = core.add_entity(doorpos,"celevator:car_door")
+ ref:set_yaw(yaw)
+ ref:set_properties({
+ wield_item = nname,
+ })
+ table.insert(refs,ref)
+ end
+ end
+ return refs
+end
+
+function celevator.doors.twospeedglass.hwopen(pos,drivepos)
+ celevator.doors.hwdoor_step_enabled = true
+ local hwdoors_moving = core.deserialize(celevator.storage:get_string("hwdoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ if not hwdoors_moving[hash] then
+ local param2 = celevator.get_node(pos).param2
+ local fdir = core.fourdir_to_dir(param2)
+ local otherpanel = vector.add(pos,vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2))
+ local positions = {
+ pos,
+ vector.add(pos,vector.new(0,1,0)),
+ vector.add(pos,vector.new(0,2,0)),
+ otherpanel,
+ vector.add(otherpanel,vector.new(0,1,0)),
+ vector.add(otherpanel,vector.new(0,2,0)),
+ }
+ local oldnodes = {}
+ for i,position in ipairs(positions) do
+ oldnodes[i] = celevator.get_node(position)
+ end
+ local erefs = celevator.drives.entity.nodestoentities(positions,"celevator:hwdoor_moving")
+ hwdoors_moving[hash] = {
+ direction = "open",
+ positions = positions,
+ nodes = oldnodes,
+ time = 0,
+ opendir = vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2),
+ drivepos = drivepos,
+ param2 = param2,
+ doortype = "twospeedglass",
+ }
+ celevator.doors.erefs[hash] = erefs
+ celevator.storage:set_string("hwdoors_moving",core.serialize(hwdoors_moving))
+ core.set_node(pos,{name="celevator:hwdoor_placeholder",param2=param2})
+ local pmeta = celevator.get_meta(pos)
+ pmeta:set_string("data",core.serialize(hwdoors_moving[hash]))
+ pmeta:set_string("state","opening")
+ pmeta:set_string("doortype","twospeedglass")
+ local carpos = vector.add(pos,fdir)
+ local carndef = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.doors.caropen(carpos)
+ end
+ elseif hwdoors_moving[hash].direction == "close" then
+ hwdoors_moving[hash].direction = "open"
+ hwdoors_moving[hash].time = math.pi-hwdoors_moving[hash].time
+ celevator.storage:set_string("hwdoors_moving",core.serialize(hwdoors_moving))
+ local fdir = core.fourdir_to_dir(hwdoors_moving[hash].param2)
+ local carpos = vector.add(pos,fdir)
+ local carndef = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.doors.caropen(carpos)
+ end
+ core.set_node(pos,{name="celevator:hwdoor_placeholder",param2=hwdoors_moving[hash].param2})
+ local pmeta = celevator.get_meta(pos)
+ pmeta:set_string("data",core.serialize(hwdoors_moving[hash]))
+ pmeta:set_string("state","opening")
+ pmeta:set_string("doortype","twospeedglass")
+ end
+end
+
+function celevator.doors.twospeedglass.hwclose(pos,drivepos,nudge)
+ celevator.doors.hwdoor_step_enabled = true
+ local hwdoors_moving = core.deserialize(celevator.storage:get_string("hwdoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ if hwdoors_moving[hash] then
+ return
+ end
+ local pmeta = celevator.get_meta(pos)
+ local state = pmeta:get_string("state")
+ if state ~= "open" then return end
+ local fdir = core.fourdir_to_dir(celevator.get_node(pos).param2)
+ local carpos = vector.add(pos,fdir)
+ local carndef = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.doors.carclose(carpos,nudge)
+ end
+ local data = core.deserialize(pmeta:get_string("data"))
+ if not data then return end
+ for i=1,6,1 do
+ core.set_node(data.positions[i],data.nodes[i])
+ end
+ data.direction = "close"
+ data.time = 0
+ data.drivepos = drivepos
+ data.nudging = nudge
+ local erefs = celevator.drives.entity.nodestoentities(data.positions,"celevator:hwdoor_moving")
+ local foffset = vector.multiply(data.opendir,2)
+ local soffset = data.opendir
+ for i=1,3,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),foffset))
+ end
+ for i=4,6,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),soffset))
+ end
+ celevator.doors.erefs[hash] = erefs
+ hwdoors_moving[hash] = data
+ celevator.storage:set_string("hwdoors_moving",core.serialize(hwdoors_moving))
+end
+
+function celevator.doors.twospeedglass.hwstep(hash,data,dtime,hwdoors_moving)
+ local present = celevator.doors.erefs[hash]
+ if present then
+ for i=1,6,1 do
+ if not celevator.doors.erefs[hash][i]:get_pos() then
+ present = false
+ break
+ end
+ end
+ end
+ if present then
+ if data.direction == "open" then
+ data.time = data.time+dtime
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2))
+ end
+ if data.time >= math.pi then
+ for i=1,6,1 do
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ celevator.get_meta(data.positions[1]):set_string("state","open")
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","open") end
+ hwdoors_moving[hash] = nil
+ end
+ elseif data.direction == "close" then
+ local speed = 0.66
+ if data.nudging then speed = 0.2 end
+ data.time = data.time+(speed*dtime)
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*-speed))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*-speed))
+ end
+ if data.time >= math.pi then
+ for i=1,6,1 do
+ celevator.doors.erefs[hash][i]:set_pos(data.positions[i])
+ end
+ celevator.drives.entity.entitiestonodes(celevator.doors.erefs[hash])
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","closed") end
+ hwdoors_moving[hash] = nil
+ end
+ end
+ else
+ if data.direction == "open" then
+ for i=1,6,1 do
+ if celevator.doors.erefs[hash] then
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ end
+ celevator.get_meta(data.positions[1]):set_string("state","open")
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","open") end
+ hwdoors_moving[hash] = nil
+ elseif data.direction == "close" then
+ for i=1,6,1 do
+ core.set_node(data.positions[i],data.nodes[i])
+ end
+ celevator.get_meta(data.positions[1]):set_string("state","closed")
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","closed") end
+ hwdoors_moving[hash] = nil
+ end
+ end
+end
+
+function celevator.doors.twospeedglass.caropen(pos)
+ celevator.doors.cardoor_step_enabled = true
+ local cardoors_moving = core.deserialize(celevator.storage:get_string("cardoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ local cartimer = core.get_node_timer(pos)
+ cartimer:start(0.25)
+ if not cardoors_moving[hash] then
+ local fdir = core.fourdir_to_dir(celevator.get_node(pos).param2)
+ local otherpanel = vector.add(pos,vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2))
+ local positions = {
+ pos,
+ vector.add(pos,vector.new(0,1,0)),
+ vector.add(pos,vector.new(0,2,0)),
+ otherpanel,
+ vector.add(otherpanel,vector.new(0,1,0)),
+ vector.add(otherpanel,vector.new(0,2,0)),
+ }
+ local erefs = {}
+ for _,dpos in ipairs(positions) do
+ local objs = core.get_objects_inside_radius(dpos,0.5)
+ for _,obj in pairs(objs) do
+ if obj:get_luaentity() and obj:get_luaentity().name == "celevator:car_door" then
+ table.insert(erefs,obj)
+ end
+ end
+ end
+ cardoors_moving[hash] = {
+ direction = "open",
+ positions = positions,
+ time = 0,
+ opendir = vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2),
+ doortype = "twospeedglass",
+ }
+ core.sound_play("celevator_door_open",{
+ pos = pos,
+ gain = 0.4,
+ max_hear_distance = 10
+ },true)
+ celevator.doors.erefs[hash] = erefs
+ celevator.storage:set_string("cardoors_moving",core.serialize(cardoors_moving))
+ local meta = celevator.get_meta(pos)
+ meta:set_string("doordata",core.serialize(cardoors_moving[hash]))
+ meta:set_string("doorstate","opening")
+ elseif cardoors_moving[hash].direction == "close" then
+ if cardoors_moving[hash].soundhandle then
+ core.sound_stop(cardoors_moving[hash].soundhandle)
+ end
+ core.sound_play("celevator_door_reverse",{
+ pos = pos,
+ gain = 1,
+ max_hear_distance = 10
+ },true)
+ core.sound_play("celevator_door_open",{
+ pos = pos,
+ gain = 0.4,
+ start_time = math.max(0,2.75-cardoors_moving[hash].time),
+ max_hear_distance = 10
+ },true)
+ cardoors_moving[hash].direction = "open"
+ cardoors_moving[hash].time = math.pi-cardoors_moving[hash].time
+ celevator.storage:set_string("cardoors_moving",core.serialize(cardoors_moving))
+ end
+end
+
+function celevator.doors.twospeedglass.carclose(pos,nudge)
+ celevator.doors.cardoor_step_enabled = true
+ local cardoors_moving = core.deserialize(celevator.storage:get_string("cardoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ if cardoors_moving[hash] then
+ return
+ end
+ local meta = celevator.get_meta(pos)
+ local state = meta:get_string("doorstate")
+ if state ~= "open" then return end
+ local data = core.deserialize(meta:get_string("doordata"))
+ if not data then return end
+ local dir = core.fourdir_to_dir(celevator.get_node(pos).param2)
+ data.direction = "close"
+ data.time = 0
+ data.doortype = "twospeedglass"
+ local erefs = celevator.doors.spawncardoors(pos,dir,"twospeedglass")
+ local soffset = data.opendir
+ local foffset = vector.multiply(soffset,2)
+ for i=1,3,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),foffset))
+ end
+ for i=4,6,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),soffset))
+ end
+ celevator.doors.erefs[hash] = erefs
+ if nudge then
+ data.soundhandle = core.sound_play("celevator_nudge",{
+ pos = pos,
+ gain = 0.75,
+ max_hear_distance = 10
+ })
+ else
+ data.soundhandle = core.sound_play("celevator_door_close",{
+ pos = pos,
+ gain = 0.3,
+ max_hear_distance = 10
+ })
+ end
+ data.nudging = nudge
+ cardoors_moving[hash] = data
+ celevator.storage:set_string("cardoors_moving",core.serialize(cardoors_moving))
+end
+
+function celevator.doors.twospeedglass.carstep(hash,data,dtime,cardoors_moving)
+ local present = celevator.doors.erefs[hash]
+ if present then
+ for i=1,6,1 do
+ if not (celevator.doors.erefs[hash][i] and celevator.doors.erefs[hash][i]:get_pos()) then
+ present = false
+ break
+ end
+ end
+ end
+ if present then
+ if data.direction == "open" then
+ data.time = data.time+dtime
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2))
+ end
+ if data.time >= math.pi then
+ for i=1,6,1 do
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ celevator.get_meta(data.positions[1]):set_string("doorstate","open")
+ cardoors_moving[hash] = nil
+ end
+ elseif data.direction == "close" then
+ local speed = 0.66
+ if data.nudging then speed = 0.2 end
+ data.time = data.time+(speed*dtime)
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*-speed))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*-speed))
+ end
+ if data.time >= math.pi then
+ for _,ref in ipairs(celevator.doors.erefs[hash]) do
+ ref:remove()
+ end
+ local carmeta = celevator.get_meta(data.positions[1])
+ carmeta:set_string("doorstate","closed")
+ cardoors_moving[hash] = nil
+ local cartimer = core.get_node_timer(data.positions[1])
+ cartimer:stop()
+ local fdir = core.facedir_to_dir(core.get_node(data.positions[1]).param2)
+ celevator.doors.spawncardoors(data.positions[1],fdir,"twospeedglass")
+ end
+ end
+ else
+ if data.direction == "open" then
+ for i=1,6,1 do
+ if celevator.doors.erefs[hash] and celevator.doors.erefs[hash][i] then
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ end
+ celevator.get_meta(data.positions[1]):set_string("doorstate","open")
+ cardoors_moving[hash] = nil
+ elseif data.direction == "close" then
+ local fdir = core.fourdir_to_dir(celevator.get_node(data.positions[1]).param2)
+ celevator.doors.spawncardoors(data.positions[1],vector.rotate_around_axis(fdir,vector.new(0,1,0),math.pi),"twospeedglass")
+ celevator.get_meta(data.positions[1]):set_string("doorstate","closed")
+ cardoors_moving[hash] = nil
+ end
+ end
+end
diff --git a/door_2speedmetal.lua b/door_2speedmetal.lua
new file mode 100644
index 0000000..b074722
--- /dev/null
+++ b/door_2speedmetal.lua
@@ -0,0 +1,635 @@
+celevator.doors.twospeedmetal = {}
+
+local S = core.get_translator("celevator")
+
+core.register_node("celevator:hwdoor_fast_steel_bottom",{
+ description = S("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 = core.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 = core.dir_to_yaw(core.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 core.get_node(piecepos).name == piecename then core.remove_node(piecepos) end
+ end
+ end
+ end,
+ _celevator_doortype = "twospeedmetal",
+})
+
+core.register_node("celevator:hwdoor_fast_steel_middle",{
+ description = S("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},
+ },
+ },
+ _celevator_doortype = "twospeedmetal",
+})
+
+core.register_node("celevator:hwdoor_fast_steel_top",{
+ description = S("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},
+ },
+ },
+ _celevator_doortype = "twospeedmetal",
+})
+
+core.register_node("celevator:hwdoor_slow_steel_bottom",{
+ description = S("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},
+ },
+ },
+ _celevator_doortype = "twospeedmetal",
+})
+
+core.register_node("celevator:hwdoor_slow_steel_middle",{
+ description = S("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},
+ },
+ },
+ _celevator_doortype = "twospeedmetal",
+})
+
+core.register_node("celevator:hwdoor_slow_steel_top",{
+ description = S("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},
+ },
+ },
+ _celevator_doortype = "twospeedmetal",
+})
+
+core.register_node("celevator:hwdoor_steel",{
+ description = S("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
+ core.remove_node(pos)
+ return true
+ end
+ local name = player:get_player_name()
+ local newnode = core.get_node(pos)
+ local facedir = core.dir_to_yaw(core.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 placeoffset = vector.new(x,y,0)
+ local placepos = vector.add(pos,vector.rotate_around_axis(placeoffset,vector.new(0,1,0),facedir))
+ local replaces = core.get_node(placepos).name
+ if not (core.registered_nodes[replaces] and core.registered_nodes[replaces].buildable_to) then
+ local errormsg = S("Can't place door here - position @1m to the right and @2m up is blocked!",x,y)
+ core.chat_send_player(name,errormsg)
+ core.remove_node(pos)
+ return true
+ end
+ if core.is_protected(placepos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ local errormsg = S("Can't place door here - position @1m to the right and @2m up is protected!",x,y)
+ core.chat_send_player(name,errormsg)
+ core.record_protection_violation(placepos,name)
+ core.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))
+ core.set_node(placepos,{name=piecename,param2=newnode.param2})
+ if y==0 then
+ celevator.doors.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 = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.get_meta(carpos):set_string("doortype","steel")
+ celevator.doors.spawncardoors(carpos,core.fourdir_to_dir(newnode.param2),"steel",true)
+ end
+ end,
+})
+
+core.register_lbm({
+ label = "Respawn hoistway door sills (2-speed metal)",
+ name = "celevator:spawn_sill_twospeedmetal",
+ nodenames = {
+ "celevator:hwdoor_fast_steel_bottom",
+ "celevator:hwdoor_slow_steel_bottom",
+ },
+ run_at_every_load = true,
+ action = celevator.doors.placesill,
+})
+
+celevator.doors.twospeedmetal.spawncardoors = function(pos,dir,replace)
+ local refs = {}
+ for x=2,1,-1 do
+ for y=1,3,1 do
+ local yaw = core.dir_to_yaw(dir)+math.pi
+ 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_steel_%s",xnames[x],ynames[y])
+ if replace then
+ local oldrefs = core.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 = core.add_entity(doorpos,"celevator:car_door")
+ ref:set_yaw(yaw)
+ ref:set_properties({
+ wield_item = nname,
+ })
+ table.insert(refs,ref)
+ end
+ end
+ return refs
+end
+
+function celevator.doors.twospeedmetal.hwopen(pos,drivepos)
+ celevator.doors.hwdoor_step_enabled = true
+ local hwdoors_moving = core.deserialize(celevator.storage:get_string("hwdoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ if not hwdoors_moving[hash] then
+ local param2 = celevator.get_node(pos).param2
+ local fdir = core.fourdir_to_dir(param2)
+ local otherpanel = vector.add(pos,vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2))
+ local positions = {
+ pos,
+ vector.add(pos,vector.new(0,1,0)),
+ vector.add(pos,vector.new(0,2,0)),
+ otherpanel,
+ vector.add(otherpanel,vector.new(0,1,0)),
+ vector.add(otherpanel,vector.new(0,2,0)),
+ }
+ local oldnodes = {}
+ for i,position in ipairs(positions) do
+ oldnodes[i] = celevator.get_node(position)
+ end
+ local erefs = celevator.drives.entity.nodestoentities(positions,"celevator:hwdoor_moving")
+ hwdoors_moving[hash] = {
+ direction = "open",
+ positions = positions,
+ nodes = oldnodes,
+ time = 0,
+ opendir = vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2),
+ drivepos = drivepos,
+ param2 = param2,
+ doortype = "twospeedmetal",
+ }
+ celevator.doors.erefs[hash] = erefs
+ celevator.storage:set_string("hwdoors_moving",core.serialize(hwdoors_moving))
+ core.set_node(pos,{name="celevator:hwdoor_placeholder",param2=param2})
+ local pmeta = celevator.get_meta(pos)
+ pmeta:set_string("data",core.serialize(hwdoors_moving[hash]))
+ pmeta:set_string("state","opening")
+ pmeta:set_string("doortype","twospeedmetal")
+ local carpos = vector.add(pos,fdir)
+ local carndef = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.doors.caropen(carpos)
+ end
+ elseif hwdoors_moving[hash].direction == "close" then
+ hwdoors_moving[hash].direction = "open"
+ hwdoors_moving[hash].time = math.pi-hwdoors_moving[hash].time
+ celevator.storage:set_string("hwdoors_moving",core.serialize(hwdoors_moving))
+ local fdir = core.fourdir_to_dir(hwdoors_moving[hash].param2)
+ local carpos = vector.add(pos,fdir)
+ local carndef = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.doors.caropen(carpos)
+ end
+ core.set_node(pos,{name="celevator:hwdoor_placeholder",param2=hwdoors_moving[hash].param2})
+ local pmeta = celevator.get_meta(pos)
+ pmeta:set_string("data",core.serialize(hwdoors_moving[hash]))
+ pmeta:set_string("state","opening")
+ pmeta:set_string("doortype","twospeedmetal")
+ end
+end
+
+function celevator.doors.twospeedmetal.hwclose(pos,drivepos,nudge)
+ celevator.doors.hwdoor_step_enabled = true
+ local hwdoors_moving = core.deserialize(celevator.storage:get_string("hwdoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ if hwdoors_moving[hash] then
+ return
+ end
+ local pmeta = celevator.get_meta(pos)
+ local state = pmeta:get_string("state")
+ if state ~= "open" then return end
+ local fdir = core.fourdir_to_dir(celevator.get_node(pos).param2)
+ local carpos = vector.add(pos,fdir)
+ local carndef = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.doors.carclose(carpos,nudge)
+ end
+ local data = core.deserialize(pmeta:get_string("data"))
+ if not data then return end
+ for i=1,6,1 do
+ core.set_node(data.positions[i],data.nodes[i])
+ end
+ data.direction = "close"
+ data.time = 0
+ data.drivepos = drivepos
+ data.nudging = nudge
+ local erefs = celevator.drives.entity.nodestoentities(data.positions,"celevator:hwdoor_moving")
+ local foffset = vector.multiply(data.opendir,2)
+ local soffset = data.opendir
+ for i=1,3,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),foffset))
+ end
+ for i=4,6,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),soffset))
+ end
+ celevator.doors.erefs[hash] = erefs
+ hwdoors_moving[hash] = data
+ celevator.storage:set_string("hwdoors_moving",core.serialize(hwdoors_moving))
+end
+
+function celevator.doors.twospeedmetal.hwstep(hash,data,dtime,hwdoors_moving)
+ local present = celevator.doors.erefs[hash]
+ if present then
+ for i=1,6,1 do
+ if not celevator.doors.erefs[hash][i]:get_pos() then
+ present = false
+ break
+ end
+ end
+ end
+ if present then
+ if data.direction == "open" then
+ data.time = data.time+dtime
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2))
+ end
+ if data.time >= math.pi then
+ for i=1,6,1 do
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ celevator.get_meta(data.positions[1]):set_string("state","open")
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","open") end
+ hwdoors_moving[hash] = nil
+ end
+ elseif data.direction == "close" then
+ local speed = 0.66
+ if data.nudging then speed = 0.2 end
+ data.time = data.time+(speed*dtime)
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*-speed))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*-speed))
+ end
+ if data.time >= math.pi then
+ for i=1,6,1 do
+ celevator.doors.erefs[hash][i]:set_pos(data.positions[i])
+ end
+ celevator.drives.entity.entitiestonodes(celevator.doors.erefs[hash])
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","closed") end
+ hwdoors_moving[hash] = nil
+ end
+ end
+ else
+ if data.direction == "open" then
+ for i=1,6,1 do
+ if celevator.doors.erefs[hash] then
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ end
+ celevator.get_meta(data.positions[1]):set_string("state","open")
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","open") end
+ hwdoors_moving[hash] = nil
+ elseif data.direction == "close" then
+ for i=1,6,1 do
+ core.set_node(data.positions[i],data.nodes[i])
+ end
+ celevator.get_meta(data.positions[1]):set_string("state","closed")
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","closed") end
+ hwdoors_moving[hash] = nil
+ end
+ end
+end
+
+function celevator.doors.twospeedmetal.caropen(pos)
+ celevator.doors.cardoor_step_enabled = true
+ local cardoors_moving = core.deserialize(celevator.storage:get_string("cardoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ local cartimer = core.get_node_timer(pos)
+ cartimer:start(0.25)
+ if not cardoors_moving[hash] then
+ local fdir = core.fourdir_to_dir(celevator.get_node(pos).param2)
+ local otherpanel = vector.add(pos,vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2))
+ local positions = {
+ pos,
+ vector.add(pos,vector.new(0,1,0)),
+ vector.add(pos,vector.new(0,2,0)),
+ otherpanel,
+ vector.add(otherpanel,vector.new(0,1,0)),
+ vector.add(otherpanel,vector.new(0,2,0)),
+ }
+ local erefs = {}
+ for _,dpos in ipairs(positions) do
+ local objs = core.get_objects_inside_radius(dpos,0.5)
+ for _,obj in pairs(objs) do
+ if obj:get_luaentity() and obj:get_luaentity().name == "celevator:car_door" then
+ table.insert(erefs,obj)
+ end
+ end
+ end
+ cardoors_moving[hash] = {
+ direction = "open",
+ positions = positions,
+ time = 0,
+ opendir = vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2),
+ doortype = "twospeedmetal",
+ }
+ core.sound_play("celevator_door_open",{
+ pos = pos,
+ gain = 0.4,
+ max_hear_distance = 10
+ },true)
+ celevator.doors.erefs[hash] = erefs
+ celevator.storage:set_string("cardoors_moving",core.serialize(cardoors_moving))
+ local meta = celevator.get_meta(pos)
+ meta:set_string("doordata",core.serialize(cardoors_moving[hash]))
+ meta:set_string("doorstate","opening")
+ elseif cardoors_moving[hash].direction == "close" then
+ if cardoors_moving[hash].soundhandle then
+ core.sound_stop(cardoors_moving[hash].soundhandle)
+ end
+ core.sound_play("celevator_door_reverse",{
+ pos = pos,
+ gain = 1,
+ max_hear_distance = 10
+ },true)
+ core.sound_play("celevator_door_open",{
+ pos = pos,
+ gain = 0.4,
+ start_time = math.max(0,2.75-cardoors_moving[hash].time),
+ max_hear_distance = 10
+ },true)
+ cardoors_moving[hash].direction = "open"
+ cardoors_moving[hash].time = math.pi-cardoors_moving[hash].time
+ celevator.storage:set_string("cardoors_moving",core.serialize(cardoors_moving))
+ end
+end
+
+function celevator.doors.twospeedmetal.carclose(pos,nudge)
+ celevator.doors.cardoor_step_enabled = true
+ local cardoors_moving = core.deserialize(celevator.storage:get_string("cardoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ if cardoors_moving[hash] then
+ return
+ end
+ local meta = celevator.get_meta(pos)
+ local state = meta:get_string("doorstate")
+ if state ~= "open" then return end
+ local data = core.deserialize(meta:get_string("doordata"))
+ if not data then return end
+ local dir = core.fourdir_to_dir(celevator.get_node(pos).param2)
+ data.direction = "close"
+ data.time = 0
+ data.doortype = "twospeedmetal"
+ local erefs = celevator.doors.spawncardoors(pos,dir,"twospeedmetal")
+ local soffset = data.opendir
+ local foffset = vector.multiply(soffset,2)
+ for i=1,3,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),foffset))
+ end
+ for i=4,6,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),soffset))
+ end
+ celevator.doors.erefs[hash] = erefs
+ if nudge then
+ data.soundhandle = core.sound_play("celevator_nudge",{
+ pos = pos,
+ gain = 0.75,
+ max_hear_distance = 10
+ })
+ else
+ data.soundhandle = core.sound_play("celevator_door_close",{
+ pos = pos,
+ gain = 0.3,
+ max_hear_distance = 10
+ })
+ end
+ data.nudging = nudge
+ cardoors_moving[hash] = data
+ celevator.storage:set_string("cardoors_moving",core.serialize(cardoors_moving))
+end
+
+function celevator.doors.twospeedmetal.carstep(hash,data,dtime,cardoors_moving)
+ local present = celevator.doors.erefs[hash]
+ if present then
+ for i=1,6,1 do
+ if not (celevator.doors.erefs[hash][i] and celevator.doors.erefs[hash][i]:get_pos()) then
+ present = false
+ break
+ end
+ end
+ end
+ if present then
+ if data.direction == "open" then
+ data.time = data.time+dtime
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2))
+ end
+ if data.time >= math.pi then
+ for i=1,6,1 do
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ celevator.get_meta(data.positions[1]):set_string("doorstate","open")
+ cardoors_moving[hash] = nil
+ end
+ elseif data.direction == "close" then
+ local speed = 0.66
+ if data.nudging then speed = 0.2 end
+ data.time = data.time+(speed*dtime)
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*-speed))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*-speed))
+ end
+ if data.time >= math.pi then
+ for _,ref in ipairs(celevator.doors.erefs[hash]) do
+ ref:remove()
+ end
+ local carmeta = celevator.get_meta(data.positions[1])
+ carmeta:set_string("doorstate","closed")
+ cardoors_moving[hash] = nil
+ local cartimer = core.get_node_timer(data.positions[1])
+ cartimer:stop()
+ local fdir = core.facedir_to_dir(core.get_node(data.positions[1]).param2)
+ celevator.doors.spawncardoors(data.positions[1],fdir,"twospeedmetal")
+ end
+ end
+ else
+ if data.direction == "open" then
+ for i=1,6,1 do
+ if celevator.doors.erefs[hash] and celevator.doors.erefs[hash][i] then
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ end
+ celevator.get_meta(data.positions[1]):set_string("doorstate","open")
+ cardoors_moving[hash] = nil
+ elseif data.direction == "close" then
+ local fdir = core.fourdir_to_dir(celevator.get_node(data.positions[1]).param2)
+ celevator.doors.spawncardoors(data.positions[1],vector.rotate_around_axis(fdir,vector.new(0,1,0),math.pi),"twospeedmetal")
+ celevator.get_meta(data.positions[1]):set_string("doorstate","closed")
+ cardoors_moving[hash] = nil
+ end
+ end
+end
diff --git a/door_centerglass.lua b/door_centerglass.lua
new file mode 100644
index 0000000..9684399
--- /dev/null
+++ b/door_centerglass.lua
@@ -0,0 +1,641 @@
+celevator.doors.centerglass = {}
+
+local S = core.get_translator("celevator")
+
+core.register_node("celevator:hwdoor_left_glass_bottom",{
+ description = S("Glass Hoistway Door (left, 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_glass_topbottom.png^[transformFY",
+ "celevator_door_glass_topbottom.png^[transformFY",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ _celevator_hwdoor_root = 1,
+ oddly_breakable_by_hand = 2,
+ },
+ drop = "celevator:hwdoor_centerglass",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ use_texture_alpha = "clip",
+ 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 = core.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 = core.dir_to_yaw(core.fourdir_to_dir(node.param2))
+ local xnames = {
+ [0] = "left",
+ [1] = "right",
+ }
+ 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_glass_%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 core.get_node(piecepos).name == piecename then core.remove_node(piecepos) end
+ end
+ end
+ end,
+ _celevator_doortype = "centerglass",
+})
+
+core.register_node("celevator:hwdoor_left_glass_middle",{
+ description = S("Glass Hoistway Door (left, middle - you hacker you!)"),
+ tiles = {
+ "celevator_transparent.png",
+ "celevator_transparent.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_glass_middle.png",
+ "celevator_door_glass_middle.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ use_texture_alpha = "clip",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.4,0.5,0.5,0.5},
+ },
+ },
+ _celevator_doortype = "centerglass",
+})
+
+core.register_node("celevator:hwdoor_left_glass_top",{
+ description = S("Glass Hoistway Door (left, 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_glass_topbottom.png",
+ "celevator_door_glass_topbottom.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ use_texture_alpha = "clip",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.4,0.5,0.5,0.5},
+ },
+ },
+ _celevator_doortype = "centerglass",
+})
+
+core.register_node("celevator:hwdoor_right_glass_bottom",{
+ description = S("Glass Hoistway Door (right, 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_glass_topbottom.png^[transformFY",
+ "celevator_door_glass_topbottom.png^[transformFY",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ use_texture_alpha = "clip",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.4,0.5,0.5,0.5},
+ },
+ },
+ _celevator_doortype = "centerglass",
+})
+
+core.register_node("celevator:hwdoor_right_glass_middle",{
+ description = S("Glass Hoistway Door (right, middle - you hacker you!)"),
+ tiles = {
+ "celevator_transparent.png",
+ "celevator_transparent.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_glass_edge.png",
+ "celevator_door_glass_middle.png",
+ "celevator_door_glass_middle.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ use_texture_alpha = "clip",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.4,0.5,0.5,0.5},
+ },
+ },
+ _celevator_doortype = "centerglass",
+})
+
+core.register_node("celevator:hwdoor_right_glass_top",{
+ description = S("Glass Hoistway Door (right, 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_glass_topbottom.png",
+ "celevator_door_glass_topbottom.png",
+ },
+ groups = {
+ not_in_creative_inventory = 1,
+ },
+ drop = "",
+ paramtype = "light",
+ paramtype2 = "4dir",
+ drawtype = "nodebox",
+ use_texture_alpha = "clip",
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5,-0.5,0.4,0.5,0.5,0.5},
+ },
+ },
+ _celevator_doortype = "centerglass",
+})
+
+core.register_node("celevator:hwdoor_centerglass",{
+ description = S("Center-Opening Glass Elevator Hoistway Door"),
+ paramtype2 = "4dir",
+ buildable_to = true,
+ inventory_image = "celevator_door_centerglass_inventory.png",
+ wield_image = "celevator_door_centerglass_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
+ core.remove_node(pos)
+ return true
+ end
+ local name = player:get_player_name()
+ local newnode = core.get_node(pos)
+ local facedir = core.dir_to_yaw(core.fourdir_to_dir(newnode.param2))
+ local xnames = {
+ [0] = "left",
+ [1] = "right",
+ }
+ local ynames = {
+ [0] = "bottom",
+ [1] = "middle",
+ [2] = "top",
+ }
+ for x=0,1,1 do
+ for y=0,2,1 do
+ 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 = core.get_node(placepos).name
+ if not (core.registered_nodes[replaces] and core.registered_nodes[replaces].buildable_to) then
+ local errormsg = S("Can't place door here - position @1m to the right and @2m up is blocked!",x,y)
+ core.chat_send_player(name,errormsg)
+ core.remove_node(pos)
+ return true
+ end
+ if core.is_protected(placepos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ local errormsg = S("Can't place door here - position @1m to the right and @2m up is protected!",x,y)
+ core.chat_send_player(name,errormsg)
+ core.record_protection_violation(placepos,name)
+ core.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_glass_%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))
+ core.set_node(placepos,{name=piecename,param2=newnode.param2})
+ if y==0 then
+ celevator.doors.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 = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.get_meta(carpos):set_string("doortype","centerglass")
+ celevator.doors.spawncardoors(carpos,core.fourdir_to_dir(newnode.param2),"centerglass",true)
+ end
+ end,
+})
+
+core.register_lbm({
+ label = "Respawn hoistway door sills (center-opening glass)",
+ name = "celevator:spawn_sill_centerglass",
+ nodenames = {
+ "celevator:hwdoor_left_glass_bottom",
+ "celevator:hwdoor_right_glass_bottom",
+ },
+ run_at_every_load = true,
+ action = celevator.doors.placesill,
+})
+
+celevator.doors.centerglass.spawncardoors = function(pos,dir,replace)
+ local refs = {}
+ for x=2,1,-1 do
+ for y=1,3,1 do
+ local yaw = core.dir_to_yaw(dir)+math.pi
+ local doorpos = vector.add(pos,vector.rotate_around_axis(vector.new(x-2,y-1,0),vector.new(0,1,0),yaw))
+ local xnames = {"left","right"}
+ local ynames = {"bottom","middle","top"}
+ local nname = string.format("celevator:hwdoor_%s_glass_%s",xnames[x],ynames[y])
+ if replace then
+ local oldrefs = core.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 = core.add_entity(doorpos,"celevator:car_door")
+ ref:set_yaw(yaw)
+ ref:set_properties({
+ wield_item = nname,
+ })
+ table.insert(refs,ref)
+ end
+ end
+ return refs
+end
+
+function celevator.doors.centerglass.hwopen(pos,drivepos)
+ celevator.doors.hwdoor_step_enabled = true
+ local hwdoors_moving = core.deserialize(celevator.storage:get_string("hwdoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ if not hwdoors_moving[hash] then
+ local param2 = celevator.get_node(pos).param2
+ local fdir = core.fourdir_to_dir(param2)
+ local otherpanel = vector.add(pos,vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2))
+ local positions = {
+ pos,
+ vector.add(pos,vector.new(0,1,0)),
+ vector.add(pos,vector.new(0,2,0)),
+ otherpanel,
+ vector.add(otherpanel,vector.new(0,1,0)),
+ vector.add(otherpanel,vector.new(0,2,0)),
+ }
+ local oldnodes = {}
+ for i,position in ipairs(positions) do
+ oldnodes[i] = celevator.get_node(position)
+ end
+ local erefs = celevator.drives.entity.nodestoentities(positions,"celevator:hwdoor_moving")
+ hwdoors_moving[hash] = {
+ direction = "open",
+ positions = positions,
+ nodes = oldnodes,
+ time = 0,
+ opendir = vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2),
+ drivepos = drivepos,
+ param2 = param2,
+ doortype = "centerglass",
+ }
+ celevator.doors.erefs[hash] = erefs
+ celevator.storage:set_string("hwdoors_moving",core.serialize(hwdoors_moving))
+ core.set_node(pos,{name="celevator:hwdoor_placeholder",param2=param2})
+ local pmeta = celevator.get_meta(pos)
+ pmeta:set_string("data",core.serialize(hwdoors_moving[hash]))
+ pmeta:set_string("state","opening")
+ pmeta:set_string("doortype","centerglass")
+ local carpos = vector.add(pos,fdir)
+ local carndef = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.doors.caropen(carpos)
+ end
+ elseif hwdoors_moving[hash].direction == "close" then
+ hwdoors_moving[hash].direction = "open"
+ hwdoors_moving[hash].time = math.pi-hwdoors_moving[hash].time
+ celevator.storage:set_string("hwdoors_moving",core.serialize(hwdoors_moving))
+ local fdir = core.fourdir_to_dir(hwdoors_moving[hash].param2)
+ local carpos = vector.add(pos,fdir)
+ local carndef = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.doors.caropen(carpos)
+ end
+ core.set_node(pos,{name="celevator:hwdoor_placeholder",param2=hwdoors_moving[hash].param2})
+ local pmeta = celevator.get_meta(pos)
+ pmeta:set_string("data",core.serialize(hwdoors_moving[hash]))
+ pmeta:set_string("state","opening")
+ pmeta:set_string("doortype","centerglass")
+ end
+end
+
+function celevator.doors.centerglass.hwclose(pos,drivepos,nudge)
+ celevator.doors.hwdoor_step_enabled = true
+ local hwdoors_moving = core.deserialize(celevator.storage:get_string("hwdoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ if hwdoors_moving[hash] then
+ return
+ end
+ local pmeta = celevator.get_meta(pos)
+ local state = pmeta:get_string("state")
+ if state ~= "open" then return end
+ local fdir = core.fourdir_to_dir(celevator.get_node(pos).param2)
+ local carpos = vector.add(pos,fdir)
+ local carndef = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.doors.carclose(carpos,nudge)
+ end
+ local data = core.deserialize(pmeta:get_string("data"))
+ if not data then return end
+ for i=1,6,1 do
+ core.set_node(data.positions[i],data.nodes[i])
+ end
+ data.direction = "close"
+ data.time = 0
+ data.drivepos = drivepos
+ data.nudging = nudge
+ local erefs = celevator.drives.entity.nodestoentities(data.positions,"celevator:hwdoor_moving")
+ local roffset = vector.multiply(data.opendir,-1)
+ local loffset = data.opendir
+ for i=1,3,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),roffset))
+ end
+ for i=4,6,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),loffset))
+ end
+ celevator.doors.erefs[hash] = erefs
+ hwdoors_moving[hash] = data
+ celevator.storage:set_string("hwdoors_moving",core.serialize(hwdoors_moving))
+end
+
+function celevator.doors.centerglass.hwstep(hash,data,dtime,hwdoors_moving)
+ local present = celevator.doors.erefs[hash]
+ if present then
+ for i=1,6,1 do
+ if not celevator.doors.erefs[hash][i]:get_pos() then
+ present = false
+ break
+ end
+ end
+ end
+ if present then
+ if data.direction == "open" then
+ data.time = data.time+dtime
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*-0.5))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*0.5))
+ end
+ if data.time >= math.pi then
+ for i=1,6,1 do
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ celevator.get_meta(data.positions[1]):set_string("state","open")
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","open") end
+ hwdoors_moving[hash] = nil
+ end
+ elseif data.direction == "close" then
+ local speed = 0.66
+ if data.nudging then speed = 0.2 end
+ data.time = data.time+(speed*dtime)
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*speed))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*-speed))
+ end
+ if data.time >= math.pi then
+ for i=1,6,1 do
+ celevator.doors.erefs[hash][i]:set_pos(data.positions[i])
+ end
+ celevator.drives.entity.entitiestonodes(celevator.doors.erefs[hash])
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","closed") end
+ hwdoors_moving[hash] = nil
+ end
+ end
+ else
+ if data.direction == "open" then
+ for i=1,6,1 do
+ if celevator.doors.erefs[hash] then
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ end
+ celevator.get_meta(data.positions[1]):set_string("state","open")
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","open") end
+ hwdoors_moving[hash] = nil
+ elseif data.direction == "close" then
+ for i=1,6,1 do
+ core.set_node(data.positions[i],data.nodes[i])
+ end
+ celevator.get_meta(data.positions[1]):set_string("state","closed")
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","closed") end
+ hwdoors_moving[hash] = nil
+ end
+ end
+end
+
+function celevator.doors.centerglass.caropen(pos)
+ celevator.doors.cardoor_step_enabled = true
+ local cardoors_moving = core.deserialize(celevator.storage:get_string("cardoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ local cartimer = core.get_node_timer(pos)
+ cartimer:start(0.25)
+ if not cardoors_moving[hash] then
+ local fdir = core.fourdir_to_dir(celevator.get_node(pos).param2)
+ local otherpanel = vector.add(pos,vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2))
+ local positions = {
+ pos,
+ vector.add(pos,vector.new(0,1,0)),
+ vector.add(pos,vector.new(0,2,0)),
+ otherpanel,
+ vector.add(otherpanel,vector.new(0,1,0)),
+ vector.add(otherpanel,vector.new(0,2,0)),
+ }
+ local erefs = {}
+ for _,dpos in ipairs(positions) do
+ local objs = core.get_objects_inside_radius(dpos,0.5)
+ for _,obj in pairs(objs) do
+ if obj:get_luaentity() and obj:get_luaentity().name == "celevator:car_door" then
+ table.insert(erefs,obj)
+ end
+ end
+ end
+ cardoors_moving[hash] = {
+ direction = "open",
+ positions = positions,
+ time = 0,
+ opendir = vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2),
+ doortype = "centerglass",
+ }
+ core.sound_play("celevator_door_open",{
+ pos = pos,
+ gain = 0.4,
+ max_hear_distance = 10
+ },true)
+ celevator.doors.erefs[hash] = erefs
+ celevator.storage:set_string("cardoors_moving",core.serialize(cardoors_moving))
+ local meta = celevator.get_meta(pos)
+ meta:set_string("doordata",core.serialize(cardoors_moving[hash]))
+ meta:set_string("doorstate","opening")
+ elseif cardoors_moving[hash].direction == "close" then
+ if cardoors_moving[hash].soundhandle then
+ core.sound_stop(cardoors_moving[hash].soundhandle)
+ end
+ core.sound_play("celevator_door_reverse",{
+ pos = pos,
+ gain = 1,
+ max_hear_distance = 10
+ },true)
+ core.sound_play("celevator_door_open",{
+ pos = pos,
+ gain = 0.4,
+ start_time = math.max(0,2.75-cardoors_moving[hash].time),
+ max_hear_distance = 10
+ },true)
+ cardoors_moving[hash].direction = "open"
+ cardoors_moving[hash].time = math.pi-cardoors_moving[hash].time
+ celevator.storage:set_string("cardoors_moving",core.serialize(cardoors_moving))
+ end
+end
+
+function celevator.doors.centerglass.carclose(pos,nudge)
+ celevator.doors.cardoor_step_enabled = true
+ local cardoors_moving = core.deserialize(celevator.storage:get_string("cardoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ if cardoors_moving[hash] then
+ return
+ end
+ local meta = celevator.get_meta(pos)
+ local state = meta:get_string("doorstate")
+ if state ~= "open" then return end
+ local data = core.deserialize(meta:get_string("doordata"))
+ if not data then return end
+ local dir = core.fourdir_to_dir(celevator.get_node(pos).param2)
+ data.direction = "close"
+ data.time = 0
+ data.doortype = "centerglass"
+ local erefs = celevator.doors.spawncardoors(pos,dir,"centerglass")
+ local loffset = data.opendir
+ local roffset = vector.multiply(loffset,-1)
+ for i=1,3,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),roffset))
+ end
+ for i=4,6,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),loffset))
+ end
+ celevator.doors.erefs[hash] = erefs
+ if nudge then
+ data.soundhandle = core.sound_play("celevator_nudge",{
+ pos = pos,
+ gain = 0.75,
+ max_hear_distance = 10
+ })
+ else
+ data.soundhandle = core.sound_play("celevator_door_close",{
+ pos = pos,
+ gain = 0.3,
+ max_hear_distance = 10
+ })
+ end
+ data.nudging = nudge
+ cardoors_moving[hash] = data
+ celevator.storage:set_string("cardoors_moving",core.serialize(cardoors_moving))
+end
+
+function celevator.doors.centerglass.carstep(hash,data,dtime,cardoors_moving)
+ local present = celevator.doors.erefs[hash]
+ if present then
+ for i=1,6,1 do
+ if not (celevator.doors.erefs[hash][i] and celevator.doors.erefs[hash][i]:get_pos()) then
+ present = false
+ break
+ end
+ end
+ end
+ if present then
+ if data.direction == "open" then
+ data.time = data.time+dtime
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*-0.5))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*0.5))
+ end
+ if data.time >= math.pi then
+ for i=1,6,1 do
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ celevator.get_meta(data.positions[1]):set_string("doorstate","open")
+ cardoors_moving[hash] = nil
+ end
+ elseif data.direction == "close" then
+ local speed = 0.66
+ if data.nudging then speed = 0.2 end
+ data.time = data.time+(speed*dtime)
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*speed))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*-speed))
+ end
+ if data.time >= math.pi then
+ for _,ref in ipairs(celevator.doors.erefs[hash]) do
+ ref:remove()
+ end
+ local carmeta = celevator.get_meta(data.positions[1])
+ carmeta:set_string("doorstate","closed")
+ cardoors_moving[hash] = nil
+ local cartimer = core.get_node_timer(data.positions[1])
+ cartimer:stop()
+ local fdir = core.facedir_to_dir(core.get_node(data.positions[1]).param2)
+ celevator.doors.spawncardoors(data.positions[1],fdir,"centerglass")
+ end
+ end
+ else
+ if data.direction == "open" then
+ for i=1,6,1 do
+ if celevator.doors.erefs[hash] and celevator.doors.erefs[hash][i] then
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ end
+ celevator.get_meta(data.positions[1]):set_string("doorstate","open")
+ cardoors_moving[hash] = nil
+ elseif data.direction == "close" then
+ local fdir = core.fourdir_to_dir(celevator.get_node(data.positions[1]).param2)
+ celevator.doors.spawncardoors(data.positions[1],vector.rotate_around_axis(fdir,vector.new(0,1,0),math.pi),"centerglass")
+ celevator.get_meta(data.positions[1]):set_string("doorstate","closed")
+ cardoors_moving[hash] = nil
+ end
+ end
+end
diff --git a/door_centermetal.lua b/door_centermetal.lua
new file mode 100644
index 0000000..8857ed0
--- /dev/null
+++ b/door_centermetal.lua
@@ -0,0 +1,636 @@
+celevator.doors.centermetal = {}
+
+local S = core.get_translator("celevator")
+
+core.register_node("celevator:hwdoor_left_steel_bottom",{
+ description = S("Steel Hoistway Door (left, 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_centersteel",
+ 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 = core.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 = core.dir_to_yaw(core.fourdir_to_dir(node.param2))
+ local xnames = {
+ [0] = "left",
+ [1] = "right",
+ }
+ 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 core.get_node(piecepos).name == piecename then core.remove_node(piecepos) end
+ end
+ end
+ end,
+ _celevator_doortype = "centermetal",
+})
+
+core.register_node("celevator:hwdoor_left_steel_middle",{
+ description = S("Steel Hoistway Door (left, 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},
+ },
+ },
+ _celevator_doortype = "centermetal",
+})
+
+core.register_node("celevator:hwdoor_left_steel_top",{
+ description = S("Steel Hoistway Door (left, 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},
+ },
+ },
+ _celevator_doortype = "centermetal",
+})
+
+core.register_node("celevator:hwdoor_right_steel_bottom",{
+ description = S("Steel Hoistway Door (right, 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.4,0.5,0.5,0.5},
+ },
+ },
+ _celevator_doortype = "centermetal",
+})
+
+core.register_node("celevator:hwdoor_right_steel_middle",{
+ description = S("Steel Hoistway Door (right, 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},
+ },
+ },
+ _celevator_doortype = "centermetal",
+})
+
+core.register_node("celevator:hwdoor_right_steel_top",{
+ description = S("Steel Hoistway Door (right, 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},
+ },
+ },
+ _celevator_doortype = "centermetal",
+})
+
+core.register_node("celevator:hwdoor_centersteel",{
+ description = S("Center-Opening Steel Elevator Hoistway Door"),
+ paramtype2 = "4dir",
+ buildable_to = true,
+ inventory_image = "celevator_door_centermetal_inventory.png",
+ wield_image = "celevator_door_centermetal_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
+ core.remove_node(pos)
+ return true
+ end
+ local name = player:get_player_name()
+ local newnode = core.get_node(pos)
+ local facedir = core.dir_to_yaw(core.fourdir_to_dir(newnode.param2))
+ local xnames = {
+ [0] = "left",
+ [1] = "right",
+ }
+ local ynames = {
+ [0] = "bottom",
+ [1] = "middle",
+ [2] = "top",
+ }
+ for x=0,1,1 do
+ for y=0,2,1 do
+ 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 = core.get_node(placepos).name
+ if not (core.registered_nodes[replaces] and core.registered_nodes[replaces].buildable_to) then
+ local errormsg = S("Can't place door here - position @1m to the right and @2m up is blocked!",x,y)
+ core.chat_send_player(name,errormsg)
+ core.remove_node(pos)
+ return true
+ end
+ if core.is_protected(placepos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ local errormsg = S("Can't place door here - position @1m to the right and @2m up is protected!",x,y)
+ core.chat_send_player(name,errormsg)
+ core.record_protection_violation(placepos,name)
+ core.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))
+ core.set_node(placepos,{name=piecename,param2=newnode.param2})
+ if y==0 then
+ celevator.doors.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 = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.get_meta(carpos):set_string("doortype","centermetal")
+ celevator.doors.spawncardoors(carpos,core.fourdir_to_dir(newnode.param2),"centermetal",true)
+ end
+ end,
+})
+
+core.register_lbm({
+ label = "Respawn hoistway door sills (center-opening steel)",
+ name = "celevator:spawn_sill_centermetal",
+ nodenames = {
+ "celevator:hwdoor_left_steel_bottom",
+ "celevator:hwdoor_right_steel_bottom",
+ },
+ run_at_every_load = true,
+ action = celevator.doors.placesill,
+})
+
+celevator.doors.centermetal.spawncardoors = function(pos,dir,replace)
+ local refs = {}
+ for x=2,1,-1 do
+ for y=1,3,1 do
+ local yaw = core.dir_to_yaw(dir)+math.pi
+ local doorpos = vector.add(pos,vector.rotate_around_axis(vector.new(x-2,y-1,0),vector.new(0,1,0),yaw))
+ local xnames = {"left","right"}
+ local ynames = {"bottom","middle","top"}
+ local nname = string.format("celevator:hwdoor_%s_steel_%s",xnames[x],ynames[y])
+ if replace then
+ local oldrefs = core.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 = core.add_entity(doorpos,"celevator:car_door")
+ ref:set_yaw(yaw)
+ ref:set_properties({
+ wield_item = nname,
+ })
+ table.insert(refs,ref)
+ end
+ end
+ return refs
+end
+
+function celevator.doors.centermetal.hwopen(pos,drivepos)
+ celevator.doors.hwdoor_step_enabled = true
+ local hwdoors_moving = core.deserialize(celevator.storage:get_string("hwdoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ if not hwdoors_moving[hash] then
+ local param2 = celevator.get_node(pos).param2
+ local fdir = core.fourdir_to_dir(param2)
+ local otherpanel = vector.add(pos,vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2))
+ local positions = {
+ pos,
+ vector.add(pos,vector.new(0,1,0)),
+ vector.add(pos,vector.new(0,2,0)),
+ otherpanel,
+ vector.add(otherpanel,vector.new(0,1,0)),
+ vector.add(otherpanel,vector.new(0,2,0)),
+ }
+ local oldnodes = {}
+ for i,position in ipairs(positions) do
+ oldnodes[i] = celevator.get_node(position)
+ end
+ local erefs = celevator.drives.entity.nodestoentities(positions,"celevator:hwdoor_moving")
+ hwdoors_moving[hash] = {
+ direction = "open",
+ positions = positions,
+ nodes = oldnodes,
+ time = 0,
+ opendir = vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2),
+ drivepos = drivepos,
+ param2 = param2,
+ doortype = "centermetal",
+ }
+ celevator.doors.erefs[hash] = erefs
+ celevator.storage:set_string("hwdoors_moving",core.serialize(hwdoors_moving))
+ core.set_node(pos,{name="celevator:hwdoor_placeholder",param2=param2})
+ local pmeta = celevator.get_meta(pos)
+ pmeta:set_string("data",core.serialize(hwdoors_moving[hash]))
+ pmeta:set_string("state","opening")
+ pmeta:set_string("doortype","centermetal")
+ local carpos = vector.add(pos,fdir)
+ local carndef = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.doors.caropen(carpos)
+ end
+ elseif hwdoors_moving[hash].direction == "close" then
+ hwdoors_moving[hash].direction = "open"
+ hwdoors_moving[hash].time = math.pi-hwdoors_moving[hash].time
+ celevator.storage:set_string("hwdoors_moving",core.serialize(hwdoors_moving))
+ local fdir = core.fourdir_to_dir(hwdoors_moving[hash].param2)
+ local carpos = vector.add(pos,fdir)
+ local carndef = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.doors.caropen(carpos)
+ end
+ core.set_node(pos,{name="celevator:hwdoor_placeholder",param2=hwdoors_moving[hash].param2})
+ local pmeta = celevator.get_meta(pos)
+ pmeta:set_string("data",core.serialize(hwdoors_moving[hash]))
+ pmeta:set_string("state","opening")
+ pmeta:set_string("doortype","centermetal")
+ end
+end
+
+function celevator.doors.centermetal.hwclose(pos,drivepos,nudge)
+ celevator.doors.hwdoor_step_enabled = true
+ local hwdoors_moving = core.deserialize(celevator.storage:get_string("hwdoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ if hwdoors_moving[hash] then
+ return
+ end
+ local pmeta = celevator.get_meta(pos)
+ local state = pmeta:get_string("state")
+ if state ~= "open" then return end
+ local fdir = core.fourdir_to_dir(celevator.get_node(pos).param2)
+ local carpos = vector.add(pos,fdir)
+ local carndef = core.registered_nodes[celevator.get_node(carpos).name] or {}
+ if carndef._root then
+ celevator.doors.carclose(carpos,nudge)
+ end
+ local data = core.deserialize(pmeta:get_string("data"))
+ if not data then return end
+ for i=1,6,1 do
+ core.set_node(data.positions[i],data.nodes[i])
+ end
+ data.direction = "close"
+ data.time = 0
+ data.drivepos = drivepos
+ data.nudging = nudge
+ data.doortype = "centermetal"
+ local erefs = celevator.drives.entity.nodestoentities(data.positions,"celevator:hwdoor_moving")
+ local roffset = vector.multiply(data.opendir,-1)
+ local loffset = data.opendir
+ for i=1,3,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),roffset))
+ end
+ for i=4,6,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),loffset))
+ end
+ celevator.doors.erefs[hash] = erefs
+ hwdoors_moving[hash] = data
+ celevator.storage:set_string("hwdoors_moving",core.serialize(hwdoors_moving))
+end
+
+function celevator.doors.centermetal.hwstep(hash,data,dtime,hwdoors_moving)
+ local present = celevator.doors.erefs[hash]
+ if present then
+ for i=1,6,1 do
+ if not celevator.doors.erefs[hash][i]:get_pos() then
+ present = false
+ break
+ end
+ end
+ end
+ if present then
+ if data.direction == "open" then
+ data.time = data.time+dtime
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*-0.5))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*0.5))
+ end
+ if data.time >= math.pi then
+ for i=1,6,1 do
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ celevator.get_meta(data.positions[1]):set_string("state","open")
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","open") end
+ hwdoors_moving[hash] = nil
+ end
+ elseif data.direction == "close" then
+ local speed = 0.66
+ if data.nudging then speed = 0.2 end
+ data.time = data.time+(speed*dtime)
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*speed))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*-speed))
+ end
+ if data.time >= math.pi then
+ for i=1,6,1 do
+ celevator.doors.erefs[hash][i]:set_pos(data.positions[i])
+ end
+ celevator.drives.entity.entitiestonodes(celevator.doors.erefs[hash])
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","closed") end
+ hwdoors_moving[hash] = nil
+ end
+ end
+ else
+ if data.direction == "open" then
+ for i=1,6,1 do
+ if celevator.doors.erefs[hash] then
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ end
+ celevator.get_meta(data.positions[1]):set_string("state","open")
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","open") end
+ hwdoors_moving[hash] = nil
+ elseif data.direction == "close" then
+ for i=1,6,1 do
+ core.set_node(data.positions[i],data.nodes[i])
+ end
+ celevator.get_meta(data.positions[1]):set_string("state","closed")
+ if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","closed") end
+ hwdoors_moving[hash] = nil
+ end
+ end
+end
+
+function celevator.doors.centermetal.caropen(pos)
+ celevator.doors.cardoor_step_enabled = true
+ local cardoors_moving = core.deserialize(celevator.storage:get_string("cardoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ local cartimer = core.get_node_timer(pos)
+ cartimer:start(0.25)
+ if not cardoors_moving[hash] then
+ local fdir = core.fourdir_to_dir(celevator.get_node(pos).param2)
+ local otherpanel = vector.add(pos,vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2))
+ local positions = {
+ pos,
+ vector.add(pos,vector.new(0,1,0)),
+ vector.add(pos,vector.new(0,2,0)),
+ otherpanel,
+ vector.add(otherpanel,vector.new(0,1,0)),
+ vector.add(otherpanel,vector.new(0,2,0)),
+ }
+ local erefs = {}
+ for _,dpos in ipairs(positions) do
+ local objs = core.get_objects_inside_radius(dpos,0.5)
+ for _,obj in pairs(objs) do
+ if obj:get_luaentity() and obj:get_luaentity().name == "celevator:car_door" then
+ table.insert(erefs,obj)
+ end
+ end
+ end
+ cardoors_moving[hash] = {
+ direction = "open",
+ positions = positions,
+ time = 0,
+ opendir = vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2),
+ doortype = "centermetal",
+ }
+ core.sound_play("celevator_door_open",{
+ pos = pos,
+ gain = 0.4,
+ max_hear_distance = 10
+ },true)
+ celevator.doors.erefs[hash] = erefs
+ celevator.storage:set_string("cardoors_moving",core.serialize(cardoors_moving))
+ local meta = celevator.get_meta(pos)
+ meta:set_string("doordata",core.serialize(cardoors_moving[hash]))
+ meta:set_string("doorstate","opening")
+ elseif cardoors_moving[hash].direction == "close" then
+ if cardoors_moving[hash].soundhandle then
+ core.sound_stop(cardoors_moving[hash].soundhandle)
+ end
+ core.sound_play("celevator_door_reverse",{
+ pos = pos,
+ gain = 1,
+ max_hear_distance = 10
+ },true)
+ core.sound_play("celevator_door_open",{
+ pos = pos,
+ gain = 0.4,
+ start_time = math.max(0,2.75-cardoors_moving[hash].time),
+ max_hear_distance = 10
+ },true)
+ cardoors_moving[hash].direction = "open"
+ cardoors_moving[hash].time = math.pi-cardoors_moving[hash].time
+ celevator.storage:set_string("cardoors_moving",core.serialize(cardoors_moving))
+ end
+end
+
+function celevator.doors.centermetal.carclose(pos,nudge)
+ celevator.doors.cardoor_step_enabled = true
+ local cardoors_moving = core.deserialize(celevator.storage:get_string("cardoors_moving")) or {}
+ local hash = core.hash_node_position(pos)
+ if cardoors_moving[hash] then
+ return
+ end
+ local meta = celevator.get_meta(pos)
+ local state = meta:get_string("doorstate")
+ if state ~= "open" then return end
+ local data = core.deserialize(meta:get_string("doordata"))
+ if not data then return end
+ local dir = core.fourdir_to_dir(celevator.get_node(pos).param2)
+ data.direction = "close"
+ data.time = 0
+ data.doortype = "centermetal"
+ local erefs = celevator.doors.spawncardoors(pos,dir,"centermetal")
+ local loffset = data.opendir
+ local roffset = vector.multiply(loffset,-1)
+ for i=1,3,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),roffset))
+ end
+ for i=4,6,1 do
+ erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),loffset))
+ end
+ celevator.doors.erefs[hash] = erefs
+ if nudge then
+ data.soundhandle = core.sound_play("celevator_nudge",{
+ pos = pos,
+ gain = 0.75,
+ max_hear_distance = 10
+ })
+ else
+ data.soundhandle = core.sound_play("celevator_door_close",{
+ pos = pos,
+ gain = 0.3,
+ max_hear_distance = 10
+ })
+ end
+ data.nudging = nudge
+ cardoors_moving[hash] = data
+ celevator.storage:set_string("cardoors_moving",core.serialize(cardoors_moving))
+end
+
+function celevator.doors.centermetal.carstep(hash,data,dtime,cardoors_moving)
+ local present = celevator.doors.erefs[hash]
+ if present then
+ for i=1,6,1 do
+ if not (celevator.doors.erefs[hash][i] and celevator.doors.erefs[hash][i]:get_pos()) then
+ present = false
+ break
+ end
+ end
+ end
+ if present then
+ if data.direction == "open" then
+ data.time = data.time+dtime
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*-0.5))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*0.5))
+ end
+ if data.time >= math.pi then
+ for i=1,6,1 do
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ celevator.get_meta(data.positions[1]):set_string("doorstate","open")
+ cardoors_moving[hash] = nil
+ end
+ elseif data.direction == "close" then
+ local speed = 0.66
+ if data.nudging then speed = 0.2 end
+ data.time = data.time+(speed*dtime)
+ local vel = math.sin(data.time)
+ for i=1,3,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*speed))
+ end
+ for i=4,6,1 do
+ celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*-speed))
+ end
+ if data.time >= math.pi then
+ for _,ref in ipairs(celevator.doors.erefs[hash]) do
+ ref:remove()
+ end
+ local carmeta = celevator.get_meta(data.positions[1])
+ carmeta:set_string("doorstate","closed")
+ cardoors_moving[hash] = nil
+ local cartimer = core.get_node_timer(data.positions[1])
+ cartimer:stop()
+ local fdir = core.facedir_to_dir(core.get_node(data.positions[1]).param2)
+ celevator.doors.spawncardoors(data.positions[1],fdir,"centermetal")
+ end
+ end
+ else
+ if data.direction == "open" then
+ for i=1,6,1 do
+ if celevator.doors.erefs[hash] and celevator.doors.erefs[hash][i] then
+ celevator.doors.erefs[hash][i]:remove()
+ end
+ end
+ celevator.get_meta(data.positions[1]):set_string("doorstate","open")
+ cardoors_moving[hash] = nil
+ elseif data.direction == "close" then
+ local fdir = core.fourdir_to_dir(celevator.get_node(data.positions[1]).param2)
+ celevator.doors.spawncardoors(data.positions[1],vector.rotate_around_axis(fdir,vector.new(0,1,0),math.pi),"centermetal")
+ celevator.get_meta(data.positions[1]):set_string("doorstate","closed")
+ cardoors_moving[hash] = nil
+ end
+ end
+end
diff --git a/doors.lua b/doors.lua
index 4443c5d..58c8643 100644
--- a/doors.lua
+++ b/doors.lua
@@ -1,206 +1,37 @@
celevator.doors = {}
+local S = core.get_translator("celevator")
+
celevator.doors.erefs = {}
-local function placesill(pos,node)
- local erefs = minetest.get_objects_inside_radius(pos,0.5)
+local typealiases = {
+ glass = "twospeedglass",
+ steel = "twospeedmetal",
+}
+
+local function typelookup(doortype)
+ if (not doortype) or doortype == "" then return "twospeedglass" end
+ return typealiases[doortype] or doortype
+end
+
+--These get overwritten on globalstep and aren't settings.
+--They're just set to true here so the globalstep functions run at least once,
+--in case a door was moving when the server last shut down.
+celevator.doors.hwdoor_step_enabled = true
+celevator.doors.cardoor_step_enabled = true
+
+function celevator.doors.placesill(pos,node)
+ local erefs = core.get_objects_inside_radius(pos,0.5)
for _,ref in pairs(erefs) do
if ref:get_luaentity() and ref:get_luaentity().name == "celevator:door_sill" then return end
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
- entity:set_properties({
- wield_item = "celevator:door_sill_double",
- })
- end
+ local yaw = core.dir_to_yaw(core.fourdir_to_dir(node.param2))
+ local entity = core.add_entity(pos,"celevator:door_sill")
entity:set_yaw(yaw)
end
-minetest.register_node("celevator:hwdoor_fast_glass_bottom",{
- description = "Glass 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_glass_topbottom.png^[transformFY",
- "celevator_door_glass_topbottom.png^[transformFY",
- },
- groups = {
- not_in_creative_inventory = 1,
- _celevator_hwdoor_root = 1,
- oddly_breakable_by_hand = 2,
- },
- drop = "celevator:hwdoor_glass",
- paramtype = "light",
- paramtype2 = "4dir",
- drawtype = "nodebox",
- use_texture_alpha = "clip",
- 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_glass_%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_glass_middle",{
- description = "Glass 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_glass_middle.png",
- "celevator_door_glass_middle.png",
- },
- groups = {
- not_in_creative_inventory = 1,
- },
- drop = "",
- paramtype = "light",
- paramtype2 = "4dir",
- drawtype = "nodebox",
- use_texture_alpha = "clip",
- node_box = {
- type = "fixed",
- fixed = {
- {-0.5,-0.5,0.4,0.5,0.5,0.5},
- },
- },
-})
-
-minetest.register_node("celevator:hwdoor_fast_glass_top",{
- description = "Glass 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_glass_topbottom.png",
- "celevator_door_glass_topbottom.png",
- },
- groups = {
- not_in_creative_inventory = 1,
- },
- drop = "",
- paramtype = "light",
- paramtype2 = "4dir",
- drawtype = "nodebox",
- use_texture_alpha = "clip",
- node_box = {
- type = "fixed",
- fixed = {
- {-0.5,-0.5,0.4,0.5,0.5,0.5},
- },
- },
-})
-
-minetest.register_node("celevator:hwdoor_slow_glass_bottom",{
- description = "Glass 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_glass_topbottom.png^[transformFY",
- "celevator_door_glass_topbottom.png^[transformFY",
- },
- groups = {
- not_in_creative_inventory = 1,
- },
- drop = "",
- paramtype = "light",
- paramtype2 = "4dir",
- drawtype = "nodebox",
- use_texture_alpha = "clip",
- node_box = {
- type = "fixed",
- fixed = {
- {-0.5,-0.5,0.3,0.5,0.5,0.4},
- },
- },
-})
-
-minetest.register_node("celevator:hwdoor_slow_glass_middle",{
- description = "Glass 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_glass_middle.png",
- "celevator_door_glass_middle.png",
- },
- groups = {
- not_in_creative_inventory = 1,
- },
- drop = "",
- paramtype = "light",
- paramtype2 = "4dir",
- drawtype = "nodebox",
- use_texture_alpha = "clip",
- node_box = {
- type = "fixed",
- fixed = {
- {-0.5,-0.5,0.3,0.5,0.5,0.4},
- },
- },
-})
-
-minetest.register_node("celevator:hwdoor_slow_glass_top",{
- description = "Glass 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_glass_topbottom.png",
- "celevator_door_glass_topbottom.png",
- },
- groups = {
- not_in_creative_inventory = 1,
- },
- drop = "",
- paramtype = "light",
- paramtype2 = "4dir",
- drawtype = "nodebox",
- use_texture_alpha = "clip",
- 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!)",
+core.register_node("celevator:hwdoor_placeholder",{
+ description = S("Hoistway Door Open-State Placeholder (you hacker you!)"),
groups = {
not_in_creative_inventory = 1,
},
@@ -225,496 +56,122 @@ minetest.register_node("celevator:hwdoor_placeholder",{
},
})
-minetest.register_entity("celevator:hwdoor_moving",{
+core.register_entity("celevator:hwdoor_moving",{
initial_properties = {
- visual = "wielditem",
- visual_size = vector.new(0.667,0.667,0.667),
- wield_item = "default:dirt",
+ visual = "node",
+ node = {name="air"},
static_save = false,
pointable = false,
},
})
-function celevator.doors.hwopen(pos,drivepos)
- local hwdoors_moving = minetest.deserialize(celevator.storage:get_string("hwdoors_moving")) or {}
- local hash = minetest.hash_node_position(pos)
- if not hwdoors_moving[hash] then
- local param2 = celevator.get_node(pos).param2
- local fdir = minetest.fourdir_to_dir(param2)
- local otherpanel = vector.add(pos,vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2))
- local positions = {
- pos,
- vector.add(pos,vector.new(0,1,0)),
- vector.add(pos,vector.new(0,2,0)),
- otherpanel,
- vector.add(otherpanel,vector.new(0,1,0)),
- vector.add(otherpanel,vector.new(0,2,0)),
- }
- local oldnodes = {}
- for i,position in ipairs(positions) do
- oldnodes[i] = celevator.get_node(position)
- end
- local erefs = celevator.drives.entity.nodestoentities(positions,"celevator:hwdoor_moving")
- hwdoors_moving[hash] = {
- direction = "open",
- positions = positions,
- nodes = oldnodes,
- time = 0,
- opendir = vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2),
- drivepos = drivepos,
- param2 = param2,
- }
- celevator.doors.erefs[hash] = erefs
- celevator.storage:set_string("hwdoors_moving",minetest.serialize(hwdoors_moving))
- minetest.set_node(pos,{name="celevator:hwdoor_placeholder",param2=param2})
- local pmeta = celevator.get_meta(pos)
- pmeta:set_string("data",minetest.serialize(hwdoors_moving[hash]))
- pmeta:set_string("state","opening")
- local carpos = vector.add(pos,fdir)
- if celevator.get_node(carpos).name == "celevator:car_000" then
- celevator.doors.caropen(carpos)
- end
- elseif hwdoors_moving[hash].direction == "close" then
- hwdoors_moving[hash].direction = "open"
- hwdoors_moving[hash].time = math.pi-hwdoors_moving[hash].time
- 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
- celevator.doors.caropen(carpos)
- end
- minetest.set_node(pos,{name="celevator:hwdoor_placeholder",param2=hwdoors_moving[hash].param2})
- local pmeta = celevator.get_meta(pos)
- pmeta:set_string("data",minetest.serialize(hwdoors_moving[hash]))
- pmeta:set_string("state","opening")
+function celevator.doors.hwopen(pos,...)
+ local nname = celevator.get_node(pos).name
+ local doortype
+ if nname == "celevator:hwdoor_placeholder" then
+ doortype = celevator.get_meta(pos):get_string("doortype")
+ else
+ local ndef = core.registered_nodes[nname]
+ if not ndef then return end
+ doortype = ndef._celevator_doortype
end
+ if not doortype then
+ local hwdoors_moving = core.deserialize(celevator.storage:get_string("hwdoors_moving")) or {}
+ doortype = hwdoors_moving[core.hash_node_position(pos)].doortype
+ end
+ celevator.doors[typelookup(doortype)].hwopen(pos,...)
end
-function celevator.doors.hwclose(pos,drivepos,nudge)
- local hwdoors_moving = minetest.deserialize(celevator.storage:get_string("hwdoors_moving")) or {}
- local hash = minetest.hash_node_position(pos)
- if hwdoors_moving[hash] then
- return
- end
+function celevator.doors.hwclose(pos,...)
local pmeta = celevator.get_meta(pos)
- local state = pmeta:get_string("state")
- 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
- celevator.doors.carclose(carpos,nudge)
- end
- local data = minetest.deserialize(pmeta:get_string("data"))
- if not data then return end
- for i=1,6,1 do
- minetest.set_node(data.positions[i],data.nodes[i])
- end
- data.direction = "close"
- data.time = 0
- data.drivepos = drivepos
- data.nudging = nudge
- local erefs = celevator.drives.entity.nodestoentities(data.positions,"celevator:hwdoor_moving")
- local foffset = vector.multiply(data.opendir,2)
- local soffset = data.opendir
- for i=1,3,1 do
- erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),foffset))
- end
- for i=4,6,1 do
- erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),soffset))
- end
- celevator.doors.erefs[hash] = erefs
- hwdoors_moving[hash] = data
- celevator.storage:set_string("hwdoors_moving",minetest.serialize(hwdoors_moving))
+ local doortype = typelookup(pmeta:get_string("doortype"))
+ celevator.doors[doortype].hwclose(pos,...)
end
function celevator.doors.hwstep(dtime)
- local hwdoors_moving = minetest.deserialize(celevator.storage:get_string("hwdoors_moving")) or {}
+ if not celevator.doors.hwdoor_step_enabled then return end
+ local hwdoors_moving = core.deserialize(celevator.storage:get_string("hwdoors_moving")) or {}
local save = false
for hash,data in pairs(hwdoors_moving) do
save = true
- local present = celevator.doors.erefs[hash]
- if present then
- for i=1,6,1 do
- if not celevator.doors.erefs[hash][i]:get_pos() then
- present = false
- break
- end
- end
- end
- if present then
- if data.direction == "open" then
- data.time = data.time+dtime
- local vel = math.sin(data.time)
- for i=1,3,1 do
- celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel))
- end
- for i=4,6,1 do
- celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2))
- end
- if data.time >= math.pi then
- for i=1,6,1 do
- celevator.doors.erefs[hash][i]:remove()
- end
- celevator.get_meta(data.positions[1]):set_string("state","open")
- if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","open") end
- hwdoors_moving[hash] = nil
- end
- elseif data.direction == "close" then
- local speed = 0.66
- if data.nudging then speed = 0.2 end
- data.time = data.time+(speed*dtime)
- local vel = math.sin(data.time)
- for i=1,3,1 do
- celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*-speed))
- end
- for i=4,6,1 do
- celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*-speed))
- end
- if data.time >= math.pi then
- for i=1,6,1 do
- celevator.doors.erefs[hash][i]:set_pos(data.positions[i])
- end
- celevator.drives.entity.entitiestonodes(celevator.doors.erefs[hash])
- if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","closed") end
- hwdoors_moving[hash] = nil
- end
- end
- else
- if data.direction == "open" then
- for i=1,6,1 do
- if celevator.doors.erefs[hash] then
- celevator.doors.erefs[hash][i]:remove()
- end
- end
- celevator.get_meta(data.positions[1]):set_string("state","open")
- if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","open") end
- hwdoors_moving[hash] = nil
- elseif data.direction == "close" then
- for i=1,6,1 do
- minetest.set_node(data.positions[i],data.nodes[i])
- end
- celevator.get_meta(data.positions[1]):set_string("state","closed")
- if hwdoors_moving[hash].drivepos then celevator.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","closed") end
- hwdoors_moving[hash] = nil
- end
- end
+ local doortype = typelookup(data.doortype)
+ celevator.doors[doortype].hwstep(hash,data,dtime,hwdoors_moving)
end
if save then
- celevator.storage:set_string("hwdoors_moving",minetest.serialize(hwdoors_moving))
+ celevator.storage:set_string("hwdoors_moving",core.serialize(hwdoors_moving))
end
+ celevator.doors.hwdoor_step_enabled = save
end
-minetest.register_globalstep(celevator.doors.hwstep)
+core.register_globalstep(celevator.doors.hwstep)
function celevator.doors.carstep(dtime)
- local cardoors_moving = minetest.deserialize(celevator.storage:get_string("cardoors_moving")) or {}
+ if not celevator.doors.cardoor_step_enabled then return end
+ local cardoors_moving = core.deserialize(celevator.storage:get_string("cardoors_moving")) or {}
local save = false
for hash,data in pairs(cardoors_moving) do
save = true
- local present = celevator.doors.erefs[hash]
- if present then
- for i=1,6,1 do
- if not (celevator.doors.erefs[hash][i] and celevator.doors.erefs[hash][i]:get_pos()) then
- present = false
- break
- end
- end
- end
- if present then
- if data.direction == "open" then
- data.time = data.time+dtime
- local vel = math.sin(data.time)
- for i=1,3,1 do
- celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel))
- end
- for i=4,6,1 do
- celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2))
- end
- if data.time >= math.pi then
- for i=1,6,1 do
- celevator.doors.erefs[hash][i]:remove()
- end
- celevator.get_meta(data.positions[1]):set_string("doorstate","open")
- cardoors_moving[hash] = nil
- end
- elseif data.direction == "close" then
- local speed = 0.66
- if data.nudging then speed = 0.2 end
- data.time = data.time+(speed*dtime)
- local vel = math.sin(data.time)
- for i=1,3,1 do
- celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel*-speed))
- end
- for i=4,6,1 do
- celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*-speed))
- end
- if data.time >= math.pi then
- for _,ref in ipairs(celevator.doors.erefs[hash]) do
- ref:set_velocity(vector.new(0,0,0))
- end
- celevator.get_meta(data.positions[1]):set_string("doorstate","closed")
- cardoors_moving[hash] = nil
- local cartimer = minetest.get_node_timer(data.positions[1])
- cartimer:stop()
- end
- end
- else
- if data.direction == "open" then
- for i=1,6,1 do
- if celevator.doors.erefs[hash] and celevator.doors.erefs[hash][i] then
- celevator.doors.erefs[hash][i]:remove()
- end
- end
- celevator.get_meta(data.positions[1]):set_string("doorstate","open")
- cardoors_moving[hash] = nil
- elseif data.direction == "close" then
- local fdir = minetest.fourdir_to_dir(celevator.get_node(data.positions[1]).param2)
- celevator.doors.spawncardoors(data.positions[1],vector.rotate_around_axis(fdir,vector.new(0,1,0),math.pi))
- celevator.get_meta(data.positions[1]):set_string("doorstate","closed")
- cardoors_moving[hash] = nil
- end
- end
+ local doortype = typelookup(data.doortype)
+ celevator.doors[doortype].carstep(hash,data,dtime,cardoors_moving)
end
if save then
- celevator.storage:set_string("cardoors_moving",minetest.serialize(cardoors_moving))
+ celevator.storage:set_string("cardoors_moving",core.serialize(cardoors_moving))
end
+ celevator.doors.cardoor_step_enabled = save
end
-minetest.register_globalstep(celevator.doors.carstep)
+core.register_globalstep(celevator.doors.carstep)
-minetest.register_entity("celevator:car_door",{
+core.register_entity("celevator:car_door",{
initial_properties = {
visual = "wielditem",
visual_size = vector.new(0.667,0.667,0.667),
wield_item = "default:dirt",
static_save = false,
pointable = false,
- glow = minetest.LIGHT_MAX,
+ glow = core.LIGHT_MAX,
},
})
-function celevator.doors.spawncardoors(pos,dir)
- local refs = {}
- for x=2,1,-1 do
- for y=1,3,1 do
- local yaw = minetest.dir_to_yaw(dir)+math.pi
- 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 ref = minetest.add_entity(doorpos,"celevator:car_door")
- ref:set_yaw(yaw)
- ref:set_properties({
- wield_item = nname,
- })
- table.insert(refs,ref)
- end
- end
- return refs
+function celevator.doors.spawncardoors(pos,dir,doortype,replace)
+ doortype = typelookup(doortype)
+ return celevator.doors[doortype].spawncardoors(pos,dir,replace)
end
function celevator.doors.caropen(pos)
- local cardoors_moving = minetest.deserialize(celevator.storage:get_string("cardoors_moving")) or {}
- local hash = minetest.hash_node_position(pos)
- local cartimer = minetest.get_node_timer(pos)
- cartimer:start(0.25)
- if not cardoors_moving[hash] then
- local fdir = minetest.fourdir_to_dir(celevator.get_node(pos).param2)
- local otherpanel = vector.add(pos,vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2))
- local positions = {
- pos,
- vector.add(pos,vector.new(0,1,0)),
- vector.add(pos,vector.new(0,2,0)),
- otherpanel,
- vector.add(otherpanel,vector.new(0,1,0)),
- vector.add(otherpanel,vector.new(0,2,0)),
- }
- local erefs = {}
- for _,dpos in ipairs(positions) do
- local objs = minetest.get_objects_inside_radius(dpos,0.1)
- for _,obj in pairs(objs) do
- if obj:get_luaentity() and obj:get_luaentity().name == "celevator:car_door" then
- table.insert(erefs,obj)
- end
- end
- end
- cardoors_moving[hash] = {
- direction = "open",
- positions = positions,
- time = 0,
- opendir = vector.rotate_around_axis(fdir,vector.new(0,1,0),-math.pi/2),
- }
- minetest.sound_play("celevator_door_open",{
- pos = pos,
- gain = 0.4,
- max_hear_distance = 10
- },true)
- celevator.doors.erefs[hash] = erefs
- celevator.storage:set_string("cardoors_moving",minetest.serialize(cardoors_moving))
- local meta = celevator.get_meta(pos)
- meta:set_string("doordata",minetest.serialize(cardoors_moving[hash]))
- meta:set_string("doorstate","opening")
- elseif cardoors_moving[hash].direction == "close" then
- if cardoors_moving[hash].soundhandle then
- minetest.sound_stop(cardoors_moving[hash].soundhandle)
- end
- minetest.sound_play("celevator_door_reverse",{
- pos = pos,
- gain = 1,
- max_hear_distance = 10
- },true)
- minetest.sound_play("celevator_door_open",{
- pos = pos,
- gain = 0.4,
- start_time = math.max(0,2.75-cardoors_moving[hash].time),
- max_hear_distance = 10
- },true)
- cardoors_moving[hash].direction = "open"
- cardoors_moving[hash].time = math.pi-cardoors_moving[hash].time
- celevator.storage:set_string("cardoors_moving",minetest.serialize(cardoors_moving))
- end
+ local meta = celevator.get_meta(pos)
+ local doortype = typelookup(meta:get_string("doortype"))
+ celevator.doors[doortype].caropen(pos)
end
-function celevator.doors.carclose(pos,nudge)
- local cardoors_moving = minetest.deserialize(celevator.storage:get_string("cardoors_moving")) or {}
- local hash = minetest.hash_node_position(pos)
- if cardoors_moving[hash] then
- return
- end
+function celevator.doors.carclose(pos,...)
local meta = celevator.get_meta(pos)
- local state = meta:get_string("doorstate")
- if state ~= "open" then return end
- local data = minetest.deserialize(meta:get_string("doordata"))
- if not data then return end
- 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 soffset = data.opendir
- local foffset = vector.multiply(soffset,2)
- for i=1,3,1 do
- erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),foffset))
- end
- for i=4,6,1 do
- erefs[i]:set_pos(vector.add(erefs[i]:get_pos(),soffset))
- end
- celevator.doors.erefs[hash] = erefs
- if nudge then
- data.soundhandle = minetest.sound_play("celevator_nudge",{
- pos = pos,
- gain = 0.75,
- max_hear_distance = 10
- })
- else
- data.soundhandle = minetest.sound_play("celevator_door_close",{
- pos = pos,
- gain = 0.3,
- max_hear_distance = 10
- })
- end
- data.nudging = nudge
- cardoors_moving[hash] = data
- celevator.storage:set_string("cardoors_moving",minetest.serialize(cardoors_moving))
+ local doortype = typelookup(meta:get_string("doortype"))
+ celevator.doors[doortype].carclose(pos,...)
end
-minetest.register_abm({
+core.register_abm({
label = "Respawn car doors",
- nodenames = {"celevator:car_000"},
+ nodenames = {"group:_celevator_car_root"},
interval = 1,
chance = 1,
action = function(pos)
- if minetest.get_meta(pos):get_string("doorstate") ~= "closed" then return end
- local entitiesnearby = minetest.get_objects_inside_radius(pos,0.5)
+ if core.get_meta(pos):get_string("doorstate") ~= "closed" then return end
+ local entitiesnearby = core.get_objects_inside_radius(pos,0.5)
for _,i in pairs(entitiesnearby) do
if i:get_luaentity() and i:get_luaentity().name == "celevator:car_door" then
return
end
end
- local fdir = minetest.facedir_to_dir(minetest.get_node(pos).param2)
- celevator.doors.spawncardoors(pos,fdir)
+ local fdir = core.facedir_to_dir(core.get_node(pos).param2)
+ local carmeta = core.get_meta(pos)
+ local doortype = carmeta:get_string("doortype")
+ celevator.doors.spawncardoors(pos,fdir,doortype)
end,
})
-minetest.register_node("celevator:hwdoor_glass",{
- description = "Glass Elevator Hoistway Door",
- paramtype2 = "4dir",
- buildable_to = true,
- inventory_image = "celevator_door_glass_inventory.png",
- wield_image = "celevator_door_glass_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 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
- for x=0,1,1 do
- for y=0,2,1 do
- local piecename = string.format("celevator:hwdoor_%s_glass_%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
- end,
-})
-
-minetest.register_node("celevator:door_sill_single",{
- description = "Hoistway Door Sill, Single Track (you hacker you!)",
- drop = "",
- groups = {
- not_in_creative_inventory = 1,
- },
- paramtype = "light",
- drawtype = "nodebox",
- node_box = {
- type = "fixed",
- fixed = {
- {-0.5,-0.5,0.28,0.5,-0.495,0.5},
- },
- },
- tiles = {
- "celevator_door_sill_single.png^[transformR180",
- "celevator_cabinet_sides.png",
- },
-})
-
-minetest.register_node("celevator:door_sill_double",{
- description = "Hoistway Door Sill, Double Track (you hacker you!)",
+core.register_node("celevator:door_sill",{
+ description = S("Hoistway Door Sill, Double Track (you hacker you!)"),
drop = "",
groups = {
not_in_creative_inventory = 1,
@@ -728,26 +185,19 @@ minetest.register_node("celevator:door_sill_double",{
},
},
tiles = {
- "celevator_door_sill_double.png^[transformR180",
+ "celevator_door_sill.png^[transformR180",
"celevator_cabinet_sides.png",
},
})
-minetest.register_entity("celevator:door_sill",{
+core.register_entity("celevator:door_sill",{
initial_properties = {
visual = "wielditem",
visual_size = vector.new(0.667,0.667,0.667),
- wield_item = "celevator:door_sill_single",
+ wield_item = "celevator:door_sill",
static_save = false,
pointable = false,
- glow = minetest.LIGHT_MAX,
+ glow = core.LIGHT_MAX,
},
})
-minetest.register_lbm({
- label = "Respawn hoistway door sills",
- name = "celevator:spawn_sill",
- nodenames = {"celevator:hwdoor_fast_glass_bottom","celevator:hwdoor_slow_glass_bottom"},
- run_at_every_load = true,
- action = placesill,
-})
diff --git a/drive_entity.lua b/drive_entity.lua
index ae72bca..edc47c6 100644
--- a/drive_entity.lua
+++ b/drive_entity.lua
@@ -1,6 +1,12 @@
+local S = core.get_translator("celevator")
+
+local copfscontext = {}
+
+local keyswitchfscontext = {}
+
celevator.drives.entity = {
- name = "Drive",
- description = "Normal entity-based drive",
+ name = S("Elevator Drive"),
+ description = S("Normal entity-based drive"),
nname = "celevator:drive",
buzzsoundhandles = {},
movementsoundhandles = {},
@@ -9,30 +15,37 @@ celevator.drives.entity = {
carsoundstate = {},
entityinfo = {},
sheaverefs = {},
+ step_enabled = true, --Not a setting, is overwritten on globalstep, true here to check for running drives on startup
}
+local playerposlimits = {}
+
local function update_ui(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local apos = tonumber(meta:get_string("apos")) or 0
- local status = "Idle"
+ local status
local vel = tonumber(meta:get_string("vel")) or 0
local state = meta:get_string("state")
+ local velstr = string.format("%0.02f",math.abs(vel))
+ local aposstr = string.format("%0.02f",apos)
if state == "running" and vel > 0 then
- status = string.format("Running: Up, %0.02f m/s",vel)
+ status = S("Drive - Running: Up, @1m/s - Position: @2m",velstr,aposstr)
elseif state == "running" and vel < 0 then
- status = string.format("Running: Down, %0.02f m/s",math.abs(vel))
+ status = S("Drive - Running: Down, @1m/s - Position: @2m",velstr,aposstr)
elseif state == "fakerunning" and vel > 0 then
- status = string.format("Running (simulated): Up, %0.02f m/s",vel)
+ status = S("Drive - Running (simulated): Up, @1m/s - Position: @2m",velstr,aposstr)
elseif state == "fakerunning" and vel < 0 then
- status = string.format("Running (simulated): Down, %0.02f m/s",math.abs(vel))
+ status = S("Drive - Running (simulated): Down, @1m/s - Position: @2m",velstr,aposstr)
+ else
+ status = S("Drive - Idle")
end
- meta:set_string("infotext",string.format("Drive - %s - Position: %0.02f m",status,apos))
+ meta:set_string("infotext",status)
end
local function playbuzz(pos)
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
if celevator.drives.entity.buzzsoundhandles[hash] == "cancel" then return end
- celevator.drives.entity.buzzsoundhandles[hash] = minetest.sound_play("celevator_drive_run",{
+ celevator.drives.entity.buzzsoundhandles[hash] = core.sound_play("celevator_drive_run",{
pos = pos,
loop = true,
gain = 0.1,
@@ -40,78 +53,78 @@ local function playbuzz(pos)
end
local function startbuzz(pos)
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
if celevator.drives.entity.buzzsoundhandles[hash] == "cancel" then
celevator.drives.entity.buzzsoundhandles[hash] = nil
return
end
if celevator.drives.entity.buzzsoundhandles[hash] then return end
celevator.drives.entity.buzzsoundhandles[hash] = "pending"
- minetest.after(0.5,playbuzz,pos)
+ core.after(0.5,playbuzz,pos)
end
local function stopbuzz(pos)
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
if not celevator.drives.entity.buzzsoundhandles[hash] then return end
if celevator.drives.entity.buzzsoundhandles[hash] == "pending" then
celevator.drives.entity.buzzsoundhandles[hash] = "cancel"
end
if type(celevator.drives.entity.buzzsoundhandles[hash]) ~= "string" then
- minetest.sound_stop(celevator.drives.entity.buzzsoundhandles[hash])
+ core.sound_stop(celevator.drives.entity.buzzsoundhandles[hash])
celevator.drives.entity.buzzsoundhandles[hash] = nil
end
end
local function motorsound(pos,newstate)
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
local oldstate = celevator.drives.entity.movementsoundstate[hash]
oldstate = oldstate or "idle"
if oldstate == newstate then return end
- local carid = minetest.get_meta(pos):get_int("carid")
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carid = core.get_meta(pos):get_int("carid")
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not (carinfo and carinfo.machinepos) then return end
local oldhandle = celevator.drives.entity.movementsoundhandles[hash]
if newstate == "slow" then
if oldstate == "idle" then
- minetest.sound_play("celevator_brake_release",{
+ core.sound_play("celevator_brake_release",{
pos = carinfo.machinepos,
gain = 1,
},true)
- celevator.drives.entity.movementsoundhandles[hash] = minetest.sound_play("celevator_motor_slow",{
+ celevator.drives.entity.movementsoundhandles[hash] = core.sound_play("celevator_motor_slow",{
pos = carinfo.machinepos,
loop = true,
gain = 1,
})
elseif oldstate == "accel" or oldstate == "fast" or oldstate == "decel" then
- if oldhandle then minetest.sound_stop(oldhandle) end
- celevator.drives.entity.movementsoundhandles[hash] = minetest.sound_play("celevator_motor_slow",{
+ if oldhandle then core.sound_stop(oldhandle) end
+ celevator.drives.entity.movementsoundhandles[hash] = core.sound_play("celevator_motor_slow",{
pos = carinfo.machinepos,
loop = true,
gain = 1,
})
end
elseif newstate == "accel" then
- if oldhandle then minetest.sound_stop(oldhandle) end
- celevator.drives.entity.movementsoundhandles[hash] = minetest.sound_play("celevator_motor_accel",{
+ if oldhandle then core.sound_stop(oldhandle) end
+ celevator.drives.entity.movementsoundhandles[hash] = core.sound_play("celevator_motor_accel",{
pos = carinfo.machinepos,
gain = 1,
})
elseif newstate == "fast" then
- if oldhandle then minetest.sound_stop(oldhandle) end
- celevator.drives.entity.movementsoundhandles[hash] = minetest.sound_play("celevator_motor_fast",{
+ if oldhandle then core.sound_stop(oldhandle) end
+ celevator.drives.entity.movementsoundhandles[hash] = core.sound_play("celevator_motor_fast",{
pos = carinfo.machinepos,
loop = true,
gain = 1,
})
elseif newstate == "decel" then
- if oldhandle then minetest.sound_stop(oldhandle) end
- celevator.drives.entity.movementsoundhandles[hash] = minetest.sound_play("celevator_motor_decel",{
+ if oldhandle then core.sound_stop(oldhandle) end
+ celevator.drives.entity.movementsoundhandles[hash] = core.sound_play("celevator_motor_decel",{
pos = carinfo.machinepos,
gain = 1,
})
elseif newstate == "idle" then
- if oldhandle then minetest.sound_stop(oldhandle) end
- minetest.sound_play("celevator_brake_apply",{
+ if oldhandle then core.sound_stop(oldhandle) end
+ core.sound_play("celevator_brake_apply",{
pos = carinfo.machinepos,
gain = 1,
},true)
@@ -121,7 +134,7 @@ end
local function carsound(pos,newstate,speed)
if speed < 0.5 then return end
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
local oldstate = celevator.drives.entity.carsoundstate[hash]
oldstate = oldstate or "idle"
if oldstate == newstate then return end
@@ -131,37 +144,37 @@ local function carsound(pos,newstate,speed)
local oldhandle = celevator.drives.entity.carsoundhandles[hash]
local gain = math.min(1,speed/6)
if newstate == "accel" then
- if oldhandle then minetest.sound_stop(oldhandle) end
- celevator.drives.entity.carsoundhandles[hash] = minetest.sound_play("celevator_car_start",{
+ if oldhandle then core.sound_stop(oldhandle) end
+ celevator.drives.entity.carsoundhandles[hash] = core.sound_play("celevator_car_start",{
object = eref,
gain = gain,
})
- minetest.after(3,function()
+ core.after(3,function()
if celevator.drives.entity.carsoundstate[hash] == "accel" then
carsound(pos,"run",speed)
end
end)
elseif newstate == "run" then
- if oldhandle then minetest.sound_stop(oldhandle) end
- celevator.drives.entity.carsoundhandles[hash] = minetest.sound_play("celevator_car_run",{
+ if oldhandle then core.sound_stop(oldhandle) end
+ celevator.drives.entity.carsoundhandles[hash] = core.sound_play("celevator_car_run",{
object = eref,
loop = true,
gain = gain,
})
elseif newstate == "decel" then
- if oldhandle then minetest.sound_stop(oldhandle) end
- celevator.drives.entity.carsoundhandles[hash] = minetest.sound_play("celevator_car_stop",{
+ if oldhandle then core.sound_stop(oldhandle) end
+ celevator.drives.entity.carsoundhandles[hash] = core.sound_play("celevator_car_stop",{
object = eref,
gain = gain,
})
elseif newstate == "stopped" then
- if oldhandle then minetest.sound_stop(oldhandle) end
+ if oldhandle then core.sound_stop(oldhandle) end
end
celevator.drives.entity.carsoundstate[hash] = newstate
end
local function compareexchangesound(pos,compare,new)
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
local oldstate = celevator.drives.entity.movementsoundstate[hash]
if oldstate == compare then
motorsound(pos,new)
@@ -170,17 +183,17 @@ end
local function accelsound(pos)
motorsound(pos,"slow")
- minetest.after(1,compareexchangesound,pos,"slow","accel")
- minetest.after(4,compareexchangesound,pos,"accel","fast")
+ core.after(1,compareexchangesound,pos,"slow","accel")
+ core.after(4,compareexchangesound,pos,"accel","fast")
end
local function decelsound(pos)
motorsound(pos,"decel")
- minetest.after(2,compareexchangesound,pos,"decel","slow")
+ core.after(2,compareexchangesound,pos,"decel","slow")
end
-minetest.register_node("celevator:drive",{
- description = "Elevator "..celevator.drives.entity.name,
+core.register_node("celevator:drive",{
+ description = celevator.drives.entity.name,
groups = {
cracky = 1,
_celevator_drive = 1,
@@ -206,7 +219,7 @@ minetest.register_node("celevator:drive",{
},
_celevator_drive_type = "entity",
after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
meta:set_string("apos","0")
meta:set_string("dpos","0")
meta:set_string("vel","0")
@@ -220,38 +233,109 @@ minetest.register_node("celevator:drive",{
on_destruct = stopbuzz,
})
-minetest.register_entity("celevator:car_moving",{
+core.register_entity("celevator:car_moving",{
initial_properties = {
- visual = "wielditem",
- visual_size = vector.new(0.667,0.667,0.667),
- wield_item = "default:dirt",
+ visual = "node",
+ node = {name="air"},
static_save = false,
- glow = minetest.LIGHT_MAX,
+ glow = core.LIGHT_MAX,
pointable = false,
},
})
+core.register_entity("celevator:player_holder",{
+ initial_properties = {
+ visual = "cube",
+ textures = {
+ "blank.png",
+ "blank.png",
+ "blank.png",
+ "blank.png",
+ "blank.png",
+ "blank.png",
+ },
+ 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 = 40
+ 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/10),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)
+ local hash = core.hash_node_position(pos)
if nodes[hash] then return nodes end
nodes[hash] = true
- if minetest.get_item_group(celevator.get_node(pos).name,"_connects_xp") == 1 then
+ if core.get_item_group(celevator.get_node(pos).name,"_connects_xp") == 1 then
celevator.drives.entity.gathercar(vector.add(pos,vector.rotate_around_axis(vector.new(1,0,0),vector.new(0,1,0),yaw)),yaw,nodes)
end
- if minetest.get_item_group(celevator.get_node(pos).name,"_connects_xm") == 1 then
+ if core.get_item_group(celevator.get_node(pos).name,"_connects_xm") == 1 then
celevator.drives.entity.gathercar(vector.add(pos,vector.rotate_around_axis(vector.new(-1,0,0),vector.new(0,1,0),yaw)),yaw,nodes)
end
- if minetest.get_item_group(celevator.get_node(pos).name,"_connects_yp") == 1 then
+ if core.get_item_group(celevator.get_node(pos).name,"_connects_yp") == 1 then
celevator.drives.entity.gathercar(vector.add(pos,vector.new(0,1,0)),yaw,nodes)
end
- if minetest.get_item_group(celevator.get_node(pos).name,"_connects_ym") == 1 then
+ if core.get_item_group(celevator.get_node(pos).name,"_connects_ym") == 1 then
celevator.drives.entity.gathercar(vector.add(pos,vector.new(0,-1,0)),yaw,nodes)
end
- if minetest.get_item_group(celevator.get_node(pos).name,"_connects_zp") == 1 then
+ if core.get_item_group(celevator.get_node(pos).name,"_connects_zp") == 1 then
celevator.drives.entity.gathercar(vector.add(pos,vector.rotate_around_axis(vector.new(0,0,1),vector.new(0,1,0),yaw)),yaw,nodes)
end
- if minetest.get_item_group(celevator.get_node(pos).name,"_connects_zm") == 1 then
+ if core.get_item_group(celevator.get_node(pos).name,"_connects_zm") == 1 then
celevator.drives.entity.gathercar(vector.add(pos,vector.rotate_around_axis(vector.new(0,0,-1),vector.new(0,1,0),yaw)),yaw,nodes)
end
return nodes
@@ -259,18 +343,50 @@ 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)
- local eref = minetest.add_entity(pos,(ename or "celevator:car_moving"))
+ local attach = core.get_objects_inside_radius(pos,0.9)
+ local eref = core.add_entity(pos,(ename or "celevator:car_moving"))
eref:set_properties({
- wield_item = node.name,
+ node = {name = node.name},
+ })
+ eref:set_yaw(core.dir_to_yaw(core.fourdir_to_dir(node.param2)))
+ eref:set_armor_groups({
+ immortal = 1,
})
- 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 = core.registered_nodes[node.name] or {}
+ local nbox = ndef.selection_box or ndef.node_box
+ if nbox and nbox.fixed then
+ local selbox = {0,0,0,0,0,0}
+ if type(nbox.fixed[1]) ~= "table" then
+ selbox = table.copy(nbox.fixed)
+ else
+ for _,box in ipairs(nbox.fixed) do
+ for i=1,3 do
+ selbox[i] = math.min(selbox[i],box[i])
+ end
+ for i=4,6 do
+ selbox[i] = math.max(selbox[i],box[i])
+ end
+ end
+ end
+ selbox.rotate = true
+ eref:set_properties({selectionbox=selbox})
+ end
+ 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)
+ local topattach = core.get_objects_inside_radius(toppos,0.75)
for _,ref in pairs(topattach) do
table.insert(attach,ref)
end
@@ -285,16 +401,49 @@ function celevator.drives.entity.nodestoentities(nodes,ename)
}
if attachref:get_luaentity() and included[attachref:get_luaentity().name] then
table.insert(refs,attachref)
- else
+ elseif attachref:is_player() then
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)
+ local holder = core.add_entity(attachpos,"celevator:player_holder")
+ holder:set_attach(eref,"",vector.multiply(attachoffset,10),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.subtract(attachpos,basepos)
+ attachref:set_attach(eref,"",vector.multiply(attachoffset,10),vector.new(0,0,0))
+ end
+ end
+ local meta = celevator.get_meta(pos)
+ local carid = meta:get_int("carid")
+ if carid ~= 0 then
+ if core.get_item_group(node.name,"_has_cop") == 1 then
+ eref:set_properties({
+ pointable = true,
+ })
+ eref:get_luaentity().on_rightclick = function(self,player)
+ celevator.drives.entity.coprightclick(carid,player,self.object:get_pos())
+ end
+ elseif core.get_item_group(node.name,"_has_keyswitches") == 1 then
+ eref:set_properties({
+ pointable = true,
+ })
+ eref:get_luaentity().on_rightclick = function(self,player)
+ celevator.drives.entity.keyswitchrightclick(carid,player,self.object:get_pos())
+ end
end
end
end
- minetest.remove_node(pos)
+ core.remove_node(pos)
end
return refs
end
@@ -307,12 +456,10 @@ function celevator.drives.entity.entitiestonodes(refs,carid)
local ename = eref:get_luaentity() and eref:get_luaentity().name
if pos and (ename == "celevator:car_moving" or ename == "celevator:hwdoor_moving") then
pos = vector.round(pos)
- local node = {
- name = eref:get_properties().wield_item,
- param2 = minetest.dir_to_fourdir(minetest.yaw_to_dir(eref:get_yaw()))
- }
- if minetest.get_item_group(eref:get_properties().wield_item,"_connects_yp") ~= 1 then top = true end
- minetest.set_node(pos,node)
+ local node = eref:get_properties().node or {name="air"}
+ node.param2 = core.dir_to_fourdir(core.yaw_to_dir(eref:get_yaw()))
+ if core.get_item_group(node.name,"_connects_yp") ~= 1 then top = true end
+ core.set_node(pos,node)
eref:remove()
if carid then celevator.get_meta(pos):set_int("carid",carid) end
elseif pos and ename == "celevator:incar_pi_entity" then
@@ -329,14 +476,19 @@ function celevator.drives.entity.entitiestonodes(refs,carid)
["celevator:car_door"] = true,
["celevator:tapehead"] = true,
}
- for _,i in ipairs(minetest.get_objects_inside_radius(pos,0.9)) do
+ for _,i in ipairs(core.get_objects_inside_radius(pos,0.9)) do
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)
+ core.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)
@@ -352,15 +504,16 @@ function celevator.drives.entity.entitiestonodes(refs,carid)
end
function celevator.drives.entity.step(dtime)
- local entitydrives_running = minetest.deserialize(celevator.storage:get_string("entitydrives_running")) or {}
+ if not celevator.drives.entity.step_enabled then return end
+ local entitydrives_running = core.deserialize(celevator.storage:get_string("entitydrives_running")) or {}
local save = false
for i,hash in ipairs(entitydrives_running) do
save = true
- local pos = minetest.get_position_from_hash(hash)
+ local pos = core.get_position_from_hash(hash)
local node = celevator.get_node(pos)
local sound = false
if node.name == "ignore" then
- minetest.forceload_block(pos,true)
+ core.forceload_block(pos,true)
elseif node.name ~= "celevator:drive" then
table.remove(entitydrives_running,i)
else
@@ -373,10 +526,11 @@ 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"))
+ local origin = core.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))
+ core.log("error","[celevator] [entity drive] Invalid origin for drive at "..core.pos_to_string(pos))
meta:set_string("fault","badorigin")
table.remove(entitydrives_running,i)
return
@@ -391,10 +545,10 @@ function celevator.drives.entity.step(dtime)
end
end
local startv = vector.add(origin,vector.new(0,startpos,0))
- local hashes = celevator.drives.entity.gathercar(startv,minetest.dir_to_yaw(minetest.fourdir_to_dir(celevator.get_node(startv).param2)))
+ local hashes = celevator.drives.entity.gathercar(startv,core.dir_to_yaw(core.fourdir_to_dir(celevator.get_node(startv).param2)))
local nodes = {}
for carhash in pairs(hashes) do
- local carpos = minetest.get_position_from_hash(carhash)
+ local carpos = core.get_position_from_hash(carhash)
if vector.equals(startv,carpos) then
table.insert(nodes,1,carpos) --0,0,0 node must be first in the list
else
@@ -402,7 +556,12 @@ function celevator.drives.entity.step(dtime)
end
end
local carparam2 = celevator.get_node(nodes[1]).param2
+ local cardef = core.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 +591,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,core.dir_to_yaw(core.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
+ core.after(0.25,celevator.drives.entity.updatecopformspec,pos)
+ 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 +645,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,core.dir_to_yaw(core.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
+ core.after(0.25,celevator.drives.entity.updatecopformspec,pos)
+ 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
@@ -515,25 +688,40 @@ function celevator.drives.entity.step(dtime)
end
end
if save then
- celevator.storage:set_string("entitydrives_running",minetest.serialize(entitydrives_running))
+ celevator.storage:set_string("entitydrives_running",core.serialize(entitydrives_running))
end
+ celevator.drives.entity.step_enabled = save
end
-minetest.register_globalstep(celevator.drives.entity.step)
+core.register_globalstep(celevator.drives.entity.step)
function celevator.drives.entity.moveto(pos,target,inspection)
local meta = celevator.get_meta(pos)
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
- local origin = minetest.string_to_pos(meta:get_string("origin"))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ 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 = core.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))
+ core.log("error","[celevator] [entity drive] Invalid origin for drive at "..core.pos_to_string(pos))
meta:set_string("fault","badorigin")
return
end
- if target < 0 or origin.y + target > (carinfo.machinepos.y-3) then
+ if target < 0 or origin.y + target > (carinfo.machinepos.y-3) or target ~= target then
meta:set_string("fault","outofbounds")
return
end
@@ -553,8 +741,8 @@ function celevator.drives.entity.moveto(pos,target,inspection)
meta:set_string("state","start")
meta:set_int("inspection",inspection and 1 or 0)
meta:set_string("startpos",meta:get_string("apos"))
- local hash = minetest.hash_node_position(pos)
- local entitydrives_running = minetest.deserialize(celevator.storage:get_string("entitydrives_running")) or {}
+ local hash = core.hash_node_position(pos)
+ local entitydrives_running = core.deserialize(celevator.storage:get_string("entitydrives_running")) or {}
local running = false
for _,dhash in ipairs(entitydrives_running) do
if hash == dhash then
@@ -563,8 +751,9 @@ function celevator.drives.entity.moveto(pos,target,inspection)
end
end
if not running then
+ celevator.drives.entity.step_enabled = true
table.insert(entitydrives_running,hash)
- celevator.storage:set_string("entitydrives_running",minetest.serialize(entitydrives_running))
+ celevator.storage:set_string("entitydrives_running",core.serialize(entitydrives_running))
--Controller needs to see something so it knows the drive is running
local apos = tonumber(meta:get_string("apos"))
if apos and apos > target then
@@ -587,7 +776,7 @@ function celevator.drives.entity.estop(pos)
local apos = math.floor(tonumber(meta:get_string("apos"))+0.5)
meta:set_string("dpos",tostring(apos))
meta:set_string("apos",tostring(apos))
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
local handles = celevator.drives.entity.entityinfo[hash].handles
meta:set_string("state","stopped")
meta:set_string("vel","0")
@@ -596,11 +785,12 @@ function celevator.drives.entity.estop(pos)
stopbuzz(pos)
motorsound(pos,"idle")
if carid ~= 0 then celevator.drives.entity.sheavetonode(carid) end
- minetest.after(0.25,celevator.drives.entity.updatecopformspec,pos)
+ core.after(0.25,celevator.drives.entity.updatecopformspec,pos)
end
function celevator.drives.entity.setmaxvel(pos,maxvel)
+ if maxvel ~= maxvel then return end
local meta = celevator.get_meta(pos)
meta:set_string("maxvel",tostring(maxvel))
end
@@ -611,12 +801,12 @@ function celevator.drives.entity.rezero(pos)
end
function celevator.drives.entity.getstatus(pos,call2)
- local node = minetest.get_node(pos)
+ local node = core.get_node(pos)
if node.name == "ignore" and not call2 then
- minetest.forceload_block(pos,true)
+ core.forceload_block(pos,true)
return celevator.drives.entity.get_status(pos,true)
elseif node.name ~= "celevator:drive" then
- minetest.log("error","[celevator] [entity drive] Could not load drive status at "..minetest.pos_to_string(pos))
+ core.log("error","[celevator] [entity drive] Could not load drive status at "..core.pos_to_string(pos))
return {fault = "metaload"}
else
local meta = celevator.get_meta(pos)
@@ -635,27 +825,27 @@ function celevator.drives.entity.getstatus(pos,call2)
end
function celevator.drives.entity.movedoors(drivepos,direction,nudge)
- local drivehash = minetest.hash_node_position(drivepos)
- local entitydrives_running = minetest.deserialize(celevator.storage:get_string("entitydrives_running")) or {}
+ local drivehash = core.hash_node_position(drivepos)
+ local entitydrives_running = core.deserialize(celevator.storage:get_string("entitydrives_running")) or {}
local drivemeta = celevator.get_meta(drivepos)
for _,hash in pairs(entitydrives_running) do
if drivehash == hash then
- minetest.log("error","[celevator] [entity drive] Attempted to open doors while drive at "..minetest.pos_to_string(drivepos).." was still moving")
+ core.log("error","[celevator] [entity drive] Attempted to open doors while drive at "..core.pos_to_string(drivepos).." was still moving")
drivemeta:set_string("fault","doorinterlock")
return
end
end
- local origin = minetest.string_to_pos(drivemeta:get_string("origin"))
+ local origin = core.string_to_pos(drivemeta:get_string("origin"))
if not origin then
- minetest.log("error","[celevator] [entity drive] Invalid origin for drive at "..minetest.pos_to_string(drivepos))
+ core.log("error","[celevator] [entity drive] Invalid origin for drive at "..core.pos_to_string(drivepos))
drivemeta:set_string("fault","badorigin")
return
end
local apos = tonumber(drivemeta:get_string("apos")) or 0
local carpos = vector.add(origin,vector.new(0,apos,0))
local carnode = celevator.get_node(carpos)
- local hwdoorpos = vector.add(carpos,vector.rotate_around_axis(minetest.fourdir_to_dir(carnode.param2),vector.new(0,1,0),math.pi))
- local isroot = minetest.get_item_group(celevator.get_node(hwdoorpos).name,"_celevator_hwdoor_root") == 1
+ local hwdoorpos = vector.add(carpos,vector.rotate_around_axis(core.fourdir_to_dir(carnode.param2),vector.new(0,1,0),math.pi))
+ local isroot = core.get_item_group(celevator.get_node(hwdoorpos).name,"_celevator_hwdoor_root") == 1
if direction == "open" and (isroot or drivemeta:get_string("doorstate") == "closing") then
celevator.doors.hwopen(hwdoorpos,drivepos)
drivemeta:set_string("doorstate","opening")
@@ -671,27 +861,29 @@ end
function celevator.drives.entity.pibeep(drivepos)
local drivemeta = celevator.get_meta(drivepos)
- local origin = minetest.string_to_pos(drivemeta:get_string("origin"))
+ local origin = core.string_to_pos(drivemeta:get_string("origin"))
if not origin then
- minetest.log("error","[celevator] [entity drive] Invalid origin for drive at "..minetest.pos_to_string(drivepos))
+ core.log("error","[celevator] [entity drive] Invalid origin for drive at "..core.pos_to_string(drivepos))
drivemeta:set_string("fault","badorigin")
return
end
local apos = tonumber(drivemeta:get_string("apos")) or 0
local beeppos = vector.add(origin,vector.new(0,apos+2,0))
- minetest.sound_play("celevator_pi_beep",{
+ core.sound_play("celevator_pi_beep",{
pos = beeppos,
gain = 1,
},true)
end
local function carsearch(pos)
- for i=1,500,1 do
+ local maxdistance = tonumber(core.settings:get("celevator.max_height")) or 500
+ maxdistance = math.max(1,maxdistance)
+ for i=1,maxdistance,1 do
local searchpos = vector.subtract(pos,vector.new(0,i,0))
local node = celevator.get_node(searchpos)
- if minetest.get_item_group(node.name,"_celevator_car") == 1 then
- local yaw = minetest.dir_to_yaw(minetest.fourdir_to_dir(node.param2))
- local offsettext = minetest.registered_nodes[node.name]._position
+ if core.get_item_group(node.name,"_celevator_car") == 1 then
+ local yaw = core.dir_to_yaw(core.fourdir_to_dir(node.param2))
+ local offsettext = core.registered_nodes[node.name]._position
local xoffset = tonumber(string.sub(offsettext,1,1))
local yoffset = tonumber(string.sub(offsettext,2,2))
local zoffset = tonumber(string.sub(offsettext,3,3))
@@ -707,36 +899,36 @@ local function updatecarpos(pos)
if meta:get_int("carid") == 0 then return end
local carpos = carsearch(pos)
if carpos then
- meta:set_string("origin",minetest.pos_to_string(carpos))
- celevator.get_meta(carpos):set_string("machinepos",minetest.pos_to_string(pos))
- meta:set_string("infotext",string.format("Using car with origin %s",minetest.pos_to_string(carpos)))
+ meta:set_string("origin",core.pos_to_string(carpos))
+ celevator.get_meta(carpos):set_string("machinepos",core.pos_to_string(pos))
+ meta:set_string("infotext",S("Using car with origin @1",core.pos_to_string(carpos)))
local carid = meta:get_int("carid")
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not (carinfo and carinfo.controllerpos) then return end
carinfo.origin = carpos
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
local drivepos = celevator.controller.finddrive(carinfo.controllerpos)
if drivepos then
local drivemeta = celevator.get_meta(drivepos)
if drivemeta:get_string("state") == "uninit" then
- drivemeta:set_string("origin",minetest.pos_to_string(carpos))
+ drivemeta:set_string("origin",core.pos_to_string(carpos))
drivemeta:set_string("state","stopped")
drivemeta:set_int("carid",carid)
end
end
- local caryaw = minetest.dir_to_yaw(minetest.fourdir_to_dir(celevator.get_node(carpos).param2))
+ local caryaw = core.dir_to_yaw(core.fourdir_to_dir(celevator.get_node(carpos).param2))
local carnodes = celevator.drives.entity.gathercar(carpos,caryaw)
for hash in pairs(carnodes) do
- local carmeta = celevator.get_meta(minetest.get_position_from_hash(hash))
+ local carmeta = celevator.get_meta(core.get_position_from_hash(hash))
carmeta:set_int("carid",carid)
end
else
- meta:set_string("infotext","No car found! Punch to try again")
+ meta:set_string("infotext",S("No car found! Punch to try again"))
end
end
-minetest.register_node("celevator:machine",{
- description = "Elevator Hoist Machine",
+core.register_node("celevator:machine",{
+ description = S("Elevator Hoist Machine"),
groups = {
dig_immediate = 2,
_celevator_machine = 1,
@@ -780,54 +972,54 @@ minetest.register_node("celevator:machine",{
},
after_place_node = function(pos,player)
if not player:is_player() then
- minetest.remove_node(pos)
+ core.remove_node(pos)
return true
end
- local newnode = minetest.get_node(pos)
- local facedir = minetest.dir_to_yaw(minetest.fourdir_to_dir(newnode.param2))
+ local newnode = core.get_node(pos)
+ local facedir = core.dir_to_yaw(core.fourdir_to_dir(newnode.param2))
local motorpos = vector.add(pos,vector.rotate_around_axis(vector.new(-1,0,0),vector.new(0,1,0),facedir))
- local motorreplaces = minetest.get_node(motorpos).name
+ local motorreplaces = core.get_node(motorpos).name
local sheavepos = vector.add(pos,vector.rotate_around_axis(vector.new(0,0,-1),vector.new(0,1,0),facedir))
- local sheavereplaces = minetest.get_node(sheavepos).name
+ local sheavereplaces = core.get_node(sheavepos).name
local name = player:get_player_name()
- if not (minetest.registered_nodes[motorreplaces] and minetest.registered_nodes[motorreplaces].buildable_to) then
- minetest.chat_send_player(name,"Can't place machine here - no room for the motor (to the left)!")
- minetest.remove_node(pos)
+ if not (core.registered_nodes[motorreplaces] and core.registered_nodes[motorreplaces].buildable_to) then
+ core.chat_send_player(name,S("Can't place machine here - no room for the motor (to the left)!"))
+ core.remove_node(pos)
return true
end
- if minetest.is_protected(motorpos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
- minetest.chat_send_player(name,"Can't place machine here - space for the motor (to the left) is protected!")
- minetest.record_protection_violation(motorpos,name)
- minetest.remove_node(pos)
+ if core.is_protected(motorpos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ core.chat_send_player(name,S("Can't place machine here - space for the motor (to the left) is protected!"))
+ core.record_protection_violation(motorpos,name)
+ core.remove_node(pos)
return true
end
- if not (minetest.registered_nodes[sheavereplaces] and minetest.registered_nodes[sheavereplaces].buildable_to) then
- minetest.chat_send_player(name,"Can't place machine here - no room for the sheave (in front)!")
- minetest.remove_node(pos)
+ if not (core.registered_nodes[sheavereplaces] and core.registered_nodes[sheavereplaces].buildable_to) then
+ core.chat_send_player(name,S("Can't place machine here - no room for the sheave (in front)!"))
+ core.remove_node(pos)
return true
end
- if minetest.is_protected(sheavepos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
- minetest.chat_send_player(name,"Can't place machine here - space for the sheave (in front) is protected!")
- minetest.record_protection_violation(sheavepos,name)
- minetest.remove_node(pos)
+ if core.is_protected(sheavepos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ core.chat_send_player(name,S("Can't place machine here - space for the sheave (in front) is protected!"))
+ core.record_protection_violation(sheavepos,name)
+ core.remove_node(pos)
return true
end
- local meta = minetest.get_meta(pos)
- meta:set_string("formspec","formspec_version[7]size[8,5]field[0.5,0.5;7,1;carid;Car ID;]button[3,3.5;2,1;save;Save]")
- minetest.set_node(motorpos,{name="celevator:motor",param2=newnode.param2})
- minetest.set_node(sheavepos,{name="celevator:sheave",param2=newnode.param2})
+ local meta = core.get_meta(pos)
+ meta:set_string("formspec","formspec_version[7]size[8,5]field[0.5,0.5;7,1;carid;"..S("Car ID")..";]button[3,3.5;2,1;save;"..S("Save").."]")
+ core.set_node(motorpos,{name="celevator:motor",param2=newnode.param2})
+ core.set_node(sheavepos,{name="celevator:sheave",param2=newnode.param2})
end,
after_dig_node = function(pos,node)
- local facedir = minetest.dir_to_yaw(minetest.fourdir_to_dir(node.param2))
+ local facedir = core.dir_to_yaw(core.fourdir_to_dir(node.param2))
local motorpos = vector.add(pos,vector.rotate_around_axis(vector.new(-1,0,0),vector.new(0,1,0),facedir))
- if minetest.get_node(motorpos).name == "celevator:motor" then
- minetest.remove_node(motorpos)
+ if core.get_node(motorpos).name == "celevator:motor" then
+ core.remove_node(motorpos)
end
local sheavepos = vector.add(pos,vector.rotate_around_axis(vector.new(0,0,-1),vector.new(0,1,0),facedir))
- if minetest.get_node(sheavepos).name == "celevator:sheave" then
- minetest.remove_node(sheavepos)
+ if core.get_node(sheavepos).name == "celevator:sheave" then
+ core.remove_node(sheavepos)
end
- local erefs = minetest.get_objects_inside_radius(sheavepos,0.5)
+ local erefs = core.get_objects_inside_radius(sheavepos,0.5)
for _,ref in pairs(erefs) do
if ref:get_luaentity() and ref:get_luaentity().name == "celevator:sheave_moving" then
ref:remove()
@@ -835,26 +1027,26 @@ minetest.register_node("celevator:machine",{
end
end,
on_punch = function(pos)
- local meta = minetest.get_meta(pos)
- if not minetest.string_to_pos(meta:get_string("origin")) then
+ local meta = core.get_meta(pos)
+ if not core.string_to_pos(meta:get_string("origin")) then
updatecarpos(pos)
end
end,
on_receive_fields = function(pos,_,fields)
if tonumber(fields.carid) then
local carid = tonumber(fields.carid)
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then return end
local oldmachinepos = carinfo.machinepos
if oldmachinepos then
local oldmachine = celevator.get_node(oldmachinepos)
- if oldmachine.name == "celevator:machine" then
+ if oldmachine.name == "celevator:machine" and not vector.equals(pos,oldmachinepos) then
return
end
end
carinfo.machinepos = pos
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
- local meta = minetest.get_meta(pos)
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
+ local meta = core.get_meta(pos)
meta:set_int("carid",carid)
meta:set_string("formspec","")
updatecarpos(pos)
@@ -862,9 +1054,11 @@ minetest.register_node("celevator:machine",{
end,
})
-minetest.register_node("celevator:motor",{
- description = "Hoist Motor (you hacker you!)",
+core.register_node("celevator:motor",{
+ description = S("Hoist Motor (you hacker you!)"),
groups = {
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
drop = "",
@@ -896,9 +1090,11 @@ minetest.register_node("celevator:motor",{
},
})
-minetest.register_node("celevator:sheave",{
- description = "Sheave (you hacker you!)",
+core.register_node("celevator:sheave",{
+ description = S("Sheave (you hacker you!)"),
groups = {
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
drop = "",
@@ -929,9 +1125,11 @@ minetest.register_node("celevator:sheave",{
},
})
-minetest.register_node("celevator:sheave_centered",{
- description = "Centered Sheave (you hacker you!)",
+core.register_node("celevator:sheave_centered",{
+ description = S("Centered Sheave (you hacker you!)"),
groups = {
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
drop = "",
@@ -962,7 +1160,7 @@ minetest.register_node("celevator:sheave_centered",{
},
})
-minetest.register_entity("celevator:sheave_moving",{
+core.register_entity("celevator:sheave_moving",{
initial_properties = {
visual = "wielditem",
visual_size = vector.new(0.667,0.667,0.667),
@@ -973,13 +1171,13 @@ minetest.register_entity("celevator:sheave_moving",{
})
function celevator.drives.entity.sheavetoentity(carid)
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not (carinfo and carinfo.machinepos) then return end
- local dir = minetest.fourdir_to_dir(celevator.get_node(carinfo.machinepos).param2)
+ local dir = core.fourdir_to_dir(celevator.get_node(carinfo.machinepos).param2)
local pos = vector.add(carinfo.machinepos,vector.multiply(dir,-1))
- minetest.set_node(pos,{
+ core.set_node(pos,{
name = "celevator:sheave",
- param2 = minetest.dir_to_fourdir(dir),
+ param2 = core.dir_to_fourdir(dir),
})
local sheaverefs = celevator.drives.entity.nodestoentities({pos},"celevator:sheave_moving")
celevator.drives.entity.sheaverefs[carid] = sheaverefs
@@ -988,48 +1186,111 @@ function celevator.drives.entity.sheavetoentity(carid)
end
function celevator.drives.entity.sheavetonode(carid)
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not (carinfo and carinfo.machinepos) then return end
- local dir = minetest.fourdir_to_dir(celevator.get_node(carinfo.machinepos).param2)
+ local dir = core.fourdir_to_dir(celevator.get_node(carinfo.machinepos).param2)
local pos = vector.add(carinfo.machinepos,vector.multiply(dir,-1))
local erefs = celevator.drives.entity.sheaverefs[carid]
if erefs and erefs[1] then
erefs[1]:remove()
end
- minetest.set_node(pos,{
+ core.set_node(pos,{
name = "celevator:sheave",
- param2 = minetest.dir_to_fourdir(dir),
+ param2 = core.dir_to_fourdir(dir),
})
end
function celevator.drives.entity.updatecopformspec(drivepos)
- local entitydrives_running = minetest.deserialize(celevator.storage:get_string("entitydrives_running")) or {}
- if entitydrives_running[minetest.hash_node_position(drivepos)] then return end
+ local entitydrives_running = core.deserialize(celevator.storage:get_string("entitydrives_running")) or {}
+ if entitydrives_running[core.hash_node_position(drivepos)] then return end
local drivemeta = celevator.get_meta(drivepos)
local carid = drivemeta:get_int("carid")
if carid == 0 then return end
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then return end
local copformspec = celevator.get_meta(carinfo.controllerpos):get_string("copformspec")
local switchformspec = celevator.get_meta(carinfo.controllerpos):get_string("switchformspec")
- local origin = minetest.string_to_pos(drivemeta:get_string("origin"))
- if not origin then
- minetest.log("error","[celevator] [entity drive] Invalid origin for drive at "..minetest.pos_to_string(drivepos))
- drivemeta:set_string("fault","badorigin")
- return
+ for playername,context in pairs(copfscontext) do
+ if carid == context.carid then
+ core.show_formspec(playername,"celevator:cop",copformspec)
+ end
end
- local apos = tonumber(drivemeta:get_string("apos")) or 0
- if apos == math.floor(apos) then
- local carpos = vector.add(origin,vector.new(0,apos,0))
- local carnodes = celevator.drives.entity.gathercar(carpos,minetest.dir_to_yaw(minetest.fourdir_to_dir(celevator.get_node(carpos).param2)))
- 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
- celevator.get_meta(piecepos):set_string("formspec",copformspec)
- elseif piece.name == "celevator:car_000" then
- celevator.get_meta(piecepos):set_string("formspec",switchformspec)
- end
+ for playername,context in pairs(keyswitchfscontext) do
+ if carid == context.carid then
+ core.show_formspec(playername,"celevator:keyswitches",switchformspec)
end
end
end
+
+function celevator.drives.entity.coprightclick(carid,player,pos)
+ if type(player) == "userdata" then player = player:get_player_name() end
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ if not (carinfo and carinfo.controllerpos) then return end
+ if not celevator.controller.iscontroller(carinfo.controllerpos) then return end
+ local meta = celevator.get_meta(carinfo.controllerpos)
+ local formspec = meta:get_string("copformspec")
+ core.show_formspec(player,"celevator:cop",formspec)
+ copfscontext[player] = {carid = carid,pos = pos}
+end
+
+function celevator.drives.entity.keyswitchrightclick(carid,player,pos)
+ if type(player) == "userdata" then player = player:get_player_name() end
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ if not (carinfo and carinfo.controllerpos) then return end
+ if not celevator.controller.iscontroller(carinfo.controllerpos) then return end
+ local meta = celevator.get_meta(carinfo.controllerpos)
+ local formspec = meta:get_string("switchformspec")
+ core.show_formspec(player,"celevator:keyswitches",formspec)
+ keyswitchfscontext[player] = {carid = carid,pos = pos}
+end
+
+core.register_on_player_receive_fields(function(player,formname,fields)
+ local playername = player:get_player_name()
+ if formname == "celevator:cop" then
+ if fields.quit then
+ copfscontext[playername] = nil
+ end
+ local carid = (copfscontext[playername] or {}).carid
+ if not carid then return end
+ local coppos = copfscontext[playername].pos
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ if not carinfo then return end
+ local protected = core.is_protected(vector.round(coppos),playername) and not core.check_player_privs(playername,{protection_bypass=true})
+ local event = {
+ type = "cop",
+ fields = fields,
+ player = playername,
+ protected = protected,
+ }
+ if fields.alarm then
+ core.sound_play({name="celevator_alarm"},{pos=coppos,max_hear_distance=32,ephemeral=true})
+ elseif fields.phone then
+ core.sound_play({name="celevator_phone"},{pos=coppos,gain=0.3,max_hear_distance=8,ephemeral=true})
+ end
+ celevator.controller.run(carinfo.controllerpos,event)
+ return true
+ elseif formname == "celevator:keyswitches" then
+ if fields.quit then
+ keyswitchfscontext[playername] = nil
+ end
+ local carid = (keyswitchfscontext[playername] or {}).carid
+ if not carid then return end
+ local switchpos = keyswitchfscontext[playername].pos
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ if not carinfo then return end
+ if core.is_protected(switchpos,playername) and not core.check_player_privs(playername,{protection_bypass=true}) then
+ core.chat_send_player(playername,S("You don't have access to these switches."))
+ core.record_protection_violation(switchpos,playername)
+ return
+ end
+ local event = {
+ type = "copswitches",
+ fields = fields,
+ player = playername,
+ }
+ celevator.controller.run(carinfo.controllerpos,event)
+ return true
+ else
+ return false
+ end
+end)
diff --git a/drive_null.lua b/drive_null.lua
index 1a22e22..5fd2d5d 100644
--- a/drive_null.lua
+++ b/drive_null.lua
@@ -1,27 +1,34 @@
+local S = core.get_translator("celevator")
+
celevator.drives.null = {
- name = "Null Drive",
- description = "Simulation only, no movement, for testing and demonstration",
+ name = S("Null Drive"),
+ description = S("Simulation only, no movement, for testing and demonstration"),
nname = "celevator:drive_null",
soundhandles = {},
+ step_enabled = true, --Not a setting, is overwritten on globalstep, true here to check for running drives on startup
}
local function update_ui(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local apos = tonumber(meta:get_string("apos")) or 0
- local status = "Idle"
+ local status
local vel = tonumber(meta:get_string("vel")) or 0
+ local velstr = string.format("%0.02f",math.abs(vel))
+ local aposstr = string.format("%0.02f",apos)
if vel > 0 then
- status = string.format("Running: Up, %0.02f m/s",vel)
+ status = S("Null Drive - Running: Up, @1m/s - Position: @2m",velstr,aposstr)
elseif vel < 0 then
- status = string.format("Running: Down, %0.02f m/s",math.abs(vel))
+ status = S("Null Drive - Running: Down, @1m/s - Position: @2m",velstr,aposstr)
+ else
+ status = S("Null Drive - Idle")
end
- meta:set_string("infotext",string.format("Null Drive - %s - Position: %0.02f m",status,apos))
+ meta:set_string("infotext",status)
end
local function playbuzz(pos)
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
if celevator.drives.null.soundhandles[hash] == "cancel" then return end
- celevator.drives.null.soundhandles[hash] = minetest.sound_play("celevator_drive_run",{
+ celevator.drives.null.soundhandles[hash] = core.sound_play("celevator_drive_run",{
pos = pos,
loop = true,
gain = 0.4,
@@ -29,32 +36,33 @@ local function playbuzz(pos)
end
local function startbuzz(pos)
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
if celevator.drives.null.soundhandles[hash] == "cancel" then
celevator.drives.null.soundhandles[hash] = nil
return
end
if celevator.drives.null.soundhandles[hash] then return end
celevator.drives.null.soundhandles[hash] = "pending"
- minetest.after(0.5,playbuzz,pos)
+ core.after(0.5,playbuzz,pos)
end
local function stopbuzz(pos)
- local hash = minetest.hash_node_position(pos)
+ local hash = core.hash_node_position(pos)
if not celevator.drives.null.soundhandles[hash] then return end
if celevator.drives.null.soundhandles[hash] == "pending" then
celevator.drives.null.soundhandles[hash] = "cancel"
end
if type(celevator.drives.null.soundhandles[hash]) ~= "string" then
- minetest.sound_stop(celevator.drives.null.soundhandles[hash])
+ core.sound_stop(celevator.drives.null.soundhandles[hash])
celevator.drives.null.soundhandles[hash] = nil
end
end
-minetest.register_node("celevator:drive_null",{
+core.register_node("celevator:drive_null",{
description = celevator.drives.null.name,
groups = {
- cracky = 1,
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
not_in_creative_inventory = 1,
},
tiles = {
@@ -78,7 +86,7 @@ minetest.register_node("celevator:drive_null",{
},
_celevator_drive_type = "null",
after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
meta:set_string("apos","0")
meta:set_string("dpos","0")
meta:set_string("vel","0")
@@ -90,19 +98,20 @@ minetest.register_node("celevator:drive_null",{
})
function celevator.drives.null.step(dtime)
- local nulldrives_running = minetest.deserialize(celevator.storage:get_string("nulldrives_running")) or {}
+ if not celevator.drives.null.step_enabled then return end
+ local nulldrives_running = core.deserialize(celevator.storage:get_string("nulldrives_running")) or {}
local save = false
for i,hash in ipairs(nulldrives_running) do
save = true
- local pos = minetest.get_position_from_hash(hash)
+ local pos = core.get_position_from_hash(hash)
local node = celevator.get_node(pos)
local sound = false
if node.name == "ignore" then
- minetest.forceload_block(pos,true)
+ core.forceload_block(pos,true)
elseif node.name ~= "celevator:drive_null" then
table.remove(nulldrives_running,i)
else
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local apos = tonumber(meta:get_string("apos")) or 0
local dpos = tonumber(meta:get_string("dpos")) or 0
local maxvel = tonumber(meta:get_string("maxvel")) or 0.2
@@ -144,17 +153,18 @@ function celevator.drives.null.step(dtime)
end
end
if save then
- celevator.storage:set_string("nulldrives_running",minetest.serialize(nulldrives_running))
+ celevator.storage:set_string("nulldrives_running",core.serialize(nulldrives_running))
end
+ celevator.drives.null.step_enabled = save
end
-minetest.register_globalstep(celevator.drives.null.step)
+core.register_globalstep(celevator.drives.null.step)
function celevator.drives.null.moveto(pos,target)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
meta:set_string("dpos",tostring(target))
- local hash = minetest.hash_node_position(pos)
- local nulldrives_running = minetest.deserialize(celevator.storage:get_string("nulldrives_running")) or {}
+ local hash = core.hash_node_position(pos)
+ local nulldrives_running = core.deserialize(celevator.storage:get_string("nulldrives_running")) or {}
local running = false
for _,dhash in ipairs(nulldrives_running) do
if hash == dhash then
@@ -163,8 +173,9 @@ function celevator.drives.null.moveto(pos,target)
end
end
if not running then
+ celevator.drives.null.step_enabled = true
table.insert(nulldrives_running,hash)
- celevator.storage:set_string("nulldrives_running",minetest.serialize(nulldrives_running))
+ celevator.storage:set_string("nulldrives_running",core.serialize(nulldrives_running))
end
end
@@ -173,13 +184,13 @@ function celevator.drives.null.resetpos(pos)
end
function celevator.drives.null.estop(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
meta:set_string("dpos",meta:get_string("apos"))
meta:set_string("vel","0")
end
function celevator.drives.null.setmaxvel(pos,maxvel)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
meta:set_string("maxvel",tostring(maxvel))
end
@@ -188,35 +199,35 @@ function celevator.drives.null.rezero(pos)
end
function celevator.drives.null.movedoors(drivepos,direction)
- local drivehash = minetest.hash_node_position(drivepos)
- local nulldrives_running = minetest.deserialize(celevator.storage:get_string("nulldrives_running")) or {}
+ local drivehash = core.hash_node_position(drivepos)
+ local nulldrives_running = core.deserialize(celevator.storage:get_string("nulldrives_running")) or {}
for _,hash in pairs(nulldrives_running) do
if drivehash == hash then return end
end
- local drivemeta = minetest.get_meta(drivepos)
+ local drivemeta = core.get_meta(drivepos)
if direction == "open" then
drivemeta:set_string("doorstate","opening")
- minetest.after(math.pi+0.5,function()
- minetest.get_meta(drivepos):set_string("doorstate","open")
+ core.after(math.pi+0.5,function()
+ core.get_meta(drivepos):set_string("doorstate","open")
end)
elseif direction == "close" then
drivemeta:set_string("doorstate","closing")
- minetest.after((math.pi/0.66)+0.5,function()
- minetest.get_meta(drivepos):set_string("doorstate","closed")
+ core.after((math.pi/0.66)+0.5,function()
+ core.get_meta(drivepos):set_string("doorstate","closed")
end)
end
end
function celevator.drives.null.getstatus(pos,call2)
- local node = minetest.get_node(pos)
+ local node = core.get_node(pos)
if node.name == "ignore" and not call2 then
- minetest.forceload_block(pos,true)
+ core.forceload_block(pos,true)
return celevator.drives.null.get_status(pos,true)
elseif node.name ~= "celevator:drive_null" then
- minetest.log("error","[celevator] [null drive] Could not load drive status at "..minetest.pos_to_string(pos))
+ core.log("error","[celevator] [null drive] Could not load drive status at "..core.pos_to_string(pos))
return
else
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local ret = {}
ret.apos = tonumber(meta:get_string("apos")) or 0
ret.dpos = tonumber(meta:get_string("dpos")) or 0
@@ -232,7 +243,7 @@ function celevator.drives.null.resetfault(pos)
--This drive has no possible faults at this time
--(drive communication faults are generated by the controller),
--but the controller expects to be able to call this
- minetest.get_meta(pos):set_string("fault","")
+ core.get_meta(pos):set_string("fault","")
end
function celevator.drives.null.updatecopformspec()
diff --git a/framework.lua b/framework.lua
index 1793634..e2aed27 100644
--- a/framework.lua
+++ b/framework.lua
@@ -1,20 +1,20 @@
celevator = {
drives = {},
- storage = minetest.get_mod_storage(),
+ storage = core.get_mod_storage(),
}
function celevator.get_node(pos)
- local node = minetest.get_node_or_nil(pos)
+ local node = core.get_node_or_nil(pos)
if node then return node end
VoxelManip(pos,pos)
- return minetest.get_node(pos)
+ return core.get_node(pos)
end
function celevator.get_meta(pos)
- if minetest.get_node_or_nil(pos) then
- return minetest.get_meta(pos)
+ if core.get_node_or_nil(pos) then
+ return core.get_meta(pos)
else
VoxelManip(pos,pos)
- return minetest.get_meta(pos)
+ return core.get_meta(pos)
end
end
diff --git a/fs1switch.lua b/fs1switch.lua
index 5949250..49be80a 100644
--- a/fs1switch.lua
+++ b/fs1switch.lua
@@ -1,5 +1,7 @@
celevator.fs1switch = {}
+local S = core.get_translator("celevator")
+
local function maketex(switchpos,lit)
local tex = "celevator_fs1switch_"..switchpos..".png"
if lit then tex = tex.."^celevator_fs1switch_led.png" end
@@ -12,42 +14,42 @@ local nodebox = {
}
local function resetspring(pos)
- local node = minetest.get_node(pos)
+ local node = core.get_node(pos)
local offstates = {
["celevator:fs1switch_reset"] = "celevator:fs1switch_off",
["celevator:fs1switch_reset_lit"] = "celevator:fs1switch_off_lit",
}
if offstates[node.name] then
node.name = offstates[node.name]
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
end
end
local function rightclick(pos,node,player)
if not (player and player:is_player()) then return end
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
if meta:get_string("formspec") ~= "" 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 a key for this switch.")
- minetest.record_protection_violation(pos,name)
+ if core.is_protected(pos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ core.chat_send_player(name,S("You don't have a key for this switch."))
+ core.record_protection_violation(pos,name)
return
end
if node.name == "celevator:fs1switch_off" then
node.name = "celevator:fs1switch_on"
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
elseif node.name == "celevator:fs1switch_on" then
node.name = "celevator:fs1switch_reset"
- minetest.swap_node(pos,node)
- minetest.after(0.5,resetspring,pos)
+ core.swap_node(pos,node)
+ core.after(0.5,resetspring,pos)
elseif node.name == "celevator:fs1switch_off_lit" or node.name == "celevator:fs1switch_on_lit" then
node.name = "celevator:fs1switch_reset_lit"
- minetest.swap_node(pos,node)
- minetest.after(0.5,resetspring,pos)
+ core.swap_node(pos,node)
+ core.after(0.5,resetspring,pos)
end
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)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then return end
local controllerpos = carinfo.controllerpos
local dispatcher = false
@@ -56,7 +58,7 @@ local function rightclick(pos,node,player)
dispatcher = true
end
if not controllerpos then return end
- local controllermeta = minetest.get_meta(controllerpos)
+ local controllermeta = core.get_meta(controllerpos)
if controllermeta:get_int("carid") ~= carid then return end
if node.name == "celevator:fs1switch_reset" or node.name == "celevator:fs1switch_reset_lit" then
if dispatcher then
@@ -87,32 +89,41 @@ function celevator.fs1switch.setled(pos,on)
local node = celevator.get_node(pos)
if on and onstates[node.name] then
node.name = onstates[node.name]
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
elseif (not on) and offstates[node.name] then
node.name = offstates[node.name]
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
end
end
local function unpair(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.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)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not (carinfo and carinfo.fs1switches) then return end
for i,fs1switch in pairs(carinfo.fs1switches) do
if vector.equals(pos,fs1switch.pos) then
table.remove(carinfo.fs1switches,i)
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
end
end
end
local switchstates = {"off","on","reset"}
+local descriptions = {
+ off = S("Elevator Fire Service Phase 1 Keyswitch"),
+ on = S("Elevator Fire Service Phase 1 Keyswitch (on state - you hacker you!)"),
+ reset = S("Elevator Fire Service Phase 1 Keyswitch (reset state - you hacker you!)"),
+ offlit = S("Elevator Fire Service Phase 1 Keyswitch (lit - you hacker you!)"),
+ onlit = S("Elevator Fire Service Phase 1 Keyswitch (on state, lit - you hacker you!)"),
+ resetlit = S("Elevator Fire Service Phase 1 Keyswitch (reset state, lit - you hacker you!)"),
+}
+
for _,switchpos in ipairs(switchstates) do
- minetest.register_node("celevator:fs1switch_"..switchpos,{
- description = "Elevator Fire Service Phase 1 Keyswitch"..(switchpos == "off" and "" or string.format(" (%s state - you hacker you!)",switchpos)),
+ core.register_node("celevator:fs1switch_"..switchpos,{
+ description = descriptions[switchpos],
groups = {
dig_immediate = 2,
not_in_creative_inventory = (switchpos == "off" and 0 or 1),
@@ -136,36 +147,36 @@ for _,switchpos in ipairs(switchstates) do
fixed = nodebox,
},
after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("formspec","formspec_version[7]size[8,5]field[0.5,0.5;7,1;carid;Car ID;]button[3,3.5;2,1;save;Save]")
+ local meta = core.get_meta(pos)
+ meta:set_string("formspec","formspec_version[7]size[8,5]field[0.5,0.5;7,1;carid;"..S("Car ID")..";]button[3,3.5;2,1;save;"..S("Save").."]")
end,
on_receive_fields = function(pos,_,fields,player)
local carid = tonumber(fields.carid or 0)
if not (carid and carid >= 1 and carid == math.floor(carid)) then return end
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then return end
local controllerpos = carinfo.controllerpos or carinfo.dispatcherpos
if not controllerpos then return end
local name = player:get_player_name()
- if minetest.is_protected(controllerpos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
+ if core.is_protected(controllerpos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
if player:is_player() then
- minetest.chat_send_player(name,"Can't connect to a controller/dispatcher you don't have access to.")
- minetest.record_protection_violation(controllerpos,name)
+ core.chat_send_player(name,S("Can't connect to a controller/dispatcher you don't have access to."))
+ core.record_protection_violation(controllerpos,name)
end
return
end
if not carinfo.fs1switches then carinfo.fs1switches = {} end
table.insert(carinfo.fs1switches,{pos=pos})
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
- local meta = minetest.get_meta(pos)
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
+ local meta = core.get_meta(pos)
meta:set_int("carid",carid)
meta:set_string("formspec","")
end,
on_rightclick = rightclick,
on_destruct = unpair,
})
- minetest.register_node("celevator:fs1switch_"..switchpos.."_lit",{
- description = "Elevator Fire Service Phase 1 Keyswitch"..string.format(" (%s state, lit - you hacker you!)",switchpos),
+ core.register_node("celevator:fs1switch_"..switchpos.."_lit",{
+ description = descriptions[switchpos.."lit"],
groups = {
dig_immediate = 2,
not_in_creative_inventory = 1,
diff --git a/genericswitch.lua b/genericswitch.lua
index d52e9c9..71342f8 100644
--- a/genericswitch.lua
+++ b/genericswitch.lua
@@ -1,13 +1,15 @@
+local S = core.get_translator("celevator")
+
local inputoptions = {
{
id = "none",
- desc = "(none)",
+ desc = S("(none)"),
func_on = function() end,
needsfloor = false,
},
{
id = "carcall",
- desc = "Car Call at Landing:",
+ desc = S("Car Call at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -19,7 +21,7 @@ local inputoptions = {
},
{
id = "upcall",
- desc = "Up Call (simplex car) at Landing:",
+ desc = S("Up Call (simplex car) at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -31,7 +33,7 @@ local inputoptions = {
},
{
id = "downcall",
- desc = "Down Call (simplex car) at Landing:",
+ desc = S("Down Call (simplex car) at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -43,7 +45,7 @@ local inputoptions = {
},
{
id = "swingupcall",
- desc = "Up Call (swing) at Landing:",
+ desc = S("Up Call (swing) at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -55,7 +57,7 @@ local inputoptions = {
},
{
id = "swingdowncall",
- desc = "Down Call (swing) at Landing:",
+ desc = S("Down Call (swing) at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -67,7 +69,7 @@ local inputoptions = {
},
{
id = "fs1off",
- desc = "Deactivate Fire Service Phase 1",
+ desc = S("Deactivate Fire Service Phase 1"),
func_on = function(controllerpos)
celevator.controller.run(controllerpos,{
type = "fs1switch",
@@ -78,7 +80,7 @@ local inputoptions = {
},
{
id = "fs1on",
- desc = "Activate Fire Service (main landing) Phase 1",
+ desc = S("Activate Fire Service (main landing) Phase 1"),
func_on = function(controllerpos)
celevator.controller.run(controllerpos,{
type = "fs1switch",
@@ -89,7 +91,7 @@ local inputoptions = {
},
{
id = "fs1onalt",
- desc = "Activate Fire Service (alternate landing) Phase 1",
+ desc = S("Activate Fire Service (alternate landing) Phase 1"),
func_on = function(controllerpos)
celevator.controller.run(controllerpos,{
type = "fs1switch",
@@ -101,7 +103,7 @@ local inputoptions = {
},
{
id = "mrsmoke",
- desc = "Machine Room or Hoistway Smoke Detector",
+ desc = S("Machine Room or Hoistway Smoke Detector"),
func_on = function(controllerpos)
celevator.controller.run(controllerpos,{
type = "mrsmoke",
@@ -111,7 +113,7 @@ local inputoptions = {
},
{
id = "secdeny",
- desc = "Lock Car Calls at Landing:",
+ desc = S("Lock Car Calls at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -126,7 +128,7 @@ local inputoptions = {
},
{
id = "secauth",
- desc = "Require Auth for Car Calls at Landing:",
+ desc = S("Require Auth for Car Calls at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -141,7 +143,7 @@ local inputoptions = {
},
{
id = "secallow",
- desc = "Unlock Car Calls at Landing:",
+ desc = S("Unlock Car Calls at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -154,18 +156,42 @@ local inputoptions = {
end,
needsfloor = true,
},
+ {
+ id = "swingon",
+ desc = S("Activate Swing Operation"),
+ func_on = function(controllerpos)
+ celevator.controller.run(controllerpos,{
+ type = "remotemsg",
+ channel = "swing",
+ msg = true,
+ })
+ end,
+ needsfloor = false,
+ },
+ {
+ id = "swingoff",
+ desc = S("Deactivate Swing Operation"),
+ func_on = function(controllerpos)
+ celevator.controller.run(controllerpos,{
+ type = "remotemsg",
+ channel = "swing",
+ msg = false,
+ })
+ end,
+ needsfloor = false,
+ },
}
local dinputoptions = {
{
id = "none",
- desc = "(none)",
+ desc = S("(none)"),
func_on = function() end,
needsfloor = false,
},
{
id = "upcall",
- desc = "Up Call at Landing:",
+ desc = S("Up Call at Landing:"),
func_on = function(dispatcherpos,floor)
celevator.dispatcher.run(dispatcherpos,{
type = "remotemsg",
@@ -177,7 +203,7 @@ local dinputoptions = {
},
{
id = "downcall",
- desc = "Down Call at Landing:",
+ desc = S("Down Call at Landing:"),
func_on = function(dispatcherpos,floor)
celevator.dispatcher.run(dispatcherpos,{
type = "remotemsg",
@@ -189,7 +215,7 @@ local dinputoptions = {
},
{
id = "fs1off",
- desc = "Deactivate Fire Service Phase 1",
+ desc = S("Deactivate Fire Service Phase 1"),
func_on = function(dispatcherpos)
celevator.dispatcher.run(dispatcherpos,{
type = "fs1switch",
@@ -200,7 +226,7 @@ local dinputoptions = {
},
{
id = "fs1on",
- desc = "Activate Fire Service Phase 1",
+ desc = S("Activate Fire Service Phase 1"),
func_on = function(dispatcherpos)
celevator.dispatcher.run(dispatcherpos,{
type = "fs1switch",
@@ -212,46 +238,46 @@ local dinputoptions = {
}
local function updateinputform(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local dmode = meta:get_int("dispatcher") == 1
- local fs = "formspec_version[7]size[8,8.5]"
- fs = fs.."tabheader[0,0;1;tab;Controller,Dispatcher;"..(dmode and "2" or "1")..";true;true]"
- fs = fs.."vertlabel[0.33,1;ON]"
- fs = fs.."dropdown[1,0.5;6,1;signal_on;"
+ local fs = "formspec_version[7]size[9,8.5]"
+ fs = fs.."tabheader[0,0;1;tab;"..S("Controller")..","..S("Dispatcher")..";"..(dmode and "2" or "1")..";true;true]"
+ fs = fs.."vertlabel[0.33,1;"..S("ON").."]"
+ fs = fs.."dropdown[1,0.5;7,1;signal_on;"
local selected_on = 1
local currentid_on = meta:get_string("signal_on")
for k,v in ipairs(dmode and dinputoptions or inputoptions) do
- fs = fs..minetest.formspec_escape(v.desc)..","
+ fs = fs..core.formspec_escape(v.desc)..","
if v.id == currentid_on then selected_on = k end
end
fs = string.sub(fs,1,-2)
fs = fs..";"..selected_on..";false]"
- fs = fs.."field[0.5,2;3,1;carid;"..(dmode and "Dispatcher ID" or "Car ID")..";${carid}]"
- fs = fs.."field[4.5,2;3,1;floor_on;Landing Number;${floor_on}]"
- fs = fs.."box[0,3.25;8,0.1;#CCCCCC]"
- fs = fs.."vertlabel[0.33,4;OFF]"
- fs = fs.."dropdown[1,3.5;6,1;signal_off;"
+ fs = fs.."field[0.5,2;3,1;carid;"..(dmode and S("Dispatcher ID") or S("Car ID"))..";${carid}]"
+ fs = fs.."field[4.5,2;3,1;floor_on;"..S("Landing Number")..";${floor_on}]"
+ fs = fs.."box[0,3.25;9,0.1;#CCCCCC]"
+ fs = fs.."vertlabel[0.33,4;"..S("OFF").."]"
+ fs = fs.."dropdown[1,3.5;7,1;signal_off;"
local selected_off = 1
local currentid_off = meta:get_string("signal_off")
for k,v in ipairs(dmode and dinputoptions or inputoptions) do
- fs = fs..minetest.formspec_escape(v.desc)..","
+ fs = fs..core.formspec_escape(v.desc)..","
if v.id == currentid_off then selected_off = k end
end
fs = string.sub(fs,1,-2)
fs = fs..";"..selected_off..";false]"
- fs = fs.."field[4.5,5;3,1;floor_off;Landing Number;${floor_off}]"
- fs = fs.."label[1.5,6.5;Not all signal options require a landing number.]"
- fs = fs.."button_exit[2.5,7;3,1;save;Save]"
+ fs = fs.."field[4.5,5;3,1;floor_off;"..S("Landing Number")..";${floor_off}]"
+ fs = fs.."label[1.5,6.5;"..S("Not all signal options require a landing number.").."]"
+ fs = fs.."button_exit[2.5,7;3,1;save;"..S("Save").."]"
meta:set_string("formspec",fs)
end
local function handleinputfields(pos,_,fields,player)
if fields.quit and not fields.save then return end
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local name = player:get_player_name()
- if minetest.is_protected(pos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
+ if core.is_protected(pos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
if player:is_player() then
- minetest.record_protection_violation(pos,name)
+ core.record_protection_violation(pos,name)
end
return
end
@@ -260,24 +286,24 @@ local function handleinputfields(pos,_,fields,player)
if not tonumber(fields.carid) then return end
meta:set_int("carid",fields.carid)
local carid = tonumber(fields.carid)
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {}
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {}
if dmode then
if not carinfo.dispatcherpos then return end
if not celevator.dispatcher.isdispatcher(carinfo.dispatcherpos) then return end
- if minetest.is_protected(carinfo.dispatcherpos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
+ if core.is_protected(carinfo.dispatcherpos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
if player:is_player() then
- minetest.chat_send_player(name,"Can't connect to a dispatcher you don't have access to.")
- minetest.record_protection_violation(carinfo.dispatcherpos,name)
+ core.chat_send_player(name,S("Can't connect to a dispatcher you don't have access to."))
+ core.record_protection_violation(carinfo.dispatcherpos,name)
end
return
end
else
if not carinfo.controllerpos then return end
if not celevator.controller.iscontroller(carinfo.controllerpos) then return end
- if minetest.is_protected(carinfo.controllerpos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
+ if core.is_protected(carinfo.controllerpos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
if player:is_player() then
- minetest.chat_send_player(name,"Can't connect to a controller you don't have access to.")
- minetest.record_protection_violation(carinfo.controllerpos,name)
+ core.chat_send_player(name,S("Can't connect to a controller you don't have access to."))
+ core.record_protection_violation(carinfo.controllerpos,name)
end
return
end
@@ -305,22 +331,22 @@ local function handleinputfields(pos,_,fields,player)
meta:set_string("signal_on",def_on.id)
meta:set_string("signal_off",def_off.id)
updateinputform(pos)
- local infotext = carid.." - "..def_on.desc..(def_on.needsfloor and " "..floor_on or "")
+ local infotext = " - "..def_on.desc..(def_on.needsfloor and " "..floor_on or "")
if def_on.id == "none" or def_off.id ~= "none" then
infotext = infotext.." / "..def_off.desc..(def_off.needsfloor and " "..floor_off or "")
end
if dmode then
- infotext = "Dispatcher: "..infotext
+ infotext = S("Dispatcher: @1",carid)..infotext
else
- infotext = "Car: "..infotext
+ infotext = S("Car: @1",carid)..infotext
end
meta:set_string("infotext",infotext)
if def_on.id ~= "none" or def_off.id ~= "none" then
meta:set_string("formspec","")
local momentary = def_off.id == "none"
- local node = minetest.get_node(pos)
+ local node = core.get_node(pos)
node.name = (momentary and "celevator:genericswitch_momentary_off" or "celevator:genericswitch_maintained_off")
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
end
elseif fields.tab then
meta:set_int("dispatcher",tonumber(fields.tab)-1)
@@ -329,10 +355,10 @@ local function handleinputfields(pos,_,fields,player)
end
local function handleinput(pos,on)
- local meta = minetest.get_meta(pos)
+ local meta = core.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))) or {}
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {}
local dmode = meta:get_int("dispatcher") == 1
if dmode then
if not carinfo.dispatcherpos then return end
@@ -358,8 +384,8 @@ local function handleinput(pos,on)
end
end
-minetest.register_node("celevator:genericswitch",{
- description = "Elevator Keyswitch",
+core.register_node("celevator:genericswitch",{
+ description = S("Elevator Keyswitch"),
tiles = {
"celevator_cabinet_sides.png",
"celevator_cabinet_sides.png",
@@ -381,15 +407,15 @@ minetest.register_node("celevator:genericswitch",{
},
},
after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
meta:set_int("floor",1)
updateinputform(pos)
end,
on_receive_fields = handleinputfields,
})
-minetest.register_node("celevator:genericswitch_maintained_off",{
- description = "Elevator Keyswitch (maintained, off state - you hacker you!)",
+core.register_node("celevator:genericswitch_maintained_off",{
+ description = S("Elevator Keyswitch (maintained, off state - you hacker you!)"),
tiles = {
"celevator_cabinet_sides.png",
"celevator_cabinet_sides.png",
@@ -414,19 +440,19 @@ minetest.register_node("celevator:genericswitch_maintained_off",{
},
on_rightclick = function(pos,node,player)
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 a key for this switch.")
- minetest.record_protection_violation(pos,name)
+ if core.is_protected(pos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ core.chat_send_player(name,S("You don't have a key for this switch."))
+ core.record_protection_violation(pos,name)
return
end
node.name = "celevator:genericswitch_maintained_on"
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
handleinput(pos,true)
end,
})
-minetest.register_node("celevator:genericswitch_maintained_on",{
- description = "Elevator Keyswitch (maintained, on state - you hacker you!)",
+core.register_node("celevator:genericswitch_maintained_on",{
+ description = S("Elevator Keyswitch (maintained, on state - you hacker you!)"),
tiles = {
"celevator_cabinet_sides.png",
"celevator_cabinet_sides.png",
@@ -451,19 +477,19 @@ minetest.register_node("celevator:genericswitch_maintained_on",{
},
on_rightclick = function(pos,node,player)
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 a key for this switch.")
- minetest.record_protection_violation(pos,name)
+ if core.is_protected(pos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ core.chat_send_player(name,S("You don't have a key for this switch."))
+ core.record_protection_violation(pos,name)
return
end
node.name = "celevator:genericswitch_maintained_off"
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
handleinput(pos,false)
end,
})
-minetest.register_node("celevator:genericswitch_momentary_off",{
- description = "Elevator Keyswitch (momentary, off state - you hacker you!)",
+core.register_node("celevator:genericswitch_momentary_off",{
+ description = S("Elevator Keyswitch (momentary, off state - you hacker you!)"),
tiles = {
"celevator_cabinet_sides.png",
"celevator_cabinet_sides.png",
@@ -488,26 +514,26 @@ minetest.register_node("celevator:genericswitch_momentary_off",{
},
on_rightclick = function(pos,node,player)
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 a key for this switch.")
- minetest.record_protection_violation(pos,name)
+ if core.is_protected(pos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
+ core.chat_send_player(name,S("You don't have a key for this switch."))
+ core.record_protection_violation(pos,name)
return
end
node.name = "celevator:genericswitch_momentary_on"
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
handleinput(pos,true)
- minetest.after(1,function()
- local newnode = minetest.get_node(pos)
+ core.after(1,function()
+ local newnode = core.get_node(pos)
if newnode.name == "celevator:genericswitch_momentary_on" then
newnode.name = "celevator:genericswitch_momentary_off"
- minetest.swap_node(pos,newnode)
+ core.swap_node(pos,newnode)
end
end)
end,
})
-minetest.register_node("celevator:genericswitch_momentary_on",{
- description = "Elevator Keyswitch (momentary, on state - you hacker you!)",
+core.register_node("celevator:genericswitch_momentary_on",{
+ description = S("Elevator Keyswitch (momentary, on state - you hacker you!)"),
tiles = {
"celevator_cabinet_sides.png",
"celevator_cabinet_sides.png",
diff --git a/governor.lua b/governor.lua
new file mode 100644
index 0000000..d4e9da6
--- /dev/null
+++ b/governor.lua
@@ -0,0 +1,137 @@
+local S = core.get_translator("celevator")
+
+local function spawngovsheave(pos)
+ local entitiesnearby = core.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 = core.add_entity(pos,"celevator:governor_sheave")
+ local fdir = core.fourdir_to_dir(core.get_node(pos).param2)
+ local yaw = core.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
+
+core.register_node("celevator:governor",{
+ description = S("Elevator Governor"),
+ groups = {
+ cracky = 3,
+ oddly_breakable_by_hand = 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)
+ core.get_meta(pos):set_string("formspec","field[carid;"..S("Car ID")..";]")
+ spawngovsheave(pos)
+ end,
+ after_dig_node = function(pos)
+ local entitiesnearby = core.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 = core.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 = core.get_meta(pos)
+ meta:set_string("controllerpos",core.pos_to_string(carinfo.controllerpos))
+ meta:set_string("formspec","")
+ end,
+})
+
+core.register_node("celevator:governor_sheave",{
+ description = S("Governor Sheave (you hacker you!)"),
+ groups = {
+ cracky = 3,
+ oddly_breakable_by_hand = 1,
+ 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 = {},
+ },
+})
+
+core.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())
+ if not core.compare_block_status(governorpos,"active") then return self.object:remove() end
+ local governormeta = celevator.get_meta(governorpos)
+ local controllerpos = core.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,
+})
+
+core.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..02c1264 100644
--- a/init.lua
+++ b/init.lua
@@ -1,7 +1,16 @@
local components = {
"framework",
"car",
+ "car_standard",
+ "car_glassback",
+ "car_metal",
+ "car_metalglass",
+ "car_fullglass",
"doors",
+ "door_2speedglass",
+ "door_2speedmetal",
+ "door_centerglass",
+ "door_centermetal",
"drive_null",
"drive_entity",
"controller",
@@ -12,19 +21,22 @@ local components = {
"dbdkiosk",
"genericswitch",
"decorations",
+ "governor",
"crafts",
+ "chatcommands",
}
local integrations = {
"laptop",
"mesecons",
"digilines",
+ "digistuff",
}
for _,i in ipairs(integrations) do
- if minetest.get_modpath(i) then table.insert(components,i) end
+ if core.get_modpath(i) then table.insert(components,i) end
end
for _,v in ipairs(components) do
- dofile(string.format("%s%s%s.lua",minetest.get_modpath("celevator"),DIR_DELIM,v))
+ dofile(string.format("%s/%s.lua",core.get_modpath("celevator"),v))
end
diff --git a/laptop.lua b/laptop.lua
index a65739c..a44bf2b 100644
--- a/laptop.lua
+++ b/laptop.lua
@@ -1,11 +1,13 @@
+local S = core.get_translator("celevator")
+
laptop.register_app("celevator",{
app_name = "mView",
- app_info = "Remote interface for MTronic XT elevator controllers",
+ app_info = S("Remote interface for MTronic XT elevator controllers"),
app_icon = "celevator_laptop_icon.png",
formspec_func = function(_,mtos)
local ram = mtos.bdev:get_app_storage("ram","celevator")
local mem = mtos.bdev:get_app_storage("hdd","celevator")
- if not mem then return mtos.theme:get_label("0.5,0.5","This application requires a hard disk drive.") end
+ if not mem then return mtos.theme:get_label("0.5,0.5",S("This application requires a hard disk drive.")) end
if not mem.connections then mem.connections = {} end
if not ram.screenstate then ram.screenstate = (#mem.connections > 0 and "connections" or "welcome") end
if not mem.selectedconnection then mem.selectedconnection = 1 end
@@ -16,73 +18,77 @@ laptop.register_app("celevator",{
if ram.screenstate == "welcome" then
fs = fs.."background9[5.5,1;4,2;celevator_fs_bg.png;false;3]"
fs = fs.."image[5.75,1;4,2;celevator_logo.png]"
- fs = fs..mtos.theme:get_label("2,4","Welcome to the mView remote interface for MTronic XT elevator controllers!")
- fs = fs..mtos.theme:get_label("2,6","Add a connection to get started.")
- fs = fs..mtos.theme:get_button("5.5,7;4,1","major","connections","Add/Edit Connections")
+ fs = fs..mtos.theme:get_label("2,4",S("Welcome to the mView remote interface for MTronic XT elevator controllers!"))
+ fs = fs..mtos.theme:get_label("2,6",S("Add a connection to get started."))
+ fs = fs..mtos.theme:get_button("5.5,7;4,1","major","connections",S("Add/Edit Connections"))
elseif ram.screenstate == "connections" then
- fs = fs..mtos.theme:get_label("0.5,0.5","MANAGE CONNECTIONS")
+ fs = fs..mtos.theme:get_label("0.5,0.5",S("MANAGE CONNECTIONS"))
if #mem.connections > 0 then
fs = fs.."textlist[1,2;6,7;connection;"
for i=#mem.connections,1,-1 do
- local text = string.format("ID %d - %s",mem.connections[i].carid,mem.connections[i].name)
- fs = fs..minetest.formspec_escape(text)
+ local text = S("ID @1 - @2",mem.connections[i].carid,mem.connections[i].name)
+ fs = fs..core.formspec_escape(text)
fs = fs..(i==1 and "" or ",")
end
fs = fs..";"..tostring(#mem.connections-mem.selectedconnection+1)..";false]"
else
- fs = fs..mtos.theme:get_label("1,2","No Connections")
+ fs = fs..mtos.theme:get_label("1,2",S("No Connections"))
end
- fs = fs..mtos.theme:get_button("8,2;3,1","major","new","New Connection")
+ fs = fs..mtos.theme:get_button("8,2;3,1","major","new",S("New Connection"))
if mem.connections[mem.selectedconnection] then
- fs = fs..mtos.theme:get_button("8,3;3,1","major","edit","Edit Connection")
- fs = fs..mtos.theme:get_button("8,4;3,1","major","delete","Delete Connection")
- fs = fs..mtos.theme:get_button("8,7;3,1","major","connect","Connect >")
- if #mem.connections > mem.selectedconnection then fs = fs..mtos.theme:get_button("8,5;3,1","major","moveup","Move Up") end
- if mem.selectedconnection > 1 then fs = fs..mtos.theme:get_button("8,6;3,1","major","movedown","Move Down") end
+ fs = fs..mtos.theme:get_button("8,3;3,1","major","edit",S("Edit Connection"))
+ fs = fs..mtos.theme:get_button("8,4;3,1","major","delete",S("Delete Connection"))
+ fs = fs..mtos.theme:get_button("8,7;3,1","major","connect",S("Connect >"))
+ if #mem.connections > mem.selectedconnection then fs = fs..mtos.theme:get_button("8,5;3,1","major","moveup",S("Move Up")) end
+ if mem.selectedconnection > 1 then fs = fs..mtos.theme:get_button("8,6;3,1","major","movedown",S("Move Down")) end
end
elseif ram.screenstate == "newconnection" then
- fs = fs..mtos.theme:get_label("0.5,0.5","NEW CONNECTION")
- fs = fs..mtos.theme:get_label("0.5,1","Please enter the ID you would like to connect to and a name for the connection.")
- fs = fs..mtos.theme:get_label("0.7,1.8","ID")
- fs = fs..mtos.theme:get_label("3.7,1.8","Name")
- fs = fs..string.format("field[1,2.5;2,1;carid;;%s]",minetest.formspec_escape(mem.newconnection.carid))
- fs = fs..string.format("field[4,2.5;4,1;name;;%s]",minetest.formspec_escape(mem.newconnection.name))
- fs = fs..mtos.theme:get_button("3,4;3,1","major","save","Save")
- fs = fs..mtos.theme:get_button("3,5.5;3,1","major","cancel","Cancel")
+ fs = fs..mtos.theme:get_label("0.5,0.5",S("NEW CONNECTION"))
+ fs = fs..mtos.theme:get_label("0.5,1",S("Please enter the ID you would like to connect to and a name for the connection."))
+ fs = fs..mtos.theme:get_label("0.7,1.8",S("ID"))
+ fs = fs..mtos.theme:get_label("3.7,1.8",S("Name"))
+ fs = fs..string.format("field[1,2.5;2,1;carid;;%s]",core.formspec_escape(mem.newconnection.carid))
+ fs = fs..string.format("field[4,2.5;4,1;name;;%s]",core.formspec_escape(mem.newconnection.name))
+ fs = fs..mtos.theme:get_button("3,4;3,1","major","save",S("Save"))
+ fs = fs..mtos.theme:get_button("3,5.5;3,1","major","cancel",S("Cancel"))
elseif ram.screenstate == "editconnection" then
- fs = fs..mtos.theme:get_label("0.5,0.5","EDIT CONNECTION")
- fs = fs..mtos.theme:get_label("0.7,1.8","ID: "..mem.connections[mem.selectedconnection].carid)
- fs = fs..mtos.theme:get_label("3.7,1.8","Name")
- fs = fs..string.format("field[4,2.5;4,1;name;;%s]",minetest.formspec_escape(mem.connections[mem.selectedconnection].name))
- fs = fs..mtos.theme:get_button("3,4;3,1","major","save","Save")
- fs = fs..mtos.theme:get_button("3,5.5;3,1","major","cancel","Cancel")
+ fs = fs..mtos.theme:get_label("0.5,0.5",S("EDIT CONNECTION"))
+ fs = fs..mtos.theme:get_label("0.7,1.8",S("ID: @1",mem.connections[mem.selectedconnection].carid))
+ fs = fs..mtos.theme:get_label("3.7,1.8",S("Name"))
+ fs = fs..string.format("field[4,2.5;4,1;name;;%s]",core.formspec_escape(mem.connections[mem.selectedconnection].name))
+ fs = fs..mtos.theme:get_button("3,4;3,1","major","save",S("Save"))
+ fs = fs..mtos.theme:get_button("3,5.5;3,1","major","cancel",S("Cancel"))
elseif ram.screenstate == "notfound" then
- fs = fs..mtos.theme:get_label("0.5,0.5","Error")
- 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")
+ fs = fs..mtos.theme:get_label("0.5,0.5",S("Error"))
+ fs = fs..mtos.theme:get_label("0.5,1",S("Could not find a controller or dispatcher with the given ID."))
+ fs = fs..mtos.theme:get_label("0.5,1.3",S("Please check the ID number and try again."))
+ fs = fs..mtos.theme:get_button("0.5,3;2,1","major","ok",S("OK"))
+ elseif ram.screenstate == "protected" then
+ fs = fs..mtos.theme:get_label("0.5,0.5",S("Error"))
+ fs = fs..mtos.theme:get_label("0.5,1",S("Controller or dispatcher is protected."))
+ fs = fs..mtos.theme:get_button("0.5,3;2,1","major","ok",S("OK"))
elseif ram.screenstate == "dispatcherstatus" then
local connection = mem.connections[mem.selectedconnection]
local pos = connection.pos
if celevator.dispatcher.isdispatcher(pos) then
- local meta = minetest.get_meta(pos)
- local dmem = minetest.deserialize(meta:get_string("mem"))
+ local meta = core.get_meta(pos)
+ local dmem = core.deserialize(meta:get_string("mem"))
if not dmem then return end
fs = fs.."background9[-0.1,0.4;15.2,10.05;celevator_fs_bg.png;false;3]"
- fs = fs.."label[0.5,0.5;"..string.format("Connected to %s (ID %d)",connection.name,connection.carid).."]"
- fs = fs.."button[1,1;2,1;disconnect;Disconnect]"
+ fs = fs.."label[0.5,0.5;"..S("Connected to @1 (ID @2)",connection.name,connection.carid).."]"
+ fs = fs.."button[1,1;2,1;disconnect;"..S("Disconnect").."]"
fs = fs.."box[0.5,1;0.1,9;#AAAAAAFF]"
fs = fs.."box[14.25,1;0.1,9;#AAAAAAFF]"
fs = fs.."style_type[label;font_size=*0.75]"
- fs = fs.."label[0.05,10;UP]"
- fs = fs.."label[14.35,10;DOWN]"
+ fs = fs.."image[0.15,9.8;0.2,0.4;celevator_menu_small_arrow.png]"
+ fs = fs.."image[14.55,9.8;0.2,0.4;celevator_menu_small_arrow.png^[transformFY]"
fs = fs.."style_type[image_button;font=mono;font_size=*0.66]"
for car=1,#dmem.params.carids,1 do
local xp = (car-1)*0.75+1
local carid = dmem.params.carids[car]
local carstate = dmem.carstatus[carid].state
- fs = fs..string.format("label[%f,9.8;CAR %d]",xp,car)
- fs = fs..string.format("label[%f,10;%s]",xp+0.1,minetest.colorize("#ff5555",(carstate == "normal" and " IN" or "OUT")))
+ fs = fs..string.format("label[%f,9.8;%s]",xp,S("CAR @1",car))
+ fs = fs..string.format("label[%f,10;%s]",xp+0.1,core.colorize("#ff5555",(carstate == "normal" and S(" IN") or S("OUT"))))
end
local lowestfloor = (mem.screenpage-1)*10+1
local maxfloor = #dmem.params.floornames
@@ -138,11 +144,11 @@ laptop.register_app("celevator",{
local floor = i+lowestfloor-1
fs = fs..string.format("label[0.62,%f;%s]",yp+0.05,dmem.params.floornames[floor])
local uplabel = ""
- if dmem.upcalls[floor] then uplabel = minetest.colorize("#55FF55",math.floor(dmem.upeta[floor] or 0)) end
+ if dmem.upcalls[floor] then uplabel = core.colorize("#55FF55",math.floor(dmem.upeta[floor] or 0)) end
if floor < #dmem.params.floornames then fs = fs..string.format("image_button[0,%f;0.66,0.66;celevator_fs_bg.png;upcall%d;%s]",yp,floor,uplabel) end
fs = fs..string.format("label[14,%f;%s]",yp+0.05,dmem.params.floornames[floor])
local dnlabel = ""
- if dmem.dncalls[floor] then dnlabel = minetest.colorize("#FF5555",math.floor(dmem.dneta[floor] or 0)) end
+ if dmem.dncalls[floor] then dnlabel = core.colorize("#FF5555",math.floor(dmem.dneta[floor] or 0)) end
if floor > 1 then fs = fs..string.format("image_button[14.4,%f;0.66,0.66;celevator_fs_bg.png;dncall%d;%s]",yp,floor,dnlabel) end
for car=1,#dmem.params.carids,1 do
local xp = (car-1)*0.75+1
@@ -150,10 +156,10 @@ laptop.register_app("celevator",{
local carfloor = realtocarfloor(carid,floor)
if carfloor then
local ccdot = dmem.carstatus[carid].carcalls[carfloor] and "*" or ""
- local groupup = dmem.carstatus[carid].groupupcalls[carfloor] and minetest.colorize("#55FF55","^") or ""
- local swingup = dmem.carstatus[carid].swingupcalls[carfloor] and minetest.colorize("#FFFF55","^") or ""
- local swingdn = dmem.carstatus[carid].swingdncalls[carfloor] and minetest.colorize("#FFFF55","v") or ""
- local groupdn = dmem.carstatus[carid].groupdncalls[carfloor] and minetest.colorize("#FF5555","v") or ""
+ local groupup = dmem.carstatus[carid].groupupcalls[carfloor] and core.colorize("#55FF55","^") or ""
+ local swingup = dmem.carstatus[carid].swingupcalls[carfloor] and core.colorize("#FFFF55","^") or ""
+ local swingdn = dmem.carstatus[carid].swingdncalls[carfloor] and core.colorize("#FFFF55","v") or ""
+ local groupdn = dmem.carstatus[carid].groupdncalls[carfloor] and core.colorize("#FF5555","v") or ""
ccdot = groupup..swingup..ccdot..swingdn..groupdn
if getpos(carid) == floor then
local cargraphics = {
@@ -165,9 +171,9 @@ laptop.register_app("celevator",{
}
ccdot = cargraphics[dmem.carstatus[carid].doorstate]
if dmem.carstatus[carid].direction == "up" then
- ccdot = minetest.colorize("#55FF55",ccdot)
+ ccdot = core.colorize("#55FF55",ccdot)
elseif dmem.carstatus[carid].direction == "down" then
- ccdot = minetest.colorize("#FF5555",ccdot)
+ ccdot = core.colorize("#FF5555",ccdot)
end
end
fs = fs..string.format("image_button[%f,%f;0.66,0.66;celevator_fs_bg.png;carcall%02d%d;%s]",xp,yp,car,floor,ccdot)
@@ -182,32 +188,33 @@ laptop.register_app("celevator",{
local connection = mem.connections[mem.selectedconnection]
local pos = connection.pos
if celevator.controller.iscontroller(pos) then
- local meta = minetest.get_meta(pos)
- local cmem = minetest.deserialize(meta:get_string("mem"))
+ local meta = core.get_meta(pos)
+ local cmem = core.deserialize(meta:get_string("mem"))
if not cmem then return end
local modenames = {
- normal = "Normal Operation",
- uninit = "Uninitialized",
- resync = "Position Sync - Floor",
- bfdemand = "Position Sync - Terminal",
- fault = "Fault",
- stop = "Emergency Stop",
- mrinspect = "Machine Room Inspection",
- carinspect = "Car Top Inspection",
- inspconflict = "Inspection Conflict",
- fs1 = "Fire Service - Phase 1",
- fs2 = "Fire Service - Phase 2",
- fs2hold = "Fire Service - Phase 2 Hold",
- indep = "Independent Service",
- capture = "Captured",
- test = "Test Mode",
+ normal = S("Normal Operation"),
+ uninit = S("Uninitialized"),
+ resync = S("Position Sync - Floor"),
+ bfdemand = S("Position Sync - Terminal"),
+ fault = S("Fault"),
+ stop = S("Emergency Stop"),
+ mrinspect = S("Machine Room Inspection"),
+ carinspect = S("Car Top Inspection"),
+ inspconflict = "Inspection Conflict", -- No longer used
+ fs1 = S("Fire Service - Phase 1"),
+ fs2 = S("Fire Service - Phase 2"),
+ fs2hold = S("Fire Service - Phase 2 Hold"),
+ indep = S("Independent Service"),
+ capture = S("Captured"),
+ test = S("Test Mode"),
+ swing = S("Swing Operation"),
}
local doorstates = {
- open = "Open",
- opening = "Opening",
- closing = "Closing",
- closed = "Closed",
- testtiming = "Closed",
+ open = S("Doors Open"),
+ opening = S("Doors Opening"),
+ closing = S("Doors Closing"),
+ closed = S("Doors Closed"),
+ testtiming = S("Doors Closed"),
}
local carpos = 0
local carfloor = 0
@@ -219,15 +226,18 @@ laptop.register_app("celevator",{
break
end
end
- fs = fs..mtos.theme:get_label("1,1",string.format("Connected to %s (ID %d)",connection.name,connection.carid))
+ fs = fs..mtos.theme:get_label("1,1",S("Connected to @1 (ID @2)",connection.name,connection.carid))
fs = fs..mtos.theme:get_label("1,2",modenames[cmem.carstate])
- fs = fs..mtos.theme:get_label("1,2.5",string.format("Doors %s",doorstates[cmem.doorstate]))
- local pi = minetest.formspec_escape(cmem.params.floornames[carfloor])
- fs = fs..mtos.theme:get_label("1,3",string.format("Position: %0.02fm Speed: %+0.02fm/s PI: %s",cmem.drive.status.apos,cmem.drive.status.vel,pi))
+ fs = fs..mtos.theme:get_label("1,2.5",doorstates[cmem.doorstate])
+ local pi = core.formspec_escape(cmem.params.floornames[carfloor])
+ local posfmt = string.format("%0.02f",cmem.drive.status.apos)
+ local speedfmt = string.format("%+0.02f",cmem.drive.status.vel)
+ local posmsg = S("Position: @1m Speed: @2m/s PI: @3",posfmt,speedfmt,pi)
+ fs = fs..mtos.theme:get_label("1,3",posmsg)
if #cmem.faultlog > 0 then
- fs = fs..mtos.theme:get_label("1,3.5","Fault(s) Active")
+ fs = fs..mtos.theme:get_label("1,3.5",S("Fault(s) Active"))
else
- fs = fs..mtos.theme:get_label("1,3.5","No Current Faults")
+ fs = fs..mtos.theme:get_label("1,3.5",S("No Current Faults"))
end
fs = fs.."background9[8,0.3;6.2,10;celevator_fs_bg.png;false;3]"
fs = fs.."style_type[image_button;font=mono;font_size=*0.75]"
@@ -235,14 +245,14 @@ laptop.register_app("celevator",{
fs = fs.."box[11.808,0.75;0.05,9;#AAAAAAFF]"
fs = fs.."box[12.708,0.75;0.05,9;#AAAAAAFF]"
fs = fs.."box[13.725,0.75;0.1,9;#AAAAAAFF]"
- fs = fs.."label[11.25,0.3;UP]"
- fs = fs.."label[12.042,0.3;CAR]"
- fs = fs.."label[12.825,0.3;DOWN]"
+ fs = fs.."image[11.2,0.3;0.2,0.4;celevator_menu_small_arrow.png]"
+ fs = fs.."label[12.042,0.3;"..S("CAR").."]"
+ fs = fs.."image[13.1,0.3;0.2,0.4;celevator_menu_small_arrow.png^[transformFY]"
if mem.scrollfollowscar then mem.screenpage = math.floor((carfloor-1)/10)+1 end
local maxfloor = #cmem.params.floornames
local bottom = (mem.screenpage-1)*10+1
if maxfloor > 10 then
- fs = fs..string.format("checkbox[8.4,1.5;scrollfollowscar;Follow Car;%s]",tostring(mem.scrollfollowscar))
+ fs = fs..string.format("checkbox[8.4,1.7;scrollfollowscar;"..S("Follow Car")..";%s]",tostring(mem.scrollfollowscar))
if bottom+9 < maxfloor then
fs = fs.."image_button[8.5,1;0.75,0.75;celevator_menu_arrow.png;scrollup;;false;false;celevator_menu_arrow.png]"
end
@@ -254,7 +264,7 @@ laptop.register_app("celevator",{
local ypos = (11-(i*0.9))*0.9-0.75
local floornum = bottom+i
if floornum > maxfloor then break end
- fs = fs..string.format("label[10.125,%f;%s]",ypos-0.2,minetest.formspec_escape(cmem.params.floornames[floornum]))
+ fs = fs..string.format("label[10.125,%f;%s]",ypos-0.2,core.formspec_escape(cmem.params.floornames[floornum]))
local ccdot = cmem.carcalls[floornum] and "*" or ""
if carfloor == floornum then
local cargraphics = {
@@ -266,25 +276,25 @@ laptop.register_app("celevator",{
}
ccdot = cargraphics[cmem.doorstate]
if cmem.direction == "up" then
- ccdot = minetest.colorize("#55FF55",ccdot)
+ ccdot = core.colorize("#55FF55",ccdot)
elseif cmem.direction == "down" then
- ccdot = minetest.colorize("#FF5555",ccdot)
+ ccdot = core.colorize("#FF5555",ccdot)
end
end
fs = fs..string.format("image_button[11.925,%f;0.75,0.75;celevator_fs_bg.png;carcall%d;%s]",ypos-0.25,floornum,ccdot)
if floornum < maxfloor then
- local arrow = cmem.upcalls[floornum] and minetest.colorize("#55FF55","^") or ""
+ local arrow = cmem.upcalls[floornum] and core.colorize("#55FF55","^") or ""
if cmem.params.groupmode == "group" then
- arrow = cmem.groupupcalls[floornum] and minetest.colorize("#55FF55","^") or ""
- arrow = (cmem.swingupcalls[floornum] and minetest.colorize("#FFFF55","^") or "")..arrow
+ arrow = cmem.groupupcalls[floornum] and core.colorize("#55FF55","^") or ""
+ arrow = (cmem.swingupcalls[floornum] and core.colorize("#FFFF55","^") or "")..arrow
end
fs = fs..string.format("image_button[11.025,%f;0.75,0.75;celevator_fs_bg.png;upcall%d;%s]",ypos-0.25,floornum,arrow)
end
if floornum > 1 then
- local arrow = cmem.dncalls[floornum] and minetest.colorize("#FF5555","v") or ""
+ local arrow = cmem.dncalls[floornum] and core.colorize("#FF5555","v") or ""
if cmem.params.groupmode == "group" then
- arrow = cmem.swingdncalls[floornum] and minetest.colorize("#FFFF55","v") or ""
- arrow = (cmem.groupdncalls[floornum] and minetest.colorize("#FF5555","v") or "")..arrow
+ arrow = cmem.swingdncalls[floornum] and core.colorize("#FFFF55","v") or ""
+ arrow = (cmem.groupdncalls[floornum] and core.colorize("#FF5555","v") or "")..arrow
end
fs = fs..string.format("image_button[12.825,%f;0.75,0.75;celevator_fs_bg.png;downcall%d;%s]",ypos-0.25,floornum,arrow)
end
@@ -292,7 +302,7 @@ laptop.register_app("celevator",{
else
ram.screenstate = "notfound"
end
- fs = fs..mtos.theme:get_button("1,8;3,1","major","disconnect","Disconnect")
+ fs = fs..mtos.theme:get_button("1,8;3,1","major","disconnect",S("Disconnect"))
end
return fs
end,
@@ -305,7 +315,7 @@ laptop.register_app("celevator",{
ram.screenstate = "connections"
end
elseif ram.screenstate == "connections" then
- local exp = fields.connection and minetest.explode_textlist_event(fields.connection) or {}
+ local exp = fields.connection and core.explode_textlist_event(fields.connection) or {}
if fields.new then
ram.screenstate = "newconnection"
mem.newconnection.name = "Untitled"
@@ -331,10 +341,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 core.is_protected(cpos,mtos.sysram.current_player) and not core.check_player_privs(mtos.sysram.current_player,{protection_bypass=true}) then
+ core.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
@@ -352,7 +368,7 @@ laptop.register_app("celevator",{
if fields.save then
local carid = tonumber(fields.carid)
if not (carid and math.floor(carid) == carid) then return end
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then return end
local pos = carinfo.controllerpos
local itemtype
@@ -365,6 +381,11 @@ laptop.register_app("celevator",{
ram.screenstate = "notfound"
return
end
+ if core.is_protected(pos,mtos.sysram.current_player) and not core.check_player_privs(mtos.sysram.current_player,{protection_bypass=true}) then
+ core.record_protection_violation(pos,mtos.sysram.current_player)
+ ram.screenstate = "protected"
+ return
+ end
local connection = {
name = fields.name,
carid = carid,
@@ -381,6 +402,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"
@@ -388,8 +413,8 @@ laptop.register_app("celevator",{
end
local pos = mem.connections[mem.selectedconnection].pos
if celevator.dispatcher.isdispatcher(pos) then
- local meta = minetest.get_meta(pos)
- local dmem = minetest.deserialize(meta:get_string("mem"))
+ local meta = core.get_meta(pos)
+ local dmem = core.deserialize(meta:get_string("mem"))
if not dmem then return end
for k in pairs(fields) do
if string.sub(k,1,7) == "carcall" then
@@ -446,8 +471,8 @@ laptop.register_app("celevator",{
end
local pos = mem.connections[mem.selectedconnection].pos
if celevator.controller.iscontroller(pos) then
- local meta = minetest.get_meta(pos)
- local cmem = minetest.deserialize(meta:get_string("mem"))
+ local meta = core.get_meta(pos)
+ local cmem = core.deserialize(meta:get_string("mem"))
if not cmem then return end
local carcallacceptstates = {
normal = true,
diff --git a/locale/celevator.es.tr b/locale/celevator.es.tr
new file mode 100644
index 0000000..17d002e
--- /dev/null
+++ b/locale/celevator.es.tr
@@ -0,0 +1,377 @@
+# textdomain: celevator
+Elevator Up Call Button=Botón de llamada de ascensor (subir)
+Elevator Down Call Button=Botón de llamada de ascensor (bajar)
+Elevator Up and Down Call Buttons=Botón de llamada de ascensor (subir y bajar)
+Elevator Call Button (on state - you hacker you!)=Botón de llamada de ascensor (estado activado)
+Error reading car information!@nPlease remove and replace this node.=¡Error al leer la información de la cabina!@nRetire y reemplace este bloque.
+Controller/dispatcher is missing!@nPlease remove and replace this node.=¡El controlador/despachador no está presente!@nRetire y reemplace este bloque.
+Controller/dispatcher found but with incorrect ID!@nPlease remove and replace this node.=¡El controlador/despachador tiene un número incorrecto!@nRetire y reemplace este bloque.
+Car (part @1 - you hacker you!)=Cabina del ascensor (parte @1)
+You don't have access to these switches.=No tienes acceso a estos interruptores.
+Really remove this car?=¿De verdad quieres eliminar esta cabina?
+Yes=Sí
+No=No
+Car-top Inspection Box, Off State (you hacker you!)=Controles de inspección en el techo de la cabina (estado desactivado)
+Car-top Inspection Box, On State (you hacker you!)=Controles de inspección en el techo de la cabina (estado activado)
+Full-Glass Elevator Car=Cabina del ascensor en todo vidrio
+Glass-Back Elevator Car=Cabina del ascensor con parte trasera en vidrio
+Metal Elevator Car=Cabina del ascensor en metal
+Can't place car here - position @1m to the right, @2m up, and @3m back is blocked!=No se puede colocar la cabina aquí - hay una posición bloqueada @1 m a la derecha, @2 m hacia arriba, y @3 m hacia atrás
+Can't place car here - position @1m to the right, @2m up, and @3m back is protected!=No se puede colocar la cabina aquí - hay una posición protegida @1 m a la derecha, @2 m hacia arriba, y @3 m hacia atrás
+Metal Glass-Back Elevator Car=Cabina del ascensor en metal con parte trasera en vidrio
+Basic Elevator Car=Cabina del ascensor básica
+Places a car call at the specified landing on the specified elevator=Realiza una llamada de ascensor en la planta y ascensor especificados
+<car ID> <landing number>=<número del ascensor> <número de planta>
+Invalid car ID=Número de ascensor no válido
+Invalid landing number=Número de planta no válido
+No such car or car info is missing=El ascensor especificado o su información no existe
+Controller is missing=El controlador no está presente
+Controller found but with wrong ID=El controlador tiene un número incorrecto
+Controller is protected=El controlador está protegido
+Command sent=Comando enviado
+Places an up hall call at the specified landing on the specified elevator or dispatcher=Realiza una llamada para subir a la planta y el ascensor/despachador especificados
+Dispatcher is missing=El despachador no está presente
+Dispatcher found but with wrong ID=El despachador tiene un número incorrecto
+Dispatcher is protected=El despachador está protegido
+Places a down hall call at the specified landing on the specified elevator or dispatcher=Realiza una llamada para bajar a la planta y el ascensor/despachador especificados
+View the status of the specified elevator=Mostrar el estado del ascensor especificado
+<car ID>=<número del ascensor>
+Failed to load controller memory=Error al leer la memoria del controlador
+Reload celevator controller firmware from disk=Recargar el firmware del controlador celevator
+Elevator Controller=Controlador de ascensor
+Controller (door open - you hacker you!)=Controlador (con puerta abierta)
+Controller (top section - you hacker you!)=Controlador (mitad superior)
+Controller (top section, car in motion - you hacker you!)=Controlador (mitad superior con cabina en movimiento)
+Controller (top section, open - you hacker you!)=Controlador (mitad superior con puerta abierta)
+Controller (top section, open, car in motion - you hacker you!)=Controlador (mitad superior con puerta abierta y cabina en movimiento)
+Door Open Timeout=El tiempo para abrir las puertas ha expirado
+Door Close Timeout=El tiempo para cerrar las puertas ha expirado
+Lost Communication With Drive=Comunicación perdida con el inversor
+Drive Not Configured=Inversor no inicializado
+Drive Metadata Load Failure=Error al leer la memoria del inversor
+Drive Origin Invalid=Error en posición de origen del inversor
+Attempted to Move Doors With Car in Motion=Intentó abrir las puertas con la cabina en movimiento
+Target Position Out of Bounds=Error en posición objetivo
+Hoist Machine Missing=La máquina no está presente
+Drive<->Machine ID Mismatch=Desajuste entre números de inversor <-> máquina
+Controller<->Drive ID Mismatch=Desajuste entre números de controlador <-> inversor
+Welcome to your new MTronic XT elevator controller!=¡Bienvenido a su nuevo controlador de ascensor MTronic XT!
+This setup wizard is designed to get your elevator up and running as quickly as possible.=Este asistente de configuración está diseñado para poner en funcionamiento su ascensor lo más rápido posible.
+This applies to the whole celevator mod, not just this controller:=Esto se aplica a todo el mod «celevator», no solo a este controlador:
+Select a group operation mode:=Seleccione un modo de operación en grupo:
+Simplex=Único ascensor
+This will be the only elevator in the group. Hall calls will be handled by this controller.=Este será el único ascensor del grupo.@nLas llamadas desde los pisos serán gestionadas por este controlador.
+Group=Grupo
+This elevator will participate in a group with others. Hall calls will be handled by a dispatcher.=Este ascensor participará en un grupo con otros ascensores.@nLas llamadas desde las plantas serán gestionadas por un despachador.
+Waiting for connection from dispatcher...=Esperando la conexión del despachador...
+This controller's car ID is: @1=El número de este ascensor es: @1
+Enter details of all floors this elevator will serve, then press Done.=Ingrese los detalles de todas las plantas a las que dará servicio este ascensor y, a continuación, haga clic en «Listo».
+CAR STATUS=ESTADO DE LA CABINA
+Fault History=Historial de averías
+Edit Parameters=Editar parámetros
+FAULT=AVERÍA
+INSP/ACCESS=INSP./ACCESO
+NORMAL OPERATION=FUNCIONAMIENTO NORMAL
+UP=SUBIENDO
+DRIVE CMD=COMANDO AL INVERSOR
+DOWN=BAJANDO
+HIGH SPEED=ALTA VELOCIDAD
+DOOR ZONE=ZONA DE PUERTA
+DOORS LOCKED=PUERTAS BLOQUEADAS
+RUN=MARCHA
+STOP=PARADA
+CAPTURE=CAPTURAR
+TEST=PRUEBA
+INSPECT=INSPECC.
+NORMAL=NORMAL
+UP =SUBIR
+DOWN =BAJAR
+EDIT PARAMETERS=EDITAR PARÁMETROS
+Door Dwell Timer=Temporizador de puerta
+Contract Speed (m/s)=Velocidad máx. (m/s)
+Inspection Speed (m/s)=Velocidad inspecc. (m/s)
+Main Egress Landing=Planta principal
+Nudging Timer=Temporizador de empuje
+Alternate Recall Landing=Planta alterna
+Reset Doors=Restablecer puertas
+Reset Controller=Restablecer controlador
+Car Call Security=Seguridad de llamadas
+FAULT HISTORY=HISTORIAL DE AVERÍAS
+Clear=Borrar
+CAR CALL SECURITY=SEGURIDAD DE LLAMADAS
+Authorized Users Only=Solo usarios autorizados
+Locked=Bloqueado
+Security Disabled=Función de seguridad deshabilitada
+Allow Swing Calls When Not In Swing Operation=Permitir llamadas separadas aun cuando esté en modo grupo
+Unlock in Independent=Desbloqear en modo de servicio independiente
+Extra Allowed Users=Usuarios adicionales permitidos
+Hide Button=Ocultar el botón
+Also Hide in Fire/Independent Service=También en modos de incendio/servicio independiente
+Main landing cannot be locked=La planta principal no se puede bloquear.
+Suppress Beep Sound=Desactivar el sonido «bip»
+ID @1: Floor @2 - @3 - @4=Número @1: Planta @2 - @3 - @4
+Call@nCancel=Cancelar
+HOLD=MANTENIDO
+FIRE SVC=INCENDIO
+IND SVC=INDEPENDIENTE
+CAR LIGHT=LUZ
+CAR FAN=VENTILADOR
+Normal Operation=Funcionamiento normal
+Fault=Avería
+Emergency Stop=Parada de emergencia
+Independent Service=Modo de servicio independiente
+Swing Operation=Modo separado
+Doors Opening=Puertas abriéndose
+Doors Open=Puertas abiertas
+Doors Closing=Puertas cerrándose
+Doors Closed=Puertas cerradas
+Please select a floor:=Por favor, seleccione una planta:
+Please use elevator=Por favor, use el ascensor
+ERROR=ERROR
+Could not find a suitable elevator=No se pudo encontrar un ascensor adecuado.
+Please try again later=Por favor, inténtelo de nuevo más tarde.
+Elevator Destination Entry Kiosk=Puesto de selección de destino del ascensor
+Landing Number=Número de planta
+Elevator Elastomeric Buffer=Amortiguador elástico para ascensor
+Elevator Oil-Filled Buffer=Amortiguador hidráulico para ascensor
+Elevator Oil-Filled Buffer (top half - you hacker you!)=Amortiguador hidráulico para ascensor (mitad superior)
+Elevator Guide Rail=Carril guía de ascensor
+Elevator Guide Rail with Bracket=Carril guía con soporte de ascensor
+Elevator Positioning System Tape=Cinta del sistema de posicionamiento de ascensor
+Elevator Positioning System Tape with Magnets=Cinta con imanes del sistema de posicionamiento de ascensor
+Elevator Positioning System Tape with Bracket=Cinta con soporte del sistema de posicionamiento de ascensor
+Elevator Positioning System Tapehead (off, you hacker you!)=Lector de cinta del sistema de posicionamiento de ascensor (desactivado)
+Elevator Positioning System Tapehead (ULM on, you hacker you!)=Lector de cinta del sistema de posicionamiento de ascensor (señal ULM activado)
+Elevator Positioning System Tapehead (ULM and DZ on, you hacker you!)=Lector de cinta del sistema de posicionamiento de ascensor (señales ULM y DZ activado)
+Elevator Positioning System Tapehead (ULM, DLM, and DZ on, you hacker you!)=Lector de cinta del sistema de posicionamiento de ascensor (señales ULM, DLM, y DZ activado)
+Elevator Positioning System Tapehead (DLM and DZ on, you hacker you!)=Lector de cinta del sistema de posicionamiento de ascensor (señales DLM y DZ activado)
+Elevator Positioning System Tapehead (DLM on, you hacker you!)=Lector de cinta del sistema de posicionamiento de ascensor (señal DLM activado)
+Elevator Digilines Input/Output=Módulo de entrada/salida de Digilines para el ascensor
+Channel=Canal
+Elevator Digilines Multi-Car Input/Output=Módulo de entrada/salida de Digilines para múltiples ascensores
+You need either the 'protection_bypass' or 'server' privilege to use this.=Necesitas el privilegio 'protection_bypass' o 'server' para poder usar esto.
+Elevator Dispatcher=Despachador de ascensor
+Dispatcher (door open - you hacker you!)=Despachador de ascensor (con puerta abierta)
+Dispatcher (top section - you hacker you!)=Despachador de ascensor (mitad superior)
+Dispatcher (top section, open - you hacker you!)=Despachador de ascensor (mitad superior con puerta abierta)
+Firmware reloaded successfully=El firmware se recargó correctamente
+Can't place cabinet - no room for the top half!=No se puede colocar el armario de control aquí - ¡no hay espacio para la mitad superior!
+Can't place cabinet - top half is protected!=No se puede colocar el armario de control aquí - ¡el espacio para la mitad superior está protegido!
+Hold the sneak button while digging to remove.=Mantén pulsado el botón de sigilo mientras cavas para eliminarlo.
+Can't open cabinet - cabinet is locked.=No se puede abrir el armario - la puerta está cerrada con llave.
+Welcome to your new MTronic XT elevator dispatcher!=¡Bienvenido a su nuevo despachador de ascensores MTronic XT!
+Before continuing, make sure you have at least two controllers in group operation mode and ready to connect.=Antes de continuar, asegúrese de tener al menos dos controladores en modo de funcionamiento grupal y listos para conectarse.
+This applies to the whole celevator mod, not just this dispatcher:=Esto se aplica a todo el mod «celevator», no solo a este despachador:
+Enter details of all floors this group will serve, then press Next.=Ingrese los detalles de todas las plantas a las que dará servicio este grupo y, a continuación, haga clic en «Siguiente».
+Include all floors served by any car in the group, even if not served by all cars.=Incluya todas las plantas a las que pueda acceder cualquiera de los ascensores del grupo, incluso si no todas las plantas son accesibles por todos los ascensores.
+Connect to each car in the group, then click Done.=Conéctese a cada ascensor del grupo y luego haga clic en «Listo».
+EDIT CONNECTIONS=EDITAR CONEXIONES
+Car @1 - ID #@2=Ascensor @1 - Número @2
+Remove Connection=Eliminar conexión
+Enter the car ID and select the floors served (click them to toggle), then click Connect.=Ingrese la identificación del ascensor y seleccione las plantas servidas (haga clic en ellas para cambiar sí/no), luego haga clic en «Conectar».
+You must select at least two floors.=Debe seleccionar al menos dos plantas.
+Connect=Conectar
+YES=SÍ
+NO=NO
+Car ID: @1=Número del ascensor: @1
+Connecting to controller...=Conectando al controlador...
+Connection timed out!=¡El tiempo de conexión ha expirado!
+Make sure the car ID is correct and@nthat the controller is ready to connect.=Asegúrese de que el número del ascensor esté correcto@ny que el controlador esté listo para conectar
+GROUP DISPLAY=ESTADO DEL GRUPO
+Menu=Menú
+MAIN MENU=MENÚ PRINCIPAL
+Edit Connections=Editar conexiones
+Press Next to begin.=Haz clic en «siguiente» para comenzar.
+License Info=Información de la licencia
+Next >=Siguiente >
+< Back=< Atrás
+Done=Listo
+EDIT FLOOR TABLE=EDICIÓN DE LA TABLA DE PLANTAS
+@1 - Height: @2 - PI: @3=@1 - Altura: @2 - Nombre: @3
+New Floor=Planta nueva
+Edit Floor=Editar planta
+Remove Floor=Eliminar planta
+The Floor Height is the distance (in meters/nodes) from the floor level of this floor to the floor level of the next floor.=La altura de la planta es la distancia (en metros/nodos) desde el nivel del suelo de esta planta hasta el nivel del suelo de la planta siguiente.
+(not used at the highest floor)=(No se utiliza en la planta más alta)
+The Floor Name is how the floor will be displayed on the position indicators.=El nombre de la planta es la forma en que se mostrará la planta en los indicadores de posición.
+Editing Floor @1=Editando la planta @1
+Floor Height=Altura de la planta
+Floor Name=Nombre de la planta
+Edit Floor Table=Tabla de plantas
+Back=Atrás
+No Connections=Nignuna conexión
+New Connection=Conexión nueva
+Edit Connection=Editar conexión
+NEW CONNECTION=CONEXIÓN NUEVA
+EDIT CONNECTION=EDITAR CONEXIÓN
+CAR @1=ASC. @1
+ IN= OK
+OUT= --
+OK=OK
+Move Up=Subir
+Move Down=Bajar
+ID: @1=Número: @1
+Glass Hoistway Door (fast, bottom - you hacker you!)=Puerta de ascensor en vidrio (alta velocidad, parte inferior)
+Glass Hoistway Door (fast, middle - you hacker you!)=Puerta de ascensor en vidrio (alta velocidad, parte media)
+Glass Hoistway Door (fast, top - you hacker you!)=Puerta de ascensor en vidrio (alta velocidad, parte superior)
+Glass Hoistway Door (slow, bottom - you hacker you!)=Puerta de ascensor en vidrio (baja velocidad, parte inferior)
+Glass Hoistway Door (slow, middle - you hacker you!)=Puerta de ascensor en vidrio (baja velocidad, parte media)
+Glass Hoistway Door (slow, top - you hacker you!)=Puerta de ascensor en vidrio (baja velocidad, parte superior)
+Glass Elevator Hoistway Door=Puerta de ascensor en vidrio
+Steel Hoistway Door (fast, bottom - you hacker you!)=Puerta de ascensor en acero (alta velocidad, parte inferior)
+Steel Hoistway Door (fast, middle - you hacker you!)=Puerta de ascensor en acero (alta velocidad, parte media)
+Steel Hoistway Door (fast, top - you hacker you!)=Puerta de ascensor en acero (alta velocidad, parte superior)
+Steel Hoistway Door (slow, bottom - you hacker you!)=Puerta de ascensor en acero (baja velocidad, parte inferior)
+Steel Hoistway Door (slow, middle - you hacker you!)=Puerta de ascensor en acero (baja velocidad, parte media)
+Steel Hoistway Door (slow, top - you hacker you!)=Puerta de ascensor en acero (baja velocidad, parte superior)
+Steel Elevator Hoistway Door=Puerta de ascensor en acero
+Can't place door here - position @1m to the right and @2m up is blocked!=No se puede colocar la puerta aquí - hay una posición bloqueada @1 m a la derecha y @2 m hacia arriba
+Can't place door here - position @1m to the right and @2m up is protected!=No se puede colocar la puerta aquí - hay una posición protegida @1 m a la derecha y @2 m hacia arriba
+Glass Hoistway Door (left, bottom - you hacker you!)=Puerta de ascensor en vidrio (lado izquierdo, parte inferior)
+Glass Hoistway Door (left, middle - you hacker you!)=Puerta de ascensor en vidrio (lado izquierdo, parte media)
+Glass Hoistway Door (left, top - you hacker you!)=Puerta de ascensor en vidrio (lado izquierdo, parte superior)
+Glass Hoistway Door (right, bottom - you hacker you!)=Puerta de ascensor en vidrio (lado derecho, parte inferior)
+Glass Hoistway Door (right, middle - you hacker you!)=Puerta de ascensor en vidrio (lado derecho, parte media)
+Glass Hoistway Door (right, top - you hacker you!)=Puerta de ascensor en vidrio (lado derecho, parte superior)
+Center-Opening Glass Elevator Hoistway Door=Puerta de ascensor en vidrio de apertura central
+Steel Hoistway Door (left, bottom - you hacker you!)=Puerta de ascensor en acero (lado izquierdo, parte inferior)
+Steel Hoistway Door (left, middle - you hacker you!)=Puerta de ascensor en acero (lado izquierdo, parte media)
+Steel Hoistway Door (left, top - you hacker you!)=Puerta de ascensor en acero (lado izquierdo, parte superior)
+Steel Hoistway Door (right, bottom - you hacker you!)=Puerta de ascensor en acero (lado derecho, parte inferior)
+Steel Hoistway Door (right, middle - you hacker you!)=Puerta de ascensor en acero (lado derecho, parte media)
+Steel Hoistway Door (right, top - you hacker you!)=Puerta de ascensor en acero (lado derecho, parte superior)
+Center-Opening Steel Elevator Hoistway Door=Puerta de ascensor en acero de apertura central
+Hoistway Door Open-State Placeholder (you hacker you!)=Marcador de posición para puertas de ascensor abiertas
+Hoistway Door Sill, Double Track (you hacker you!)=Alféizar de puerta para ascensor (pista doble)
+Elevator Drive=Inversor de frecuencia para ascensor
+Normal entity-based drive=Inversor de frecuencia normal basado en entidades
+Drive - Running: Up, @1m/s - Position: @2m=Inversor - Subiendo a @1 m/s - Posición: @2 m
+Drive - Running: Down, @1m/s - Position: @2m=Inversor - Bajando a @1 m/s - Posición: @2 m
+Drive - Running (simulated): Up, @1m/s - Position: @2m=Inversor - Subiendo (simulado) a @1 m/s - Posición: @2 m
+Drive - Running (simulated): Down, @1m/s - Position: @2m=Inversor - Bajando (simulado) a @1 m/s - Posición: @2 m
+Drive - Idle=Inversor - Inactivo
+Using car with origin @1=Usando la cabina con posición de origen @1
+No car found! Punch to try again=¡No se encontró ninguna cabina! Golpea para intentarlo de nuevo
+Elevator Hoist Machine=Máquina del ascensor
+Can't place machine here - no room for the motor (to the left)!=No se puede colocar la máquina aquí - ¡no hay espacio para el motor (a la izquierda)!
+Can't place machine here - space for the motor (to the left) is protected!=No se puede colocar la máquina aquí - ¡el espacio para el motor (a la izquierda) está protegida!
+Can't place machine here - no room for the sheave (in front)!=No se puede colocar la máquina aquí - ¡no hay espacio para la polea (al frente)!
+Can't place machine here - space for the sheave (in front) is protected!=No se puede colocar la máquina aquí - ¡el espacio para la polea (al frente) está protegida!
+Hoist Motor (you hacker you!)=Motor
+Sheave (you hacker you!)=Polea
+Centered Sheave (you hacker you!)=Polea centrada
+Null Drive=Inversor de frecuencia simulado
+Simulation only, no movement, for testing and demonstration=Solo para simulación y prueba, sin movimiento
+Null Drive - Running: Up, @1m/s - Position: @2m=Inversor Simulado - Subiendo a @1 m/s - Posición: @2 m
+Null Drive - Running: Down, @1m/s - Position: @2m=Inversor Simulado - Bajando a @1 m/s - Posición: @2 m
+Null Drive - Idle=Inversor Simulado - Inactivo
+Elevator Fire Service Phase 1 Keyswitch=Interruptor de la fase 1 del modo de incendio del ascensor
+Elevator Fire Service Phase 1 Keyswitch (on state - you hacker you!)=Interruptor de la fase 1 del modo de incendio del ascensor (estado activado)
+Elevator Fire Service Phase 1 Keyswitch (reset state - you hacker you!)=Interruptor de la fase 1 del modo de incendio del ascensor (estado de reinicio)
+Elevator Fire Service Phase 1 Keyswitch (lit - you hacker you!)=Interruptor de la fase 1 del modo de incendio del ascensor (con luz activado)
+Elevator Fire Service Phase 1 Keyswitch (on state, lit - you hacker you!)=Interruptor de la fase 1 del modo de incendio del ascensor (estado activado y con luz activado)
+Elevator Fire Service Phase 1 Keyswitch (reset state, lit - you hacker you!)=Interruptor de la fase 1 del modo de incendio del ascensor (estado de reinicio y con luz activado)
+Can't connect to a controller/dispatcher you don't have access to.=No se puede conectar a un controlador/despachador al que no se tiene acceso.
+Save=Guardar
+Car ID=Número del ascensor
+Elevator Keyswitch=Interruptor de llave del ascensor
+Elevator Keyswitch (maintained, off state - you hacker you!)=Interruptor de llave del ascensor (mantenido, en estado desactivado)
+Elevator Keyswitch (maintained, on state - you hacker you!)=Interruptor de llave del ascensor (mantenido, en estado activado)
+Elevator Keyswitch (momentary, off state - you hacker you!)=Interruptor de llave del ascensor (momentáneo, en estado desactivado)
+Elevator Keyswitch (momentary, on state - you hacker you!)=Interruptor de llave del ascensor (momentáneo, en estado activado)
+(none)=(ninguno)
+ON=ENCENDIDO
+OFF=APAGADO
+Dispatcher ID=Número del despachador
+You don't have a key for this switch.=No tienes la llave para este interruptor.
+Car Call at Landing:=Llamada de cabina a la planta:
+Up Call (simplex car) at Landing:=Llamada para subir (único ascensor) de la planta:
+Down Call (simplex car) at Landing:=Llamada para bajar (único ascensor) de la planta:
+Up Call (swing) at Landing:=Llamada para subir (modo separado) de la planta:
+Down Call (swing) at Landing:=Llamada para bajar (modo separado) de la planta:
+Deactivate Fire Service Phase 1=Desactivar la fase 1 del modo de incendio
+Activate Fire Service (main landing) Phase 1=Activar la fase 1 (planta primaria) del modo de incendio
+Activate Fire Service (alternate landing) Phase 1=Activar la fase 1 (planta alternativa) del modo de incendio
+Machine Room or Hoistway Smoke Detector=Detector de humo en la sala de máquinas o en el hueco
+Lock Car Calls at Landing:=Bloquea las llamadas a la planta:
+Require Auth for Car Calls at Landing:=Requiere autentificación para las llamadas a la planta:
+Unlock Car Calls at Landing:=Desbloquea las llamadas a la planta:
+Activate Swing Operation=Activar modo separado
+Deactivate Swing Operation=Desactivar modo separado
+Up Call at Landing:=Llamada para subir de la planta:
+Down Call at Landing:=Llamada para bajar de la planta:
+Activate Fire Service Phase 1=Activar la fase 1 del modo de incendio
+Controller=Controlador
+Dispatcher=Despachador
+Not all signal options require a landing number.=No todas las opciones de señalización requieren@nun número de planta.
+Dispatcher: @1=Despachador: @1
+Car: @1=Ascensor: @1
+Can't connect to a dispatcher you don't have access to.=No se puede conectar a un despachador al que no se tiene acceso.
+Can't connect to a controller you don't have access to.=No se puede conectar a un controlador al que no se tiene acceso.
+Elevator Governor=Limitador de velocidad del ascensor
+Governor Sheave (you hacker you!)=Polea de limitador de velocidad
+Remote interface for MTronic XT elevator controllers=Interfaz remota para controladores de ascensores MTronic XT
+This application requires a hard disk drive.=Este aplicación requiere un disco duro.
+Welcome to the mView remote interface for MTronic XT elevator controllers!=¡Bienvenido a la interfaz remota mView para los controladores de ascensores MTronic XT!
+Add a connection to get started.=Añade una conexión para empezar.
+Add/Edit Connections=Añadir/editar conexiones
+MANAGE CONNECTIONS=GESTIONAR CONEXIONES
+ID @1 - @2=Número @1 - @2
+Delete Connection=Eliminar conexión
+Connect >=Conectar >
+Please enter the ID you would like to connect to and a name for the connection.=Por favor, introduzca el número al que desea conectarse y un nombre para la conexión.
+ID=Número
+Name=Nombre
+Error=Error
+Could not find a controller or dispatcher with the given ID.=No se pudo encontrar un controlador o despachador con el número proporcionado.
+Please check the ID number and try again.=Por favor, compruebe el número y inténtelo de nuevo.
+Controller or dispatcher is protected.=El controlador o el despachador está protegido.
+Connected to @1 (ID @2)=Conectado a @1 (Número @2)
+Disconnect=Desconectar
+Uninitialized=No inicializado
+Position Sync - Floor=Sincronización de posición - planta
+Position Sync - Terminal=Sincronización de posición - terminal
+Machine Room Inspection=Modo de inspección (sala de máquinas)
+Car Top Inspection=Modo de inspección (techo de la cabina)
+Fire Service - Phase 1=Modo de incendio (fase 1)
+Fire Service - Phase 2=Modo de incendio (fase 2)
+Fire Service - Phase 2 Hold=Modo de incendio (fase 2, modo de retención)
+Captured=Capturado
+Test Mode=Modo de prueba
+Cancel=Cancelar
+CAR=CABINA
+Follow Car=Seguimiento de cabina
+Position: @1m Speed: @2m/s PI: @3=Posición: @1 m Velocidad: @2 m/s Planta: @3
+Fault(s) Active=Avería(s) activa(s)
+No Current Faults=Ninguna avería
+Inspection (Any)=Modo de inspección (cualquier)
+Fire Service=Modo de incendio
+Fire Service Phase 1=Modo de incendio - fase 1
+Fire Service Phase 2=Modo de incendio - fase 2
+Moving Up=Subiendo
+Moving Down=Bajando
+Moving (Any Direction)=Moviéndose en cualquier dirección
+Collecting Up Calls=Recopilando llamadas para subir
+Collecting Down Calls=Recopilando llamadas para bajar
+Car Light Switch=Interruptor de luz
+Car Fan Switch=Interruptor de ventilador
+Up Call Exists at Landing:=Existe una llamada de subida en la planta:
+Down Call Exists at Landing:=Existe una llamada de bajada en la planta:
+Car Call Exists at Landing:=Existe una llamada desde el ascensor en la planta:
+Car at Landing:=Está en la planta:
+Moving to Landing:=Está moviéndose a la planta:
+Elevator Mesecons Output=Salida Mesecons para ascensor
+Elevator Mesecons Output (on state - you hacker you!)=Salida Mesecons para ascensor (estado activado)
+Elevator Mesecons Input=Entrada Mesecons para ascensor
+Elevator Mesecons Input (on state - you hacker you!)=Entrada Mesecons para ascensor (estado activado)
+Elevator Position Indicator=Indicador de posición del ascensor
+Elevator Up Lantern=Luz indicadora de llegada del ascensor (subiendo)
+Elevator Up Lantern (vertical)=Luz vertical indicadora de llegada del ascensor (subiendo)
+Elevator Up Position Indicator / Lantern Combo=Luz indicadora de llegada del ascensor (subiendo) e indicador de su posición
+Elevator Down Lantern=Luz indicadora de llegada del ascensor (bajando)
+Elevator Down Lantern (vertical)=Luz vertical indicadora de llegada del ascensor (bajando)
+Elevator Down Position Indicator / Lantern Combo=Luz indicadora de llegada del ascensor (bajando) e indicador de su posición
+Elevator Up and Down Lantern=Luz indicadora de llegada del ascensor (subiendo y bajando)
+Elevator Up and Down Lantern (vertical)=Luz vertical indicadora de llegada del ascensor (subiendo y bajando)
+Elevator Up and Down Position Indicator / Lantern Combo=Luz indicadora de llegada del ascensor (subiendo y bajando) e indicador de su posición
+Sound=Sonida
diff --git a/locale/template.txt b/locale/template.txt
new file mode 100644
index 0000000..17e2f72
--- /dev/null
+++ b/locale/template.txt
@@ -0,0 +1,377 @@
+# textdomain: celevator
+Elevator Up Call Button=
+Elevator Down Call Button=
+Elevator Up and Down Call Buttons=
+Elevator Call Button (on state - you hacker you!)=
+Error reading car information!@nPlease remove and replace this node.=
+Controller/dispatcher is missing!@nPlease remove and replace this node.=
+Controller/dispatcher found but with incorrect ID!@nPlease remove and replace this node.=
+Car (part @1 - you hacker you!)=
+You don't have access to these switches.=
+Really remove this car?=
+Yes=
+No=
+Car-top Inspection Box, Off State (you hacker you!)=
+Car-top Inspection Box, On State (you hacker you!)=
+Full-Glass Elevator Car=
+Glass-Back Elevator Car=
+Metal Elevator Car=
+Can't place car here - position @1m to the right, @2m up, and @3m back is blocked!=
+Can't place car here - position @1m to the right, @2m up, and @3m back is protected!=
+Metal Glass-Back Elevator Car=
+Basic Elevator Car=
+Places a car call at the specified landing on the specified elevator=
+<car ID> <landing number>=
+Invalid car ID=
+Invalid landing number=
+No such car or car info is missing=
+Controller is missing=
+Controller found but with wrong ID=
+Controller is protected=
+Command sent=
+Places an up hall call at the specified landing on the specified elevator or dispatcher=
+Dispatcher is missing=
+Dispatcher found but with wrong ID=
+Dispatcher is protected=
+Places a down hall call at the specified landing on the specified elevator or dispatcher=
+View the status of the specified elevator=
+<car ID>=
+Failed to load controller memory=
+Reload celevator controller firmware from disk=
+Elevator Controller=
+Controller (door open - you hacker you!)=
+Controller (top section - you hacker you!)=
+Controller (top section, car in motion - you hacker you!)=
+Controller (top section, open - you hacker you!)=
+Controller (top section, open, car in motion - you hacker you!)=
+Door Open Timeout=
+Door Close Timeout=
+Lost Communication With Drive=
+Drive Not Configured=
+Drive Metadata Load Failure=
+Drive Origin Invalid=
+Attempted to Move Doors With Car in Motion=
+Target Position Out of Bounds=
+Hoist Machine Missing=
+Drive<->Machine ID Mismatch=
+Controller<->Drive ID Mismatch=
+Welcome to your new MTronic XT elevator controller!=
+This setup wizard is designed to get your elevator up and running as quickly as possible.=
+This applies to the whole celevator mod, not just this controller:=
+Select a group operation mode:=
+Simplex=
+This will be the only elevator in the group. Hall calls will be handled by this controller.=
+Group=
+This elevator will participate in a group with others. Hall calls will be handled by a dispatcher.=
+Waiting for connection from dispatcher...=
+This controller's car ID is: @1=
+Enter details of all floors this elevator will serve, then press Done.=
+CAR STATUS=
+Fault History=
+Edit Parameters=
+FAULT=
+INSP/ACCESS=
+NORMAL OPERATION=
+UP=
+DRIVE CMD=
+DOWN=
+HIGH SPEED=
+DOOR ZONE=
+DOORS LOCKED=
+RUN=
+STOP=
+CAPTURE=
+TEST=
+INSPECT=
+NORMAL=
+UP =
+DOWN =
+EDIT PARAMETERS=
+Door Dwell Timer=
+Contract Speed (m/s)=
+Inspection Speed (m/s)=
+Main Egress Landing=
+Nudging Timer=
+Alternate Recall Landing=
+Reset Doors=
+Reset Controller=
+Car Call Security=
+FAULT HISTORY=
+Clear=
+CAR CALL SECURITY=
+Authorized Users Only=
+Locked=
+Security Disabled=
+Allow Swing Calls When Not In Swing Operation=
+Unlock in Independent=
+Extra Allowed Users=
+Hide Button=
+Also Hide in Fire/Independent Service=
+Main landing cannot be locked=
+Suppress Beep Sound=
+ID @1: Floor @2 - @3 - @4=
+Call@nCancel=
+HOLD=
+FIRE SVC=
+IND SVC=
+CAR LIGHT=
+CAR FAN=
+Normal Operation=
+Fault=
+Emergency Stop=
+Independent Service=
+Swing Operation=
+Doors Opening=
+Doors Open=
+Doors Closing=
+Doors Closed=
+Please select a floor:=
+Please use elevator=
+ERROR=
+Could not find a suitable elevator=
+Please try again later=
+Elevator Destination Entry Kiosk=
+Landing Number=
+Elevator Elastomeric Buffer=
+Elevator Oil-Filled Buffer=
+Elevator Oil-Filled Buffer (top half - you hacker you!)=
+Elevator Guide Rail=
+Elevator Guide Rail with Bracket=
+Elevator Positioning System Tape=
+Elevator Positioning System Tape with Magnets=
+Elevator Positioning System Tape with Bracket=
+Elevator Positioning System Tapehead (off, you hacker you!)=
+Elevator Positioning System Tapehead (ULM on, you hacker you!)=
+Elevator Positioning System Tapehead (ULM and DZ on, you hacker you!)=
+Elevator Positioning System Tapehead (ULM, DLM, and DZ on, you hacker you!)=
+Elevator Positioning System Tapehead (DLM and DZ on, you hacker you!)=
+Elevator Positioning System Tapehead (DLM on, you hacker you!)=
+Elevator Digilines Input/Output=
+Channel=
+Elevator Digilines Multi-Car Input/Output=
+You need either the 'protection_bypass' or 'server' privilege to use this.=
+Elevator Dispatcher=
+Dispatcher (door open - you hacker you!)=
+Dispatcher (top section - you hacker you!)=
+Dispatcher (top section, open - you hacker you!)=
+Firmware reloaded successfully=
+Can't place cabinet - no room for the top half!=
+Can't place cabinet - top half is protected!=
+Hold the sneak button while digging to remove.=
+Can't open cabinet - cabinet is locked.=
+Welcome to your new MTronic XT elevator dispatcher!=
+Before continuing, make sure you have at least two controllers in group operation mode and ready to connect.=
+This applies to the whole celevator mod, not just this dispatcher:=
+Enter details of all floors this group will serve, then press Next.=
+Include all floors served by any car in the group, even if not served by all cars.=
+Connect to each car in the group, then click Done.=
+EDIT CONNECTIONS=
+Car @1 - ID #@2=
+Remove Connection=
+Enter the car ID and select the floors served (click them to toggle), then click Connect.=
+You must select at least two floors.=
+Connect=
+YES=
+NO=
+Car ID: @1=
+Connecting to controller...=
+Connection timed out!=
+Make sure the car ID is correct and@nthat the controller is ready to connect.=
+GROUP DISPLAY=
+Menu=
+MAIN MENU=
+Edit Connections=
+Press Next to begin.=
+License Info=
+Next >=
+< Back=
+Done=
+EDIT FLOOR TABLE=
+@1 - Height: @2 - PI: @3=
+New Floor=
+Edit Floor=
+Remove Floor=
+The Floor Height is the distance (in meters/nodes) from the floor level of this floor to the floor level of the next floor.=
+(not used at the highest floor)=
+The Floor Name is how the floor will be displayed on the position indicators.=
+Editing Floor @1=
+Floor Height=
+Floor Name=
+Edit Floor Table=
+Back=
+No Connections=
+New Connection=
+Edit Connection=
+NEW CONNECTION=
+EDIT CONNECTION=
+CAR @1=
+ IN=
+OUT=
+OK=
+Move Up=
+Move Down=
+ID: @1=
+Glass Hoistway Door (fast, bottom - you hacker you!)=
+Glass Hoistway Door (fast, middle - you hacker you!)=
+Glass Hoistway Door (fast, top - you hacker you!)=
+Glass Hoistway Door (slow, bottom - you hacker you!)=
+Glass Hoistway Door (slow, middle - you hacker you!)=
+Glass Hoistway Door (slow, top - you hacker you!)=
+Glass Elevator Hoistway Door=
+Steel Hoistway Door (fast, bottom - you hacker you!)=
+Steel Hoistway Door (fast, middle - you hacker you!)=
+Steel Hoistway Door (fast, top - you hacker you!)=
+Steel Hoistway Door (slow, bottom - you hacker you!)=
+Steel Hoistway Door (slow, middle - you hacker you!)=
+Steel Hoistway Door (slow, top - you hacker you!)=
+Steel Elevator Hoistway Door=
+Can't place door here - position @1m to the right and @2m up is blocked!=
+Can't place door here - position @1m to the right and @2m up is protected!=
+Glass Hoistway Door (left, bottom - you hacker you!)=
+Glass Hoistway Door (left, middle - you hacker you!)=
+Glass Hoistway Door (left, top - you hacker you!)=
+Glass Hoistway Door (right, bottom - you hacker you!)=
+Glass Hoistway Door (right, middle - you hacker you!)=
+Glass Hoistway Door (right, top - you hacker you!)=
+Center-Opening Glass Elevator Hoistway Door=
+Steel Hoistway Door (left, bottom - you hacker you!)=
+Steel Hoistway Door (left, middle - you hacker you!)=
+Steel Hoistway Door (left, top - you hacker you!)=
+Steel Hoistway Door (right, bottom - you hacker you!)=
+Steel Hoistway Door (right, middle - you hacker you!)=
+Steel Hoistway Door (right, top - you hacker you!)=
+Center-Opening Steel Elevator Hoistway Door=
+Hoistway Door Open-State Placeholder (you hacker you!)=
+Hoistway Door Sill, Double Track (you hacker you!)=
+Elevator Drive=
+Normal entity-based drive=
+Drive - Running: Up, @1m/s - Position: @2m=
+Drive - Running: Down, @1m/s - Position: @2m=
+Drive - Running (simulated): Up, @1m/s - Position: @2m=
+Drive - Running (simulated): Down, @1m/s - Position: @2m=
+Drive - Idle=
+Using car with origin @1=
+No car found! Punch to try again=
+Elevator Hoist Machine=
+Can't place machine here - no room for the motor (to the left)!=
+Can't place machine here - space for the motor (to the left) is protected!=
+Can't place machine here - no room for the sheave (in front)!=
+Can't place machine here - space for the sheave (in front) is protected!=
+Hoist Motor (you hacker you!)=
+Sheave (you hacker you!)=
+Centered Sheave (you hacker you!)=
+Null Drive=
+Simulation only, no movement, for testing and demonstration=
+Null Drive - Running: Up, @1m/s - Position: @2m=
+Null Drive - Running: Down, @1m/s - Position: @2m=
+Null Drive - Idle=
+Elevator Fire Service Phase 1 Keyswitch=
+Elevator Fire Service Phase 1 Keyswitch (on state - you hacker you!)=
+Elevator Fire Service Phase 1 Keyswitch (reset state - you hacker you!)=
+Elevator Fire Service Phase 1 Keyswitch (lit - you hacker you!)=
+Elevator Fire Service Phase 1 Keyswitch (on state, lit - you hacker you!)=
+Elevator Fire Service Phase 1 Keyswitch (reset state, lit - you hacker you!)=
+Can't connect to a controller/dispatcher you don't have access to.=
+Save=
+Car ID=
+Elevator Keyswitch=
+Elevator Keyswitch (maintained, off state - you hacker you!)=
+Elevator Keyswitch (maintained, on state - you hacker you!)=
+Elevator Keyswitch (momentary, off state - you hacker you!)=
+Elevator Keyswitch (momentary, on state - you hacker you!)=
+(none)=
+ON=
+OFF=
+Dispatcher ID=
+You don't have a key for this switch.=
+Car Call at Landing:=
+Up Call (simplex car) at Landing:=
+Down Call (simplex car) at Landing:=
+Up Call (swing) at Landing:=
+Down Call (swing) at Landing:=
+Deactivate Fire Service Phase 1=
+Activate Fire Service (main landing) Phase 1=
+Activate Fire Service (alternate landing) Phase 1=
+Machine Room or Hoistway Smoke Detector=
+Lock Car Calls at Landing:=
+Require Auth for Car Calls at Landing:=
+Unlock Car Calls at Landing:=
+Activate Swing Operation=
+Deactivate Swing Operation=
+Up Call at Landing:=
+Down Call at Landing:=
+Activate Fire Service Phase 1=
+Controller=
+Dispatcher=
+Not all signal options require a landing number.=
+Dispatcher: @1=
+Car: @1=
+Can't connect to a dispatcher you don't have access to.=
+Can't connect to a controller you don't have access to.=
+Elevator Governor=
+Governor Sheave (you hacker you!)=
+Remote interface for MTronic XT elevator controllers=
+This application requires a hard disk drive.=
+Welcome to the mView remote interface for MTronic XT elevator controllers!=
+Add a connection to get started.=
+Add/Edit Connections=
+MANAGE CONNECTIONS=
+ID @1 - @2=
+Delete Connection=
+Connect >=
+Please enter the ID you would like to connect to and a name for the connection.=
+ID=
+Name=
+Error=
+Could not find a controller or dispatcher with the given ID.=
+Please check the ID number and try again.=
+Controller or dispatcher is protected.=
+Connected to @1 (ID @2)=
+Disconnect=
+Uninitialized=
+Position Sync - Floor=
+Position Sync - Terminal=
+Machine Room Inspection=
+Car Top Inspection=
+Fire Service - Phase 1=
+Fire Service - Phase 2=
+Fire Service - Phase 2 Hold=
+Captured=
+Test Mode=
+Cancel=
+CAR=
+Follow Car=
+Position: @1m Speed: @2m/s PI: @3=
+Fault(s) Active=
+No Current Faults=
+Inspection (Any)=
+Fire Service=
+Fire Service Phase 1=
+Fire Service Phase 2=
+Moving Up=
+Moving Down=
+Moving (Any Direction)=
+Collecting Up Calls=
+Collecting Down Calls=
+Car Light Switch=
+Car Fan Switch=
+Up Call Exists at Landing:=
+Down Call Exists at Landing:=
+Car Call Exists at Landing:=
+Car at Landing:=
+Moving to Landing:=
+Elevator Mesecons Output=
+Elevator Mesecons Output (on state - you hacker you!)=
+Elevator Mesecons Input=
+Elevator Mesecons Input (on state - you hacker you!)=
+Elevator Position Indicator=
+Elevator Up Lantern=
+Elevator Up Lantern (vertical)=
+Elevator Up Position Indicator / Lantern Combo=
+Elevator Down Lantern=
+Elevator Down Lantern (vertical)=
+Elevator Down Position Indicator / Lantern Combo=
+Elevator Up and Down Lantern=
+Elevator Up and Down Lantern (vertical)=
+Elevator Up and Down Position Indicator / Lantern Combo=
+Sound=
diff --git a/mesecons.lua b/mesecons.lua
index 7064821..b126381 100644
--- a/mesecons.lua
+++ b/mesecons.lua
@@ -1,3 +1,5 @@
+local S = core.get_translator("celevator")
+
local iorules = {
vector.new(-1,0,0),
vector.new(1,0,0),
@@ -20,7 +22,7 @@ end
local outputoptions = {
{
id = "normal",
- desc = "Normal Operation",
+ desc = S("Normal Operation"),
func = function(mem)
return (mem.carstate == "normal")
end,
@@ -28,7 +30,7 @@ local outputoptions = {
},
{
id = "fault",
- desc = "Fault",
+ desc = S("Fault"),
func = function(mem)
return (mem.carstate == "fault")
end,
@@ -36,7 +38,7 @@ local outputoptions = {
},
{
id = "estop",
- desc = "Emergency Stop",
+ desc = S("Emergency Stop"),
func = function(mem)
return (mem.carstate == "stop")
end,
@@ -44,7 +46,7 @@ local outputoptions = {
},
{
id = "inspect",
- desc = "Inspection (Any)",
+ desc = S("Inspection (Any)"),
func = function(mem)
return (mem.carstate == "mrinspect" or mem.carstate == "inspconflict" or mem.carstate == "carinspect")
end,
@@ -52,7 +54,7 @@ local outputoptions = {
},
{
id = "fire",
- desc = "Fire Service",
+ desc = S("Fire Service"),
func = function(mem)
return (mem.carstate == "fs1" or mem.carstate == "fs2" or mem.carstate == "fs2hold")
end,
@@ -60,7 +62,7 @@ local outputoptions = {
},
{
id = "fire1",
- desc = "Fire Service Phase 1",
+ desc = S("Fire Service Phase 1"),
func = function(mem)
return (mem.carstate == "fs1")
end,
@@ -68,7 +70,7 @@ local outputoptions = {
},
{
id = "fire2",
- desc = "Fire Service Phase 2",
+ desc = S("Fire Service Phase 2"),
func = function(mem)
return (mem.carstate == "fs2" or mem.carstate == "fs2hold")
end,
@@ -76,15 +78,23 @@ local outputoptions = {
},
{
id = "independent",
- desc = "Independent Service",
+ desc = S("Independent Service"),
func = function(mem)
return (mem.carstate == "indep")
end,
needsfloor = false,
},
{
+ id = "swing",
+ desc = S("Swing Operation"),
+ func = function(mem)
+ return (mem.carstate == "swing")
+ end,
+ needsfloor = false,
+ },
+ {
id = "opening",
- desc = "Doors Opening",
+ desc = S("Doors Opening"),
func = function(mem)
return (mem.doorstate == "opening")
end,
@@ -92,7 +102,7 @@ local outputoptions = {
},
{
id = "open",
- desc = "Doors Open",
+ desc = S("Doors Open"),
func = function(mem)
return (mem.doorstate == "open")
end,
@@ -100,7 +110,7 @@ local outputoptions = {
},
{
id = "closing",
- desc = "Doors Closing",
+ desc = S("Doors Closing"),
func = function(mem)
return (mem.doorstate == "closing")
end,
@@ -108,7 +118,7 @@ local outputoptions = {
},
{
id = "closed",
- desc = "Doors Closed",
+ desc = S("Doors Closed"),
func = function(mem)
return (mem.doorstate == "closed")
end,
@@ -116,7 +126,7 @@ local outputoptions = {
},
{
id = "moveup",
- desc = "Moving Up",
+ desc = S("Moving Up"),
func = function(mem)
return (mem.drive.status and mem.drive.status.vel > 0)
end,
@@ -124,7 +134,7 @@ local outputoptions = {
},
{
id = "movedown",
- desc = "Moving Down",
+ desc = S("Moving Down"),
func = function(mem)
return (mem.drive.status and mem.drive.status.vel < 0)
end,
@@ -132,7 +142,7 @@ local outputoptions = {
},
{
id = "moving",
- desc = "Moving (Any Direction)",
+ desc = S("Moving (Any Direction)"),
func = function(mem)
return (mem.drive.status and mem.drive.status.vel ~= 0)
end,
@@ -140,7 +150,7 @@ local outputoptions = {
},
{
id = "collectorup",
- desc = "Collecting Up Calls",
+ desc = S("Collecting Up Calls"),
func = function(mem)
return (mem.carstate == "normal" and mem.direction == "up")
end,
@@ -148,7 +158,7 @@ local outputoptions = {
},
{
id = "collectordown",
- desc = "Collecting Down Calls",
+ desc = S("Collecting Down Calls"),
func = function(mem)
return (mem.carstate == "normal" and mem.direction == "down")
end,
@@ -156,7 +166,7 @@ local outputoptions = {
},
{
id = "lightsw",
- desc = "Car Light Switch",
+ desc = S("Car Light Switch"),
func = function(mem)
return mem.lightsw
end,
@@ -164,7 +174,7 @@ local outputoptions = {
},
{
id = "fansw",
- desc = "Car Fan Switch",
+ desc = S("Car Fan Switch"),
func = function(mem)
return mem.fansw
end,
@@ -172,7 +182,7 @@ local outputoptions = {
},
{
id = "upcall",
- desc = "Up Call Exists at Landing:",
+ desc = S("Up Call Exists at Landing:"),
func = function(mem,floor)
return mem.upcalls[floor]
end,
@@ -180,7 +190,7 @@ local outputoptions = {
},
{
id = "downcall",
- desc = "Down Call Exists at Landing:",
+ desc = S("Down Call Exists at Landing:"),
func = function(mem,floor)
return mem.dncalls[floor]
end,
@@ -188,7 +198,7 @@ local outputoptions = {
},
{
id = "carcall",
- desc = "Car Call Exists at Landing:",
+ desc = S("Car Call Exists at Landing:"),
func = function(mem,floor)
return mem.carcalls[floor]
end,
@@ -196,7 +206,7 @@ local outputoptions = {
},
{
id = "apos",
- desc = "Car at Landing:",
+ desc = S("Car at Landing:"),
func = function(mem,floor)
if mem.drive.status then
return (getpos(mem,nil,true) == floor)
@@ -206,7 +216,7 @@ local outputoptions = {
},
{
id = "dpos",
- desc = "Moving to Landing:",
+ desc = S("Moving to Landing:"),
func = function(mem,floor)
if mem.drive.status then
return (getpos(mem,mem.drive.status.dpos) == floor)
@@ -219,7 +229,7 @@ local outputoptions = {
local doutputoptions = {
{
id = "fire",
- desc = "Fire Service",
+ desc = S("Fire Service"),
func = function(mem)
return mem.fs1led
end,
@@ -227,7 +237,7 @@ local doutputoptions = {
},
{
id = "upcall",
- desc = "Up Call Exists at Landing:",
+ desc = S("Up Call Exists at Landing:"),
func = function(mem,floor)
return mem.upcalls[floor]
end,
@@ -235,7 +245,7 @@ local doutputoptions = {
},
{
id = "downcall",
- desc = "Down Call Exists at Landing:",
+ desc = S("Down Call Exists at Landing:"),
func = function(mem,floor)
return mem.dncalls[floor]
end,
@@ -246,7 +256,7 @@ local doutputoptions = {
local inputoptions = {
{
id = "carcall",
- desc = "Car Call at Landing:",
+ desc = S("Car Call at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -258,7 +268,7 @@ local inputoptions = {
},
{
id = "upcall",
- desc = "Up Call (simplex car) at Landing:",
+ desc = S("Up Call (simplex car) at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -270,7 +280,7 @@ local inputoptions = {
},
{
id = "downcall",
- desc = "Down Call (simplex car) at Landing:",
+ desc = S("Down Call (simplex car) at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -282,7 +292,7 @@ local inputoptions = {
},
{
id = "swingupcall",
- desc = "Up Call (swing) at Landing:",
+ desc = S("Up Call (swing) at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -294,7 +304,7 @@ local inputoptions = {
},
{
id = "swingdowncall",
- desc = "Down Call (swing) at Landing:",
+ desc = S("Down Call (swing) at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -306,7 +316,7 @@ local inputoptions = {
},
{
id = "fs1off",
- desc = "Deactivate Fire Service Phase 1",
+ desc = S("Deactivate Fire Service Phase 1"),
func_on = function(controllerpos)
celevator.controller.run(controllerpos,{
type = "fs1switch",
@@ -317,7 +327,7 @@ local inputoptions = {
},
{
id = "fs1on",
- desc = "Activate Fire Service (main landing) Phase 1",
+ desc = S("Activate Fire Service (main landing) Phase 1"),
func_on = function(controllerpos)
celevator.controller.run(controllerpos,{
type = "fs1switch",
@@ -328,7 +338,7 @@ local inputoptions = {
},
{
id = "fs1onalt",
- desc = "Activate Fire Service (alternate landing) Phase 1",
+ desc = S("Activate Fire Service (alternate landing) Phase 1"),
func_on = function(controllerpos)
celevator.controller.run(controllerpos,{
type = "fs1switch",
@@ -340,7 +350,7 @@ local inputoptions = {
},
{
id = "mrsmoke",
- desc = "Machine Room or Hoistway Smoke Detector",
+ desc = S("Machine Room or Hoistway Smoke Detector"),
func_on = function(controllerpos)
celevator.controller.run(controllerpos,{
type = "mrsmoke",
@@ -350,7 +360,7 @@ local inputoptions = {
},
{
id = "secdeny",
- desc = "Lock Car Calls at Landing:",
+ desc = S("Lock Car Calls at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -365,7 +375,7 @@ local inputoptions = {
},
{
id = "secauth",
- desc = "Require Auth for Car Calls at Landing:",
+ desc = S("Require Auth for Car Calls at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -380,7 +390,7 @@ local inputoptions = {
},
{
id = "secallow",
- desc = "Unlock Car Calls at Landing:",
+ desc = S("Unlock Car Calls at Landing:"),
func_on = function(controllerpos,floor)
celevator.controller.run(controllerpos,{
type = "remotemsg",
@@ -393,12 +403,36 @@ local inputoptions = {
end,
needsfloor = true,
},
+ {
+ id = "swingon",
+ desc = S("Activate Swing Operation"),
+ func_on = function(controllerpos)
+ celevator.controller.run(controllerpos,{
+ type = "remotemsg",
+ channel = "swing",
+ msg = true,
+ })
+ end,
+ needsfloor = false,
+ },
+ {
+ id = "swingoff",
+ desc = S("Deactivate Swing Operation"),
+ func_on = function(controllerpos)
+ celevator.controller.run(controllerpos,{
+ type = "remotemsg",
+ channel = "swing",
+ msg = false,
+ })
+ end,
+ needsfloor = false,
+ },
}
local dinputoptions = {
{
id = "upcall",
- desc = "Up Call at Landing:",
+ desc = S("Up Call at Landing:"),
func_on = function(dispatcherpos,floor)
celevator.dispatcher.run(dispatcherpos,{
type = "remotemsg",
@@ -410,7 +444,7 @@ local dinputoptions = {
},
{
id = "downcall",
- desc = "Down Call at Landing:",
+ desc = S("Down Call at Landing:"),
func_on = function(dispatcherpos,floor)
celevator.dispatcher.run(dispatcherpos,{
type = "remotemsg",
@@ -422,7 +456,7 @@ local dinputoptions = {
},
{
id = "fs1off",
- desc = "Deactivate Fire Service Phase 1",
+ desc = S("Deactivate Fire Service Phase 1"),
func_on = function(dispatcherpos)
celevator.dispatcher.run(dispatcherpos,{
type = "fs1switch",
@@ -433,7 +467,7 @@ local dinputoptions = {
},
{
id = "fs1on",
- desc = "Activate Fire Service Phase 1",
+ desc = S("Activate Fire Service Phase 1"),
func_on = function(dispatcherpos)
celevator.dispatcher.run(dispatcherpos,{
type = "fs1switch",
@@ -445,33 +479,33 @@ local dinputoptions = {
}
local function updateoutputform(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local dmode = meta:get_int("dispatcher") == 1
- local fs = "formspec_version[7]size[8,6.5]"
- fs = fs.."tabheader[0,0;1;tab;Controller,Dispatcher;"..(dmode and "2" or "1")..";true;true]"
- fs = fs.."dropdown[1,0.5;6,1;signal;"
+ local fs = "formspec_version[7]size[9,6.5]"
+ fs = fs.."tabheader[0,0;1;tab;"..S("Controller")..","..S("Dispatcher")..";"..(dmode and "2" or "1")..";true;true]"
+ fs = fs.."dropdown[1,0.5;7,1;signal;"
local selected = 1
local currentid = meta:get_string("signal")
for k,v in ipairs(dmode and doutputoptions or outputoptions) do
- fs = fs..minetest.formspec_escape(v.desc)..","
+ fs = fs..core.formspec_escape(v.desc)..","
if v.id == currentid then selected = k end
end
fs = string.sub(fs,1,-2)
fs = fs..";"..selected..";false]"
- fs = fs.."field[0.5,2.5;3,1;carid;"..(dmode and "Dispatcher ID" or "Car ID")..";${carid}]"
- fs = fs.."field[4.5,2.5;3,1;floor;Landing Number;${floor}]"
- fs = fs.."label[1.5,4;Not all signal options require a landing number.]"
- fs = fs.."button_exit[2.5,5;3,1;save;Save]"
+ fs = fs.."field[0.5,2.5;3,1;carid;"..(dmode and S("Dispatcher ID") or S("Car ID"))..";${carid}]"
+ fs = fs.."field[4.5,2.5;3,1;floor;"..S("Landing Number")..";${floor}]"
+ fs = fs.."label[1.5,4;"..S("Not all signal options require a landing number.").."]"
+ fs = fs.."button_exit[2.5,5;3,1;save;"..S("Save").."]"
meta:set_string("formspec",fs)
end
local function handleoutputfields(pos,_,fields,player)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
if fields.quit and not fields.save 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
+ if core.is_protected(pos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
if player:is_player() then
- minetest.record_protection_violation(pos,name)
+ core.record_protection_violation(pos,name)
end
return
end
@@ -480,24 +514,24 @@ local function handleoutputfields(pos,_,fields,player)
if not tonumber(fields.carid) then return end
meta:set_int("carid",fields.carid)
local carid = tonumber(fields.carid)
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {}
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {}
if dmode then
if not carinfo.dispatcherpos then return end
if not celevator.dispatcher.isdispatcher(carinfo.dispatcherpos) then return end
- if minetest.is_protected(carinfo.dispatcherpos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
+ if core.is_protected(carinfo.dispatcherpos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
if player:is_player() then
- minetest.chat_send_player(name,"Can't connect to a dispatcher you don't have access to.")
- minetest.record_protection_violation(carinfo.dispatcherpos,name)
+ core.chat_send_player(name,S("Can't connect to a dispatcher you don't have access to."))
+ core.record_protection_violation(carinfo.dispatcherpos,name)
end
return
end
else
if not carinfo.controllerpos then return end
if not celevator.controller.iscontroller(carinfo.controllerpos) then return end
- if minetest.is_protected(carinfo.controllerpos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
+ if core.is_protected(carinfo.controllerpos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
if player:is_player() then
- minetest.chat_send_player(name,"Can't connect to a controller you don't have access to.")
- minetest.record_protection_violation(carinfo.controllerpos,name)
+ core.chat_send_player(name,S("Can't connect to a controller you don't have access to."))
+ core.record_protection_violation(carinfo.controllerpos,name)
end
return
end
@@ -514,11 +548,11 @@ local function handleoutputfields(pos,_,fields,player)
if def.needsfloor and not floor then return end
meta:set_string("signal",def.id)
updateoutputform(pos)
- local infotext = carid.." - "..def.desc..(def.needsfloor and " "..floor or "")
+ local infotext = " - "..def.desc..(def.needsfloor and " "..floor or "")
if dmode then
- infotext = "Dispatcher: "..infotext
+ infotext = S("Dispatcher: @1",carid)..infotext
else
- infotext = "Car: "..infotext
+ infotext = S("Car: @1",carid)..infotext
end
meta:set_string("infotext",infotext)
elseif fields.tab then
@@ -527,8 +561,8 @@ local function handleoutputfields(pos,_,fields,player)
end
end
-minetest.register_node("celevator:mesecons_output_off",{
- description = "Elevator Mesecons Output",
+core.register_node("celevator:mesecons_output_off",{
+ description = S("Elevator Mesecons Output"),
tiles = {
"celevator_meseconsoutput_top_off.png",
"celevator_cabinet_sides.png",
@@ -552,15 +586,15 @@ minetest.register_node("celevator:mesecons_output_off",{
},
},
after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
meta:set_int("floor",1)
updateoutputform(pos)
end,
on_receive_fields = handleoutputfields,
})
-minetest.register_node("celevator:mesecons_output_on",{
- description = "Elevator Mesecons Output (on state - you hacker you!)",
+core.register_node("celevator:mesecons_output_on",{
+ description = S("Elevator Mesecons Output (on state - you hacker you!)"),
tiles = {
"celevator_meseconsoutput_top_on.png",
"celevator_cabinet_sides.png",
@@ -586,25 +620,25 @@ minetest.register_node("celevator:mesecons_output_on",{
},
},
after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
meta:set_int("floor",1)
updateoutputform(pos)
end,
on_receive_fields = handleoutputfields,
})
-minetest.register_abm({
+core.register_abm({
label = "Update mesecons output",
nodenames = {"celevator:mesecons_output_off","celevator:mesecons_output_on",},
interval = 1,
chance = 1,
action = function(pos,node)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local dmode = meta:get_int("dispatcher") == 1
local oldstate = (node.name == "celevator:mesecons_output_on")
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))) or {}
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {}
if dmode then
if not carinfo.dispatcherpos then return end
if not celevator.dispatcher.isdispatcher(carinfo.dispatcherpos) then return end
@@ -613,7 +647,7 @@ minetest.register_abm({
if not celevator.controller.iscontroller(carinfo.controllerpos) then return end
end
local floor = meta:get_int("floor")
- local mem = minetest.deserialize(minetest.get_meta(dmode and carinfo.dispatcherpos or carinfo.controllerpos):get_string("mem")) or {}
+ local mem = core.deserialize(core.get_meta(dmode and carinfo.dispatcherpos or carinfo.controllerpos):get_string("mem")) or {}
local signal = meta:get_string("signal")
local def
for _,v in ipairs(dmode and doutputoptions or outputoptions) do
@@ -623,10 +657,14 @@ minetest.register_abm({
end
end
if not def then return end
+ if not mem.upcalls then
+ --Memory ended up blank somehow
+ return
+ end
local newstate = def.func(mem,floor)
if newstate ~= oldstate then
node.name = (newstate and "celevator:mesecons_output_on" or "celevator:mesecons_output_off")
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
if newstate then
mesecon.receptor_on(pos,iorules)
else
@@ -637,33 +675,33 @@ minetest.register_abm({
})
local function updateinputform(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local dmode = meta:get_int("dispatcher") == 1
- local fs = "formspec_version[7]size[8,6.5]"
- fs = fs.."tabheader[0,0;1;tab;Controller,Dispatcher;"..(dmode and "2" or "1")..";true;true]"
- fs = fs.."dropdown[1,0.5;6,1;signal;"
+ local fs = "formspec_version[7]size[9,6.5]"
+ fs = fs.."tabheader[0,0;1;tab;"..S("Controller")..","..S("Dispatcher")..";"..(dmode and "2" or "1")..";true;true]"
+ fs = fs.."dropdown[1,0.5;7,1;signal;"
local selected = 1
local currentid = meta:get_string("signal")
for k,v in ipairs(dmode and dinputoptions or inputoptions) do
- fs = fs..minetest.formspec_escape(v.desc)..","
+ fs = fs..core.formspec_escape(v.desc)..","
if v.id == currentid then selected = k end
end
fs = string.sub(fs,1,-2)
fs = fs..";"..selected..";false]"
- fs = fs.."field[0.5,2.5;3,1;carid;"..(dmode and "Dispatcher ID" or "Car ID")..";${carid}]"
- fs = fs.."field[4.5,2.5;3,1;floor;Landing Number;${floor}]"
- fs = fs.."label[1.5,4;Not all signal options require a landing number.]"
- fs = fs.."button_exit[2.5,5;3,1;save;Save]"
+ fs = fs.."field[0.5,2.5;3,1;carid;"..(dmode and S("Dispatcher ID") or S("Car ID"))..";${carid}]"
+ fs = fs.."field[4.5,2.5;3,1;floor;"..S("Landing Number")..";${floor}]"
+ fs = fs.."label[1.5,4;"..S("Not all signal options require a landing number.").."]"
+ fs = fs.."button_exit[2.5,5;3,1;save;"..S("Save").."]"
meta:set_string("formspec",fs)
end
local function handleinputfields(pos,_,fields,player)
if fields.quit and not fields.save then return end
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local name = player:get_player_name()
- if minetest.is_protected(pos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
+ if core.is_protected(pos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
if player:is_player() then
- minetest.record_protection_violation(pos,name)
+ core.record_protection_violation(pos,name)
end
return
end
@@ -672,24 +710,24 @@ local function handleinputfields(pos,_,fields,player)
if not tonumber(fields.carid) then return end
meta:set_int("carid",fields.carid)
local carid = tonumber(fields.carid)
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {}
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {}
if dmode then
if not carinfo.dispatcherpos then return end
if not celevator.dispatcher.isdispatcher(carinfo.dispatcherpos) then return end
- if minetest.is_protected(carinfo.dispatcherpos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
+ if core.is_protected(carinfo.dispatcherpos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
if player:is_player() then
- minetest.chat_send_player(name,"Can't connect to a dispatcher you don't have access to.")
- minetest.record_protection_violation(carinfo.dispatcherpos,name)
+ core.chat_send_player(name,S("Can't connect to a dispatcher you don't have access to."))
+ core.record_protection_violation(carinfo.dispatcherpos,name)
end
return
end
else
if not carinfo.controllerpos then return end
if not celevator.controller.iscontroller(carinfo.controllerpos) then return end
- if minetest.is_protected(carinfo.controllerpos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
+ if core.is_protected(carinfo.controllerpos,name) and not core.check_player_privs(name,{protection_bypass=true}) then
if player:is_player() then
- minetest.chat_send_player(name,"Can't connect to a controller you don't have access to.")
- minetest.record_protection_violation(carinfo.controllerpos,name)
+ core.chat_send_player(name,S("Can't connect to a controller you don't have access to."))
+ core.record_protection_violation(carinfo.controllerpos,name)
end
return
end
@@ -706,11 +744,11 @@ local function handleinputfields(pos,_,fields,player)
if def.needsfloor and not floor then return end
meta:set_string("signal",def.id)
updateinputform(pos)
- local infotext = carid.." - "..def.desc..(def.needsfloor and " "..floor or "")
+ local infotext = " - "..def.desc..(def.needsfloor and " "..floor or "")
if dmode then
- infotext = "Dispatcher: "..infotext
+ infotext = S("Dispatcher: @1",carid)..infotext
else
- infotext = "Car: "..infotext
+ infotext = S("Car: @1",carid)..infotext
end
meta:set_string("infotext",infotext)
elseif fields.tab then
@@ -720,10 +758,10 @@ local function handleinputfields(pos,_,fields,player)
end
local function handleinput(pos,on)
- local meta = minetest.get_meta(pos)
+ local meta = core.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))) or {}
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {}
local dmode = meta:get_int("dispatcher") == 1
if dmode then
if not carinfo.dispatcherpos then return end
@@ -757,8 +795,8 @@ local function handleinput(pos,on)
end
end
-minetest.register_node("celevator:mesecons_input_off",{
- description = "Elevator Mesecons Input",
+core.register_node("celevator:mesecons_input_off",{
+ description = S("Elevator Mesecons Input"),
tiles = {
"celevator_meseconsinput_top_off.png",
"celevator_cabinet_sides.png",
@@ -780,21 +818,21 @@ minetest.register_node("celevator:mesecons_input_off",{
rules = iorules,
action_on = function(pos,node)
node.name = "celevator:mesecons_input_on"
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
handleinput(pos,true)
end,
},
},
after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
meta:set_int("floor",1)
updateinputform(pos)
end,
on_receive_fields = handleinputfields,
})
-minetest.register_node("celevator:mesecons_input_on",{
- description = "Elevator Mesecons Input (on state - you hacker you!)",
+core.register_node("celevator:mesecons_input_on",{
+ description = S("Elevator Mesecons Input (on state - you hacker you!)"),
tiles = {
"celevator_meseconsinput_top_on.png",
"celevator_cabinet_sides.png",
@@ -818,13 +856,13 @@ minetest.register_node("celevator:mesecons_input_on",{
rules = iorules,
action_off = function(pos,node)
node.name = "celevator:mesecons_input_off"
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
handleinput(pos,false)
end,
},
},
after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
meta:set_int("floor",1)
updateinputform(pos)
end,
diff --git a/mod.conf b/mod.conf
index 731d6c5..d3d7e36 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,digistuff
author = cheapie
-min_minetest_version = 5.7
+min_minetest_version = 5.12
diff --git a/pilantern.lua b/pilantern.lua
index 7dda0a5..7b36253 100644
--- a/pilantern.lua
+++ b/pilantern.lua
@@ -1,6 +1,19 @@
celevator.pi = {}
celevator.lantern = {}
+celevator.lantern.chimesounds = {
+ {
+ up = "celevator_chime_up",
+ down = "celevator_chime_down",
+ },
+ {
+ up = {name="celevator_chime2_up",gain=0.7},
+ down = {name="celevator_chime2_down",gain=0.7},
+ },
+}
+
+local S = core.get_translator("celevator")
+
local boringside = "[combine:64x64"..
":0,0=celevator_cabinet_sides.png"..
":32,0=celevator_cabinet_sides.png"..
@@ -8,31 +21,33 @@ local boringside = "[combine:64x64"..
":32,32=celevator_cabinet_sides.png"
local displaytex = boringside..":16,40=celevator_pi_background.png"
-minetest.register_entity("celevator:pi_entity",{
+core.register_entity("celevator:pi_entity",{
initial_properties = {
visual = "upright_sprite",
physical = false,
collisionbox = {0,0,0,0,0,0,},
textures = {"celevator_transparent.png",},
static_save = false,
- glow = minetest.LIGHT_MAX,
+ glow = core.LIGHT_MAX,
},
})
-minetest.register_entity("celevator:incar_pi_entity",{
+core.register_entity("celevator:incar_pi_entity",{
initial_properties = {
visual = "upright_sprite",
physical = false,
collisionbox = {0,0,0,0,0,0,},
textures = {"celevator_transparent.png",},
static_save = false,
- glow = minetest.LIGHT_MAX,
+ glow = core.LIGHT_MAX,
},
on_step = function(self)
+ if not self.object then return end
local pos = self.object:get_pos()
+ if not core.compare_block_status(pos,"active") then return self.object:remove() end
local props = self.object:get_properties()
if props.breath_max and props.breath_max ~= 0 then
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",props.breath_max)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",props.breath_max)))
if not carinfo then return end
local text = carinfo.pitext or "--"
if string.len(text) < 3 then text = string.rep(" ",3-string.len(text))..text end
@@ -48,7 +63,7 @@ minetest.register_entity("celevator:incar_pi_entity",{
self.object:set_properties({textures = {etex}})
else
local carpos = vector.round(pos)
- local carmeta = minetest.get_meta(carpos)
+ local carmeta = core.get_meta(carpos)
local carid = carmeta:get_int("carid")
if carid > 0 then self.object:set_properties({breath_max=carid}) end
end
@@ -56,7 +71,7 @@ minetest.register_entity("celevator:incar_pi_entity",{
})
function celevator.pi.removeentity(pos)
- local entitiesnearby = minetest.get_objects_inside_radius(pos,0.5)
+ local entitiesnearby = core.get_objects_inside_radius(pos,0.5)
for _,i in pairs(entitiesnearby) do
if i:get_luaentity() and (i:get_luaentity().name == "celevator:pi_entity" or i:get_luaentity().name == "celevator:incar_pi_entity") then
i:remove()
@@ -80,16 +95,16 @@ end
function celevator.pi.updatedisplay(pos)
celevator.pi.removeentity(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local text = meta:get_string("text")
- local entity = minetest.add_entity(pos,"celevator:pi_entity")
- local fdir = minetest.facedir_to_dir(celevator.get_node(pos).param2)
+ local entity = core.add_entity(pos,"celevator:pi_entity")
+ local fdir = core.facedir_to_dir(celevator.get_node(pos).param2)
local uparrow = meta:get_int("uparrow") > 0
local downarrow = meta:get_int("downarrow") > 0
local flash_fs = meta:get_int("flash_fs") > 0
local flash_is = meta:get_int("flash_is") > 0
local flashtimer = meta:get_int("flashtimer") > 0
- local islantern = minetest.get_item_group(celevator.get_node(pos).name,"_celevator_lantern") == 1
+ local islantern = core.get_item_group(celevator.get_node(pos).name,"_celevator_lantern") == 1
local etex = celevator.pi.generatetexture(text,uparrow,downarrow,islantern)
if flash_fs then
if flashtimer then etex = celevator.pi.generatetexture(" FS",uparrow,downarrow,islantern) end
@@ -106,8 +121,8 @@ function celevator.pi.updatedisplay(pos)
end
function celevator.pi.flash(pos,what)
- if minetest.get_item_group(celevator.get_node(pos).name,"_celevator_pi") ~= 1 then return end
- local meta = minetest.get_meta(pos)
+ if core.get_item_group(celevator.get_node(pos).name,"_celevator_pi") ~= 1 then return end
+ local meta = core.get_meta(pos)
if what == "FS" then
meta:set_int("flash_is",0)
meta:set_int("flash_fs",1)
@@ -123,8 +138,8 @@ end
function celevator.pi.settext(pos,text)
if not text then text = " --" end
- if minetest.get_item_group(celevator.get_node(pos).name,"_celevator_pi") ~= 1 then return end
- local meta = minetest.get_meta(pos)
+ if core.get_item_group(celevator.get_node(pos).name,"_celevator_pi") ~= 1 then return end
+ local meta = core.get_meta(pos)
if string.len(text) < 3 then
text = string.rep(" ",3-string.len(text))..text
end
@@ -133,8 +148,8 @@ function celevator.pi.settext(pos,text)
end
function celevator.pi.setarrow(pos,which,active)
- if minetest.get_item_group(celevator.get_node(pos).name,"_celevator_pi") ~= 1 then return end
- local meta = minetest.get_meta(pos)
+ if core.get_item_group(celevator.get_node(pos).name,"_celevator_pi") ~= 1 then return end
+ local meta = core.get_meta(pos)
if which == "up" then
meta:set_int("uparrow",active and 1 or 0)
elseif which == "down" then
@@ -143,8 +158,8 @@ function celevator.pi.setarrow(pos,which,active)
celevator.pi.updatedisplay(pos)
end
-minetest.register_node("celevator:pi",{
- description = "Elevator Position Indicator",
+core.register_node("celevator:pi",{
+ description = S("Elevator Position Indicator"),
groups = {
dig_immediate = 2,
_celevator_pi = 1,
@@ -169,17 +184,17 @@ minetest.register_node("celevator:pi",{
},
},
after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("formspec","formspec_version[7]size[8,5]field[0.5,0.5;7,1;carid;Car ID;]button[3,3.5;2,1;save;Save]")
+ local meta = core.get_meta(pos)
+ meta:set_string("formspec","formspec_version[7]size[8,5]field[0.5,0.5;7,1;carid;"..S("Car ID")..";]button[3,3.5;2,1;save;"..S("Save").."]")
end,
on_receive_fields = function(pos,_,fields)
if tonumber(fields.carid) then
local carid = tonumber(fields.carid)
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not (carinfo and carinfo.pis) then return end
table.insert(carinfo.pis,{pos=pos})
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
- local meta = minetest.get_meta(pos)
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
+ local meta = core.get_meta(pos)
meta:set_int("carid",carid)
meta:set_string("formspec","")
celevator.pi.settext(pos,carinfo.pitext)
@@ -187,70 +202,73 @@ minetest.register_node("celevator:pi",{
end,
on_destruct = function(pos)
celevator.pi.removeentity(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.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)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not (carinfo and carinfo.pis) then return end
for i,pi in pairs(carinfo.pis) do
if vector.equals(pos,pi.pos) then
table.remove(carinfo.pis,i)
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
end
end
end,
on_construct = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
meta:set_string("text","--")
celevator.pi.updatedisplay(pos)
end,
})
function celevator.lantern.setlight(pos,dir,newstate)
+ local soundset = core.get_meta(pos):get_int("sound") or 1
+ local sounds = celevator.lantern.chimesounds[soundset]
+ if not sounds then sounds = celevator.lantern.chimesounds[1] end
local node = celevator.get_node(pos)
- if minetest.get_item_group(node.name,"_celevator_lantern") ~= 1 then return end
+ if core.get_item_group(node.name,"_celevator_lantern") ~= 1 then return end
if dir == "up" then
- if minetest.get_item_group(node.name,"_celevator_lantern_has_up") ~= 1 then return end
- local lit = minetest.get_item_group(node.name,"_celevator_lantern_up_lit") == 1
+ if core.get_item_group(node.name,"_celevator_lantern_has_up") ~= 1 then return end
+ local lit = core.get_item_group(node.name,"_celevator_lantern_up_lit") == 1
if lit == newstate then return end
local newname = "celevator:lantern_"
- if minetest.get_item_group(node.name,"_celevator_pi") == 1 then newname = "celevator:pilantern_" end
- if minetest.get_item_group(node.name,"_celevator_lantern_vertical") == 1 then newname = "celevator:lantern_vertical_" end
- if minetest.get_item_group(node.name,"_celevator_lantern_has_down") == 1 then
+ if core.get_item_group(node.name,"_celevator_pi") == 1 then newname = "celevator:pilantern_" end
+ if core.get_item_group(node.name,"_celevator_lantern_vertical") == 1 then newname = "celevator:lantern_vertical_" end
+ if core.get_item_group(node.name,"_celevator_lantern_has_down") == 1 then
newname = newname.."both"
else
newname = newname.."up"
end
if newstate then
newname = newname.."_upon"
- minetest.sound_play("celevator_chime_up",{pos = pos},true)
+ core.sound_play(sounds.up,{pos = pos},true)
end
- if minetest.get_item_group(node.name,"_celevator_lantern_down_lit") == 1 then
+ if core.get_item_group(node.name,"_celevator_lantern_down_lit") == 1 then
newname = newname.."_downon"
end
node.name = newname
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
elseif dir == "down" then
- if minetest.get_item_group(node.name,"_celevator_lantern_has_down") ~= 1 then return end
- local lit = minetest.get_item_group(node.name,"_celevator_lantern_down_lit") == 1
+ if core.get_item_group(node.name,"_celevator_lantern_has_down") ~= 1 then return end
+ local lit = core.get_item_group(node.name,"_celevator_lantern_down_lit") == 1
if lit == newstate then return end
local newname = "celevator:lantern_"
- if minetest.get_item_group(node.name,"_celevator_pi") == 1 then newname = "celevator:pilantern_" end
- if minetest.get_item_group(node.name,"_celevator_lantern_vertical") == 1 then newname = "celevator:lantern_vertical_" end
- if minetest.get_item_group(node.name,"_celevator_lantern_has_up") == 1 then
+ if core.get_item_group(node.name,"_celevator_pi") == 1 then newname = "celevator:pilantern_" end
+ if core.get_item_group(node.name,"_celevator_lantern_vertical") == 1 then newname = "celevator:lantern_vertical_" end
+ if core.get_item_group(node.name,"_celevator_lantern_has_up") == 1 then
newname = newname.."both"
else
newname = newname.."down"
end
- if minetest.get_item_group(node.name,"_celevator_lantern_up_lit") == 1 then
+ if core.get_item_group(node.name,"_celevator_lantern_up_lit") == 1 then
newname = newname.."_upon"
end
if newstate then
newname = newname.."_downon"
- minetest.sound_play("celevator_chime_down",{pos = pos},true)
+ core.sound_play(sounds.down,{pos = pos},true)
end
node.name = newname
- minetest.swap_node(pos,node)
+ core.swap_node(pos,node)
end
end
@@ -326,17 +344,59 @@ local function makeverticallanterntex(dir,upon,downon)
return(tex)
end
+local upname = S("Elevator Up Lantern")
+local upvname = S("Elevator Up Lantern (vertical)")
+local upcname = S("Elevator Up Position Indicator / Lantern Combo")
+local downname = S("Elevator Down Lantern")
+local downvname = S("Elevator Down Lantern (vertical)")
+local downcname = S("Elevator Down Position Indicator / Lantern Combo")
+local bothname = S("Elevator Up and Down Lantern")
+local bothvname = S("Elevator Up and Down Lantern (vertical)")
+local bothcname = S("Elevator Up and Down Position Indicator / Lantern Combo")
+
local validstates = {
- {"up",false,false,"Up"},
- {"up",true,false,"Up"},
- {"down",false,false,"Down"},
- {"down",false,true,"Down"},
- {"both",false,false,"Up and Down"},
- {"both",true,false,"Up and Down"},
- {"both",false,true,"Up and Down"},
- {"both",true,true,"Up and Down"},
+ {"up",false,false,upname,upvname,upcname},
+ {"up",true,false,upname,upvname,upcname},
+ {"down",false,false,downname,downvname,downcname},
+ {"down",false,true,downname,downvname,downcname},
+ {"both",false,false,bothname,bothvname,bothcname},
+ {"both",true,false,bothname,bothvname,bothcname},
+ {"both",false,true,bothname,bothvname,bothcname},
+ {"both",true,true,bothname,bothvname,bothcname},
}
+function celevator.lantern.makeformspec(pos)
+ local meta = core.get_meta(pos)
+ local fs = "formspec_version[7]size[8,5]"
+ fs = fs.."field[0.5,0.5;7,1;carid;"..S("Car ID")..";]"
+ fs = fs.."field[0.5,2;3.25,1;landing;"..S("Landing Number")..";]"
+ fs = fs.."label[4.25,1.85;"..S("Sound").."]"
+ fs = fs.."dropdown[4.25,2;3.25,1;sound;"
+ for i=1,#celevator.lantern.chimesounds do
+ fs = fs..tostring(i)..","
+ end
+ fs = string.sub(fs,1,-2)
+ fs = fs..";1;true]"
+ fs = fs.."button[3,3.5;2,1;save;"..S("Save").."]"
+ meta:set_string("formspec",fs)
+end
+
+function celevator.lantern.handlefields(pos,_,fields)
+ if not fields.save then return end
+ if tonumber(fields.carid) and tonumber(fields.landing) then
+ local carid = tonumber(fields.carid)
+ local landing = tonumber(fields.landing)
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ if not (carinfo and carinfo.lanterns) then return end
+ table.insert(carinfo.lanterns,{pos=pos,landing=landing})
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
+ local meta = core.get_meta(pos)
+ meta:set_int("carid",carid)
+ meta:set_string("formspec","")
+ meta:set_int("sound",tonumber(fields.sound) or 1)
+ end
+end
+
for _,state in ipairs(validstates) do
local nname = "celevator:pilantern_"..state[1]
local dropname = nname
@@ -350,8 +410,8 @@ for _,state in ipairs(validstates) do
light = light + 4
end
local idle = not (state[2] or state[3])
- local description = string.format("Elevator %s Position Indicator/Lantern Combo%s",state[4],(idle and "" or " (on state, you hacker you!)"))
- minetest.register_node(nname,{
+ local description = state[6]
+ core.register_node(nname,{
description = description,
groups = {
dig_immediate = 2,
@@ -383,47 +443,46 @@ for _,state in ipairs(validstates) do
{-0.25,-0.5,0.475,0.25,0.125,0.5},
},
},
- after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("formspec","formspec_version[7]size[8,5]field[0.5,0.5;7,1;carid;Car ID;]field[0.5,2;7,1;landing;Landing Number;]button[3,3.5;2,1;save;Save]")
- end,
+ after_place_node = celevator.lantern.makeformspec,
on_receive_fields = function(pos,_,fields)
+ if not fields.save then return end
if tonumber(fields.carid) and tonumber(fields.landing) then
local carid = tonumber(fields.carid)
local landing = tonumber(fields.landing)
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not (carinfo and carinfo.pis and carinfo.lanterns) then return end
table.insert(carinfo.pis,{pos=pos})
table.insert(carinfo.lanterns,{pos=pos,landing=landing})
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
- local meta = minetest.get_meta(pos)
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
+ local meta = core.get_meta(pos)
meta:set_int("carid",carid)
meta:set_string("formspec","")
celevator.pi.settext(pos,carinfo.pitext)
+ meta:set_int("sound",tonumber(fields.sound) or 1)
end
end,
on_destruct = function(pos)
celevator.pi.removeentity(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.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)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not (carinfo and carinfo.pis and carinfo.lanterns) then return end
for i,pi in pairs(carinfo.pis) do
if vector.equals(pos,pi.pos) then
table.remove(carinfo.pis,i)
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
end
end
for i,lantern in pairs(carinfo.lanterns) do
if vector.equals(pos,lantern.pos) then
table.remove(carinfo.lanterns,i)
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
end
end
end,
on_construct = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
meta:set_string("text","--")
celevator.pi.updatedisplay(pos)
end,
@@ -433,8 +492,8 @@ for _,state in ipairs(validstates) do
if state[2] then nname = nname.."_upon" end
if state[3] then nname = nname.."_downon" end
idle = not (state[2] or state[3])
- description = string.format("Elevator %s Lantern%s",state[4],(idle and "" or " (on state, you hacker you!)"))
- minetest.register_node(nname,{
+ description = state[4]
+ core.register_node(nname,{
description = description,
inventory_image = string.format("[combine:32x32:0,5=celevator_lantern_background_%s.png",(state[1] == "both" and "updown" or state[1])),
groups = {
@@ -455,33 +514,18 @@ for _,state in ipairs(validstates) do
boringside,
makelanterntex(state[1],state[2],state[3])
},
- after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("formspec","formspec_version[7]size[8,5]field[0.5,0.5;7,1;carid;Car ID;]field[0.5,2;7,1;landing;Landing Number;]button[3,3.5;2,1;save;Save]")
- end,
- on_receive_fields = function(pos,_,fields)
- if tonumber(fields.carid) and tonumber(fields.landing) then
- local carid = tonumber(fields.carid)
- local landing = tonumber(fields.landing)
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
- if not (carinfo and carinfo.lanterns) then return end
- table.insert(carinfo.lanterns,{pos=pos,landing=landing})
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
- local meta = minetest.get_meta(pos)
- meta:set_int("carid",carid)
- meta:set_string("formspec","")
- end
- end,
+ after_place_node = celevator.lantern.makeformspec,
+ on_receive_fields = celevator.lantern.handlefields,
on_destruct = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.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)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not (carinfo and carinfo.lanterns) then return end
for i,lantern in pairs(carinfo.lanterns) do
if vector.equals(pos,lantern.pos) then
table.remove(carinfo.lanterns,i)
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
end
end
end,
@@ -500,8 +544,8 @@ for _,state in ipairs(validstates) do
dropname = nname
if state[2] then nname = nname.."_upon" end
if state[3] then nname = nname.."_downon" end
- description = string.format("Elevator %s Lantern (vertical)%s",state[4],(idle and "" or " (on state, you hacker you!)"))
- minetest.register_node(nname,{
+ description = state[5]
+ core.register_node(nname,{
description = description,
inventory_image = string.format("[combine:40x40:10,0=celevator_lantern_vertical_background_%s.png",(state[1] == "both" and "updown" or state[1])),
groups = {
@@ -523,33 +567,18 @@ for _,state in ipairs(validstates) do
boringside,
makeverticallanterntex(state[1],state[2],state[3])
},
- after_place_node = function(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("formspec","formspec_version[7]size[8,5]field[0.5,0.5;7,1;carid;Car ID;]field[0.5,2;7,1;landing;Landing Number;]button[3,3.5;2,1;save;Save]")
- end,
- on_receive_fields = function(pos,_,fields)
- if tonumber(fields.carid) and tonumber(fields.landing) then
- local carid = tonumber(fields.carid)
- local landing = tonumber(fields.landing)
- local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
- if not (carinfo and carinfo.lanterns) then return end
- table.insert(carinfo.lanterns,{pos=pos,landing=landing})
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
- local meta = minetest.get_meta(pos)
- meta:set_int("carid",carid)
- meta:set_string("formspec","")
- end
- end,
+ after_place_node = celevator.lantern.makeformspec,
+ on_receive_fields = celevator.lantern.handlefields,
on_destruct = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.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)))
+ local carinfo = core.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not (carinfo and carinfo.lanterns) then return end
for i,lantern in pairs(carinfo.lanterns) do
if vector.equals(pos,lantern.pos) then
table.remove(carinfo.lanterns,i)
- celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
+ celevator.storage:set_string(string.format("car%d",carid),core.serialize(carinfo))
end
end
end,
@@ -566,15 +595,42 @@ for _,state in ipairs(validstates) do
})
end
-minetest.register_abm({
+core.register_abm({
label = "Respawn / Flash PI displays",
nodenames = {"group:_celevator_pi"},
interval = 1,
chance = 1,
action = function(pos)
- local meta = minetest.get_meta(pos)
+ local meta = core.get_meta(pos)
local flashtimer = meta:get_int("flashtimer") > 0
meta:set_int("flashtimer",flashtimer and 0 or 1)
celevator.pi.updatedisplay(pos)
end,
})
+
+core.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 = core.get_meta(pos)
+ local carid = meta:get_int("carid")
+ if not (carid and carid > 0) then return end --Not set up yet
+ local carinfo = core.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/settingtypes.txt b/settingtypes.txt
new file mode 100644
index 0000000..ef4023f
--- /dev/null
+++ b/settingtypes.txt
@@ -0,0 +1,32 @@
+[Limits]
+
+# The maximum distance that will be checked for a car when configuring a hoist machine.
+# This determines the height of the tallest possible elevator.
+# Reducing this value does not affect existing elevators.
+# NOTE: In the worst case, a vertical column of mapblocks this tall may have to be emerged.
+celevator.max_height (Maximum height) int 500 3 65535
+
+# The highest number of landings that any one elevator or group can serve.
+# Values much higher than 100 are likely to not fit on most screens.
+# Reducing this value does not remove landings from existing elevators or groups.
+celevator.max_landings (Maximum landings) int 100 2 1000
+
+# The maximum number of cars in a group.
+# Reducing this value does not remove cars from existing groups.
+celevator.max_group (Maximum group size) int 16 2 16
+
+# The maximum speed of an elevator, in meters/nodes per second.
+# Depending on the server's active block range and mapblock load speed,
+# setting an elevator to a speed too high may cause players to fall out.
+celevator.max_speed (Maximum speed) float 20.0 1.0 100.0
+
+[Protection]
+
+# Car top inspection controls require area access to operate
+celevator.cartop_protected (Car top controls protected) bool false
+
+# Controller and dispatcher cabinets require area access to open
+celevator.controller_cabinet_protected (Controller cabinet protected) bool true
+
+# Open controllers/dispatchers require area access to interact with
+celevator.controller_screen_protected (Controller screen protected) bool false
diff --git a/sounds/celevator_alarm.ogg b/sounds/celevator_alarm.ogg
new file mode 100644
index 0000000..561ac4e
--- /dev/null
+++ b/sounds/celevator_alarm.ogg
Binary files differ
diff --git a/sounds/celevator_chime2_down.ogg b/sounds/celevator_chime2_down.ogg
new file mode 100644
index 0000000..479e213
--- /dev/null
+++ b/sounds/celevator_chime2_down.ogg
Binary files differ
diff --git a/sounds/celevator_chime2_up.ogg b/sounds/celevator_chime2_up.ogg
new file mode 100644
index 0000000..4723252
--- /dev/null
+++ b/sounds/celevator_chime2_up.ogg
Binary files differ
diff --git a/sounds/celevator_phone.ogg b/sounds/celevator_phone.ogg
new file mode 100644
index 0000000..ae12398
--- /dev/null
+++ b/sounds/celevator_phone.ogg
Binary files differ
diff --git a/textures/celevator_car_fullglass_inventory.png b/textures/celevator_car_fullglass_inventory.png
new file mode 100644
index 0000000..fb50175
--- /dev/null
+++ b/textures/celevator_car_fullglass_inventory.png
Binary files differ
diff --git a/textures/celevator_car_fullglass_wield.png b/textures/celevator_car_fullglass_wield.png
new file mode 100644
index 0000000..653e453
--- /dev/null
+++ b/textures/celevator_car_fullglass_wield.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_copbutton_alarm.png b/textures/celevator_copbutton_alarm.png
new file mode 100644
index 0000000..3ad852e
--- /dev/null
+++ b/textures/celevator_copbutton_alarm.png
Binary files differ
diff --git a/textures/celevator_copbutton_phone.png b/textures/celevator_copbutton_phone.png
new file mode 100644
index 0000000..dc8b9a6
--- /dev/null
+++ b/textures/celevator_copbutton_phone.png
Binary files differ
diff --git a/textures/celevator_door_centerglass_inventory.png b/textures/celevator_door_centerglass_inventory.png
new file mode 100644
index 0000000..adc0741
--- /dev/null
+++ b/textures/celevator_door_centerglass_inventory.png
Binary files differ
diff --git a/textures/celevator_door_centermetal_inventory.png b/textures/celevator_door_centermetal_inventory.png
new file mode 100644
index 0000000..d60464e
--- /dev/null
+++ b/textures/celevator_door_centermetal_inventory.png
Binary files differ
diff --git a/textures/celevator_door_glass_inventory.png b/textures/celevator_door_glass_inventory.png
index 4ebf6f9..41450a2 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..1706658
--- /dev/null
+++ b/textures/celevator_door_metal_inventory.png
Binary files differ
diff --git a/textures/celevator_door_sill.png b/textures/celevator_door_sill.png
new file mode 100644
index 0000000..651cf50
--- /dev/null
+++ b/textures/celevator_door_sill.png
Binary files differ
diff --git a/textures/celevator_door_sill_double.png b/textures/celevator_door_sill_double.png
deleted file mode 100644
index ca80c97..0000000
--- a/textures/celevator_door_sill_double.png
+++ /dev/null
Binary files differ
diff --git a/textures/celevator_door_sill_single.png b/textures/celevator_door_sill_single.png
deleted file mode 100644
index 7f3d611..0000000
--- a/textures/celevator_door_sill_single.png
+++ /dev/null
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
diff --git a/textures/celevator_menu_small_arrow.png b/textures/celevator_menu_small_arrow.png
new file mode 100644
index 0000000..5ab4761
--- /dev/null
+++ b/textures/celevator_menu_small_arrow.png
Binary files differ