Compare commits

..

6 Commits

Author SHA1 Message Date
loosewheel
75d51c7b4d Add files via upload 2022-03-06 17:02:22 +10:00
loosewheel
b717ea2bd7 Add files via upload 2022-03-06 16:37:25 +10:00
loosewheel
cb9d799276 Add files via upload 2022-03-06 16:34:41 +10:00
loosewheel
691ba63c2b Add files via upload 2022-03-06 16:31:37 +10:00
loosewheel
7c512a504e Add files via upload 2022-03-06 16:30:15 +10:00
loosewheel
1b02b55e7f Add files via upload 2022-03-06 16:28:05 +10:00
11 changed files with 745 additions and 124 deletions

View File

@@ -53,7 +53,7 @@ v0.1.8
* Made changes to lwcomponents.register_spawner api - called function * Made changes to lwcomponents.register_spawner api - called function
must now set velocity, can use force parameter. must now set velocity, can use force parameter.
* Removed spawning from this mod. Created lwcomponents_spawners to * Removed spawning from this mod. Created lwcomponents_spawners to
register spawers. register spawners.
v0.1.9 v0.1.9
@@ -153,3 +153,11 @@ v0.1.25
* Improved unescaping item description. * Improved unescaping item description.
* Fixed custom item output from storage. * Fixed custom item output from storage.
* Added filtering to conduit forms. * Added filtering to conduit forms.
v0.1.26
* Added support for stickblocks to pistons.
* Changed description of hoppers to avoid confusion.
* Added destroyer.
* Cleaned up hopper code.
* Fixed recipe for solid conductor blocks.

View File

