90e7f15112
Can be set to 0.1-0.7m/s, cannot be higher than contract speed
1035 lines
37 KiB
Lua
1035 lines
37 KiB
Lua
celevator.drives.entity = {
|
|
name = "Drive",
|
|
description = "Normal entity-based drive",
|
|
nname = "celevator:drive",
|
|
buzzsoundhandles = {},
|
|
movementsoundhandles = {},
|
|
movementsoundstate = {},
|
|
carsoundhandles = {},
|
|
carsoundstate = {},
|
|
entityinfo = {},
|
|
sheaverefs = {},
|
|
}
|
|
|
|
local function update_ui(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
local apos = tonumber(meta:get_string("apos")) or 0
|
|
local status = "Idle"
|
|
local vel = tonumber(meta:get_string("vel")) or 0
|
|
local state = meta:get_string("state")
|
|
if state == "running" and vel > 0 then
|
|
status = string.format("Running: Up, %0.02f m/s",vel)
|
|
elseif state == "running" and vel < 0 then
|
|
status = string.format("Running: Down, %0.02f m/s",math.abs(vel))
|
|
elseif state == "fakerunning" and vel > 0 then
|
|
status = string.format("Running (simulated): Up, %0.02f m/s",vel)
|
|
elseif state == "fakerunning" and vel < 0 then
|
|
status = string.format("Running (simulated): Down, %0.02f m/s",math.abs(vel))
|
|
end
|
|
meta:set_string("infotext",string.format("Drive - %s - Position: %0.02f m",status,apos))
|
|
end
|
|
|
|
local function playbuzz(pos)
|
|
local hash = minetest.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",{
|
|
pos = pos,
|
|
loop = true,
|
|
gain = 0.2,
|
|
})
|
|
end
|
|
|
|
local function startbuzz(pos)
|
|
local hash = minetest.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)
|
|
end
|
|
|
|
local function stopbuzz(pos)
|
|
local hash = minetest.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])
|
|
celevator.drives.entity.buzzsoundhandles[hash] = nil
|
|
end
|
|
end
|
|
|
|
local function motorsound(pos,newstate)
|
|
local hash = minetest.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)))
|
|
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",{
|
|
pos = carinfo.machinepos,
|
|
gain = 1,
|
|
},true)
|
|
celevator.drives.entity.movementsoundhandles[hash] = minetest.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",{
|
|
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",{
|
|
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",{
|
|
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",{
|
|
pos = carinfo.machinepos,
|
|
gain = 1,
|
|
})
|
|
elseif newstate == "idle" then
|
|
if oldhandle then minetest.sound_stop(oldhandle) end
|
|
minetest.sound_play("celevator_brake_apply",{
|
|
pos = carinfo.machinepos,
|
|
gain = 1,
|
|
},true)
|
|
end
|
|
celevator.drives.entity.movementsoundstate[hash] = newstate
|
|
end
|
|
|
|
local function carsound(pos,newstate,speed)
|
|
if speed < 0.5 then return end
|
|
local hash = minetest.hash_node_position(pos)
|
|
local oldstate = celevator.drives.entity.carsoundstate[hash]
|
|
oldstate = oldstate or "idle"
|
|
if oldstate == newstate then return end
|
|
if not celevator.drives.entity.entityinfo[hash] then return end
|
|
local eref = celevator.drives.entity.entityinfo[hash].handles[1]
|
|
if not eref:get_pos() then return end
|
|
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",{
|
|
object = eref,
|
|
gain = gain,
|
|
})
|
|
minetest.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",{
|
|
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",{
|
|
object = eref,
|
|
gain = gain,
|
|
})
|
|
elseif newstate == "stopped" then
|
|
if oldhandle then minetest.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 oldstate = celevator.drives.entity.movementsoundstate[hash]
|
|
if oldstate == compare then
|
|
motorsound(pos,new)
|
|
end
|
|
end
|
|
|
|
local function accelsound(pos)
|
|
motorsound(pos,"slow")
|
|
minetest.after(1,compareexchangesound,pos,"slow","accel")
|
|
minetest.after(4,compareexchangesound,pos,"accel","fast")
|
|
end
|
|
|
|
local function decelsound(pos)
|
|
motorsound(pos,"decel")
|
|
minetest.after(2,compareexchangesound,pos,"decel","slow")
|
|
end
|
|
|
|
minetest.register_node("celevator:drive",{
|
|
description = "Elevator "..celevator.drives.entity.name,
|
|
groups = {
|
|
cracky = 1,
|
|
_celevator_drive = 1,
|
|
},
|
|
tiles = {
|
|
"celevator_cabinet_sides.png",
|
|
"celevator_cabinet_sides.png",
|
|
"celevator_cabinet_sides.png",
|
|
"celevator_cabinet_sides.png",
|
|
"celevator_cabinet_sides.png",
|
|
"celevator_drive_front.png",
|
|
},
|
|
paramtype = "light",
|
|
paramtype2 = "facedir",
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.4,-0.4,-0.1,0.4,0.4,0.5},
|
|
{-0.5,-0.3,0.4,-0.4,-0.22,0.32},
|
|
{-0.5,0.22,0.4,-0.4,0.3,0.32},
|
|
},
|
|
},
|
|
_celevator_drive_type = "entity",
|
|
after_place_node = function(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("apos","0")
|
|
meta:set_string("dpos","0")
|
|
meta:set_string("vel","0")
|
|
meta:set_string("maxvel","0.2")
|
|
meta:set_string("state","uninit")
|
|
meta:set_string("startpos","0")
|
|
meta:set_string("doorstate","closed")
|
|
meta:mark_as_private({"apos","dpos","vel","maxvel","state","startpos","doorstate"})
|
|
update_ui(pos)
|
|
end,
|
|
on_destruct = stopbuzz,
|
|
})
|
|
|
|
minetest.register_entity("celevator:car_moving",{
|
|
initial_properties = {
|
|
visual = "wielditem",
|
|
visual_size = vector.new(0.667,0.667,0.667),
|
|
wield_item = "default:dirt",
|
|
static_save = false,
|
|
glow = minetest.LIGHT_MAX,
|
|
pointable = false,
|
|
},
|
|
})
|
|
|
|
function celevator.drives.entity.gathercar(pos,yaw,nodes)
|
|
if not nodes then nodes = {} end
|
|
local hash = minetest.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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
end
|
|
|
|
function celevator.drives.entity.nodestoentities(nodes,ename)
|
|
local refs = {}
|
|
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"))
|
|
eref:set_properties({
|
|
wield_item = node.name,
|
|
})
|
|
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 toppos = vector.add(pos,vector.new(0,1,0))
|
|
local topattach = minetest.get_objects_inside_radius(toppos,0.75)
|
|
for _,ref in pairs(topattach) do
|
|
table.insert(attach,ref)
|
|
end
|
|
end
|
|
if not ename then --If ename is set, something other than the car is moving
|
|
for _,attachref in ipairs(attach) do
|
|
local included = {
|
|
["celevator:incar_pi_entity"] = true,
|
|
["celevator:car_top_box"] = true,
|
|
["celevator:car_door"] = true,
|
|
["celevator:tapehead"] = true,
|
|
}
|
|
if attachref:get_luaentity() and included[attachref:get_luaentity().name] then
|
|
table.insert(refs,attachref)
|
|
else
|
|
local attachpos = attachref:get_pos()
|
|
local basepos = eref:get_pos()
|
|
local attachoffset = vector.multiply(vector.subtract(attachpos,basepos),30)
|
|
attachoffset = vector.rotate_around_axis(attachoffset,vector.new(0,-1,0),eref:get_yaw())
|
|
attachref:set_attach(eref,"",attachoffset)
|
|
end
|
|
end
|
|
end
|
|
minetest.remove_node(pos)
|
|
end
|
|
return refs
|
|
end
|
|
|
|
function celevator.drives.entity.entitiestonodes(refs,carid)
|
|
local ok = true
|
|
for _,eref in ipairs(refs) do
|
|
local pos = eref:get_pos()
|
|
local top = false
|
|
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)
|
|
eref:remove()
|
|
if carid then celevator.get_meta(pos):set_int("carid",carid) end
|
|
elseif pos and ename == "celevator:incar_pi_entity" then
|
|
pos = vector.new(pos.x,math.floor(pos.y+0.5),pos.z)
|
|
eref:set_pos(pos)
|
|
elseif not ok then
|
|
eref:remove()
|
|
else
|
|
if not pos then ok = false end
|
|
end
|
|
if pos and ename == "celevator:car_moving" then
|
|
local rounded = {
|
|
["celevator:car_top_box"] = true,
|
|
["celevator:car_door"] = true,
|
|
["celevator:tapehead"] = true,
|
|
}
|
|
for _,i in ipairs(minetest.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
|
|
i:set_pos(ppos)
|
|
minetest.after(0.5,i.set_pos,i,ppos)
|
|
elseif i:get_luaentity() and rounded[i:get_luaentity().name] then
|
|
local epos = i:get_pos()
|
|
epos.y = math.floor(epos.y+0.5)
|
|
if i:get_luaentity() and i:get_luaentity().name == "celevator:car_top_box" then
|
|
epos.y = epos.y+0.1
|
|
end
|
|
i:set_pos(epos)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return ok
|
|
end
|
|
|
|
function celevator.drives.entity.step(dtime)
|
|
local entitydrives_running = minetest.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 node = celevator.get_node(pos)
|
|
local sound = false
|
|
if node.name == "ignore" then
|
|
minetest.forceload_block(pos,true)
|
|
elseif node.name ~= "celevator:drive" then
|
|
table.remove(entitydrives_running,i)
|
|
else
|
|
local meta = celevator.get_meta(pos)
|
|
local carid = meta:get_int("carid")
|
|
local state = meta:get_string("state")
|
|
if not (state == "running" or state == "start" or state == "fakerunning") then
|
|
table.remove(entitydrives_running,i)
|
|
else
|
|
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 inspection = meta:get_int("inspection") == 1
|
|
local origin = minetest.string_to_pos(meta:get_string("origin"))
|
|
if not origin then
|
|
minetest.log("error","[celevator] [entity drive] Invalid origin for drive at "..minetest.pos_to_string(pos))
|
|
meta:set_string("fault","badorigin")
|
|
table.remove(entitydrives_running,i)
|
|
return
|
|
end
|
|
if state == "start" then
|
|
if math.abs(dpos-startpos) > 0.1 then
|
|
sound = true
|
|
if not inspection then
|
|
accelsound(pos)
|
|
else
|
|
motorsound(pos,"slow")
|
|
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 nodes = {}
|
|
for carhash in pairs(hashes) do
|
|
local carpos = minetest.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
|
|
table.insert(nodes,carpos)
|
|
end
|
|
end
|
|
local carparam2 = celevator.get_node(nodes[1]).param2
|
|
meta:set_int("carparam2",carparam2)
|
|
local handles = celevator.drives.entity.nodestoentities(nodes)
|
|
celevator.drives.entity.entityinfo[hash] = {
|
|
handles = handles,
|
|
}
|
|
carsound(pos,"accel",maxvel)
|
|
meta:set_string("state","running")
|
|
celevator.drives.entity.sheavetoentity(carid)
|
|
elseif state == "running" then
|
|
if not celevator.drives.entity.entityinfo[hash] then
|
|
meta:set_string("state","fakerunning")
|
|
return
|
|
end
|
|
local handles = celevator.drives.entity.entityinfo[hash].handles
|
|
if (not handles) or (not handles[1]:get_pos()) then
|
|
meta:set_string("state","fakerunning")
|
|
return
|
|
end
|
|
local apos = handles[1]:get_pos().y - origin.y
|
|
local sheaverefs = celevator.drives.entity.sheaverefs[carid]
|
|
if sheaverefs and sheaverefs[1] then
|
|
local rotation = sheaverefs[1]:get_rotation()
|
|
if rotation then
|
|
rotation.z = math.pi*apos*-1
|
|
sheaverefs[1]:set_rotation(rotation)
|
|
end
|
|
end
|
|
local dremain = math.abs(dpos-apos)
|
|
local dmoved = math.abs(apos-startpos)
|
|
local vel
|
|
if dremain < 0.01 then
|
|
vel = 0
|
|
meta:set_string("state","stopped")
|
|
motorsound(pos,"idle")
|
|
celevator.drives.entity.sheavetonode(carid)
|
|
local ok = celevator.drives.entity.entitiestonodes(handles,carid)
|
|
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)
|
|
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
|
|
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
|
|
decelsound(pos)
|
|
carsound(pos,"decel",maxvel)
|
|
end
|
|
elseif dmoved+0.1 > maxvel or inspection then
|
|
vel = maxvel
|
|
else
|
|
vel = dmoved+0.1
|
|
end
|
|
if dpos < apos then vel = 0-vel end
|
|
for _,eref in ipairs(handles) do
|
|
eref:set_velocity(vector.new(0,vel,0))
|
|
end
|
|
meta:set_string("apos",tostring(apos))
|
|
sound = vel ~= 0
|
|
meta:set_string("vel",tostring(vel))
|
|
elseif state == "fakerunning" then
|
|
celevator.drives.entity.carsoundstate[hash] = "stopped"
|
|
local apos = tonumber(meta:get_string("apos")) or 0
|
|
local sheaverefs = celevator.drives.entity.sheaverefs[carid]
|
|
if sheaverefs and sheaverefs[1] then
|
|
local rotation = sheaverefs[1]:get_rotation()
|
|
if rotation then
|
|
rotation.z = math.pi*apos*-1
|
|
sheaverefs[1]:set_rotation(rotation)
|
|
end
|
|
end
|
|
local dremain = math.abs(dpos-apos)
|
|
local dmoved = math.abs(apos-startpos)
|
|
local vel
|
|
if dremain < 0.01 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)
|
|
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
|
|
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
|
|
decelsound(pos)
|
|
end
|
|
elseif dmoved+0.1 > maxvel or inspection then
|
|
vel = maxvel
|
|
else
|
|
vel = dmoved+0.1
|
|
end
|
|
if dpos < apos then vel = 0-vel end
|
|
apos = apos+(vel*dtime)
|
|
meta:set_string("apos",tostring(apos))
|
|
sound = vel ~= 0
|
|
meta:set_string("vel",tostring(vel))
|
|
end
|
|
end
|
|
end
|
|
update_ui(pos)
|
|
if sound then
|
|
startbuzz(pos)
|
|
else
|
|
stopbuzz(pos)
|
|
end
|
|
end
|
|
if save then
|
|
celevator.storage:set_string("entitydrives_running",minetest.serialize(entitydrives_running))
|
|
end
|
|
end
|
|
|
|
minetest.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"))
|
|
if not origin then
|
|
minetest.log("error","[celevator] [entity drive] Invalid origin for drive at "..minetest.pos_to_string(pos))
|
|
meta:set_string("fault","badorigin")
|
|
return
|
|
end
|
|
if target < 0 or origin.y + target > (carinfo.machinepos.y-3) then
|
|
meta:set_string("fault","outofbounds")
|
|
return
|
|
end
|
|
if meta:get_string("state") ~= "stopped" then
|
|
local apos = tonumber(meta:get_string("apos"))
|
|
local vel = tonumber(meta:get_string("vel"))
|
|
if vel > 0 then
|
|
if target < apos+(vel*2) then return end
|
|
elseif vel < 0 then
|
|
if target > apos-(vel*-2) then return end
|
|
else
|
|
return
|
|
end
|
|
end
|
|
meta:set_string("dpos",tostring(target))
|
|
if meta:get_string("state") == "stopped" then
|
|
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 running = false
|
|
for _,dhash in ipairs(entitydrives_running) do
|
|
if hash == dhash then
|
|
running = true
|
|
break
|
|
end
|
|
end
|
|
if not running then
|
|
table.insert(entitydrives_running,hash)
|
|
celevator.storage:set_string("entitydrives_running",minetest.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
|
|
meta:set_string("vel","-0.0001")
|
|
else
|
|
meta:set_string("vel","0.0001")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function celevator.drives.entity.resetpos(pos)
|
|
celevator.drives.entity.moveto(pos,0)
|
|
end
|
|
|
|
function celevator.drives.entity.estop(pos)
|
|
local meta = celevator.get_meta(pos)
|
|
if meta:get_string("state") ~= "running" then return end
|
|
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 handles = celevator.drives.entity.entityinfo[hash].handles
|
|
meta:set_string("state","stopped")
|
|
meta:set_string("vel","0")
|
|
local carid = meta:get_int("carid")
|
|
celevator.drives.entity.entitiestonodes(handles,carid)
|
|
stopbuzz(pos)
|
|
motorsound(pos,"idle")
|
|
if carid ~= 0 then celevator.drives.entity.sheavetonode(carid) end
|
|
minetest.after(0.25,celevator.drives.entity.updatecopformspec,pos)
|
|
end
|
|
|
|
|
|
function celevator.drives.entity.setmaxvel(pos,maxvel)
|
|
local meta = celevator.get_meta(pos)
|
|
meta:set_string("maxvel",tostring(maxvel))
|
|
end
|
|
|
|
|
|
function celevator.drives.entity.rezero(pos)
|
|
celevator.drives.entity.moveto(pos,0)
|
|
end
|
|
|
|
function celevator.drives.entity.getstatus(pos,call2)
|
|
local node = minetest.get_node(pos)
|
|
if node.name == "ignore" and not call2 then
|
|
minetest.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))
|
|
return {fault = "metaload"}
|
|
else
|
|
local meta = celevator.get_meta(pos)
|
|
local ret = {}
|
|
ret.apos = tonumber(meta:get_string("apos")) or 0
|
|
ret.dpos = tonumber(meta:get_string("dpos")) or 0
|
|
ret.vel = tonumber(meta:get_string("vel")) or 0
|
|
ret.maxvel = tonumber(meta:get_string("maxvel")) or 0.2
|
|
ret.state = meta:get_string("state")
|
|
ret.doorstate = meta:get_string("doorstate")
|
|
ret.fault = meta:get_string("fault")
|
|
ret.neareststop = ret.apos+(ret.vel*2)
|
|
if ret.fault == "" then ret.fault = nil end
|
|
return ret
|
|
end
|
|
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 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")
|
|
drivemeta:set_string("fault","doorinterlock")
|
|
return
|
|
end
|
|
end
|
|
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
|
|
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))
|
|
if direction == "open" and (minetest.get_item_group(celevator.get_node(hwdoorpos).name,"_celevator_hwdoor_root") == 1 or drivemeta:get_string("doorstate") == "closing") then
|
|
celevator.doors.hwopen(hwdoorpos,drivepos)
|
|
drivemeta:set_string("doorstate","opening")
|
|
elseif direction == "close" and celevator.get_node(hwdoorpos).name == "celevator:hwdoor_placeholder" then
|
|
celevator.doors.hwclose(hwdoorpos,drivepos,nudge)
|
|
drivemeta:set_string("doorstate","closing")
|
|
end
|
|
end
|
|
|
|
function celevator.drives.entity.resetfault(pos)
|
|
celevator.get_meta(pos):set_string("fault","")
|
|
end
|
|
|
|
function celevator.drives.entity.pibeep(drivepos)
|
|
local drivemeta = celevator.get_meta(drivepos)
|
|
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
|
|
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",{
|
|
pos = beeppos,
|
|
gain = 1,
|
|
},true)
|
|
end
|
|
|
|
local function carsearch(pos)
|
|
for i=1,500,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
|
|
local xoffset = tonumber(string.sub(offsettext,1,1))
|
|
local yoffset = tonumber(string.sub(offsettext,2,2))
|
|
local zoffset = tonumber(string.sub(offsettext,3,3))
|
|
local offset = vector.new(xoffset,yoffset,zoffset)
|
|
offset = vector.rotate_around_axis(offset,vector.new(0,1,0),yaw)
|
|
return vector.subtract(searchpos,offset)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function updatecarpos(pos)
|
|
local meta = celevator.get_meta(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)))
|
|
local carid = meta:get_int("carid")
|
|
local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
|
|
if not carinfo then return end
|
|
carinfo.origin = carpos
|
|
celevator.storage:set_string(string.format("car%d",carid),minetest.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("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 carnodes = celevator.drives.entity.gathercar(carpos,caryaw)
|
|
for hash in pairs(carnodes) do
|
|
local carmeta = celevator.get_meta(minetest.get_position_from_hash(hash))
|
|
carmeta:set_int("carid",carid)
|
|
end
|
|
else
|
|
meta:set_string("infotext","No car found! Punch to try again")
|
|
end
|
|
end
|
|
|
|
minetest.register_node("celevator:machine",{
|
|
description = "Elevator Hoist Machine",
|
|
groups = {
|
|
dig_immediate = 2,
|
|
_celevator_machine = 1,
|
|
},
|
|
paramtype = "light",
|
|
paramtype2 = "4dir",
|
|
tiles = {
|
|
"celevator_machine_top.png",
|
|
"celevator_machine_top.png",
|
|
"celevator_machine_sides.png",
|
|
"celevator_machine_sides.png",
|
|
"celevator_machine_front.png",
|
|
"celevator_machine_front.png",
|
|
},
|
|
inventory_image = "celevator_machine_inventory.png",
|
|
wield_image = "celevator_machine_inventory.png",
|
|
wield_scale = vector.new(1,1,3),
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.3,-0.5,-0.2,0.3,0.4,0.2}, -- Main body
|
|
{-0.2,0.4,-0.2,0.2,0.5,0.2}, -- Top of circle
|
|
{-0.4,-0.1,-0.2,-0.3,0.3,0.2}, -- Left of circle
|
|
{0.3,-0.1,-0.2,0.4,0.3,0.2}, -- Right of circle
|
|
{-0.42,0.075,-0.22,0.42,0.125,0.22}, -- Sealing flanges
|
|
{0.3,-0.3,-0.1,0.35,-0.1,0.1}, -- Bearing cap opposite motor
|
|
{-0.35,-0.3,-0.1,-0.3,-0.1,0.1}, -- Bearing cap on motor side
|
|
{-0.1,0,-0.5,0.1,0.2,-0.2}, -- Shaft to sheave
|
|
{-0.15,-0.05,0.2,0.15,0.25,0.25}, -- Bearing cap opposite sheave
|
|
{-0.15,-0.05,-0.25,0.15,0.25,-0.2}, -- Bearing cap on sheave side
|
|
{-0.5,-0.25,-0.05,-0.35,-0.15,0.05} -- Shaft from motor
|
|
},
|
|
},
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-1.5,-0.5,-0.5,0.5,0.5,0.5},
|
|
{-0.5,-0.5,-0.8,0.5,0.5,-0.5},
|
|
},
|
|
},
|
|
after_place_node = function(pos,player)
|
|
if not player:is_player() then
|
|
minetest.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 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 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 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)
|
|
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)
|
|
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)
|
|
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)
|
|
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})
|
|
end,
|
|
after_dig_node = function(pos,node)
|
|
local facedir = minetest.dir_to_yaw(minetest.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)
|
|
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)
|
|
end
|
|
local erefs = minetest.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()
|
|
end
|
|
end
|
|
end,
|
|
on_punch = function(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
if not minetest.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)))
|
|
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
|
|
return
|
|
end
|
|
end
|
|
carinfo.machinepos = pos
|
|
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","")
|
|
updatecarpos(pos)
|
|
end
|
|
end,
|
|
})
|
|
|
|
minetest.register_node("celevator:motor",{
|
|
description = "Hoist Motor (you hacker you!)",
|
|
groups = {
|
|
not_in_creative_inventory = 1,
|
|
},
|
|
drop = "",
|
|
paramtype = "light",
|
|
paramtype2 = "4dir",
|
|
tiles = {
|
|
"celevator_machine_top.png",
|
|
"celevator_machine_top.png",
|
|
"celevator_motor_sides.png",
|
|
"celevator_motor_sides.png",
|
|
"celevator_motor_back.png",
|
|
"celevator_motor_front.png",
|
|
},
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.5,-0.5,-0.3,0.1,0.1,0.3}, -- Motor body
|
|
{0.1,-0.25,-0.05,0.5,-0.15,0.05}, -- Shaft
|
|
{0.3,-0.4,-0.2,0.35,0,0.2}, -- Brake disc
|
|
{0.275,-0.3,-0.1,0.375,-0.1,0.1}, -- Brake disc clamp
|
|
{0.2,-0.5,0.15,0.45,0.1,0.3}, -- Brake housing
|
|
{-0.4,0.1,-0.2,0,0.3,0.2}, -- Junction box
|
|
},
|
|
},
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = {},
|
|
},
|
|
})
|
|
|
|
minetest.register_node("celevator:sheave",{
|
|
description = "Sheave (you hacker you!)",
|
|
groups = {
|
|
not_in_creative_inventory = 1,
|
|
},
|
|
drop = "",
|
|
paramtype = "light",
|
|
paramtype2 = "4dir",
|
|
tiles = {
|
|
"celevator_sheave_sides.png^[transformR90",
|
|
"celevator_sheave_sides.png^[transformR270",
|
|
"celevator_sheave_sides.png",
|
|
"celevator_sheave_sides.png^[transformR180",
|
|
"celevator_sheave_front.png",
|
|
"celevator_sheave_front.png",
|
|
},
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.3,-0.2,0.2,0.3,0.4,0.5},
|
|
{-0.4,-0.1,0.2,-0.3,0.3,0.5},
|
|
{0.3,-0.1,0.2,0.4,0.3,0.5},
|
|
{-0.2,0.4,0.2,0.2,0.5,0.5},
|
|
{-0.2,-0.3,0.2,0.2,-0.2,0.5},
|
|
},
|
|
},
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = {},
|
|
},
|
|
})
|
|
|
|
minetest.register_node("celevator:sheave_centered",{
|
|
description = "Centered Sheave (you hacker you!)",
|
|
groups = {
|
|
not_in_creative_inventory = 1,
|
|
},
|
|
drop = "",
|
|
paramtype = "light",
|
|
paramtype2 = "4dir",
|
|
tiles = {
|
|
"celevator_sheave_sides.png^[transformR90",
|
|
"celevator_sheave_sides.png^[transformR270",
|
|
"celevator_sheave_sides.png",
|
|
"celevator_sheave_sides.png^[transformR180",
|
|
"celevator_sheave_front_centered.png",
|
|
"celevator_sheave_front_centered.png",
|
|
},
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.3,-0.3,0.2,0.3,0.3,0.5},
|
|
{-0.4,-0.2,0.2,-0.3,0.2,0.5},
|
|
{0.3,-0.2,0.2,0.4,0.2,0.5},
|
|
{-0.2,0.3,0.2,0.2,0.4,0.5},
|
|
{-0.2,-0.4,0.2,0.2,-0.3,0.5},
|
|
},
|
|
},
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = {},
|
|
},
|
|
})
|
|
|
|
minetest.register_entity("celevator:sheave_moving",{
|
|
initial_properties = {
|
|
visual = "wielditem",
|
|
visual_size = vector.new(0.667,0.667,0.667),
|
|
wield_item = "celevator:sheave_centered",
|
|
static_save = false,
|
|
pointable = false,
|
|
},
|
|
})
|
|
|
|
function celevator.drives.entity.sheavetoentity(carid)
|
|
local carinfo = minetest.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 pos = vector.add(carinfo.machinepos,vector.multiply(dir,-1))
|
|
minetest.set_node(pos,{
|
|
name = "celevator:sheave",
|
|
param2 = minetest.dir_to_fourdir(dir),
|
|
})
|
|
local sheaverefs = celevator.drives.entity.nodestoentities({pos},"celevator:sheave_moving")
|
|
celevator.drives.entity.sheaverefs[carid] = sheaverefs
|
|
sheaverefs[1]:set_properties({wield_item = "celevator:sheave_centered"})
|
|
sheaverefs[1]:set_pos(vector.add(pos,vector.new(0,0.1,0)))
|
|
end
|
|
|
|
function celevator.drives.entity.sheavetonode(carid)
|
|
local carinfo = minetest.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 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,{
|
|
name = "celevator:sheave",
|
|
param2 = minetest.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 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)))
|
|
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
|
|
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
|
|
end
|
|
end
|
|
end
|