Added a rotation controller
Well that was a lot of work. Also, switched the "waiting" timer management to the actual on_timer system - I noticed that minetest.after wasn't persisting through server shutdown and restart, that could put a controller in a "broken" state.
This commit is contained in:
parent
e704249735
commit
d7e5309833
@ -52,6 +52,11 @@ Aka the "can you rebuild it six inches to the left" module. This is a much simpl
|
||||
|
||||
Since movement alone does not require fuel, a pusher module has no internal furnace.
|
||||
|
||||
Rotation Unit
|
||||
-----------
|
||||
|
||||
This magical module can rotate a Digtron array in place around itself. Right-clicking on it will rotate the Digtron 90 degrees in the direction the orange arrows on its sides indicate (widdershins around the Y axis by default, use the screwdriver to change this) assuming there's space for the Digtron in its new orientation. Builders and diggers will not trigger.
|
||||
|
||||
Digger Head
|
||||
-----------
|
||||
|
||||
|
3
init.lua
3
init.lua
@ -6,7 +6,8 @@ dofile( minetest.get_modpath( "digtron" ) .. "/node_storage.lua" ) -- contains i
|
||||
dofile( minetest.get_modpath( "digtron" ) .. "/node_diggers.lua" ) -- contains all diggers
|
||||
dofile( minetest.get_modpath( "digtron" ) .. "/node_builders.lua" ) -- contains all builders (there's just one currently)
|
||||
dofile( minetest.get_modpath( "digtron" ) .. "/node_controllers.lua" ) -- controllers
|
||||
dofile( minetest.get_modpath( "digtron" ) .."/recipes.lua" )
|
||||
dofile( minetest.get_modpath( "digtron" ) .. "/node_axle.lua" ) -- Rotation controller
|
||||
dofile( minetest.get_modpath( "digtron" ) .. "/recipes.lua" )
|
||||
|
||||
digtron.creative_mode = false -- this causes digtrons to operate without consuming fuel or building materials.
|
||||
digtron.particle_effects = true -- Enables the spray of particles out the back of a digger head and puffs of smoke from the controller
|
||||
|
58
node_axle.lua
Normal file
58
node_axle.lua
Normal file
@ -0,0 +1,58 @@
|
||||
minetest.register_node("digtron:axle", {
|
||||
description = "Digtron Rotation Unit",
|
||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1},
|
||||
drop = "digtron:axel",
|
||||
sounds = digtron.metal_sounds,
|
||||
paramtype = "light",
|
||||
paramtype2= "facedir",
|
||||
is_ground_content = false,
|
||||
-- Aims in the +Z direction by default
|
||||
tiles = {
|
||||
"digtron_axel_top.png",
|
||||
"digtron_axel_top.png",
|
||||
"digtron_axel_side.png",
|
||||
"digtron_axel_side.png",
|
||||
"digtron_axel_side.png",
|
||||
"digtron_axel_side.png",
|
||||
},
|
||||
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5, 0.3125, -0.3125, 0.5, 0.5, 0.3125}, -- Uppercap
|
||||
{-0.5, -0.5, -0.3125, 0.5, -0.3125, 0.3125}, -- Lowercap
|
||||
{-0.3125, 0.3125, -0.5, 0.3125, 0.5, -0.3125}, -- Uppercap_edge2
|
||||
{-0.3125, 0.3125, 0.3125, 0.3125, 0.5, 0.5}, -- Uppercap_edge1
|
||||
{-0.3125, -0.5, -0.5, 0.3125, -0.3125, -0.3125}, -- Lowercap_edge1
|
||||
{-0.3125, -0.5, 0.3125, 0.3125, -0.3125, 0.5}, -- Lowercap_edge2
|
||||
{-0.25, -0.3125, -0.25, 0.25, 0.3125, 0.25}, -- Axel
|
||||
}
|
||||
},
|
||||
|
||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get_string("waiting") == "true" then
|
||||
-- Been too soon since last time the digtron rotated.
|
||||
return
|
||||
end
|
||||
local image = digtron.get_layout_image(pos, clicker)
|
||||
digtron.rotate_layout_image(image, node.param2)
|
||||
if digtron.can_write_layout_image(image, clicker) then
|
||||
digtron.write_layout_image(image)
|
||||
|
||||
minetest.sound_play("whirr", {gain=1.0, pos=pos})
|
||||
meta = minetest.get_meta(pos)
|
||||
meta:set_string("waiting", "true")
|
||||
meta:set_string("infotext", nil)
|
||||
minetest.get_node_timer(pos):start(digtron.cycle_time*2)
|
||||
else
|
||||
minetest.sound_play("buzzer", {gain=1.0, pos=pos})
|
||||
meta:set_string("infotext", "Digtron is obstructed.")
|
||||
end
|
||||
end,
|
||||
|
||||
on_timer = function(pos, elapsed)
|
||||
minetest.get_meta(pos):set_string("waiting", nil)
|
||||
end,
|
||||
})
|
@ -89,6 +89,8 @@ minetest.register_node("digtron:builder", {
|
||||
offset = meta:get_int("offset")
|
||||
end
|
||||
if build_facing and build_facing >= 0 and build_facing < 24 then
|
||||
-- TODO: wallmounted facings only run from 0-5, a player could theoretically put a wallmounted item into the builder and then manually set the build facing to an invalid number
|
||||
-- Should prevent that somehow. But not tonight.
|
||||
meta:set_int("build_facing", math.floor(build_facing))
|
||||
end
|
||||
|
||||
@ -134,6 +136,10 @@ minetest.register_node("digtron:builder", {
|
||||
on_destruct = function(pos)
|
||||
digtron.remove_builder_item(pos)
|
||||
end,
|
||||
|
||||
after_place_node = function(pos)
|
||||
digtron.update_builder_item(pos)
|
||||
end,
|
||||
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
||||
|
@ -58,11 +58,11 @@ minetest.register_node("digtron:controller", {
|
||||
|
||||
-- Start the delay before digtron can run again.
|
||||
minetest.get_meta(newpos):set_string("waiting", "true")
|
||||
minetest.after(digtron.cycle_time,
|
||||
function (pos)
|
||||
minetest.get_meta(pos):set_string("waiting", nil)
|
||||
end, newpos
|
||||
)
|
||||
minetest.get_node_timer(newpos):start(digtron.cycle_time)
|
||||
end,
|
||||
|
||||
on_timer = function(pos, elapsed)
|
||||
minetest.get_meta(pos):set_string("waiting", nil)
|
||||
end,
|
||||
})
|
||||
|
||||
@ -180,6 +180,11 @@ minetest.register_node("digtron:auto_controller", {
|
||||
meta:set_string("waiting", "true")
|
||||
meta:set_string("formspec", auto_formspec)
|
||||
end,
|
||||
|
||||
on_timer = function(pos, elapsed)
|
||||
minetest.get_meta(pos):set_string("waiting", nil)
|
||||
end,
|
||||
|
||||
})
|
||||
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
@ -250,11 +255,7 @@ minetest.register_node("digtron:pusher", {
|
||||
if not can_move then
|
||||
-- mark this node as waiting, will clear this flag in digtron.cycle_time seconds
|
||||
meta:set_string("waiting", "true")
|
||||
minetest.after(digtron.cycle_time,
|
||||
function (pos)
|
||||
minetest.get_meta(pos):set_string("waiting", nil)
|
||||
end, pos
|
||||
)
|
||||
minetest.get_node_timer(pos):start(digtron.cycle_time)
|
||||
minetest.sound_play("squeal", {gain=1.0, pos=pos})
|
||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
||||
meta:set_string("infotext", "Digtron is obstructed.")
|
||||
@ -283,10 +284,11 @@ minetest.register_node("digtron:pusher", {
|
||||
|
||||
-- Start the delay before digtron can run again. Do this after moving the array or pos will be wrong.
|
||||
minetest.get_meta(pos):set_string("waiting", "true")
|
||||
minetest.after(digtron.cycle_time,
|
||||
function (pos)
|
||||
minetest.get_meta(pos):set_string("waiting", nil)
|
||||
end, pos
|
||||
)
|
||||
minetest.get_node_timer(pos):start(digtron.cycle_time)
|
||||
end,
|
||||
|
||||
on_timer = function(pos, elapsed)
|
||||
minetest.get_meta(pos):set_string("waiting", nil)
|
||||
end,
|
||||
|
||||
})
|
17
recipes.lua
17
recipes.lua
@ -102,6 +102,15 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "digtron:axle",
|
||||
recipe = {
|
||||
{"default:coal_lump","default:coal_lump","default:coal_lump"},
|
||||
{"default:coal_lump","digtron:digtron_core","default:coal_lump"},
|
||||
{"default:coal_lump","default:coal_lump","default:coal_lump"}
|
||||
}
|
||||
})
|
||||
|
||||
-- Structural
|
||||
|
||||
minetest.register_craft({
|
||||
@ -193,7 +202,6 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = "digtron:digtron_core",
|
||||
recipe = {
|
||||
@ -227,4 +235,11 @@ minetest.register_craft({
|
||||
recipe = {
|
||||
{"digtron:pusher"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "digtron:digtron_core",
|
||||
recipe = {
|
||||
{"digtron:axle"},
|
||||
}
|
||||
})
|
@ -1,13 +1,14 @@
|
||||
The sounds in this folder were sampled from source .wavs from Freesound.org. Specifically:
|
||||
|
||||
buzzer.ogg - https://freesound.org/people/hypocore/sounds/164090/ - public domain via CC 1.0 by hypocore
|
||||
construction.ogg - https://www.freesound.org/people/mediapetros/sounds/109117/ - under the CC by 3.0 license by mediapetros
|
||||
construction.ogg - https://www.freesound.org/people/mediapetros/sounds/109117/ - under the CC BY 3.0 license by mediapetros
|
||||
dingding.ogg - https://www.freesound.org/people/JohnsonBrandEditing/sounds/173932/ public domain via CC 1.0 by JohnsonBrandEditing
|
||||
squeal.ogg - https://www.freesound.org/people/RutgerMuller/sounds/104026/ public domain via CC 1.0 by RutgerMuller
|
||||
honk.ogg - https://freesound.org/people/bigmanjoe/sounds/349922/ public domain via CC 1.0 by bigmanjoe
|
||||
truck.ogg - https://www.freesound.org/people/jberkuta14/sounds/134898/ public domain via CC 1.0 by jberkuta14
|
||||
sploosh.ogg - https://www.freesound.org/people/mr_marcello/sounds/257609/ public domain via CC 1.0 by mr_marcello
|
||||
woopwoopwoop.ogg - https://www.freesound.org/people/gregconquest/sounds/188012/ public domain via CC 1.0 by gregconquest
|
||||
whirr.ogg - https://www.freesound.org/people/daveincamas/sounds/25034/ - under the CC BY 3.0 license by daveincamas
|
||||
|
||||
|
||||
Creative Commons Attribution 3.0 license:
|
||||
|
BIN
sounds/whirr.ogg
Normal file
BIN
sounds/whirr.ogg
Normal file
Binary file not shown.
BIN
textures/digtron_axel_side.png
Normal file
BIN
textures/digtron_axel_side.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 737 B |
BIN
textures/digtron_axel_top.png
Normal file
BIN
textures/digtron_axel_top.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 743 B |
@ -122,11 +122,7 @@ digtron.execute_cycle = function(pos, clicker)
|
||||
if not can_move then
|
||||
-- mark this node as waiting, will clear this flag in digtron.cycle_time seconds
|
||||
minetest.get_meta(pos):set_string("waiting", "true")
|
||||
minetest.after(digtron.cycle_time,
|
||||
function (pos)
|
||||
minetest.get_meta(pos):set_string("waiting", nil)
|
||||
end, pos
|
||||
)
|
||||
minetest.get_node_timer(pos):start(digtron.cycle_time)
|
||||
minetest.sound_play("squeal", {gain=1.0, pos=pos})
|
||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
||||
return pos, "Digtron is obstructed.\n" .. status_text, 3 --Abort, don't dig and don't build.
|
||||
@ -181,11 +177,7 @@ digtron.execute_cycle = function(pos, clicker)
|
||||
|
||||
if not can_build then
|
||||
minetest.get_meta(pos):set_string("waiting", "true")
|
||||
minetest.after(digtron.cycle_time,
|
||||
function (pos)
|
||||
minetest.get_meta(pos):set_string("waiting", nil)
|
||||
end, pos
|
||||
)
|
||||
minetest.get_node_timer(pos):start(digtron.cycle_time)
|
||||
local return_string = nil
|
||||
local return_code = 5
|
||||
if test_build_return_code == 3 then
|
||||
|
250
util_layout.lua
250
util_layout.lua
@ -108,4 +108,252 @@ digtron.get_all_digtron_neighbours = function(pos, player)
|
||||
end
|
||||
|
||||
return layout
|
||||
end
|
||||
end
|
||||
|
||||
-- Rotation magic
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
local facedir_rotate = {
|
||||
['x'] = {
|
||||
[-1] = {[0]=4, 5, 6, 7, 22, 23, 20, 21, 0, 1, 2, 3, 13, 14, 15, 12, 19, 16, 17, 18, 10, 11, 8, 9}, -- 270 degrees
|
||||
[1] = {[0]=8, 9, 10, 11, 0, 1, 2, 3, 22, 23, 20, 21, 15, 12, 13, 14, 17, 18, 19, 16, 6, 7, 4, 5}, -- 90 degrees
|
||||
},
|
||||
['y'] = {
|
||||
[-1] = {[0]=3, 0, 1, 2, 19, 16, 17, 18, 15, 12, 13, 14, 7, 4, 5, 6, 11, 8, 9, 10, 21, 22, 23, 20}, -- 270 degrees
|
||||
[1] = {[0]=1, 2, 3, 0, 13, 14, 15, 12, 17, 18, 19, 16, 9, 10, 11, 8, 5, 6, 7, 4, 23, 20, 21, 22}, -- 90 degrees
|
||||
},
|
||||
['z'] = {
|
||||
[-1] = {[0]=16, 17, 18, 19, 5, 6, 7, 4, 11, 8, 9, 10, 0, 1, 2, 3, 20, 21, 22, 23, 12, 13, 14, 15}, -- 270 degrees
|
||||
[1] = {[0]=12, 13, 14, 15, 7, 4, 5, 6, 9, 10, 11, 8, 20, 21, 22, 23, 0, 1, 2, 3, 16, 17, 18, 19}, -- 90 degrees
|
||||
}
|
||||
}
|
||||
|
||||
local wallmounted_rotate = {
|
||||
['x'] = {
|
||||
[-1] = {[0]=4, 5, 2, 3, 1, 0}, -- 270 degrees
|
||||
[1] = {[0]=5, 4, 2, 3, 0, 1}, -- 90 degrees
|
||||
},
|
||||
['y'] = {
|
||||
[-1] = {[0]=0, 1, 4, 5, 3, 2}, -- 270 degrees
|
||||
[1] = {[0]=0, 1, 5, 4, 2, 3}, -- 90 degrees
|
||||
},
|
||||
['z'] = {
|
||||
[-1] = {[0]=3, 2, 0, 1, 4, 5}, -- 270 degrees
|
||||
[1] = {[0]=2, 3, 1, 0, 4, 5}, -- 90 degrees
|
||||
}
|
||||
}
|
||||
|
||||
--90 degrees CW about x-axis: (x, y, z) -> (x, -z, y)
|
||||
--90 degrees CCW about x-axis: (x, y, z) -> (x, z, -y)
|
||||
--90 degrees CW about y-axis: (x, y, z) -> (-z, y, x)
|
||||
--90 degrees CCW about y-axis: (x, y, z) -> (z, y, -x)
|
||||
--90 degrees CW about z-axis: (x, y, z) -> (y, -x, z)
|
||||
--90 degrees CCW about z-axis: (x, y, z) -> (-y, x, z)
|
||||
local rotate_pos = function(axis, direction, pos)
|
||||
if axis == "x" then
|
||||
if direction < 0 then
|
||||
return {x= pos.x, y= -pos.z, z= pos.y}
|
||||
else
|
||||
return {x= pos.x, y= pos.z, z= -pos.y}
|
||||
end
|
||||
elseif axis == "y" then
|
||||
if direction < 0 then
|
||||
return {x= -pos.z, y= pos.y, z= pos.x}
|
||||
else
|
||||
return {x= pos.z, y= pos.y, z= -pos.x}
|
||||
end
|
||||
else
|
||||
if direction < 0 then
|
||||
return {x= -pos.y, y= pos.x, z= pos.z}
|
||||
else
|
||||
return {x= pos.y, y= -pos.x, z= pos.z}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local get_node_image = function(pos, node)
|
||||
local node_image = {node=node, pos={x=pos.x, y=pos.y, z=pos.z}}
|
||||
node_image.paramtype2 = minetest.registered_nodes[node.name].paramtype2
|
||||
local meta = minetest.get_meta(pos)
|
||||
node_image.meta = meta:to_table()
|
||||
|
||||
-- Record what kind of thing we've got in a builder node so its facing can be rotated properly
|
||||
if minetest.get_item_group(node.name, "digtron") == 4 then
|
||||
local build_item = node_image.meta.inventory.main[1]
|
||||
if build_item ~= "" then
|
||||
local build_item_def = minetest.registered_nodes[ItemStack(build_item):get_name()]
|
||||
node_image.build_item_paramtype2 = build_item_def.paramtype2
|
||||
end
|
||||
end
|
||||
return node_image
|
||||
end
|
||||
|
||||
local rotate_node_image = function(node_image, origin, axis, direction, old_pos_pointset)
|
||||
-- Facings
|
||||
if node_image.paramtype2 == "wallmounted" then
|
||||
node_image.node.param2 = wallmounted_rotate[axis][direction][node_image.node.param2]
|
||||
elseif node_image.paramtype2 == "facedir" then
|
||||
node_image.node.param2 = facedir_rotate[axis][direction][node_image.node.param2]
|
||||
end
|
||||
|
||||
if node_image.build_item_paramtype2 == "wallmounted" then
|
||||
node_image.meta.fields.build_facing = wallmounted_rotate[axis][direction][node_image.meta.fields.build_facing]
|
||||
elseif node_image.build_item_paramtype2 == "facedir" then
|
||||
node_image.meta.fields.build_facing = facedir_rotate[axis][direction][node_image.meta.fields.build_facing]
|
||||
end
|
||||
|
||||
node_image.meta.fields.waiting = nil -- If we're rotating a controller that's in the "waiting" state, clear it. Otherwise it may stick like that.
|
||||
|
||||
-- record the old location so we can destroy the old node if the rotation operation is possible
|
||||
old_pos_pointset:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, true)
|
||||
|
||||
-- position in space relative to origin
|
||||
local pos = vector.subtract(node_image.pos, origin)
|
||||
pos = rotate_pos(axis, direction, pos)
|
||||
-- Move back to original reference frame
|
||||
node_image.pos = vector.add(pos, origin)
|
||||
|
||||
return node_image
|
||||
end
|
||||
|
||||
digtron.rotate_layout_image = function(layout_image, facedir)
|
||||
-- To convert this into the direction the "top" of the axel node is pointing in:
|
||||
-- 0, 1, 2, 3 == (0,1,0)
|
||||
-- 4, 5, 6, 7 == (0,0,1)
|
||||
-- 8, 9, 10, 11 == (0,0,-1)
|
||||
-- 12, 13, 14, 15 == (1,0,0)
|
||||
-- 16, 17, 18, 19 == (-1,0,0)
|
||||
-- 20, 21, 22, 23== (0,-1,0)
|
||||
|
||||
local top = {
|
||||
[0]={axis="y", dir=-1},
|
||||
{axis="z", dir=1},
|
||||
{axis="z", dir=-1},
|
||||
{axis="x", dir=1},
|
||||
{axis="x", dir=-1},
|
||||
{axis="y", dir=1},
|
||||
}
|
||||
local params = top[math.floor(facedir/4)]
|
||||
|
||||
layout_image.old_pos_pointset = Pointset:create()
|
||||
|
||||
for k, node_image in pairs(layout_image.all) do
|
||||
rotate_node_image(node_image, layout_image.controller, params.axis, params.dir, layout_image.old_pos_pointset)
|
||||
end
|
||||
return layout_image
|
||||
end
|
||||
|
||||
digtron.can_write_layout_image = function(layout_image, player)
|
||||
for k, node_image in pairs(layout_image.all) do
|
||||
if not layout_image.old_pos_pointset:get(node_image.pos.x, node_image.pos.y, node_image.pos.z)
|
||||
and not minetest.registered_nodes[minetest.get_node(node_image.pos).name].buildable_to then
|
||||
return false
|
||||
elseif minetest.is_protected(node_image.pos, player:get_player_name()) and not minetest.check_player_privs(player, "protection_bypass") then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
digtron.write_layout_image = function(layout_image)
|
||||
-- destroy the old digtron
|
||||
local oldpos, _ = layout_image.old_pos_pointset:pop()
|
||||
while oldpos ~= nil do
|
||||
local old_def = minetest.registered_nodes[minetest.get_node(oldpos).name]
|
||||
minetest.remove_node(oldpos)
|
||||
if old_def.after_dig_node ~= nil then
|
||||
old_def.after_dig_node(oldpos)
|
||||
end
|
||||
oldpos, _ = layout_image.old_pos_pointset:pop()
|
||||
end
|
||||
|
||||
-- create the new one
|
||||
for k, node_image in pairs(layout_image.all) do
|
||||
minetest.add_node(node_image.pos, node_image.node)
|
||||
minetest.get_meta(node_image.pos):from_table(node_image.meta)
|
||||
|
||||
local new_def = minetest.registered_nodes[node_image.node.name]
|
||||
if new_def.after_place_node ~= nil then
|
||||
new_def.after_place_node(node_image.pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Similar to get_layout, but far more comprehensive. This produces a data structure plus a set of temporary inventories that will allow the digtron to be rotated and then recreated.
|
||||
digtron.get_layout_image = function(pos, player)
|
||||
|
||||
local image = {}
|
||||
--initialize. We're assuming that the start position is a controller digtron, should be a safe assumption since only the controller node should call this
|
||||
image.all = {}
|
||||
image.extents = {}
|
||||
image.controller = {x=pos.x, y=pos.y, z=pos.z} --Make a deep copy of the pos parameter just in case the calling code wants to play silly buggers with it
|
||||
image.contains_protected_node = false -- used to indicate if at least one node in this digtron array is protected from the player.
|
||||
|
||||
table.insert(image.all, get_node_image(pos, minetest.get_node(pos)))
|
||||
|
||||
image.extents.max_x = pos.x
|
||||
image.extents.min_x = pos.x
|
||||
image.extents.max_y = pos.y
|
||||
image.extents.min_y = pos.y
|
||||
image.extents.max_z = pos.z
|
||||
image.extents.min_z = pos.z
|
||||
|
||||
-- temporary pointsets used while searching
|
||||
local to_test = Pointset.create()
|
||||
local tested = Pointset.create()
|
||||
|
||||
tested:set(pos.x, pos.y, pos.z, true)
|
||||
to_test:set(pos.x + 1, pos.y, pos.z, true)
|
||||
to_test:set(pos.x - 1, pos.y, pos.z, true)
|
||||
to_test:set(pos.x, pos.y + 1, pos.z, true)
|
||||
to_test:set(pos.x, pos.y - 1, pos.z, true)
|
||||
to_test:set(pos.x, pos.y, pos.z + 1, true)
|
||||
to_test:set(pos.x, pos.y, pos.z - 1, true)
|
||||
|
||||
if minetest.is_protected(pos, player:get_player_name()) and not minetest.check_player_privs(player, "protection_bypass") then
|
||||
image.contains_protected_node = true
|
||||
end
|
||||
|
||||
-- Do a loop on to_test positions, adding new to_test positions as we find digtron nodes. This is a flood fill operation
|
||||
-- that follows node faces (no diagonals)
|
||||
local testpos, _ = to_test:pop()
|
||||
while testpos ~= nil do
|
||||
tested:set(testpos.x, testpos.y, testpos.z, true) -- track nodes we've looked at to prevent infinite loops
|
||||
local node = minetest.get_node(testpos)
|
||||
|
||||
if node.name == "ignore" then
|
||||
--buildtron array is next to unloaded nodes, too dangerous to do anything. Abort.
|
||||
return nil
|
||||
end
|
||||
|
||||
local group_number = minetest.get_item_group(node.name, "digtron")
|
||||
if group_number > 0 then
|
||||
--found one. Add it to the digtrons output
|
||||
table.insert(image.all, get_node_image(testpos, node))
|
||||
|
||||
if minetest.is_protected(pos, player:get_player_name()) and not minetest.check_player_privs(player, "protection_bypass") then
|
||||
image.contains_protected_node = true
|
||||
end
|
||||
|
||||
-- update extents
|
||||
image.extents.max_x = math.max(image.extents.max_x, testpos.x)
|
||||
image.extents.min_x = math.min(image.extents.min_x, testpos.x)
|
||||
image.extents.max_y = math.max(image.extents.max_y, testpos.y)
|
||||
image.extents.min_y = math.min(image.extents.min_y, testpos.y)
|
||||
image.extents.max_z = math.max(image.extents.max_z, testpos.z)
|
||||
image.extents.min_z = math.min(image.extents.min_z, testpos.z)
|
||||
|
||||
--queue up potential new test points adjacent to this digtron node
|
||||
to_test:set_if_not_in(tested, testpos.x + 1, testpos.y, testpos.z, true)
|
||||
to_test:set_if_not_in(tested, testpos.x - 1, testpos.y, testpos.z, true)
|
||||
to_test:set_if_not_in(tested, testpos.x, testpos.y + 1, testpos.z, true)
|
||||
to_test:set_if_not_in(tested, testpos.x, testpos.y - 1, testpos.z, true)
|
||||
to_test:set_if_not_in(tested, testpos.x, testpos.y, testpos.z + 1, true)
|
||||
to_test:set_if_not_in(tested, testpos.x, testpos.y, testpos.z - 1, true)
|
||||
end
|
||||
|
||||
testpos, _ = to_test:pop()
|
||||
end
|
||||
|
||||
return image
|
||||
end
|
||||
|
@ -6,8 +6,10 @@ digtron.move_node = function(pos, newpos, player_name)
|
||||
minetest.log("action", string.format("%s moves %s from (%d, %d, %d) to (%d, %d, %d), displacing %s", player_name, node.name, pos.x, pos.y, pos.z, newpos.x, newpos.y, newpos.z, oldnode.name))
|
||||
minetest.add_node(newpos, { name=node.name, param1=node.param1, param2=node.param2 })
|
||||
-- copy the metadata
|
||||
local oldmeta = minetest.get_meta(pos):to_table()
|
||||
minetest.get_meta(newpos):from_table(oldmeta)
|
||||
local oldmeta_table = minetest.get_meta(pos):to_table()
|
||||
local meta = minetest.get_meta(newpos)
|
||||
meta:from_table(oldmeta_table)
|
||||
meta:set_string("waiting", nil) -- If a controller moves another controller that's in the waiting state, clear the waiting state otherwise it might get stuck like that (we've moved it away from the target of the pending 'clear the waiting state' delegate call). That means you can run a digtron as fast as you want by rapidly clicking between two different controllers, but shhh - don't tell the player that.
|
||||
|
||||
-- Move the little floaty entity inside the builders
|
||||
if minetest.get_item_group(node.name, "digtron") == 4 then
|
||||
|
Loading…
x
Reference in New Issue
Block a user