summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcheapie <no-email-for-you@example.com>2023-08-08 22:16:42 -0500
committercheapie <no-email-for-you@example.com>2023-08-08 22:16:42 -0500
commit08cbd3adfe523ae8ad4e7263f11ff5ae1d521230 (patch)
treee9881649c7e2f78dcb5a7c16971455906019853a
parentca33ea9d98cbf6dbd5afa668ce676ba0d9064632 (diff)
downloadcelevator-08cbd3adfe523ae8ad4e7263f11ff5ae1d521230.tar
celevator-08cbd3adfe523ae8ad4e7263f11ff5ae1d521230.tar.gz
celevator-08cbd3adfe523ae8ad4e7263f11ff5ae1d521230.tar.bz2
celevator-08cbd3adfe523ae8ad4e7263f11ff5ae1d521230.tar.xz
celevator-08cbd3adfe523ae8ad4e7263f11ff5ae1d521230.zip
Add initial car motion functionality
Place a machine (no texture yet) above the car somewhere when the car is at the lowest floor, then pair it to the drive with the pairing tool. Not much error checking yet, it'll probably crash if you do anything weird.
-rw-r--r--car.lua24
-rw-r--r--controllerfw.lua5
-rw-r--r--drive_entity.lua102
-rw-r--r--pairingtool.lua43
4 files changed, 169 insertions, 5 deletions
diff --git a/car.lua b/car.lua
index c89015e..5211ecb 100644
--- a/car.lua
+++ b/car.lua
@@ -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)