diff options
-rw-r--r-- | car.lua | 24 | ||||
-rw-r--r-- | controllerfw.lua | 5 | ||||
-rw-r--r-- | drive_entity.lua | 102 | ||||
-rw-r--r-- | pairingtool.lua | 43 |
4 files changed, 169 insertions, 5 deletions
@@ -314,11 +314,33 @@ local pieces = { for _,def in ipairs(pieces) do def.groups = { dig_immediate = 2, + _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 - def.light_source = minetest.LIGHT_MAX + def.light_source = 9 minetest.register_node("celevator:car_"..def._position,def) end diff --git a/controllerfw.lua b/controllerfw.lua index 2640af2..4ac888c 100644 --- a/controllerfw.lua +++ b/controllerfw.lua @@ -19,6 +19,10 @@ if not mem.drive.status then } end +if mem.drive.state == "uninit" then + fault("driveuninit",true) +end + local juststarted = false local modenames = { @@ -48,6 +52,7 @@ local doorstates = { local faultnames = { drivecomm = "Lost Communication With Drive", + driveuninit = "Drive Not Configured", } local function drivecmd(command) diff --git a/drive_entity.lua b/drive_entity.lua index 79a3990..ace5dd6 100644 --- a/drive_entity.lua +++ b/drive_entity.lua @@ -57,6 +57,7 @@ minetest.register_node("celevator:drive",{ description = celevator.drives.entity.name, groups = { cracky = 1, + _celevator_drive = 1, }, tiles = { "celevator_cabinet_sides.png", @@ -84,9 +85,8 @@ minetest.register_node("celevator:drive",{ meta:set_string("dpos","0") meta:set_string("vel","0") meta:set_string("maxvel","0.2") - meta:set_string("state","stopped") + meta:set_string("state","uninit") meta:set_string("startpos","0") - meta:set_string("origin",minetest.pos_to_string(vector.new(-726,9,77))) update_ui(pos) end, on_destruct = stopbuzz, @@ -98,9 +98,36 @@ minetest.register_entity("celevator:car_moving",{ visual_size = vector.new(0.667,0.667,0.667), wield_item = "default:dirt", static_save = false, + glow = minetest.LIGHT_MAX, }, }) +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(minetest.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(minetest.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(minetest.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(minetest.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(minetest.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(minetest.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) local refs = {} for _,pos in ipairs(nodes) do @@ -156,7 +183,18 @@ function celevator.drives.entity.step() end if state == "start" then sound = true - local handles = celevator.drives.entity.nodestoentities({vector.add(origin,vector.new(0,startpos,0))}) + 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(minetest.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 handles = celevator.drives.entity.nodestoentities(nodes) celevator.drives.entity.entityinfo[hash] = { handles = handles, } @@ -207,6 +245,7 @@ minetest.register_globalstep(celevator.drives.entity.step) function celevator.drives.entity.moveto(pos,target) local meta = minetest.get_meta(pos) + if meta:get_string("state") ~= "stopped" then return end meta:set_string("dpos",tostring(target)) meta:set_string("state","start") meta:set_string("startpos",meta:get_string("apos")) @@ -233,7 +272,7 @@ end function celevator.drives.entity.estop(pos) local meta = minetest.get_meta(pos) - if meta:get_string("state") == "stopped" then return end + 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)) local hash = minetest.hash_node_position(pos) @@ -270,6 +309,61 @@ function celevator.drives.entity.getstatus(pos,call2) 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") return ret end end + +local function carsearch(pos) + for i=1,500,1 do + local searchpos = vector.subtract(pos,vector.new(0,i,0)) + local node = minetest.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 = minetest.get_meta(pos) + local carpos = carsearch(pos) + if carpos then + meta:set_string("origin",minetest.pos_to_string(carpos)) + meta:set_string("infotext",string.format("Using car with origin %s",minetest.pos_to_string(carpos))) + else + meta:set_string("infotext","No car found! Punch to try again") + end +end + +minetest.register_node("celevator:machine",{ + description = "Hoist Machine", + groups = { + dig_immediate = 2, + _celevator_machine = 1, + }, + paramtype = "light", + paramtype2 = "4dir", + tiles = { + "default_dirt.png", + }, + after_place_node = updatecarpos, + on_punch = function(pos,_,player) + if not player:is_player() 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,"Can't open cabinet - cabinet is locked.") + minetest.record_protection_violation(pos,name) + return + end + updatecarpos(pos) + end, +}) diff --git a/pairingtool.lua b/pairingtool.lua index 9bea461..7a48f31 100644 --- a/pairingtool.lua +++ b/pairingtool.lua @@ -50,6 +50,49 @@ minetest.register_tool("celevator:pairingtool",{ local stackmeta = itemstack:get_meta() stackmeta:set_string("controllerpos",minetest.pos_to_string(pos)) minetest.chat_send_player(name,"Now pairing with controller at "..minetest.pos_to_string(pos)) + elseif minetest.get_item_group(node.name,"_celevator_drive") == 1 then + local stackmeta = itemstack:get_meta() + stackmeta:set_string("drivepos",minetest.pos_to_string(pos)) + minetest.chat_send_player(name,"Now pairing with drive at "..minetest.pos_to_string(pos)) + elseif minetest.get_item_group(node.name,"_celevator_machine") == 1 then + local stackmeta = itemstack:get_meta() + local nodemeta = minetest.get_meta(pos) + local oldpairing = minetest.string_to_pos(nodemeta:get_string("drivepos")) + local drivepos = minetest.string_to_pos(stackmeta:get_string("drivepos")) + local origin = minetest.string_to_pos(nodemeta:get_string("origin")) + if not origin then + minetest.chat_send_player(name,"Car has not been located! Try punching the machine to search for one.") + elseif not drivepos then + minetest.chat_send_player(name,"Nothing has been selected to pair with! Punch a drive first.") + elseif oldpairing then + local drivemeta = minetest.get_meta(oldpairing) + drivemeta:set_string("machinepos","") + drivemeta:set_string("apos","0") + drivemeta:set_string("dpos","0") + drivemeta:set_string("vel","0") + drivemeta:set_string("maxvel","0.2") + drivemeta:set_string("state","uninit") + drivemeta:set_string("startpos","0") + drivemeta:set_string("origin",minetest.pos_to_string(origin)) + nodemeta:set_string("drivepos","") + minetest.chat_send_player(player:get_player_name(),"Unpaired from "..minetest.pos_to_string(oldpairing)) + elseif minetest.get_item_group(minetest.get_node(drivepos).name,"_celevator_drive") ~= 1 then + minetest.chat_send_player(name,"Drive has been removed. Punch a new drive to pair to that one.") + else + if minetest.is_protected(drivepos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then + minetest.chat_send_player(name,"Unable to pair - drive at "..minetest.pos_to_string(drivepos).." is protected!") + minetest.record_protection_violation(drivepos,name) + elseif minetest.is_protected(pos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then + minetest.chat_send_player(name,"Unable to pair - item to be paired is protected!") + minetest.record_protection_violation(pos,name) + else + local drivemeta = minetest.get_meta(drivepos) + nodemeta:set_string("drivepos",minetest.pos_to_string(drivepos)) + drivemeta:set_string("machinepos",minetest.pos_to_string(pos)) + drivemeta:set_string("state","stopped") + minetest.chat_send_player(player:get_player_name(),"Machine paired to "..minetest.pos_to_string(drivepos)) + end + end elseif minetest.get_item_group(node.name,"_celevator_callbutton") == 1 then local stackmeta = itemstack:get_meta() local nodemeta = minetest.get_meta(pos) |