From a50ceb4d277020a9b1259f759b1f1d13211f740d Mon Sep 17 00:00:00 2001 From: cheapie Date: Sat, 13 Apr 2024 17:00:40 -0500 Subject: Add car doors --- .luacheckrc | 1 + car.lua | 5 ++ doors.lua | 204 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- drive_entity.lua | 6 +- 4 files changed, 211 insertions(+), 5 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index 2a41057..15da4af 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -9,4 +9,5 @@ read_globals = { "vector", "screwdriver", "minetest", + "table.copy", } diff --git a/car.lua b/car.lua index 2684243..40d85b6 100644 --- a/car.lua +++ b/car.lua @@ -357,6 +357,11 @@ for _,def in ipairs(pieces) do } celevator.controller.run(carinfo.controllerpos,event) end + if def._position == "000" then + def.on_construct = function(pos) + minetest.get_meta(pos):set_string("doorstate","closed") + end + end minetest.register_node("celevator:car_"..def._position,def) end diff --git a/doors.lua b/doors.lua index 47254f3..bfe33fe 100644 --- a/doors.lua +++ b/doors.lua @@ -189,7 +189,8 @@ function celevator.doors.hwopen(pos) if hwdoors_moving[hash] then return end - local fdir = minetest.fourdir_to_dir(minetest.get_node(pos).param2) + local param2 = minetest.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, @@ -213,10 +214,14 @@ function celevator.doors.hwopen(pos) } celevator.doors.erefs[hash] = erefs celevator.storage:set_string("hwdoors_moving",minetest.serialize(hwdoors_moving)) - minetest.set_node(pos,{name="celevator:hwdoor_placeholder"}) + minetest.set_node(pos,{name="celevator:hwdoor_placeholder",param2=param2}) local pmeta = minetest.get_meta(pos) pmeta:set_string("data",minetest.serialize(hwdoors_moving[hash])) pmeta:set_string("state","opening") + local carpos = vector.add(pos,fdir) + if minetest.get_node(carpos).name == "celevator:car_000" then + celevator.doors.caropen(carpos) + end end function celevator.doors.hwclose(pos) @@ -228,6 +233,11 @@ function celevator.doors.hwclose(pos) local pmeta = minetest.get_meta(pos) local state = pmeta:get_string("state") if state ~= "open" then return end + local fdir = minetest.fourdir_to_dir(minetest.get_node(pos).param2) + local carpos = vector.add(pos,fdir) + if minetest.get_node(carpos).name == "celevator:car_000" then + celevator.doors.carclose(carpos) + end local data = minetest.deserialize(pmeta:get_string("data")) if not data then return end for i=1,6,1 do @@ -249,7 +259,7 @@ function celevator.doors.hwclose(pos) celevator.storage:set_string("hwdoors_moving",minetest.serialize(hwdoors_moving)) end -function celevator.doors.step(dtime) +function celevator.doors.hwstep(dtime) local hwdoors_moving = minetest.deserialize(celevator.storage:get_string("hwdoors_moving")) or {} local save = false for hash,data in pairs(hwdoors_moving) do @@ -318,4 +328,190 @@ function celevator.doors.step(dtime) end end -minetest.register_globalstep(celevator.doors.step) +minetest.register_globalstep(celevator.doors.hwstep) + +function celevator.doors.carstep(dtime) + local cardoors_moving = minetest.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 + minetest.get_meta(data.positions[1]):set_string("doorstate","open") + cardoors_moving[hash] = nil + end + elseif data.direction == "close" then + data.time = data.time+(0.66*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.66)) + end + for i=4,6,1 do + celevator.doors.erefs[hash][i]:set_velocity(vector.multiply(data.opendir,vel/2*-0.66)) + end + if data.time >= math.pi then + for i=1,6,1 do + celevator.doors.erefs[hash][i]:set_velocity(vector.new(0,0,0)) + end + minetest.get_meta(data.positions[1]):set_string("doorstate","closed") + cardoors_moving[hash] = nil + 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 + minetest.get_meta(data.positions[1]):set_string("doorstate","open") + cardoors_moving[hash] = nil + elseif data.direction == "close" then + local fdir = minetest.fourdir_to_dir(minetest.get_node(data.positions[1]).param2) + celevator.doors.spawncardoors(data.positions[1],vector.rotate_around_axis(fdir,vector.new(0,1,0),math.pi)) + minetest.get_meta(data.positions[1]):set_string("doorstate","closed") + cardoors_moving[hash] = nil + end + end + end + if save then + celevator.storage:set_string("cardoors_moving",minetest.serialize(cardoors_moving)) + end +end + +minetest.register_globalstep(celevator.doors.carstep) + +minetest.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, + }, +}) + +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 +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) + if cardoors_moving[hash] then + return + end + local fdir = minetest.fourdir_to_dir(minetest.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 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), + } + celevator.doors.erefs[hash] = erefs + celevator.storage:set_string("cardoors_moving",minetest.serialize(cardoors_moving)) + local meta = minetest.get_meta(pos) + meta:set_string("doordata",minetest.serialize(cardoors_moving[hash])) + meta:set_string("doorstate","opening") +end + +function celevator.doors.carclose(pos) + 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 + local meta = minetest.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(minetest.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 + cardoors_moving[hash] = data + celevator.storage:set_string("cardoors_moving",minetest.serialize(cardoors_moving)) +end + +minetest.register_abm({ + label = "Respawn car doors", + nodenames = {"celevator:car_000"}, + 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) + 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) + end, +}) diff --git a/drive_entity.lua b/drive_entity.lua index 2491e69..b651538 100644 --- a/drive_entity.lua +++ b/drive_entity.lua @@ -225,7 +225,11 @@ function celevator.drives.entity.nodestoentities(nodes,ename) table.insert(refs,eref) if not ename then --If ename is set, something other than the car is moving for _,attachref in ipairs(attach) do - if attachref:get_luaentity() and attachref:get_luaentity().name == "celevator:incar_pi_entity" then + local included = { + ["celevator:incar_pi_entity"] = true, + ["celevator:car_door"] = true, + } + if attachref:get_luaentity() and included[attachref:get_luaentity().name] then table.insert(refs,attachref) else local attachpos = attachref:get_pos() -- cgit v1.2.3