celevator.doors = {} celevator.doors.erefs = {} minetest.register_node("celevator:hwdoor_fast_glass_bottom",{ description = "Glass Hoistway Door (fast, bottom)", 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 = { dig_immediate = 2, _celevator_hwdoor_root = 1, }, 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_middle",{ description = "Glass Hoistway Door (fast, middle)", 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 = { dig_immediate = 2, }, 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)", 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 = { dig_immediate = 2, }, 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)", 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 = { dig_immediate = 2, }, 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)", 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 = { dig_immediate = 2, }, 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)", 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 = { dig_immediate = 2, }, 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", tiles = { "celevator_transparent.png", }, paramtype = "light", paramtype2 = "4dir", drawtype = "airlike", collision_box = { type = "fixed", fixed = { {0,0,0,0,0,0} } }, selection_box = { type = "fixed", fixed = { {0,0,0,0,0,0} } }, }) minetest.register_entity("celevator:hwdoor_moving",{ initial_properties = { visual = "wielditem", visual_size = vector.new(0.667,0.667,0.667), wield_item = "default:dirt", static_save = 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 = 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, 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] = minetest.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 = 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 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 minetest.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 = minetest.get_meta(pos) pmeta:set_string("data",minetest.serialize(hwdoors_moving[hash])) pmeta:set_string("state","opening") end end function celevator.doors.hwclose(pos,drivepos) 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 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 minetest.set_node(data.positions[i],data.nodes[i]) end data.direction = "close" data.time = 0 data.drivepos = drivepos 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)) end 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 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 minetest.get_meta(data.positions[1]):set_string("state","open") minetest.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","open") hwdoors_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_pos(data.positions[i]) end celevator.drives.entity.entitiestonodes(celevator.doors.erefs[hash]) minetest.get_meta(hwdoors_moving[hash].drivepos):set_string("doorstate","closed") 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 minetest.get_meta(data.positions[1]):set_string("state","open") 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 minetest.get_meta(data.positions[1]):set_string("state","closed") hwdoors_moving[hash] = nil end end end if save then celevator.storage:set_string("hwdoors_moving",minetest.serialize(hwdoors_moving)) end end 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 not cardoors_moving[hash] then 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") elseif cardoors_moving[hash].direction == "close" then 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 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, })