@@ -101,6 +101,16 @@ minetest.register_craft( {
}) })
minetest.register_craft( {
output = "lwcomponents:destroyer",
recipe = {
{ "default:stone", "", "group:wood" },
{ "", "default:steel_ingot", "" },
{ "group:wood", "", "default:stone" }
},
})
minetest.register_craft( { minetest.register_craft( {
output = "lwcomponents:cannon_shell 10", output = "lwcomponents:cannon_shell 10",
recipe = { recipe = {
@@ -437,7 +447,7 @@ end -- utils.digilines_supported and utils.mesecon_supported
if utils.unifieddyes_supported and utils.mesecon_supported then if utils.unifieddyes_supported and utils.mesecon_supported then
minetest.register_craft ({ minetest.register_craft ({
output = "lwcomputers:solid_conductor_off 3", output = "lwcomponents:solid_conductor_off 3",
recipe = { recipe = {
{ "default:mese_crystal_fragment", "group:wood", ""}, { "default:mese_crystal_fragment", "group:wood", ""},
{ "group:wood", "group:wood", "dye:white" }, { "group:wood", "group:wood", "dye:white" },
@@ -446,7 +456,7 @@ minetest.register_craft ({
minetest.register_craft ({ minetest.register_craft ({
output = "lwcomputers:solid_horizontal_conductor_off 3", output = "lwcomponents:solid_horizontal_conductor_off 3",
recipe = { recipe = {
{ "group:wood", "group:wood", ""}, { "group:wood", "group:wood", ""},
{ "default:mese_crystal_fragment", "group:wood", "dye:white" }, { "default:mese_crystal_fragment", "group:wood", "dye:white" },

164
destroyer.lua Normal file
View File

@@ -0,0 +1,164 @@
local utils = ...
local S = utils.S
local function trash (pos)
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
if inv then
local stack = inv:get_stack ("trash", 1)
if stack and not stack:is_empty () then
utils.on_destroy (stack)
inv:set_stack ("trash", 1, nil)
end
end
end
local function trash_delayed (pos)
minetest.after (0.1, trash, pos)
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos)
if meta then
local inv = meta:get_inventory ()
if inv then
meta:set_string ("inventory", "{ trash = { [1] = '' } }")
meta:set_string ("formspec",
"formspec_version[3]"..
"size[11.75,8.5,false]"..
"label[5.15,1.0;Destroy]"..
"list[context;trash;5.3,1.25;1,1;]"..
"list[current_player;main;1.0,2.75;8,4;]"..
"listring[]")
inv:set_size ("trash", 1)
inv:set_width ("trash", 1)
end
end
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack
return false
end
local function on_metadata_inventory_put (pos, listname, index, stack, player)
if listname == "trash" then
trash_delayed (pos)
end
end
local function on_metadata_inventory_move (pos, from_list, from_index,
to_list, to_index, count, player)
if to_list == "trash" then
trash_delayed (pos)
end
end
local function pipeworks_support ()
if utils.pipeworks_supported then
return
{
priority = 100,
input_inventory = "trash",
connect_sides = { left = 1, right = 1, front = 1, back = 1, bottom = 1, top = 1 },
insert_object = function (pos, node, stack, direction)
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
if inv then
trash_delayed (pos)
return inv:add_item ("trash", stack)
end
return stack
end,
can_insert = function (pos, node, stack, direction)
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
if inv then
return inv:room_for_item ("trash", stack)
end
return false
end,
can_remove = function (pos, node, stack, dir)
-- returns the maximum number of items of that stack that can be removed
return 0
end,
remove_items = function (pos, node, stack, dir, count)
-- removes count items and returns them
return stack
end
}
end
return nil
end
local destroyer_groups = { cracky = 3 }
if utils.pipeworks_supported then
destroyer_groups.tubedevice = 1
destroyer_groups.tubedevice_receiver = 1
end
minetest.register_node("lwcomponents:destroyer", {
description = S("Destroyer"),
drawtype = "normal",
tiles = { "lwcomponents_destroyer_top.png", "lwcomponents_destroyer_top.png",
"lwcomponents_destroyer_side.png", "lwcomponents_destroyer_side.png",
"lwcomponents_destroyer_side.png", "lwcomponents_destroyer_side.png" },
is_ground_content = false,
groups = table.copy (destroyer_groups),
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "none",
param2 = 0,
floodable = false,
tube = pipeworks_support (),
after_place_node = after_place_node,
after_dig_node = utils.pipeworks_after_dig,
on_metadata_inventory_put = on_metadata_inventory_put,
on_metadata_inventory_move = on_metadata_inventory_move,
})
utils.hopper_add_container({
{"bottom", "lwcomponents:destroyer", "trash"}, -- insert items below from hopper above
{"side", "lwcomponents:destroyer", "trash"}, -- insert items from hopper at side
})
--

11
docs/destroyer.txt Normal file
View File

@@ -0,0 +1,11 @@
Destroyer
---------
Destroyers dispose of items placed in their single slot inventory (basically
a trash). Items can be push into destroyers with tubes from pipeworks or
hoppers attached to the top or sides, so they are suitable for automation.
Items cannot be pulled out of destroyers.
Note that destroyers act when an item is placed in their inventory, as with
storage indexers it is best to use the hopper from this mod to feed them
in multi-player games.

View File

@@ -7,6 +7,18 @@ of the pusher when extended. Sticky piston draw back a single node in
front of the pusher when retracted. Piston also act as a digilines front of the pusher when retracted. Piston also act as a digilines
conductor. conductor.
Sticky blocks are also supported. Any sticky block structure attached to
the pusher will also be pushed, up to the maximum setting. Any free blocks
(not attached to the sticky blocks) in front will be pushed up to the
maximum setting. This limit is from the pusher, not the sticky block. When
retracting a maximum of one free block depth will be pulled. Any sticky
block structure extending laterally by more than half the maximum limit
will not be pushed.
Any entities in front of or standing on a moving node are pushed/pulled,
if nothing is in the way of their base position. Any entities against a
sticky face are not pulled.
UI UI
Channel - digilines channel of piston. Channel - digilines channel of piston.

View File

@@ -149,6 +149,29 @@ end
local function call_allow_metadata_inventory_put (def, pos, listname, index, stack, placer)
if def.allow_metadata_inventory_put and placer then
local result, count = pcall (def.allow_metadata_inventory_put,
pos, listname, index, stack, placer)
if result then
return count
end
end
return utils.settings.default_stack_max
end
local function call_on_metadata_inventory_put (def, pos, listname, index, stack, placer)
if def.on_metadata_inventory_put and placer then
pcall (def.on_metadata_inventory_put, pos, listname, index, stack, placer)
end
end
local function place_item (dest_pos, dest_node, dest_inv_name, stack, placer) local function place_item (dest_pos, dest_node, dest_inv_name, stack, placer)
local dest_def = minetest.registered_nodes[dest_node.name] local dest_def = minetest.registered_nodes[dest_node.name]
@@ -169,16 +192,12 @@ local function place_item (dest_pos, dest_node, dest_inv_name, stack, placer)
if inv_stack and not inv_stack:is_empty () and if inv_stack and not inv_stack:is_empty () and
utils.is_same_item (inv_stack, stack) and utils.is_same_item (inv_stack, stack) and
inv_stack:get_count () < inv_stack:get_stack_max () and inv_stack:get_count () < inv_stack:get_stack_max () and
(dest_def.allow_metadata_inventory_put == nil or (call_allow_metadata_inventory_put (dest_def, dest_pos, dest_inv_name, slot, stack, placer) > 0) then
placer == nil or
dest_def.allow_metadata_inventory_put(dest_pos, dest_inv_name, slot, stack, placer) > 0) then
inv_stack:set_count (inv_stack:get_count () + 1) inv_stack:set_count (inv_stack:get_count () + 1)
dest_inv:set_stack (dest_inv_name, slot, inv_stack) dest_inv:set_stack (dest_inv_name, slot, inv_stack)
if dest_def.on_metadata_inventory_put and placer then call_on_metadata_inventory_put (dest_def, dest_pos, dest_inv_name, slot, stack, placer)
dest_def.on_metadata_inventory_put (dest_pos, dest_inv_name, slot, stack, placer)
end
return true return true
end end
@@ -189,15 +208,11 @@ local function place_item (dest_pos, dest_node, dest_inv_name, stack, placer)
local inv_stack = dest_inv:get_stack (dest_inv_name, slot) local inv_stack = dest_inv:get_stack (dest_inv_name, slot)
if not inv_stack or inv_stack:is_empty () and if not inv_stack or inv_stack:is_empty () and
(dest_def.allow_metadata_inventory_put == nil or (call_allow_metadata_inventory_put (dest_def, dest_pos, dest_inv_name, slot, stack, placer) > 0) then
placer == nil or
dest_def.allow_metadata_inventory_put(dest_pos, dest_inv_name, slot, stack, placer) > 0) then
dest_inv:set_stack (dest_inv_name, slot, stack) dest_inv:set_stack (dest_inv_name, slot, stack)
if dest_def.on_metadata_inventory_put and placer then call_on_metadata_inventory_put (dest_def, dest_pos, dest_inv_name, slot, stack, placer)
dest_def.on_metadata_inventory_put (dest_pos, dest_inv_name, slot, stack, placer)
end
return true return true
end end
@@ -209,6 +224,28 @@ end
local function get_player_object (pos)
local meta = minetest.get_meta (pos)
local placer_name = "<unknown>"
if meta then
placer_name = meta:get_string ("placer_name")
local placer = minetest.get_player_by_name (placer_name)
if placer then
return placer
end
if placer_name == "" then
placer_name = "<unknown>"
end
end
return utils.get_dummy_player (true, placer_name)
end
local function run_hopper_action (pos) local function run_hopper_action (pos)
local node = utils.get_far_node (pos) local node = utils.get_far_node (pos)
local dest_dir = get_output_dir (node) local dest_dir = get_output_dir (node)
@@ -221,10 +258,7 @@ local function run_hopper_action (pos)
local registered_dest_invs = hopper.get_registered_inventories_for (dest_node.name) local registered_dest_invs = hopper.get_registered_inventories_for (dest_node.name)
if registered_dest_invs then if registered_dest_invs then
local meta = minetest.get_meta (pos) local placer = get_player_object (pos)
local placer_name = (meta and meta:get_string ("placer_name")) or nil
local placer = (placer_name and minetest.get_player_by_name (placer_name)) or
utils.get_dummy_player (true, placer_name or "<unknown>")
local src_pos = vector.add (pos, get_input_dir (node)) local src_pos = vector.add (pos, get_input_dir (node))
local drop = nil local drop = nil
local stack = nil local stack = nil
@@ -310,7 +344,7 @@ end
minetest.register_node ("lwcomponents:hopper", { minetest.register_node ("lwcomponents:hopper", {
description = S("Hopper"), description = S("Conduit Hopper"),
tiles = { "lwcomponents_hopper_top.png", "lwcomponents_hopper_vert_spout.png", tiles = { "lwcomponents_hopper_top.png", "lwcomponents_hopper_vert_spout.png",
"lwcomponents_hopper_side.png", "lwcomponents_hopper_side.png", "lwcomponents_hopper_side.png", "lwcomponents_hopper_side.png",
"lwcomponents_hopper_side.png", "lwcomponents_hopper_side.png" }, "lwcomponents_hopper_side.png", "lwcomponents_hopper_side.png" },
@@ -359,7 +393,7 @@ minetest.register_node ("lwcomponents:hopper", {
minetest.register_node ("lwcomponents:hopper_horz", { minetest.register_node ("lwcomponents:hopper_horz", {
description = S("Hopper"), description = S("Conduit Hopper"),
tiles = { "lwcomponents_hopper_top.png", "lwcomponents_hopper_bottom.png", tiles = { "lwcomponents_hopper_top.png", "lwcomponents_hopper_bottom.png",
"lwcomponents_hopper_side.png", "lwcomponents_hopper_side.png", "lwcomponents_hopper_side.png", "lwcomponents_hopper_side.png",
"lwcomponents_hopper_side_spout.png", "lwcomponents_hopper_side.png" }, "lwcomponents_hopper_side_spout.png", "lwcomponents_hopper_side.png" },

View File

@@ -1,4 +1,4 @@
local version = "0.1.25" local version = "0.1.26"
local mod_storage = minetest.get_mod_storage () local mod_storage = minetest.get_mod_storage ()
@@ -41,6 +41,7 @@ loadfile (modpath.."/through_wire.lua") (utils)
loadfile (modpath.."/camera.lua") (utils) loadfile (modpath.."/camera.lua") (utils)
loadfile (modpath.."/storage.lua") (utils) loadfile (modpath.."/storage.lua") (utils)
loadfile (modpath.."/force_field.lua") (utils) loadfile (modpath.."/force_field.lua") (utils)
loadfile (modpath.."/destroyer.lua") (utils)
loadfile (modpath.."/extras.lua") (utils) loadfile (modpath.."/extras.lua") (utils)
loadfile (modpath.."/digiswitch.lua") (utils) loadfile (modpath.."/digiswitch.lua") (utils)
loadfile (modpath.."/movefloor.lua") (utils) loadfile (modpath.."/movefloor.lua") (utils)

View File

@@ -43,33 +43,36 @@ end
local function push_entities (pos, vec) local function push_entities (pos, movedir, entity_list, upper_limit)
local tpos = vector.add (pos, vec) local objects = minetest.get_objects_inside_radius (pos, 1.5)
local tnode = utils.get_far_node (tpos)
local can_move = false
if tnode then for _, obj in ipairs (objects) do
if tnode.name == "air" then if obj.get_pos and obj.move_to then
can_move = true local opos = obj:get_pos ()
else
local tdef = utils.find_item_def (tnode.name)
can_move = tdef and not tdef.walkable if opos.x > (pos.x - 0.5) and opos.x < (pos.x + 0.5) and
end
end
if can_move then
local object = minetest.get_objects_inside_radius (pos, 1.5)
for j = 1, #object do
if object[j].get_pos then
local opos = object[j]:get_pos ()
if opos.x > (pos.x - 0.5) and opos.x < (pos.x + 0.5) and
opos.z > (pos.z - 0.5) and opos.z < (pos.z + 0.5) and opos.z > (pos.z - 0.5) and opos.z < (pos.z + 0.5) and
opos.y > (pos.y - 0.5) and opos.y < (pos.y + 0.5) then opos.y >= (pos.y - 0.5) and opos.y < (pos.y + upper_limit) then
object[j]:set_pos (vector.add (opos, vec)) local newpos = vector.add (opos, movedir)
local node = utils.get_far_node (vector.round (newpos))
local def = (node and utils.find_item_def (node.name)) or nil
if (node.name == "air") or (def and not def.walkable) then
entity_list[#entity_list + 1] =
{
obj = obj,
pos = newpos
}
obj:move_to (newpos)
else
entity_list[#entity_list + 1] =
{
obj = obj,
pos = opos
}
end end
end end
end end
@@ -78,76 +81,261 @@ end
local function push_nodes (pos, extent) local function update_player_position (player_list)
local node = utils.get_far_node (pos) for _, entry in ipairs (player_list) do
local player = minetest.get_player_by_name (entry.name)
if node then if player then
local vec = direction_vector (node) local pos = player:get_pos ()
local last = vector.add (pos, vector.multiply (vec, extent))
local maxnodes = utils.settings.max_piston_nodes + 1
local count = 0
for i = 1, maxnodes do if pos.y < entry.pos.y then
local tnode = utils.get_far_node (last) pos.y = entry.pos.y
player:set_pos (pos)
if not tnode then
return false
end end
end
end
end
local tdef = utils.find_item_def (tnode.name)
if tnode.name == "air" or (tdef and not tdef.walkable) then
count = i - 1
break
end
if i == maxnodes then local function queue_player_update (entity_list, movedir)
return false local players = { }
end
last = vector.add (last, vec) for _, entry in ipairs (entity_list) do
if entry.obj and entry.obj:is_player () then
players[#players + 1] =
{
pos = entry.pos,
name = entry.obj:get_player_name ()
}
end
end
if #players > 0 then
minetest.after(0.1, update_player_position, players)
end
end
local rules_alldirs =
{
{x = 1, y = 0, z = 0},
{x = -1, y = 0, z = 0},
{x = 0, y = 1, z = 0},
{x = 0, y = -1, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z = -1},
}
local function add_pos_to_list (pos, dir, movedir, node_list, check_list)
local hash = minetest.hash_node_position (pos)
if not check_list[hash] then
if minetest.is_protected (pos, "") then
return 0
end end
push_entities (last, vec) local node = utils.get_far_node (pos)
for i = 1, count, 1 do if not node then
local cpos = vector.subtract (last, vec) return 0
local cnode = utils.get_far_node (cpos) end
local cmeta = minetest.get_meta (cpos)
if not cnode or not cmeta then local def = utils.find_item_def (node.name)
return false
if node.name == "air" or (def and def.buildable_to) then
return 1
end
local meta = minetest.get_meta (pos)
local timer = minetest.get_node_timer (pos)
check_list[hash] = true
node_list[#node_list + 1] =
{
node = node,
def = def,
pos = vector.new (pos),
newpos = vector.add (pos, movedir),
meta = (meta and meta:to_table ()) or { },
node_timer =
{
(timer and timer:get_timeout ()) or 0,
(timer and timer:get_elapsed ()) or 0
}
}
if def.mvps_sticky then
local sides = def.mvps_sticky (pos, node)
for _, r in ipairs (sides) do
if add_pos_to_list (r, dir, movedir, node_list, check_list) == 0 then
return 0
end
end end
end
local tmeta = cmeta:to_table () -- If adjacent node is sticky block and connects add that
local ctimer = minetest.get_node_timer (cpos) -- position to the connected table
local ctimeout = (ctimer and ctimer:get_timeout ()) or 0 for _, r in ipairs (rules_alldirs) do
local celapsed = (ctimer and ctimer:get_elapsed ()) or 0 local apos = vector.add (pos, r)
local anode = utils.get_far_node (apos)
local adef = (anode and minetest.registered_nodes[anode.name]) or nil
push_entities (cpos, vec) if adef and adef.mvps_sticky then
local sides = adef.mvps_sticky (apos, anode)
minetest.remove_node (cpos) -- connects to this position?
minetest.set_node (last, cnode) for _, link in ipairs (sides) do
if vector.equals (link, pos) then
if add_pos_to_list (apos, dir, movedir, node_list, check_list) == 0 then
return 0
end
if tmeta then break
cmeta = minetest.get_meta (last) end
end
end
end
end
if not cmeta then return 2
end
local function node_list_last_pos (pos, node_list, length)
local movedir = node_list.movedir
local base_pos = node_list.base_pos
if movedir then
if movedir.x ~= 0 then
return vector.new ({
x = base_pos.x + (movedir.x * length),
y = pos.y,
z = pos.z
})
elseif movedir.z ~= 0 then
return vector.new ({
x = pos.x,
y = pos.y,
z = base_pos.z + (movedir.z * length)
})
elseif movedir.y ~= 0 then
return vector.new ({
x = pos.x,
y = base_pos.y + (movedir.y * length),
z = pos.z
})
end
end
return pos
end
local function get_node_list (pos, extent, length, maxnodes, pushing, node_list, check_list)
local node = utils.get_far_node (pos)
node_list = node_list or { }
check_list = check_list or { }
if node then
local dir = vector.round (direction_vector (node))
local movedir = vector.round ((pushing and dir) or vector.multiply (dir, -1))
node_list.dir = dir
node_list.movedir = movedir
node_list.base_pos = vector.add (pos, vector.multiply (dir, extent))
node_list.length = length
node_list.maxnodes = maxnodes
check_list[minetest.hash_node_position (vector.add (pos, vector.multiply (dir, extent - 1)))] = true
for i = 0, length - 1, 1 do
local tpos = vector.add (pos, vector.multiply (dir, extent + i))
local result = add_pos_to_list (tpos, dir, movedir, node_list, check_list)
if result == 0 then
return false
elseif result == 1 then
break
end
end
-- get any ahead of stickyblocks to limit
local copy_list = table.copy (node_list)
for _, n in ipairs (copy_list) do
local hash = minetest.hash_node_position (n.newpos)
if not check_list[hash] then
local last_pos = node_list_last_pos (n.newpos, node_list, length)
local this_pos = vector.new (n.newpos)
local count = 0
while not vector.equals (this_pos, last_pos) and count < length do
local result = add_pos_to_list (this_pos, dir, movedir, node_list, check_list)
if result == 0 then
return false
elseif result == 1 then
break
end
count = count + 1
this_pos = vector.add (this_pos, movedir)
end
end
end
return true
end
return false
end
local function can_node_list_move (node_list, check_list)
local movedir = node_list.movedir
local radius = math.floor (node_list.maxnodes / 2)
local base_pos = node_list.base_pos
if movedir then
for _, n in ipairs (node_list) do
-- check connected stickyblocks don't extend too far laterally
if movedir.x ~= 0 then
if math.abs (n.pos.y - base_pos.y) > radius or
math.abs (n.pos.z - base_pos.z) > radius then
return false return false
end end
elseif movedir.z ~= 0 then
cmeta:from_table (tmeta) if math.abs (n.pos.y - base_pos.y) > radius or
end math.abs (n.pos.x - base_pos.x) > radius then
return false
if ctimeout > 0 then end
ctimer = minetest.get_node_timer (last) elseif movedir.y ~= 0 then
if math.abs (n.pos.x - base_pos.x) > radius or
if ctimer then math.abs (n.pos.z - base_pos.z) > radius then
ctimer:set (ctimeout, celapsed) return false
end end
end end
last = cpos -- check moving to is clear
if not check_list[minetest.hash_node_position (n.newpos)] then
local node = utils.get_far_node (n.newpos)
local def = (node and utils.find_item_def (node.name)) or nil
if node.name ~= "air" and def and not def.buildable_to then
return false
end
end
end end
end end
@@ -156,47 +344,239 @@ end
local function pull_node (pos, extent) local function sort_node_list (node_list)
local node = utils.get_far_node (pos) local movedir = node_list.movedir
if node then if movedir then
local vec = direction_vector (node) if movedir.x > 0 then
local cpos = vector.add (pos, vector.multiply (vec, extent)) table.sort (node_list , function (n1, n2)
local cnode = utils.get_far_node (cpos) return n1.pos.x > n2.pos.x
local cdef = cnode and utils.find_item_def (cnode.name) end)
elseif movedir.x < 0 then
table.sort (node_list , function (n1, n2)
return n1.pos.x < n2.pos.x
end)
elseif movedir.z > 0 then
table.sort (node_list , function (n1, n2)
return n1.pos.z > n2.pos.z
end)
elseif movedir.z < 0 then
table.sort (node_list , function (n1, n2)
return n1.pos.z < n2.pos.z
end)
elseif movedir.y > 0 then
table.sort (node_list , function (n1, n2)
return n1.pos.y > n2.pos.y
end)
elseif movedir.y < 0 then
table.sort (node_list , function (n1, n2)
return n1.pos.y < n2.pos.y
end)
end
end
end
if cnode and cnode.name ~= "air" and cdef and cdef.walkable then
local cmeta = minetest.get_meta (cpos)
if cmeta then local on_mvps_move = function (node_list)
local tpos = vector.subtract (cpos, vec) end
local tmeta = cmeta:to_table ()
local ctimer = minetest.get_node_timer (cpos)
local ctimeout = (ctimer and ctimer:get_timeout ()) or 0
local celapsed = (ctimer and ctimer:get_elapsed ()) or 0
minetest.remove_node (cpos)
minetest.set_node (tpos, cnode)
if tmeta then
cmeta = minetest.get_meta (tpos)
if cmeta then local is_mvps_stopper = function (node, movedir, node_list, id)
cmeta:from_table (tmeta) return false
end end
end
if ctimeout > 0 then
ctimer = minetest.get_node_timer (tpos)
if ctimer then
ctimer:set (ctimeout, celapsed) local update_mesecons_connections_removed = function (node_list)
end end
end
local update_mesecons_connections_added = function (node_list)
end
if utils.mesecon_supported then
if mesecon.on_mvps_move then
on_mvps_move = function (node_list)
for _, callback in ipairs (mesecon.on_mvps_move) do
callback (node_list)
end end
end end
end end
if mesecon.is_mvps_stopper then
is_mvps_stopper = function (node, movedir, node_list, id)
return mesecon.is_mvps_stopper (node, movedir, node_list, id)
end
end
if mesecon.on_dignode then
update_mesecons_connections_removed = function (node_list)
for _, node in ipairs (node_list) do
mesecon.on_dignode (node.oldpos, node.node)
end
end
end
if mesecon.on_placenode then
update_mesecons_connections_added = function (node_list)
for _, node in ipairs (node_list) do
mesecon.on_placenode (node.pos, utils.get_far_node (node.pos))
end
end
end
end
local function push_nodes (pos, extent)
local node_list = { }
local check_list = { }
local entity_list = { }
local maxnodes = utils.settings.max_piston_nodes
if not get_node_list (pos, extent, maxnodes, maxnodes, true, node_list, check_list) then
return false
end
if not can_node_list_move (node_list, check_list, maxnodes) then
return false
end
sort_node_list (node_list)
for id, node in ipairs (node_list) do
if is_mvps_stopper (node.node, node_list.movedir, node_list, id) then
return false
end
end
for _, node in ipairs (node_list) do
node.oldpos = vector.new (node.pos)
node.pos = vector.new (node.newpos)
node.newpos = nil
minetest.remove_node (node.oldpos)
end
update_mesecons_connections_removed (node_list)
-- push entities in front first
for _, node in ipairs (node_list) do
if not check_list[minetest.hash_node_position (node.pos)] then
push_entities (node.pos, node_list.movedir, entity_list, 0.5)
end
end
for _, node in ipairs (node_list) do
push_entities (node.oldpos, node_list.movedir, entity_list, 1.0)
minetest.set_node (node.pos, node.node)
if node.meta then
local meta = minetest.get_meta (node.pos)
if meta then
meta:from_table (node.meta)
end
end
if node.node_timer[1] > 0 then
local timer = minetest.get_node_timer (node.pos)
if timer then
timer:set (node.node_timer[1], node.node_timer[2])
end
end
end
-- push any entities in front of pusher
push_entities (node_list.base_pos, node_list.movedir, entity_list, 0.5)
on_mvps_move (node_list)
update_mesecons_connections_added (node_list)
if node_list.movedir.y >= 0 then
queue_player_update (entity_list, node_list.movedir)
end
return true
end
local function pull_node (pos, extent)
local node_list = { }
local check_list = { }
local entity_list = { }
local maxnodes = utils.settings.max_piston_nodes
if not get_node_list (pos, extent, 1, maxnodes, false, node_list, check_list) then
return false
end
if not can_node_list_move (node_list, check_list, maxnodes) then
return false
end
sort_node_list (node_list)
for id, node in ipairs (node_list) do
if is_mvps_stopper (node.node, node_list.movedir, node_list, id) then
return false
end
end
for _, node in ipairs (node_list) do
node.oldpos = vector.new (node.pos)
node.pos = vector.new (node.newpos)
node.newpos = nil
minetest.remove_node (node.oldpos)
end
update_mesecons_connections_removed (node_list)
-- push entities in front first
for _, node in ipairs (node_list) do
if not check_list[minetest.hash_node_position (node.pos)] then
push_entities (node.pos, node_list.movedir, entity_list, 0.5)
end
end
for _, node in ipairs (node_list) do
push_entities (node.oldpos, node_list.movedir, entity_list, 1.0)
minetest.set_node (node.pos, node.node)
if node.meta then
local meta = minetest.get_meta (node.pos)
if meta then
meta:from_table (node.meta)
end
end
if node.node_timer[1] > 0 then
local timer = minetest.get_node_timer (node.pos)
if timer then
timer:set (node.node_timer[1], node.node_timer[2])
end
end
end
on_mvps_move (node_list)
update_mesecons_connections_added (node_list)
if node_list.movedir.y >= 0 then
queue_player_update (entity_list, node_list.movedir)
end
return true
end end

View File

@@ -13,7 +13,7 @@ CC BY-SA 3.0
Version Version
======= =======
0.1.25 0.1.26
Minetest Version Minetest Version
@@ -59,7 +59,8 @@ Various components for mesecons and digilines.
* Puncher, punches players or entities within a given reach. * Puncher, punches players or entities within a given reach.
* Player button, sends digilines message with player name. * Player button, sends digilines message with player name.
* Breaker, digs the nodes directly in front. * Breaker, digs the nodes directly in front.
* Deployers, places the nodes directly in front. * Deployer, places the nodes directly in front.
* Destroyer, automated trash.
* Hologram, projects a hologram above the hologram node. * Hologram, projects a hologram above the hologram node.
* Fan, blows any entity, player or drop in front of the fan. * Fan, blows any entity, player or drop in front of the fan.
* Conduit, connected in a circuit to move items. * Conduit, connected in a circuit to move items.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 932 B