Compare commits

...

15 Commits

Author SHA1 Message Date
loosewheel
e3a53dcb61 Add files via upload 2022-03-08 20:11:38 +10:00
loosewheel
78f9fe2ef0 Add files via upload 2022-03-08 20:07:00 +10:00
loosewheel
dcc13da758 Add files via upload 2022-03-08 20:03:58 +10:00
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
loosewheel
e1aae60fab Add files via upload 2022-03-02 18:01:39 +10:00
loosewheel
b7a3434f26 Add files via upload 2022-03-02 17:57:22 +10:00
loosewheel
938acd2ef5 Add files via upload 2022-03-02 17:52:09 +10:00
loosewheel
5ffc83421a Add files via upload 2022-03-02 17:48:54 +10:00
loosewheel
aee35f0a96 Add files via upload 2022-03-02 17:47:24 +10:00
loosewheel
02a5ea0ca4 Add files via upload 2022-03-02 17:46:06 +10:00
44 changed files with 2688 additions and 530 deletions

View File

@@ -12,7 +12,7 @@ local break_interval = 1.0
local function get_breaker_side (pos, param2, side) local function get_breaker_side (pos, param2, side)
local base = nil local base
if side == "left" then if side == "left" then
base = { x = -1, y = pos.y, z = 0 } base = { x = -1, y = pos.y, z = 0 }
@@ -138,7 +138,7 @@ local function can_break_node (pos, breakpos)
if node_def then if node_def then
-- try tool first -- try tool first
local tool = get_tool (pos) local tool = get_tool (pos)
local dig_params = nil local dig_params
if tool then if tool then
local tool_def = minetest.registered_items[tool:get_name ()] local tool_def = minetest.registered_items[tool:get_name ()]
@@ -516,7 +516,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
minetest.remove_node (pos) minetest.remove_node (pos)
end end

View File

@@ -7,18 +7,6 @@ if utils.digilines_supported then
local function is_drop (obj)
if obj then
local entity = obj.get_luaentity and obj:get_luaentity ()
return (entity and entity.name and entity.name == "__builtin:item")
end
return false
end
local function get_entity_dims (obj) local function get_entity_dims (obj)
local dims = { -0.5, 0, -0.5, 0.5, 2, 0.5 } local dims = { -0.5, 0, -0.5, 0.5, 2, 0.5 }
local found = false local found = false
@@ -88,7 +76,7 @@ local function get_entity (pos)
end end
end end
if not is_drop (obj) then if not utils.is_drop (obj) then
local epos = vector.new (obj:get_pos ()) local epos = vector.new (obj:get_pos ())
local dims = get_entity_dims (obj) local dims = get_entity_dims (obj)
@@ -133,7 +121,7 @@ local function camera_scan (pos, resolution, distance)
local horz = (x - (resolution / 2)) * scale * view local horz = (x - (resolution / 2)) * scale * view
local vert = (y - (resolution / 2)) * scale * view local vert = (y - (resolution / 2)) * scale * view
local tpos = nil local tpos
if dir.x ~= 0 then if dir.x ~= 0 then
tpos = vector.round ({ x = (dist * dir.x) + pos.x, y = pos.y - vert, z = horz + pos.z }) tpos = vector.round ({ x = (dist * dir.x) + pos.x, y = pos.y - vert, z = horz + pos.z })
else else
@@ -158,9 +146,9 @@ local function camera_scan (pos, resolution, distance)
last_color = string.format ("0000%02X", color) last_color = string.format ("0000%02X", color)
image[y][x] = last_color image[y][x] = last_color
else else
local node = utils.get_far_node (tpos) local tnode = utils.get_far_node (tpos)
if node and node.name ~= "air" then if tnode and tnode.name ~= "air" then
local color = (((distance - dist) / distance) * 98) + 30 local color = (((distance - dist) / distance) * 98) + 30
last_color = string.format ("%02X%02X%02X", color, color, color) last_color = string.format ("%02X%02X%02X", color, color, color)
@@ -305,7 +293,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
minetest.remove_node (pos) minetest.remove_node (pos)
end end

View File

@@ -29,18 +29,6 @@ end
local function get_barrel_pos (pos)
local barrel = get_cannon_barrel (pos)
if barrel then
return barrel:get_pos ()
end
return nil
end
local function get_barrel_angle (pos) local function get_barrel_angle (pos)
local node = minetest.get_node_or_nil (pos) local node = minetest.get_node_or_nil (pos)
local barrel = get_cannon_barrel (pos) local barrel = get_cannon_barrel (pos)
@@ -181,11 +169,7 @@ end
local function aim_barrel_delayed (pos, aimpos) local function aim_barrel_delayed (pos, aimpos)
local x = tonumber (aimpos.x) or 0 if (tonumber (aimpos.z) or 0) < 1 then
local y = tonumber (aimpos.y) or 0
local z = tonumber (aimpos.z) or 0
if z < 1 then
return return
end end
@@ -230,7 +214,8 @@ local function fire_cannon (pos)
if ammo_pos and ammo_angle then if ammo_pos and ammo_angle then
local dir = vector.rotate ({ x = 0, y = 0, z = -1 }, ammo_angle) local dir = vector.rotate ({ x = 0, y = 0, z = -1 }, ammo_angle)
local owner = meta:get_string ("owner") local owner = meta:get_string ("owner")
local obj, cancel = nil, false local obj = nil
local cancel
local spawn_pos = { x = ammo_pos.x + dir.x, local spawn_pos = { x = ammo_pos.x + dir.x,
y = ammo_pos.y + dir.y, y = ammo_pos.y + dir.y,
z = ammo_pos.z + dir.z } z = ammo_pos.z + dir.z }
@@ -464,7 +449,7 @@ local function on_place (itemstack, placer, pointed_thing)
minetest.set_node (pos, { name = "lwcomponents:cannon", param1 = 0, param2 = param2 }) minetest.set_node (pos, { name = "lwcomponents:cannon", param1 = 0, param2 = param2 })
after_place_node (pos, placer, itemstack, pointed_thing) after_place_node (pos, placer, itemstack, pointed_thing)
if not utils.is_creative (player) then if not utils.is_creative (placer) then
itemstack:set_count (itemstack:get_count () - 1) itemstack:set_count (itemstack:get_count () - 1)
end end
end end
@@ -499,7 +484,7 @@ local function on_place_locked (itemstack, placer, pointed_thing)
minetest.set_node (pos, { name = "lwcomponents:cannon_locked", param1 = 0, param2 = param2 }) minetest.set_node (pos, { name = "lwcomponents:cannon_locked", param1 = 0, param2 = param2 })
after_place_node_locked (pos, placer, itemstack, pointed_thing) after_place_node_locked (pos, placer, itemstack, pointed_thing)
if not utils.is_creative (player) then if not utils.is_creative (placer) then
itemstack:set_count (itemstack:get_count () - 1) itemstack:set_count (itemstack:get_count () - 1)
end end
end end
@@ -621,7 +606,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
on_destruct (pos) on_destruct (pos)
minetest.remove_node (pos) minetest.remove_node (pos)

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
@@ -144,3 +144,26 @@ v0.1.24
* Fixed bug in utils.is_same_item (). * Fixed bug in utils.is_same_item ().
* Added force field generators. * Added force field generators.
* Removed immortal from cannon shells (shells test for same type of shell and ignore). * Removed immortal from cannon shells (shells test for same type of shell and ignore).
v0.1.25
* Added hoppers.
* Added "inventory" message to conduits.
* Removed digilines or mesecons requirement for conduits.
* Improved unescaping item description.
* Fixed custom item output from storage.
* 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.
v0.1.27
* Bug fixes and code cleanup.
* Fixed receptor state in detector.
* Improved receptor state in digiswitch.

View File

@@ -316,7 +316,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
on_destruct (pos) on_destruct (pos)
minetest.remove_node (pos) minetest.remove_node (pos)

View File

@@ -3,17 +3,13 @@ local S = utils.S
if utils.digilines_supported or utils.mesecon_supported then
local transfer_rate = 0.1 local transfer_rate = 0.1
local conduit_interval = 1.0 local conduit_interval = 1.0
local conduit_connections = utils.connections:new (mod_storage, "conduit_connections") local conduit_connections = utils.connections:new (mod_storage, "conduit_connections")
-- forward declare -- forward declare
local run_initialize_forward = nil local run_initialize = nil
@@ -55,6 +51,34 @@ end
local function get_target_for_item (meta, inv, stack)
if meta then
if inv then
local slots = inv:get_size ("filter")
for slot = 1, slots, 1 do
local s = inv:get_stack ("filter", slot)
if s and not s:is_empty () and utils.is_same_item (s, stack) then
local target = meta:get_string ("target"..slot)
if target ~= "" then
return target
end
end
end
end
if meta:get_string ("target") ~= "" then
return meta:get_string ("target")
end
end
return nil
end
local function deliver_slot (pos, slot) local function deliver_slot (pos, slot)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
@@ -222,7 +246,7 @@ local function add_to_send_list (pos, item, destpos, distance)
meta:set_string ("transfer_data", minetest.serialize (transfer_data)) meta:set_string ("transfer_data", minetest.serialize (transfer_data))
run_initialize_forward (pos) run_initialize (pos)
end end
end end
end end
@@ -235,9 +259,7 @@ local function send_to_target (pos, target, slot)
if meta then if meta then
local inv = meta:get_inventory () local inv = meta:get_inventory ()
target = (target and tostring (target)) or meta:get_string ("target") if inv then
if inv and target:len () > 0 then
if not slot then if not slot then
local slots = inv:get_size ("main") local slots = inv:get_size ("main")
@@ -245,8 +267,10 @@ local function send_to_target (pos, target, slot)
local stack = inv:get_stack ("main", i) local stack = inv:get_stack ("main", i)
if not stack:is_empty () and stack:get_count () > 0 then if not stack:is_empty () and stack:get_count () > 0 then
slot = i if target or get_target_for_item (meta, inv, stack) then
break slot = i
break
end
end end
end end
@@ -275,11 +299,13 @@ local function send_to_target (pos, target, slot)
if slot then if slot then
local stack = inv:get_stack ("main", slot) local stack = inv:get_stack ("main", slot)
if not stack:is_empty () and stack:get_count () > 0 then if stack and not stack:is_empty () then
local name = stack:get_name ()
local item = ItemStack (stack) local item = ItemStack (stack)
if item then target = (target and tostring (target)) or
get_target_for_item (meta, inv, stack)
if item and target then
item:set_count (1) item:set_count (1)
local tpos, distance = conduit_connections:is_connected (pos, target) local tpos, distance = conduit_connections:is_connected (pos, target)
@@ -311,32 +337,74 @@ end
local function get_formspec (pos)
local meta = minetest.get_meta (pos)
local automatic = "false"
local filters = ""
if meta then
automatic = meta:get_string ("automatic")
end
for i = 1, 8, 1 do
filters = string.format ("%sfield[12.7,%0.2f;3.0,0.8;target%d;;${target%d}]"..
"button[15.9,%0.2f;1.5,0.8;settarget%d;Set]",
filters,
(i * 1.25) + 0.35,
i,
i,
(i * 1.25) + 0.35,
i)
end
return
"formspec_version[3]"..
"size[18.4,12.25;true]"..
"field[1.0,1.5;3.0,0.8;channel;Channel;${channel}]"..
"button[4.2,1.5;1.5,0.8;setchannel;Set]"..
"field[1.0,3.0;3.0,0.8;target;Target;${target}]"..
"button[4.2,3.0;1.5,0.8;settarget;Set]"..
"checkbox[1.0,4.5;automatic;Automatic;"..automatic.."]"..
"list[context;main;6.0,1.0;4,4;]"..
"list[current_player;main;1.0,6.5;8,4;]"..
"listring[]"..
"label[11.5,1.25;Filter]"..
"list[context;filter;11.5,1.5;1,8;]"..
filters
end
local function run_conduit (pos, id) local function run_conduit (pos, id)
local node = utils.get_far_node (pos) local node = utils.get_far_node (pos)
if node and (node.name == "lwcomponents:conduit" or if node then
node.name == "lwcomponents:conduit_locked") then if node.name == "lwcomponents:conduit" or
local meta = minetest.get_meta (pos) node.name == "lwcomponents:conduit_locked" then
local meta = minetest.get_meta (pos)
if meta and id == meta:get_int ("conduit_id") then if meta and id == meta:get_int ("conduit_id") then
local automatic = meta:get_string ("automatic") == "true" local automatic = meta:get_string ("automatic") == "true"
if automatic then if automatic then
send_to_target (pos) send_to_target (pos)
end end
if run_deliveries (pos) or automatic then if run_deliveries (pos) or automatic then
minetest.after (conduit_interval, run_conduit, pos, id) minetest.after (conduit_interval, run_conduit, pos, id)
else else
meta:set_int ("run_active", 0) meta:set_int ("run_active", 0)
end
end end
else
conduit_connections:remove_node (pos)
end end
end end
end end
local function run_initialize (pos) run_initialize = function (pos)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
if meta then if meta then
@@ -346,29 +414,96 @@ local function run_initialize (pos)
end end
end end
end end
run_initialize_forward = run_initialize
local function get_formspec (pos) local function count_table_keys (t)
local meta = minetest.get_meta (pos) local count = 0
local automatic = "false"
if meta then for k, v in pairs (t) do
automatic = meta:get_string ("automatic") count = count + 1
end
return count
end
local function send_inventory_message (pos)
if utils.digilines_supported then
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
if meta and inv then
local channel = meta:get_string ("channel")
if channel:len () > 0 then
local inventory = { }
local slots = inv:get_size ("main")
for slot = 1, slots, 1 do
local stack = inv:get_stack ("main", slot)
if stack and not stack:is_empty () then
local name = stack:get_name ()
local description
local custom = false
local pallet_index = nil
local tstack = stack:to_table ()
if tstack and tstack.meta and count_table_keys (tstack.meta) > 0 then
custom = true
pallet_index = tstack.meta.palette_index
end
if stack:get_short_description () ~= "" then
description = stack:get_short_description ()
elseif stack:get_description () ~= "" then
description = stack:get_description ()
else
description = name
local def = utils.find_item_def (name)
if def then
if def.short_description then
description = def.short_description
elseif def.description then
description = def.description
end
end
end
inventory[slot] =
{
name = stack:get_name (),
description = utils.unescape_description (description),
count = stack:get_count (),
custom = custom,
pallet_index = pallet_index,
}
else
inventory[slot] =
{
name = "",
description = "",
count = 0,
custom = false,
pallet_index = nil,
}
end
end
utils.digilines_receptor_send (pos,
utils.digilines_default_rules,
channel,
{ action = "inventory",
inventory = inventory })
end
end
end end
return
"formspec_version[3]\n"..
"size[11.75,12.25;true]\n"..
"field[1.0,1.5;3.0,0.8;channel;Channel;${channel}]\n"..
"button[4.2,1.5;1.5,0.8;setchannel;Set]\n"..
"field[1.0,3.0;3.0,0.8;target;Target;${target}]\n"..
"button[4.2,3.0;1.5,0.8;settarget;Set]\n"..
"checkbox[1.0,4.5;automatic;Automatic;"..automatic.."]\n"..
"list[context;main;6.0,1.0;4,4;]\n"..
"list[current_player;main;1.0,6.5;8,4;]\n"..
"listring[]"
end end
@@ -394,7 +529,7 @@ local function after_place_base (pos, placer, itemstack, pointed_thing)
"field[0.5,1.0;6.0,0.8;channel;Channel;${channel}]".. "field[0.5,1.0;6.0,0.8;channel;Channel;${channel}]"..
"button[2.0,2.3;3.0,0.8;setchannel;Set]" "button[2.0,2.3;3.0,0.8;setchannel;Set]"
meta:set_string ("inventory", "{ main = { }, transfer = { } }") meta:set_string ("inventory", "{ main = { }, transfer = { }, filter = { } }")
meta:set_string ("formspec", spec) meta:set_string ("formspec", spec)
meta:set_string ("transfer_data", minetest.serialize({ })) meta:set_string ("transfer_data", minetest.serialize({ }))
meta:set_string ("automatic", "false") meta:set_string ("automatic", "false")
@@ -407,6 +542,9 @@ local function after_place_base (pos, placer, itemstack, pointed_thing)
inv:set_size ("transfer", 32) inv:set_size ("transfer", 32)
inv:set_width ("transfer", 8) inv:set_width ("transfer", 8)
inv:set_size ("filter", 8)
inv:set_width ("filter", 1)
end end
@@ -526,9 +664,25 @@ local function on_receive_fields (pos, formname, fields, sender)
meta:set_string ("automatic", fields.automatic) meta:set_string ("automatic", fields.automatic)
meta:set_string ("formspec", get_formspec (pos)) meta:set_string ("formspec", get_formspec (pos))
if fields.automatic == "true" then
meta:set_int ("run_active", 0)
end
run_initialize (pos) run_initialize (pos)
end end
end end
for i = 1, 8, 1 do
if fields[string.format ("settarget%d", i)] then
local meta = minetest.get_meta (pos)
if meta then
local name = string.format ("target%d", i)
meta:set_string (name, fields[name])
end
end
end
end end
@@ -582,7 +736,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
on_destruct (pos) on_destruct (pos)
minetest.remove_node (pos) minetest.remove_node (pos)
@@ -622,6 +775,87 @@ end
local function allow_metadata_inventory_put (pos, listname, index, stack, player)
if listname == "filter" then
local meta = minetest.get_meta (pos)
if meta then
local inv = meta:get_inventory ()
if inv then
inv:set_stack ("filter", index, ItemStack (stack:get_name ()))
end
end
return 0
end
return stack:get_stack_max ()
end
local function allow_metadata_inventory_take (pos, listname, index, stack, player)
if listname == "filter" then
local meta = minetest.get_meta (pos)
if meta then
local inv = meta:get_inventory ()
if inv then
inv:set_stack ("filter", index, nil)
end
end
return 0
end
return stack:get_stack_max ()
end
local function allow_metadata_inventory_move (pos, from_list, from_index,
to_list, to_index, count, player)
local meta = minetest.get_meta (pos)
if meta then
local inv = meta:get_inventory ()
if inv then
if from_list == "filter" then
if to_list == "filter" then
return 1
end
inv:set_stack ("filter", from_index, nil)
return 0
elseif to_list == "filter" then
local stack = inv:get_stack (from_list, from_index)
if stack and not stack:is_empty () then
inv:set_stack ("filter", to_index, ItemStack (stack:get_name ()))
end
return 0
else
local stack = inv:get_stack (from_list, from_index)
if stack and not stack:is_empty () then
return stack:get_stack_max ()
end
end
end
end
return utils.settings.default_stack_max
end
local function digilines_support () local function digilines_support ()
if utils.digilines_supported then if utils.digilines_supported then
return return
@@ -655,6 +889,9 @@ local function digilines_support ()
elseif m[1] == "transfer" then elseif m[1] == "transfer" then
send_to_target (pos) send_to_target (pos)
elseif m[1] == "inventory" then
send_inventory_message (pos)
end end
elseif type (msg) == "table" then elseif type (msg) == "table" then
@@ -797,12 +1034,48 @@ end
minetest.register_node("lwcomponents:conduit", { minetest.register_node("lwcomponents:conduit", {
description = S("Conduit"), description = S("Conduit"),
drawtype = "glasslike_framed", tiles = { "lwconduit.png" },
tiles = { "lwconduit_edge.png", "lwconduit.png" }, drawtype = "nodebox",
node_box = {
type = "connected",
fixed = { -0.375, -0.375, -0.375, 0.375, 0.375, 0.375 }, -- body
connect_top = { -0.3125, 0.3125, -0.3125, 0.3125, 0.5, 0.3125 }, -- top
connect_bottom = {-0.3125, -0.5, -0.3125, 0.3125, -0.3125, 0.3125}, -- down
connect_front = { -0.3125, -0.3125, -0.5, 0.3125, 0.3125, -0.3125 }, -- front
connect_back = { -0.3125, -0.3125, 0.5, 0.3125, 0.3125, 0.3125 }, -- back
connect_left = { -0.5, -0.3125, -0.3125, -0.3125, 0.3125, 0.3125 }, -- left
connect_right = { 0.3125, -0.3125, -0.3125, 0.5, 0.3125, 0.3125 }, -- right
},
connect_sides = { "top", "bottom", "front", "back", "left", "right" },
connects_to = { "lwcomponents:conduit", "lwcomponents:conduit_locked",
"lwcomponents:hopper", "lwcomponents:hopper_horz",
"hopper:hopper", "hopper:hopper_side",
"group:tube", "pipeworks:filter", "pipeworks:mese_filter",
"pipeworks:digiline_filter" },
selection_box = {
type = "connected",
fixed = { -0.375, -0.375, -0.375, 0.375, 0.375, 0.375 }, -- body
connect_top = { -0.3125, 0.3125, -0.3125, 0.3125, 0.5, 0.3125 }, -- top
connect_bottom = {-0.3125, -0.5, -0.3125, 0.3125, -0.3125, 0.3125}, -- down
connect_front = { -0.3125, -0.3125, -0.5, 0.3125, 0.3125, -0.3125 }, -- front
connect_back = { -0.3125, -0.3125, 0.5, 0.3125, 0.3125, 0.3125 }, -- back
connect_left = { -0.5, -0.3125, -0.3125, -0.3125, 0.3125, 0.3125 }, -- left
connect_right = { 0.3125, -0.3125, -0.3125, 0.5, 0.3125, 0.3125 }, -- right
},
collision_box = {
type = "connected",
fixed = { -0.375, -0.375, -0.375, 0.375, 0.375, 0.375 }, -- body
connect_top = { -0.3125, 0.3125, -0.3125, 0.3125, 0.5, 0.3125 }, -- top
connect_bottom = {-0.3125, -0.5, -0.3125, 0.3125, -0.3125, 0.3125}, -- down
connect_front = { -0.3125, -0.3125, -0.5, 0.3125, 0.3125, -0.3125 }, -- front
connect_back = { -0.3125, -0.3125, 0.5, 0.3125, 0.3125, 0.3125 }, -- back
connect_left = { -0.5, -0.3125, -0.3125, -0.3125, 0.3125, 0.3125 }, -- left
connect_right = { 0.3125, -0.3125, -0.3125, 0.5, 0.3125, 0.3125 }, -- right
},
is_ground_content = false, is_ground_content = false,
groups = table.copy (conduit_groups), groups = table.copy (conduit_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "light",
param1 = 0, param1 = 0,
paramtype2 = "none", paramtype2 = "none",
param2 = 0, param2 = 0,
@@ -820,19 +1093,59 @@ minetest.register_node("lwcomponents:conduit", {
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig, after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_rightclick = on_rightclick on_rightclick = on_rightclick,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
allow_metadata_inventory_move = allow_metadata_inventory_move
}) })
minetest.register_node("lwcomponents:conduit_locked", { minetest.register_node("lwcomponents:conduit_locked", {
description = S("Conduit (locked)"), description = S("Conduit (locked)"),
drawtype = "glasslike_framed", tiles = { "lwconduit.png" },
tiles = { "lwconduit_edge.png", "lwconduit.png" }, drawtype = "nodebox",
node_box = {
type = "connected",
fixed = { -0.375, -0.375, -0.375, 0.375, 0.375, 0.375 }, -- body
connect_top = { -0.3125, 0.3125, -0.3125, 0.3125, 0.5, 0.3125 }, -- top
connect_bottom = {-0.3125, -0.5, -0.3125, 0.3125, -0.3125, 0.3125}, -- down
connect_front = { -0.3125, -0.3125, -0.5, 0.3125, 0.3125, -0.3125 }, -- front
connect_back = { -0.3125, -0.3125, 0.5, 0.3125, 0.3125, 0.3125 }, -- back
connect_left = { -0.5, -0.3125, -0.3125, -0.3125, 0.3125, 0.3125 }, -- left
connect_right = { 0.3125, -0.3125, -0.3125, 0.5, 0.3125, 0.3125 }, -- right
},
connect_sides = { "top", "bottom", "front", "back", "left", "right" },
connects_to = { "lwcomponents:conduit", "lwcomponents:conduit_locked",
"lwcomponents:hopper", "lwcomponents:hopper_horz",
"hopper:hopper", "hopper:hopper_side",
"group:tube", "pipeworks:filter", "pipeworks:mese_filter",
"pipeworks:digiline_filter" },
selection_box = {
type = "connected",
fixed = { -0.375, -0.375, -0.375, 0.375, 0.375, 0.375 }, -- body
connect_top = { -0.3125, 0.3125, -0.3125, 0.3125, 0.5, 0.3125 }, -- top
connect_bottom = {-0.3125, -0.5, -0.3125, 0.3125, -0.3125, 0.3125}, -- down
connect_front = { -0.3125, -0.3125, -0.5, 0.3125, 0.3125, -0.3125 }, -- front
connect_back = { -0.3125, -0.3125, 0.5, 0.3125, 0.3125, 0.3125 }, -- back
connect_left = { -0.5, -0.3125, -0.3125, -0.3125, 0.3125, 0.3125 }, -- left
connect_right = { 0.3125, -0.3125, -0.3125, 0.5, 0.3125, 0.3125 }, -- right
},
collision_box = {
type = "connected",
fixed = { -0.375, -0.375, -0.375, 0.375, 0.375, 0.375 }, -- body
connect_top = { -0.3125, 0.3125, -0.3125, 0.3125, 0.5, 0.3125 }, -- top
connect_bottom = {-0.3125, -0.5, -0.3125, 0.3125, -0.3125, 0.3125}, -- down
connect_front = { -0.3125, -0.3125, -0.5, 0.3125, 0.3125, -0.3125 }, -- front
connect_back = { -0.3125, -0.3125, 0.5, 0.3125, 0.3125, 0.3125 }, -- back
connect_left = { -0.5, -0.3125, -0.3125, -0.3125, 0.3125, 0.3125 }, -- left
connect_right = { 0.3125, -0.3125, -0.3125, 0.5, 0.3125, 0.3125 }, -- right
},
is_ground_content = false, is_ground_content = false,
groups = table.copy (conduit_groups), groups = table.copy (conduit_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "light",
param1 = 0, param1 = 0,
paramtype2 = "none", paramtype2 = "none",
param2 = 0, param2 = 0,
@@ -850,7 +1163,10 @@ minetest.register_node("lwcomponents:conduit_locked", {
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig, after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_rightclick = on_rightclick on_rightclick = on_rightclick,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
allow_metadata_inventory_move = allow_metadata_inventory_move
}) })
@@ -896,6 +1212,25 @@ local function convert_conduits ()
end end
end end
end end
-- added v0.1.25 (2-3-22)
local tmeta = meta:to_table ()
if tmeta and tmeta.inventory then
if not tmeta.inventory.filter then
tmeta.inventory.filter =
{
[1] = "", [2] = "", [3] = "", [4] = "",
[5] = "", [6] = "", [7] = "", [8] = ""
}
meta:from_table (tmeta)
if meta:get_string ("channel") ~= "" then
meta:set_string ("formspec", get_formspec (data.pos))
end
end
end
end end
end end
end end
@@ -912,7 +1247,7 @@ local function restart_conduits ()
local meta = minetest.get_meta (data.pos) local meta = minetest.get_meta (data.pos)
if meta and meta:get_int ("run_active") ~= 0 then if meta and meta:get_int ("run_active") ~= 0 then
minetest.after (conduit_interval + (math.random (9) / 10), minetest.after (conduit_interval + (math.random (10) / 10),
run_conduit, data.pos, meta:get_int ("conduit_id")) run_conduit, data.pos, meta:get_int ("conduit_id"))
end end
end end
@@ -927,4 +1262,4 @@ end)
end -- utils.digilines_supported or utils.mesecon_supported --

View File

@@ -1,5 +1,4 @@
local utils = ... local utils = ...
local S = utils.S
@@ -81,6 +80,36 @@ minetest.register_craft( {
}) })
minetest.register_craft( {
output = "lwcomponents:conduit 5",
recipe = {
{ "default:stone", "", "default:stone" },
{ "", "default:chest", "" },
{ "default:stone", "default:steel_ingot", "default:stone" },
},
})
minetest.register_craft( {
output = "lwcomponents:conduit_locked 5",
recipe = {
{ "default:stone", "", "default:stone" },
{ "", "default:chest_locked", "" },
{ "default:stone", "default:steel_ingot", "default:stone" },
},
})
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 = {
@@ -100,6 +129,7 @@ minetest.register_craft( {
if minetest.global_exists ("fire") then if minetest.global_exists ("fire") then
minetest.register_craft( { minetest.register_craft( {
output = "lwcomponents:cannon_fire_shell 10", output = "lwcomponents:cannon_fire_shell 10",
recipe = { recipe = {
@@ -107,6 +137,7 @@ minetest.register_craft( {
{ "default:iron_lump", "default:coalblock" }, { "default:iron_lump", "default:coalblock" },
}, },
}) })
end -- minetest.global_exists ("fire") end -- minetest.global_exists ("fire")
@@ -124,6 +155,18 @@ minetest.register_craft( {
end -- utils.mesecon_supported end -- utils.mesecon_supported
if utils.hopper_supported then
minetest.register_craft( {
output = "lwcomponents:hopper",
recipe = {
{ "default:stone", "default:steel_ingot", "default:stone" },
{ "", "default:stone", "" },
},
})
end
if utils.digilines_supported or utils.mesecon_supported then if utils.digilines_supported or utils.mesecon_supported then
@@ -271,26 +314,6 @@ minetest.register_craft( {
}) })
minetest.register_craft( {
output = "lwcomponents:conduit 5",
recipe = {
{ "default:stone", "", "default:stone" },
{ "", "default:chest", "" },
{ "default:stone", "default:steel_ingot", "default:stone" },
},
})
minetest.register_craft( {
output = "lwcomponents:conduit_locked 5",
recipe = {
{ "default:stone", "", "default:stone" },
{ "", "default:chest_locked", "" },
{ "default:stone", "default:steel_ingot", "default:stone" },
},
})
minetest.register_craft({ minetest.register_craft({
output = "lwcomponents:piston 2", output = "lwcomponents:piston 2",
recipe = { recipe = {
@@ -423,7 +446,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" },
@@ -432,7 +455,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" },

View File

@@ -145,7 +145,7 @@ local function place_node (item, pos)
if not result then if not result then
if utils.settings.alert_handler_errors then if utils.settings.alert_handler_errors then
minetest.log ("error", "after_place_node handler for "..nodename.." crashed - "..msg) minetest.log ("error", "after_place_node handler for "..stack:get_name ().." crashed - "..msg)
end end
end end
end end
@@ -262,7 +262,7 @@ end
local function deployer_on (pos, node, slot, range) local function deployer_on (pos, _node, slot, range)
local node = minetest.get_node (pos) local node = minetest.get_node (pos)
range = tonumber (range) or 1 range = tonumber (range) or 1
@@ -428,7 +428,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
minetest.remove_node (pos) minetest.remove_node (pos)
end end

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
})
--

View File

@@ -21,7 +21,12 @@ local function mesecons_on (pos)
local node = utils.get_far_node (pos) local node = utils.get_far_node (pos)
if node then if node then
node.param1 = 1 if node.name == "lwcomponents:detector_locked_on" then
node.name = "lwcomponents:detector_locked_on_on"
elseif node.name == "lwcomponents:detector_on" then
node.name = "lwcomponents:detector_on_on"
end
minetest.swap_node (pos, node) minetest.swap_node (pos, node)
end end
end end
@@ -40,7 +45,12 @@ local function mesecons_off (pos)
local node = utils.get_far_node (pos) local node = utils.get_far_node (pos)
if node then if node then
node.param1 = 0 if node.name == "lwcomponents:detector_locked_on_on" then
node.name = "lwcomponents:detector_locked_on"
elseif node.name == "lwcomponents:detector_on_on" then
node.name = "lwcomponents:detector_on"
end
minetest.swap_node (pos, node) minetest.swap_node (pos, node)
end end
end end
@@ -145,7 +155,7 @@ local function get_entity_height (objref)
local entity = objref:get_luaentity () local entity = objref:get_luaentity ()
if entity and entity.name then if entity and entity.name then
def = minetest.registered_entities[entity.name] local def = minetest.registered_entities[entity.name]
if def and type (def.collisionbox) == "table" and if def and type (def.collisionbox) == "table" and
type (def.collisionbox[5]) == "number" then type (def.collisionbox[5]) == "number" then
@@ -343,30 +353,21 @@ end
local function start_detector (pos) local function start_detector (pos)
local node = minetest.get_node (pos) local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then if node then
if node.name == "lwcomponents:detector" then if node.name == "lwcomponents:detector" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:detector_on"
if meta then minetest.swap_node (pos, node)
node.name = "lwcomponents:detector_on" minetest.get_node_timer (pos):start (detect_interval)
update_form_spec (pos)
minetest.swap_node (pos, node)
minetest.get_node_timer (pos):start (detect_interval)
update_form_spec (pos)
end
elseif node.name == "lwcomponents:detector_locked" then elseif node.name == "lwcomponents:detector_locked" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:detector_locked_on"
if meta then minetest.swap_node (pos, node)
node.name = "lwcomponents:detector_locked_on" minetest.get_node_timer (pos):start (detect_interval)
update_form_spec (pos)
minetest.swap_node (pos, node)
minetest.get_node_timer (pos):start (detect_interval)
update_form_spec (pos)
end
end end
end end
@@ -376,32 +377,25 @@ end
local function stop_detector (pos) local function stop_detector (pos)
local node = minetest.get_node (pos) local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then if node then
if node.name == "lwcomponents:detector_on" then if node.name == "lwcomponents:detector_on" or
local meta = minetest.get_meta (pos) node.name == "lwcomponents:detector_on_on" then
node.name = "lwcomponents:detector"
if meta then minetest.swap_node (pos, node)
node.name = "lwcomponents:detector" minetest.get_node_timer (pos):stop ()
mesecons_off (pos)
update_form_spec (pos)
minetest.swap_node (pos, node) elseif node.name == "lwcomponents:detector_locked_on" or
minetest.get_node_timer (pos):stop () node.name == "lwcomponents:detector_locked_on_on" then
mesecons_off (pos) node.name = "lwcomponents:detector_locked"
update_form_spec (pos)
end
elseif node.name == "lwcomponents:detector_locked_on" then minetest.swap_node (pos, node)
local meta = minetest.get_meta (pos) minetest.get_node_timer (pos):stop ()
mesecons_off (pos)
if meta then update_form_spec (pos)
node.name = "lwcomponents:detector_locked"
minetest.swap_node (pos, node)
minetest.get_node_timer (pos):stop ()
mesecons_off (pos)
update_form_spec (pos)
end
end end
end end
@@ -565,7 +559,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
on_destruct (pos) on_destruct (pos)
minetest.remove_node (pos) minetest.remove_node (pos)
@@ -698,16 +691,31 @@ end
local function mesecon_support () local function mesecon_support_on ()
if utils.mesecon_supported then if utils.mesecon_supported then
return return
{ {
receptor = receptor =
{ {
state = utils.mesecon_state_on, state = utils.mesecon_state_on,
rules = function (node) rules = utils.mesecon_default_rules
return (node.param1 == 0 and { }) or utils.mesecon_default_rules }
end }
end
return nil
end
local function mesecon_support_off ()
if utils.mesecon_supported then
return
{
receptor =
{
state = utils.mesecon_state_off,
rules = utils.mesecon_default_rules
} }
} }
end end
@@ -732,7 +740,7 @@ minetest.register_node("lwcomponents:detector", {
drop = "lwcomponents:detector", drop = "lwcomponents:detector",
_digistuff_channelcopier_fieldname = "channel", _digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (), mesecons = mesecon_support_off (),
digiline = digilines_support (), digiline = digilines_support (),
on_destruct = on_destruct, on_destruct = on_destruct,
@@ -761,7 +769,7 @@ minetest.register_node("lwcomponents:detector_locked", {
drop = "lwcomponents:detector_locked", drop = "lwcomponents:detector_locked",
_digistuff_channelcopier_fieldname = "channel", _digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (), mesecons = mesecon_support_off (),
digiline = digilines_support (), digiline = digilines_support (),
on_destruct = on_destruct, on_destruct = on_destruct,
@@ -790,7 +798,7 @@ minetest.register_node("lwcomponents:detector_on", {
drop = "lwcomponents:detector", drop = "lwcomponents:detector",
_digistuff_channelcopier_fieldname = "channel", _digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (), mesecons = mesecon_support_off (),
digiline = digilines_support (), digiline = digilines_support (),
on_destruct = on_destruct, on_destruct = on_destruct,
@@ -819,7 +827,65 @@ minetest.register_node("lwcomponents:detector_locked_on", {
drop = "lwcomponents:detector_locked", drop = "lwcomponents:detector_locked",
_digistuff_channelcopier_fieldname = "channel", _digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (), mesecons = mesecon_support_off (),
digiline = digilines_support (),
on_destruct = on_destruct,
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node_locked,
on_blast = on_blast,
on_timer = on_timer,
on_rightclick = on_rightclick
})
minetest.register_node("lwcomponents:detector_on_on", {
description = S("Detector"),
tiles = { "lwdetector_face_on.png", "lwdetector_face_on.png", "lwdetector.png",
"lwdetector.png", "lwdetector.png", "lwdetector_face_on.png"},
is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
floodable = false,
drop = "lwcomponents:detector",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support_on (),
digiline = digilines_support (),
on_destruct = on_destruct,
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node,
on_blast = on_blast,
on_timer = on_timer,
on_rightclick = on_rightclick
})
minetest.register_node("lwcomponents:detector_locked_on_on", {
description = S("Detector (locked)"),
tiles = { "lwdetector_face_on.png", "lwdetector_face_on.png", "lwdetector.png",
"lwdetector.png", "lwdetector.png", "lwdetector_face_on.png"},
is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
floodable = false,
drop = "lwcomponents:detector_locked",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support_on (),
digiline = digilines_support (), digiline = digilines_support (),
on_destruct = on_destruct, on_destruct = on_destruct,

View File

@@ -8,8 +8,6 @@ if utils.digilines_supported and utils.mesecon_supported then
local function get_mesecon_rule_for_side (side) local function get_mesecon_rule_for_side (side)
local base = nil
if side == "white" then if side == "white" then
return { { x = 0, y = 1, z = 0 } } return { { x = 0, y = 1, z = 0 } }
elseif side == "black" then elseif side == "black" then
@@ -108,12 +106,59 @@ end
local function get_powered_rules (node)
local rules = { }
if is_side_on (node.param1, "switch") then
rules = table.copy (utils.mesecon_default_rules)
if is_side_on (node.param1, "white") then
rules[#rules + 1] = get_mesecon_rule_for_side ("white")[1]
end
if is_side_on (node.param1, "black") then
rules[#rules + 1] = get_mesecon_rule_for_side ("black")[1]
end
else
local sides =
{
"white",
"black",
"red",
"green",
"blue",
"yellow",
}
for _, side in ipairs (sides) do
if is_side_on (node.param1, side) then
rules[#rules + 1] = get_mesecon_rule_for_side (side)[1]
end
end
end
return rules
end
local function get_node_name (node)
if node.param1 ~= 0 then
return "lwcomponents:digiswitch_on"
end
return "lwcomponents:digiswitch"
end
local function switch_on (pos, side) local function switch_on (pos, side)
utils.mesecon_receptor_on (pos, get_mesecon_rule_for_side (side)) utils.mesecon_receptor_on (pos, get_mesecon_rule_for_side (side))
local node = utils.get_far_node (pos) local node = utils.get_far_node (pos)
if node then if node then
node.param1 = set_side_bit (node.param1, side, true) node.param1 = set_side_bit (node.param1, side, true)
node.name = get_node_name (node)
minetest.swap_node (pos, node) minetest.swap_node (pos, node)
end end
end end
@@ -126,6 +171,7 @@ local function switch_off (pos, side)
local node = utils.get_far_node (pos) local node = utils.get_far_node (pos)
if node then if node then
node.param1 = set_side_bit (node.param1, side, false) node.param1 = set_side_bit (node.param1, side, false)
node.name = get_node_name (node)
minetest.swap_node (pos, node) minetest.swap_node (pos, node)
end end
end end
@@ -188,36 +234,41 @@ end
local function mesecon_support () local function mesecon_support ()
return
{
receptor =
{
state = mesecon.state.off,
rules =
{
{ x = 0, y = 0, z = -1 },
{ x = 1, y = 0, z = 0 },
{ x = -1, y = 0, z = 0 },
{ x = 0, y = 0, z = 1 },
{ x = 1, y = 1, z = 0 },
{ x = 1, y = -1, z = 0 },
{ x = -1, y = 1, z = 0 },
{ x = -1, y = -1, z = 0 },
{ x = 0, y = 1, z = 1 },
{ x = 0, y = -1, z = 1 },
{ x = 0, y = 1, z = -1 },
{ x = 0, y = -1, z = -1 },
{ x = 0, y = 1, z = 0 },
{ x = 0, y = -1, z = 0 }
}
},
}
end
local function mesecon_support_on ()
return return
{ {
receptor = receptor =
{ {
state = mesecon.state.on, state = mesecon.state.on,
rules = get_powered_rules
rules = function (node)
if is_side_on (node.param1, "switch") then
return utils.mesecon_default_rules
end
local r = { }
local sides =
{
"white",
"black",
"red",
"green",
"blue",
"yellow",
}
for _, side in ipairs (sides) do
if is_side_on (node.param1, side) then
r[#r + 1] = get_mesecon_rule_for_side (side)[1]
end
end
return r
end
}, },
} }
end end
@@ -243,7 +294,15 @@ end
local function on_destruct (pos) local function on_destruct (pos)
utils.mesecon_receptor_off (pos, get_mesecon_rule_for_side ()) local node = utils.get_far_node (pos)
if node then
local rules = get_powered_rules (node)
if #rules > 0 then
utils.mesecon_receptor_off (pos, rules)
end
end
end end
@@ -288,4 +347,32 @@ minetest.register_node ("lwcomponents:digiswitch", {
minetest.register_node ("lwcomponents:digiswitch_on", {
description = S("Digilines Switch"),
tiles = { "lwdigiswitch_white.png", "lwdigiswitch_black.png",
"lwdigiswitch_green.png", "lwdigiswitch_red.png",
"lwdigiswitch_yellow.png", "lwdigiswitch_blue.png" },
sunlight_propagates = false,
drawtype = "normal",
node_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
}
},
paramtype = "none",
param1 = 0,
groups = { cracky = 2, oddly_breakable_by_hand = 2, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
mesecons = mesecon_support_on (),
digiline = digilines_support (),
_digistuff_channelcopier_fieldname = "channel",
on_construct = on_construct,
on_destruct = on_destruct,
on_receive_fields = on_receive_fields,
})
end -- utils.digilines_supported and utils.mesecon_supported end -- utils.digilines_supported and utils.mesecon_supported

View File

@@ -139,7 +139,8 @@ local function dispense_item (pos, node, slot)
item:set_count (1) item:set_count (1)
local spawn_pos = dispense_pos (pos, node) local spawn_pos = dispense_pos (pos, node)
local owner = meta:get_string ("owner") local owner = meta:get_string ("owner")
local obj, cancel = nil, false local obj = nil
local cancel
if utils.settings.spawn_mobs then if utils.settings.spawn_mobs then
obj, cancel = utils.spawn_registered (name, obj, cancel = utils.spawn_registered (name,
@@ -318,7 +319,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
minetest.remove_node (pos) minetest.remove_node (pos)
end end

View File

@@ -1,35 +1,47 @@
Conduit Conduit
------- -------
* This block is only available if digilines and/or mesecons are loaded.
Conduits are connected in a circuit, and can move items from their Conduits are connected in a circuit, and can move items from their
inventory to another conduit in the same circuit. inventory to another conduit in the same circuit.
When a conduit node is placed it has a simple form that asks for a channel. When a conduit node is placed it has a simple form that asks for a channel.
This channel is both the digilines' channel and the target id of this This channel is both the digilines' channel and the target id of this
conduit within the circuit. A conduit does not have to be given a name. conduit within the circuit. A conduit does not have to be given a channel.
Most of them are just used to connect other conduits together. Most of them are just used to connect other conduits together.
Transfer of items takes 0.1 seconds per conduit node moved, and will work Transfer of items takes 0.1 seconds per conduit node moved, and will work
in unloaded blocks. in unloaded blocks.
Also acts as a digilines conductor. If the hopper mod is loaded, will Filtering of items can be done by placing an item into a filter slot and
take items from the top and sides, and release them from the bottom. setting a target for that item. If an item is not filtered it is sent to
the main target. Filtering can also be implemented through digilines.
Conduits also act as a digilines conductor. If the hopper mod is loaded,
the conduit will take items from the top and sides, and release them from
the bottom. Be aware that hoppers from the hopper mod have some deficits
that can cause some nodes from this mod to not function correctly in
multi-player environments. The hoppers from this mod are more compatible.
Pipeworks tubes can push items into and pull items from the inventory. Pipeworks tubes can push items into and pull items from the inventory.
Note that if a sending conduit is moved (as with a piston) while in the
process of sending items, when the conduit is moved back into a circuit
a duplicate of the last sent item/s can be resent.
Only the owner can dig or access the form of the locked version. Only the owner can dig or access the form of the locked version.
UI UI
Channel - digilines channel/target id of circuit. Channel - digilines channel/target id of conduit.
Target - target id/channel of circuit this circuit will transfer to. Target - target id/channel of conduit this conduit will transfer to.
Automatic - if checked transfers next item every second without command. Automatic - if checked transfers next item every second without command.
Top right 16 slot inventory - storage of items. Top center 16 slot inventory - storage of items.
Bottom 32 slot inventory - player's inventory. Bottom 32 slot inventory - player's inventory.
Filter - 8 vertical slot inventory on the right, each with their accompanying
target field.
Mesecons Mesecons
Transfers the next item when power is turned on to the target circuit. Transfers the next item when power is turned on to the target conduit.
Digilines messages Digilines messages
"target <id>" "target <id>"
@@ -47,7 +59,7 @@ Digilines messages
"transfer" "transfer"
Simple transfer. Transfers the next item in the inventory to the target Simple transfer. Transfers the next item in the inventory to the target
circuit (same as mesecons power). conduit (same as mesecons power).
table message table message
{ {
@@ -57,13 +69,41 @@ table message
item = "<itemname>" item = "<itemname>"
} }
If target is not given, the circuit's set target is used. If target is not given, the conduit determines the target from it's
own settings.
slot should be a number between 1 to 16. If the slot is empty nothing slot should be a number between 1 to 16. If the slot is empty nothing
is transferred. is transferred.
item should be the registered item name. If the circuit's inventory item should be the registered item name. If the conduit's inventory
does not contain any nothing is transferred. does not contain any nothing is transferred.
Only slot or item should be given. If both are given slot is used. If Only slot or item should be given. If both are given slot is used. If
neither are given the next item in the inventory is transferred. neither are given the next item in the inventory is transferred.
"inventory"
Sends a digilines message with it's own channel in the following form:
{
action = "inventory",
inventory = {
<items>
}
}
The inventory key is an indexed list of items in the conduit in slot
order. Each item entry is a table with the following keys:
{
name -- string, the name of the item, as <mod>:<name>
description -- string, description of the item, same as in UI
count -- number, the total number of this item in storage
custom -- true if a custom item (has metadata), false if not
pallet_index -- string if the item has a pallet index, otherwise nil
}
The description is derived from the short description, if none
then the description, and if none then the item's name, as
<mod>:<name>.
Note: When sending transfer messages the simple item name, as <mod>:<name>,
will work for most items, but not for custom items. With custom items, or
to play it safe, use the table form of the transfer message and use the
index for the item from an inventory message as the slot for the transfer
message.

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

@@ -0,0 +1,160 @@
1st right click - set channel, can't be changed after that.
Following right clicks displays touchscreen form.
Sent message as a table. Each command can be sent individually or as
indexes of a table to run as batch.
Clears the current form.
{
command = "clear"
}
Adds elements to the form. The form is size[10,8]. The parameters are as
for formspec (see api docs). No version is specified.
{
command = "realcoordinates",
enabled = true or false
}
{
command = "addimage",
X = n,
Y = n,
W = n,
H = n,
texture_name = string
}
{
command = "addfield",
X = n,
Y = n,
W = n,
H = n,
name = string,
label = string,
default = string
}
{
command = "addpwdfield",
X = n,
Y = n,
W = n,
H = n,
name = string,
label = string
}
{
command = "addtextarea",
X = n,
Y = n,
W = n,
H = n,
name = string,
label = string,
default = string
}
{
command = "addlabel",
X = n,
Y = n,
label = string
}
{
command = "addvertlabel",
X = n,
Y = n,
label = string
}
{
command = "addbutton",
X = n,
Y = n,
W = n,
H = n,
name = string,
label = string
}
{
command = "addbutton_exit",
X = n,
Y = n,
W = n,
H = n,
name = string,
label = string
}
{
command = "addimage_button",
X = n,
Y = n,
W = n,
H = n,
image = string,
name = string,
label = string
}
{
command = "addimage_button_exit",
X = n,
Y = n,
W = n,
H = n,
image = string,
name = string,
label = string
}
{
command = "adddropdown",
X = n,
Y = n,
W = n,
H = n,
name = string,
selected_id = n,
choices = { string [, string ... ] }
}
{
command = "addtextlist",
X = n,
Y = n,
W = n,
H = n,
transparent = true/false,
name = string,
selected_id = n,
listelements = { string [, string ... ] }
}
If unlocked ignores protection.
{
command = "lock"
}
{
command = "locked"
}
When the touchscreen form is accessed a message is sent with the
touchscreen's channel with the 'fields' parameter from the on_receive_fields
handler, with an additional field 'clicker' with the name of the player
that accessed the form.

View File

@@ -1,21 +1,31 @@
DigiSwitch Digilines Switch
---------- ----------------
* This block is only available if both digilines and mesecons are loaded. * This block is only available if both digilines and mesecons are loaded.
Digiswitches act as both a digilines message target and a digilines cable, Digilines switches act as both a digilines message target and a digilines
as well as a mesecons power source. They can be placed beside each other cable, as well as a mesecons power source. They can be placed beside each
to form a bank, horizontally or vertically. other to form a bank, horizontally or vertically.
Right click the digiswitch to give it a channel. Right click the digilines switch to give it a channel.
Mesecon power can be delivered at 6 sides of the digiswitch, the adjacent Mesecon power can be delivered at 6 sides of the digilines switch, the
4 in the (x, z), above and below. Around the connector on these sides are a adjacent 4 in the (x, z), above and below. Around the connector on these
colored border indicating the side. The sides are named "red", "green", sides are a colored border indicating the side. The sides are named "red",
"blue", "yellow", "white" and "black". "green", "blue", "yellow", "white" and "black".
The digilines message sent to the digiswitch dictates the action, "on" or The digilines message sent to the digilines switch dictates the action,
"off". The action can be followed with the side to act upon, separated by "on" or "off". The action can be followed with the side to act upon,
a space. eg. "on white". If a side is stated only that side is acted upon. separated by a space. eg. "on white". If a side is stated only that side
If the side is omitted (or is invalid) all 6 sides are acted upon. If the is acted upon. If the side is omitted (or is invalid) all 6 sides are
side name "switch" is give the power is supplied the same as a mesecons acted upon. If the side name "switch" is given the power is supplied the
switch (all horizontal sides, one below, this height and one above). same as a mesecons switch (all horizontal sides, one below, this height
and one above).
A note on connecting mesecons wires. Mesecons does not appear to allow
for some sides to be on and some off on receptors (power sources). When
any side is on the state of the digilines switch is on, but only rules for
the powered sides are defined. This means if wires are placed while in
this state only the sides that are powered will connect. When no side is
powered the state of the digilines switch is off with rules defined for
all potentially connected sides. In this state (as when first placed)
mesecons wires will connect correctly.

12
docs/hopper.txt Normal file
View File

@@ -0,0 +1,12 @@
Hopper
------
* This block is only available if the hopper mod is loaded.
This version of a hopper will transfer items from a drop or inventory in
the node at the wide end of the hopper to the inventory in the node at the
narrow end of the hopper. The hopper has no inventory itself, and always
moves items one at a time, every second. These hoppers cannot be chained
to transfer items, but work in unloaded blocks. This hopper uses the
hopper mod's registered list of nodes, and should work with nodes with
hopper support. These hoppers can be rotated with a screwdriver, but
function as their typical placement when rotated.

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

@@ -52,6 +52,9 @@ are disposed of.
Hoppers placed to the top or sides of an indexer will feed items into the Hoppers placed to the top or sides of an indexer will feed items into the
input. Hoppers placed below an indexer will take items from the output. input. Hoppers placed below an indexer will take items from the output.
Note, when a hopper from the hopper mod is used to place items into the
input, if the player that placed the hopper leaves the game the input will
not be pulled into storage.
Pipeworks tubes can push items into the input, and pull items from the Pipeworks tubes can push items into the input, and pull items from the
output. output.
@@ -92,10 +95,9 @@ or
pallet_index -- string if the item has a pallet index, otherwise nil pallet_index -- string if the item has a pallet index, otherwise nil
id -- string, unique id of the item in storage id -- string, unique id of the item in storage
} }
The description is derived in the following manner: from a custom The description is derived from the short description, if none
description in metadata; if none then the short description from then the description, and if none then the item's name, as
the item's definition; if none then the description from the item's <mod>:<name>.
definition; if none then the item's name, as <mod>:<name>.
Note: When sending output messages the simple item name, as <mod>:<name>, Note: When sending output messages the simple item name, as <mod>:<name>,
will work for most items, but not for custom items. With custom items, or will work for most items, but not for custom items. With custom items, or

View File

@@ -254,7 +254,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
minetest.remove_node (pos) minetest.remove_node (pos)
end end

437
dummy_player.lua Normal file
View File

@@ -0,0 +1,437 @@
local function get_dummy_player (as_player, name, pos, look_dir, controls, velocity,
hp, armor_groups, properties, nametag, breath)
local obj_as_player = as_player ~= false
local obj_name = name or ""
local obj_pos = vector.new (pos or { x = 0, y = 0, z = 0 })
local obj_look_dir = vector.new (look_dir or { x = 0, y = 0, z = 0 })
local obj_controls = table.copy (controls or { })
local obj_velocity = vector.new (velocity or { x = 0, y = 0, z = 0 })
local obj_hp = hp or 20
local obj_armor_groups = table.copy (armor_groups or { })
local obj_properties = table.copy (properties or { })
local obj_nametag = table.copy (nametag or { })
local obj_breath = breath or 20
local object = { }
-- common
object.get_pos = function (self)
return vector.new (obj_pos)
end
object.set_pos = function (self, _pos)
obj_pos = vector.new (_pos)
end
object.get_velocity = function (self)
return vector.new (obj_velocity)
end
object.add_velocity = function (self, vel)
obj_velocity = vector.add (obj_velocity, vel)
end
object.move_to = function (self, _pos, continuous)
obj_pos = vector.new (_pos)
end
object.punch = function (self, puncher, time_from_last_punch, tool_capabilities, direction)
end
object.right_click = function (self, clicker)
end
object.get_hp = function (self)
return obj_hp
end
object.set_hp = function (self, _hp, reason)
obj_hp = _hp
end
object.get_inventory = function (self)
return nil
end
object.get_wield_list = function (self)
return nil
end
object.get_wield_index = function (self)
return nil
end
object.get_wielded_item = function (self)
return nil
end
object.set_wielded_item = function (self, item)
end
object.set_armor_groups = function (self, groups)
obj_armor_groups = groups
end
object.get_armor_groups = function (self)
return table.copy (obj_armor_groups)
end
object.set_animation = function (self, frame_range, frame_speed, frame_blend, frame_loop)
end
object.get_animation = function (self)
return { x = 1, y = 1 }, 15.0, 0.0, true
end
object.set_animation_frame_speed = function (self, frame_speed)
end
object.set_attach = function (self, parent, bone, position, rotation, forced_visible)
end
object.get_attach = function (self)
return nil
end
object.get_children = function (self)
return { }
end
object.set_detach = function (self)
end
object.set_bone_position = function (self, bone, position, rotation)
end
object.get_bone_position = function (self)
return nil
end
object.set_properties = function (self, _properties)
obj_properties = table.copy (_properties or { })
end
object.get_properties = function (self)
return table.copy (obj_properties)
end
object.is_player = function (self)
return obj_as_player
end
object.get_nametag_attributes = function (self)
return obj_nametag
end
object.set_nametag_attributes = function (self, attributes)
obj_nametag = table.copy (attributes)
end
-- player
object.get_player_name = function (self)
return obj_name
end
object.get_player_velocity = function (self)
return table.copy (obj_velocity)
end
object.add_player_velocity = function (self, vel)
obj_velocity = vector.add (obj_velocity, vel)
end
object.get_look_dir = function (self)
return table.copy (obj_look_dir)
end
object.get_look_vertical = function (self)
return vector.dir_to_rotation (obj_look_dir, { x = 0, y = 1, z = 0 }).x
end
object.get_look_horizontal = function (self)
return vector.dir_to_rotation (obj_look_dir, { x = 0, y = 1, z = 0 }).y
end
object.set_look_vertical = function (self, radians)
obj_look_dir = vector.new ({ x = radians, y = obj_look_dir.y, z = obj_look_dir.z })
end
object.set_look_horizontal = function (self, radians)
obj_look_dir = vector.new ({ x = obj_look_dir.x, y = radians, z = obj_look_dir.z })
end
object.get_look_pitch = function (self)
return vector.dir_to_rotation (obj_look_dir, { x = 0, y = 1, z = 0 }).x
end
object.get_look_yaw = function (self)
return vector.dir_to_rotation (obj_look_dir, { x = 0, y = 1, z = 0 }).y
end
object.set_look_pitch = function (self, radians)
obj_look_dir = vector.new ({ x = radians, y = obj_look_dir.y, z = obj_look_dir.z })
end
object.set_look_yaw = function (self, radians)
obj_look_dir = vector.new ({ x = obj_look_dir.x, y = radians, z = obj_look_dir.z })
end
object.get_breath = function (self)
return obj_breath
end
object.set_breath = function (self, value)
obj_breath = value
end
object.get_fov = function (self)
return 0, false, 0
end
object.set_fov = function (self, fov, is_multiplier, transition_time)
end
object.get_attribute = function (self, attribute)
return nil
end
object.set_attribute = function (self, attribute, value)
end
object.get_meta = function (self)
return nil
end
object.set_inventory_formspec = function (self, formspec)
end
object.get_inventory_formspec = function (self)
return ""
end
object.set_formspec_prepend = function (self, formspec)
end
object.get_formspec_prepend = function (self)
return ""
end
object.get_player_control = function (self)
return table.copy (obj_controls)
end
object.set_physics_override = function (self, override_table)
end
object.get_physics_override = function (self)
return { }
end
object.hud_add = function (self, definition)
return nil
end
object.hud_remove = function (self, id)
end
object.hud_change = function (self, id, stat, value)
end
object.hud_get = function (self, id)
return nil
end
object.hud_set_flags = function (self, flags)
end
object.hud_get_flags = function (self)
return { }
end
object.hud_set_hotbar_itemcount = function (self, count)
end
object.hud_get_hotbar_itemcount = function (self)
return 0
end
object.hud_set_hotbar_image = function (self, texturename)
end
object.hud_get_hotbar_image = function (self)
return ""
end
object.hud_set_hotbar_selected_image = function (self, texturename)
end
object.hud_get_hotbar_selected_image = function (self)
return ""
end
object.set_minimap_modes = function (self, modes, selected_mode)
end
object.set_sky = function (self, sky_parameters)
end
object.get_sky = function (self)
return nil
end
object.get_sky_color = function (self)
return nil
end
object.set_sun = function (self, sun_parameters)
end
object.get_sun = function (self)
return { }
end
object.set_moon = function (self, moon_parameters)
end
object.get_moon = function (self)
return { }
end
object.set_stars = function (self, star_parameters)
end
object.get_stars = function (self)
return { }
end
object.set_clouds = function (self, cloud_parameters)
end
object.get_clouds = function (self)
return { }
end
object.override_day_night_ratio = function (self, ratio)
end
object.get_day_night_ratio = function (self)
return nil
end
object.set_local_animation = function (self, idle, walk, dig, walk_while_dig, frame_speed)
end
object.get_local_animation = function (self)
return { x = 0, y = 0 }, { x = 0, y = 0 }, { x = 0, y = 0 }, { x = 0, y = 0 }, 30
end
object.set_eye_offset = function (self, firstperson, thirdperson)
end
object.get_eye_offset = function (self)
return { x = 0, y = 0, z = 0 }, { x = 0, y = 0, z = 0 }
end
object.send_mapblock = function (self, blockpos)
return false
end
return object
end
return get_dummy_player
--

View File

@@ -249,9 +249,6 @@ local function explode_entities (pos, radius, damage, drops)
if def and def.on_rightclick then if def and def.on_rightclick then
def.on_rightclick (obj:get_pos (), ItemStack (), child) def.on_rightclick (obj:get_pos (), ItemStack (), child)
local ent_damage = ((radius - dist) / radius * damage / 2) + (damage / 2)
local reason = { type = "set_hp", from = "lwcomponents" }
child:add_velocity (vel) child:add_velocity (vel)
child:set_hp (child:get_hp () - ent_damage, reason) child:set_hp (child:get_hp () - ent_damage, reason)
end end

View File

@@ -45,7 +45,6 @@ end
local function blow (pos) local function blow (pos)
local meta = minetest.get_meta (pos)
local node = minetest.get_node (pos) local node = minetest.get_node (pos)
local dir = direction_vector (node) local dir = direction_vector (node)
local reach = 5 local reach = 5
@@ -211,7 +210,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
minetest.remove_node (pos) minetest.remove_node (pos)
end end

View File

@@ -136,7 +136,6 @@ local function check_fuel (pos, used)
end end
if used > power then if used > power then
power = 0
meta:set_float ("power", 0) meta:set_float ("power", 0)
return false return false
@@ -232,18 +231,6 @@ end
local function is_drop (obj)
if obj then
local entity = obj.get_luaentity and obj:get_luaentity ()
return (entity and entity.name and entity.name == "__builtin:item")
end
return false
end
local function run_zap (pos) local function run_zap (pos)
minetest.sound_play ("lwforce_field_zap", { pos = pos, max_hear_distance = 10, gain = 1.0 }) minetest.sound_play ("lwforce_field_zap", { pos = pos, max_hear_distance = 10, gain = 1.0 })
@@ -290,7 +277,7 @@ local function run_field (pos, elapsed)
local obj_pos = (obj.get_pos and obj:get_pos ()) or nil local obj_pos = (obj.get_pos and obj:get_pos ()) or nil
if obj_pos and not obj:get_armor_groups ().immortal then if obj_pos and not obj:get_armor_groups ().immortal then
if not is_drop (obj) and not minetest.is_protected (obj_pos, owner) then if not utils.is_drop (obj) and not minetest.is_protected (obj_pos, owner) then
if obj:is_player () then if obj:is_player () then
if not exclude[obj:get_player_name ()] then if not exclude[obj:get_player_name ()] then
@@ -610,7 +597,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
on_destruct (pos) on_destruct (pos)
minetest.remove_node (pos) minetest.remove_node (pos)

View File

@@ -126,14 +126,14 @@ local function draw_map (pos, map)
end end
if draw then if draw then
local holonode = hologram_block[line[z]] local colornode = hologram_block[line[z]]
if node then if node then
utils.destroy_node (holopos) utils.destroy_node (holopos)
end end
if holonode then if colornode then
minetest.set_node (holopos, { name = holonode.node }) minetest.set_node (holopos, { name = colornode.node })
local nodemeta = minetest.get_meta (holopos) local nodemeta = minetest.get_meta (holopos)
@@ -231,7 +231,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
minetest.remove_node (pos) minetest.remove_node (pos)
end end

459
hopper.lua Normal file
View File

@@ -0,0 +1,459 @@
local utils, mod_storage = ...
local S = utils.S
if utils.hopper_supported then
local hopper_interval = 1.0
local hopper_list = minetest.deserialize (mod_storage:get_string ("hopper_list"))
if type (hopper_list) ~= "table" then
hopper_list = {}
end
local function add_hopper_to_list (pos)
hopper_list[minetest.pos_to_string (pos, 0)] = true
mod_storage:set_string ("hopper_list", minetest.serialize (hopper_list))
end
local function remove_hopper_from_list (pos)
hopper_list[minetest.pos_to_string (pos, 0)] = nil
mod_storage:set_string ("hopper_list", minetest.serialize (hopper_list))
end
local input_dir =
{
[0] = { x = 0, y = 1, z = 0 },
{ x = 0, y = 0, z = 1 },
{ x = 0, y = 0, z = -1 },
{ x = 1, y = 0, z = 0 },
{ x = -1, y = 0, z = 0 },
{ x = 0, y = -1, z = 0 }
}
local function get_input_dir (node)
return input_dir[math.floor (node.param2 / 4)]
end
local function get_output_dir (node)
if node then
if node.name == "lwcomponents:hopper" then
return vector.multiply (get_input_dir (node), -1)
elseif node.name == "lwcomponents:hopper_horz" then
return minetest.facedir_to_dir (node.param2)
end
end
return nil
end
local function get_drop (pos)
local objs = minetest.get_objects_inside_radius (pos, 1)
for _, obj in pairs (objs) do
local obj_pos = (obj.get_pos and obj:get_pos ())
if obj_pos and utils.is_drop (obj) then
obj_pos = vector.round (obj_pos)
if vector.equals (pos, obj_pos) then
local stack = ItemStack (obj:get_luaentity ().itemstring)
if stack and not stack:is_empty () then
stack:set_count (1)
return stack, obj
end
end
end
end
end
local function take_drop (obj)
if utils.is_drop (obj) then
local stack = ItemStack (obj:get_luaentity ().itemstring)
if stack and not stack:is_empty () then
stack:set_count (stack:get_count () - 1)
if stack:is_empty () then
obj:get_luaentity().itemstring = ""
obj:remove()
else
obj:get_luaentity().itemstring = stack:to_string ()
end
end
end
end
local function next_item_to_take (src_pos, src_node, src_inv_name)
if not src_inv_name or not minetest.registered_nodes[src_node.name] then
return
end
local src_meta = minetest.get_meta (src_pos)
local src_inv = (src_meta and src_meta:get_inventory ()) or nil
if src_inv then
local slots = src_inv:get_size (src_inv_name)
for slot = 1, slots, 1 do
local stack = src_inv:get_stack (src_inv_name, slot)
if stack and not stack:is_empty () then
stack:set_count (1)
return stack, slot
end
end
end
end
local function take_item (src_pos, src_inv_name, slot)
local src_meta = minetest.get_meta (src_pos)
local src_inv = (src_meta and src_meta:get_inventory ()) or nil
if src_inv then
local stack = src_inv:get_stack (src_inv_name, slot)
if stack and not stack:is_empty () then
stack:set_count (stack:get_count () - 1)
src_inv:set_stack (src_inv_name, slot, stack)
end
end
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 dest_def = minetest.registered_nodes[dest_node.name]
if not dest_inv_name or not dest_def then
return
end
local dest_meta = minetest.get_meta (dest_pos)
local dest_inv = (dest_meta and dest_meta:get_inventory ()) or nil
if dest_inv then
local slots = dest_inv:get_size (dest_inv_name)
-- find existing stack
for slot = 1, slots, 1 do
local inv_stack = dest_inv:get_stack (dest_inv_name, slot)
if inv_stack and not inv_stack:is_empty () and
utils.is_same_item (inv_stack, stack) and
inv_stack:get_count () < inv_stack:get_stack_max () and
(call_allow_metadata_inventory_put (dest_def, dest_pos, dest_inv_name, slot, stack, placer) > 0) then
inv_stack:set_count (inv_stack:get_count () + 1)
dest_inv:set_stack (dest_inv_name, slot, inv_stack)
call_on_metadata_inventory_put (dest_def, dest_pos, dest_inv_name, slot, stack, placer)
return true
end
end
-- find empty slot
for slot = 1, slots, 1 do
local inv_stack = dest_inv:get_stack (dest_inv_name, slot)
if not inv_stack or inv_stack:is_empty () and
(call_allow_metadata_inventory_put (dest_def, dest_pos, dest_inv_name, slot, stack, placer) > 0) then
dest_inv:set_stack (dest_inv_name, slot, stack)
call_on_metadata_inventory_put (dest_def, dest_pos, dest_inv_name, slot, stack, placer)
return true
end
end
end
return false
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 node = utils.get_far_node (pos)
local dest_dir = get_output_dir (node)
if dest_dir then
local dest_pos = vector.add (pos, dest_dir)
local dest_node = utils.get_far_node (dest_pos)
if dest_node then
local registered_dest_invs = hopper.get_registered_inventories_for (dest_node.name)
if registered_dest_invs then
local placer = get_player_object (pos)
local src_pos = vector.add (pos, get_input_dir (node))
local drop
local stack
local slot = nil
local src_inv_name = nil
stack, drop = get_drop (src_pos)
if not stack then
local src_node = utils.get_far_node (src_pos)
if src_node then
local registered_src_invs = hopper.get_registered_inventories_for (src_node.name)
if registered_src_invs then
src_inv_name = registered_src_invs["top"]
stack, slot = next_item_to_take (src_pos, src_node, src_inv_name)
end
end
end
if stack then
local dest_side = (node.name == "lwcomponents:hopper" and "bottom") or "side"
local dest_inv_name = registered_dest_invs[dest_side]
if place_item (dest_pos, dest_node, dest_inv_name, stack, placer) then
if drop then
take_drop (drop)
else
take_item (src_pos, src_inv_name, slot)
end
end
end
end
end
end
end
local function on_construct (pos)
add_hopper_to_list (pos)
end
local function on_destruct (pos)
remove_hopper_from_list (pos)
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos)
meta:set_string ("placer_name", (placer and placer:get_player_name ()) or "")
-- If return true no item is taken from itemstack
return false
end
local function on_place (itemstack, placer, pointed_thing)
if pointed_thing and pointed_thing.type == "node" then
local stack = ItemStack (itemstack)
local dir = vector.direction (pointed_thing.above, pointed_thing.under)
if dir.y == 0 then
minetest.item_place (ItemStack ("lwcomponents:hopper_horz"), placer, pointed_thing)
if not utils.is_creative (placer) then
stack:set_count (stack:get_count () - 1)
end
return stack
end
end
return minetest.item_place (itemstack, placer, pointed_thing)
end
minetest.register_node ("lwcomponents:hopper", {
description = S("Conduit Hopper"),
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" },
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-0.3125, -0.5, -0.3125, 0.3125, -0.25, 0.3125}, -- spout_vert
{-0.375, -0.375, -0.375, 0.375, 0.3125, 0.375}, -- body
{-0.5, 0, -0.5, -0.3125, 0.5, 0.5}, -- funnel_1
{-0.5, 0, 0.3125, 0.5, 0.5, 0.5}, -- funnel_2
{-0.5, 0, -0.5, 0.5, 0.5, -0.3125}, -- funnel_3
{0.3125, 0, -0.5, 0.5, 0.5, 0.5}, -- funnel_4
}
},
selection_box = {
type = "fixed",
fixed = {
{-0.3125, -0.5, -0.3125, 0.3125, -0.25, 0.3125}, -- spout_vert
{-0.375, -0.375, -0.375, 0.375, 0.3125, 0.375}, -- body
{-0.5, 0, -0.5, 0.5, 0.5, 0.5}, -- funnel
}
},
collision_box = {
type = "fixed",
fixed = {
{-0.375, -0.375, -0.375, 0.375, 0.3125, 0.375}, -- body
{-0.5, 0, -0.5, 0.5, 0.5, 0.5}, -- funnel
{-0.3125, -0.3125, 0.5, 0.3125, 0.3125, 0.3125}, -- spout_side
}
},
paramtype = "light",
param1 = 0,
paramtype2 = "facedir",
param2 = 0,
drop = "lwcomponents:hopper",
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
on_construct = on_construct,
on_destruct = on_destruct,
after_place_node = after_place_node,
on_place = on_place,
})
minetest.register_node ("lwcomponents:hopper_horz", {
description = S("Conduit Hopper"),
tiles = { "lwcomponents_hopper_top.png", "lwcomponents_hopper_bottom.png",
"lwcomponents_hopper_side.png", "lwcomponents_hopper_side.png",
"lwcomponents_hopper_side_spout.png", "lwcomponents_hopper_side.png" },
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-0.375, -0.375, -0.375, 0.375, 0.3125, 0.375}, -- body
{-0.5, 0, -0.5, -0.3125, 0.5, 0.5}, -- funnel_1
{-0.5, 0, 0.3125, 0.5, 0.5, 0.5}, -- funnel_2
{-0.5, 0, -0.5, 0.5, 0.5, -0.3125}, -- funnel_3
{0.3125, 0, -0.5, 0.5, 0.5, 0.5}, -- funnel_4
{-0.3125, -0.3125, 0.5, 0.3125, 0.3125, 0.3125}, -- spout_side
}
},
selection_box = {
type = "fixed",
fixed = {
{-0.375, -0.375, -0.375, 0.375, 0.3125, 0.375}, -- body
{-0.5, 0, -0.5, 0.5, 0.5, 0.5}, -- funnel
{-0.3125, -0.3125, 0.5, 0.3125, 0.3125, 0.3125}, -- spout_side
}
},
collision_box = {
type = "fixed",
fixed = {
{-0.375, -0.375, -0.375, 0.375, 0.3125, 0.375}, -- body
{-0.5, 0, -0.5, 0.5, 0.5, 0.5}, -- funnel
{-0.3125, -0.3125, 0.5, 0.3125, 0.3125, 0.3125}, -- spout_side
}
},
paramtype = "light",
param1 = 0,
paramtype2 = "facedir",
param2 = 0,
drop = "lwcomponents:hopper",
groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
on_construct = on_construct,
on_destruct = on_destruct,
after_place_node = after_place_node,
})
local function run_hoppers ()
for spos, _ in pairs (hopper_list) do
run_hopper_action (minetest.string_to_pos (spos))
end
minetest.after (hopper_interval, run_hoppers)
end
minetest.register_on_mods_loaded (function ()
minetest.after (3.0, run_hoppers)
end)
end -- utils.hopper_supported

View File

@@ -1,4 +1,4 @@
local version = "0.1.24" local version = "0.1.27"
local mod_storage = minetest.get_mod_storage () local mod_storage = minetest.get_mod_storage ()
@@ -16,7 +16,8 @@ local utils = { }
local modpath = minetest.get_modpath ("lwcomponents") local modpath = minetest.get_modpath ("lwcomponents")
loadfile (modpath.."/settings.lua") (utils) loadfile (modpath.."/settings.lua") (utils)
loadfile (modpath.."/utils.lua") (utils, mod_storage) utils.get_dummy_player = loadfile (modpath.."/dummy_player.lua") ()
loadfile (modpath.."/utils.lua") (utils)
loadfile (modpath.."/explode.lua") (utils) loadfile (modpath.."/explode.lua") (utils)
loadfile (modpath.."/api.lua") (utils) loadfile (modpath.."/api.lua") (utils)
utils.connections = loadfile (modpath.."/connections.lua") () utils.connections = loadfile (modpath.."/connections.lua") ()
@@ -32,6 +33,7 @@ loadfile (modpath.."/breaker.lua") (utils)
loadfile (modpath.."/deployer.lua") (utils) loadfile (modpath.."/deployer.lua") (utils)
loadfile (modpath.."/fan.lua") (utils) loadfile (modpath.."/fan.lua") (utils)
loadfile (modpath.."/conduit.lua") (utils, mod_storage) loadfile (modpath.."/conduit.lua") (utils, mod_storage)
loadfile (modpath.."/hopper.lua") (utils, mod_storage)
loadfile (modpath.."/cannon.lua") (utils) loadfile (modpath.."/cannon.lua") (utils)
loadfile (modpath.."/cannon_shell.lua") (utils) loadfile (modpath.."/cannon_shell.lua") (utils)
loadfile (modpath.."/pistons.lua") (utils) loadfile (modpath.."/pistons.lua") (utils)
@@ -39,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

@@ -237,7 +237,7 @@ local function move_entities (list, move, players)
for _, entry in ipairs (list) do for _, entry in ipairs (list) do
if entry.obj then if entry.obj then
if players or not entry.obj:is_player () then if players or not entry.obj:is_player () then
local pos = nil local pos
if entry.obj:is_player () then if entry.obj:is_player () then
pos = vector.add (entry.pos, { x = move.x, y = move.y + 0.1, z = move.z }) pos = vector.add (entry.pos, { x = move.x, y = move.y + 0.1, z = move.z })
@@ -311,7 +311,7 @@ local function move_nodes (list, move)
end end
if list[i].timeout > 0 then if list[i].timeout > 0 then
timer = minetest.get_node_timer (pos) local timer = minetest.get_node_timer (pos)
if timer then if timer then
timer:set (list[i].timeout, list[i].elapsed) timer:set (list[i].timeout, list[i].elapsed)
@@ -334,7 +334,7 @@ local function move_nodes (list, move)
end end
if list[i].timeout > 0 then if list[i].timeout > 0 then
timer = minetest.get_node_timer (pos) local timer = minetest.get_node_timer (pos)
if timer then if timer then
timer:set (list[i].timeout, list[i].elapsed) timer:set (list[i].timeout, list[i].elapsed)

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
@@ -504,7 +884,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
minetest.remove_node (pos) minetest.remove_node (pos)
end end
@@ -690,7 +1069,7 @@ minetest.register_node("lwcomponents:piston_blank_1", {
minetest.register_node("lwcomponents:piston_blank_2", { minetest.register_node("lwcomponents:piston_blank_2", {
description = S("Piston blank"), description = S("Piston blank"),
drawtype = "airlike", drawtype = "airlike",
paramtype = "none", paramtype = "light",
param1 = 0, param1 = 0,
paramtype2 = "facedir", paramtype2 = "facedir",
param2 = 0, param2 = 0,
@@ -712,7 +1091,6 @@ minetest.register_node("lwcomponents:piston_blank_2", {
is_ground_content = false, is_ground_content = false,
drop = "", drop = "",
groups = { not_in_creative_inventory = 1 }, groups = { not_in_creative_inventory = 1 },
paramtype = "light",
-- unaffected by explosions -- unaffected by explosions
on_blast = function() end, on_blast = function() end,
}) })

View File

@@ -69,7 +69,6 @@ end
local function player_button_turnoff (pos) local function player_button_turnoff (pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos)
if node.name == "lwcomponents:player_button_on" then if node.name == "lwcomponents:player_button_on" then
node.name = "lwcomponents:player_button_off" node.name = "lwcomponents:player_button_off"
@@ -85,7 +84,7 @@ end
minetest.register_node ("lwcomponents:player_button", { minetest.register_node ("lwcomponents:player_button", {
description = "Player Button", description = S("Player Button"),
drawtype = "nodebox", drawtype = "nodebox",
tiles = { tiles = {
"lwplayer_button_side.png", "lwplayer_button_side.png",
@@ -134,7 +133,7 @@ minetest.register_node ("lwcomponents:player_button", {
minetest.register_node ("lwcomponents:player_button_off", { minetest.register_node ("lwcomponents:player_button_off", {
description = "Player Button", description = S("Player Button"),
drawtype = "nodebox", drawtype = "nodebox",
tiles = { tiles = {
"lwplayer_button_side.png", "lwplayer_button_side.png",
@@ -184,7 +183,7 @@ minetest.register_node ("lwcomponents:player_button_off", {
minetest.register_node ("lwcomponents:player_button_on", { minetest.register_node ("lwcomponents:player_button_on", {
description = "Player Button", description = S("Player Button"),
drawtype = "nodebox", drawtype = "nodebox",
tiles = { tiles = {
"lwplayer_button_side.png", "lwplayer_button_side.png",

View File

@@ -97,13 +97,8 @@ local function punch (pos)
punched = true punched = true
end end
elseif object[i].get_luaentity and object[i]:get_luaentity () and elseif not utils.is_drop (object[i]) and object[i].get_pos
object[i]:get_luaentity ().name and and object[i]:get_pos () then
object[i]:get_luaentity ().name == "__builtin:item" then
-- don't punch drops
elseif object[i].get_pos and object[i]:get_pos () then
-- entity -- entity
if meta:get_string ("entities") == "true" then if meta:get_string ("entities") == "true" then
@@ -180,28 +175,19 @@ end
local function start_puncher (pos) local function start_puncher (pos)
local node = minetest.get_node (pos) local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then if node then
if node.name == "lwcomponents:puncher" then if node.name == "lwcomponents:puncher" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:puncher_on"
if meta then minetest.swap_node (pos, node)
node.name = "lwcomponents:puncher_on" update_form_spec (pos)
minetest.swap_node (pos, node)
update_form_spec (pos)
end
elseif node.name == "lwcomponents:puncher_locked" then elseif node.name == "lwcomponents:puncher_locked" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:puncher_locked_on"
if meta then minetest.swap_node (pos, node)
node.name = "lwcomponents:puncher_locked_on" update_form_spec (pos)
minetest.swap_node (pos, node)
update_form_spec (pos)
end
end end
end end
@@ -211,28 +197,19 @@ end
local function stop_puncher (pos) local function stop_puncher (pos)
local node = minetest.get_node (pos) local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then if node then
if node.name == "lwcomponents:puncher_on" then if node.name == "lwcomponents:puncher_on" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:puncher"
if meta then minetest.swap_node (pos, node)
node.name = "lwcomponents:puncher" update_form_spec (pos)
minetest.swap_node (pos, node)
update_form_spec (pos)
end
elseif node.name == "lwcomponents:puncher_locked_on" then elseif node.name == "lwcomponents:puncher_locked_on" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:puncher_locked"
if meta then minetest.swap_node (pos, node)
node.name = "lwcomponents:puncher_locked" update_form_spec (pos)
minetest.swap_node (pos, node)
update_form_spec (pos)
end
end end
end end
@@ -365,7 +342,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
minetest.remove_node (pos) minetest.remove_node (pos)
end end

View File

@@ -13,7 +13,7 @@ CC BY-SA 3.0
Version Version
======= =======
0.1.24 0.1.27
Minetest Version Minetest Version
@@ -59,16 +59,18 @@ 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.
* Cannon, shoots an item on command with directional aiming (plus 3 shells). * Cannon, shoots an item on command with directional aiming (plus 3 shells).
* Double (optionally single) reach pistons and sticky pistons. * Double (optionally single) reach pistons and sticky pistons.
* Digiswitch, digilines controlled mesecons power. * Digilines Switch, digilines controlled mesecons power.
* Movefloor, similar to vertical mesecons movestone. * Movefloor, similar to vertical mesecons movestone.
* Camera, takes a representative image. * Camera, takes a representative image.
* Storage, indexed storage units. * Storage, indexed storage units.
* Hoppers, that are more compatible with this mod.
* Force Field Generator, repels players and mobs within a radius. * Force Field Generator, repels players and mobs within a radius.
* Mesecons Through Wire, transmits through 1 to 2 solid blocks. * Mesecons Through Wire, transmits through 1 to 2 solid blocks.
* Solid color conductor blocks, same as Solid Color Block but also mesecons * Solid color conductor blocks, same as Solid Color Block but also mesecons

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 84 KiB

117
siren.lua
View File

@@ -103,30 +103,21 @@ end
local function start_siren (pos) local function start_siren (pos)
local node = minetest.get_node (pos) local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then if node then
if node.name == "lwcomponents:siren" then if node.name == "lwcomponents:siren" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:siren_on"
if meta then stop_sound (pos)
node.name = "lwcomponents:siren_on" minetest.swap_node (pos, node)
update_form_spec (pos)
stop_sound (pos)
minetest.swap_node (pos, node)
update_form_spec (pos)
end
elseif node.name == "lwcomponents:siren_locked" then elseif node.name == "lwcomponents:siren_locked" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:siren_locked_on"
if meta then stop_sound (pos)
node.name = "lwcomponents:siren_locked_on" minetest.swap_node (pos, node)
update_form_spec (pos)
stop_sound (pos)
minetest.swap_node (pos, node)
update_form_spec (pos)
end
end end
end end
@@ -136,34 +127,25 @@ end
local function stop_siren (pos) local function stop_siren (pos)
local node = minetest.get_node (pos) local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then if node then
if node.name == "lwcomponents:siren_on" or if node.name == "lwcomponents:siren_on" or
node.name == "lwcomponents:siren_alarm" then node.name == "lwcomponents:siren_alarm" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:siren"
if meta then minetest.get_node_timer (pos):stop ()
node.name = "lwcomponents:siren" stop_sound (pos)
minetest.swap_node (pos, node)
minetest.get_node_timer (pos):stop () update_form_spec (pos)
stop_sound (pos)
minetest.swap_node (pos, node)
update_form_spec (pos)
end
elseif node.name == "lwcomponents:siren_locked_on" or elseif node.name == "lwcomponents:siren_locked_on" or
node.name == "lwcomponents:siren_locked_alarm" then node.name == "lwcomponents:siren_locked_alarm" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:siren_locked"
if meta then minetest.get_node_timer (pos):stop ()
node.name = "lwcomponents:siren_locked" stop_sound (pos)
minetest.swap_node (pos, node)
minetest.get_node_timer (pos):stop () update_form_spec (pos)
stop_sound (pos)
minetest.swap_node (pos, node)
update_form_spec (pos)
end
end end
end end
@@ -173,30 +155,21 @@ end
local function start_alarm (pos) local function start_alarm (pos)
local node = minetest.get_node (pos) local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then if node then
if node.name == "lwcomponents:siren_on" then if node.name == "lwcomponents:siren_on" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:siren_alarm"
if meta then minetest.get_node_timer (pos):start (sound_interval)
node.name = "lwcomponents:siren_alarm" start_sound (pos)
minetest.swap_node (pos, node)
minetest.get_node_timer (pos):start (sound_interval)
start_sound (pos)
minetest.swap_node (pos, node)
end
elseif node.name == "lwcomponents:siren_locked_on" then elseif node.name == "lwcomponents:siren_locked_on" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:siren_locked_alarm"
if meta then minetest.get_node_timer (pos):start (sound_interval)
node.name = "lwcomponents:siren_locked_alarm" start_sound (pos)
minetest.swap_node (pos, node)
minetest.get_node_timer (pos):start (sound_interval)
start_sound (pos)
minetest.swap_node (pos, node)
end
end end
end end
@@ -206,30 +179,21 @@ end
local function stop_alarm (pos) local function stop_alarm (pos)
local node = minetest.get_node (pos) local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then if node then
if node.name == "lwcomponents:siren_alarm" then if node.name == "lwcomponents:siren_alarm" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:siren_on"
if meta then minetest.get_node_timer (pos):stop ()
node.name = "lwcomponents:siren_on" stop_sound (pos)
minetest.swap_node (pos, node)
minetest.get_node_timer (pos):stop ()
stop_sound (pos)
minetest.swap_node (pos, node)
end
elseif node.name == "lwcomponents:siren_locked_alarm" then elseif node.name == "lwcomponents:siren_locked_alarm" then
local meta = minetest.get_meta (pos) node.name = "lwcomponents:siren_locked_on"
if meta then minetest.get_node_timer (pos):stop ()
node.name = "lwcomponents:siren_locked_on" stop_sound (pos)
minetest.swap_node (pos, node)
minetest.get_node_timer (pos):stop ()
stop_sound (pos)
minetest.swap_node (pos, node)
end
end end
end end
@@ -365,7 +329,6 @@ local function on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
on_destruct (pos) on_destruct (pos)
minetest.remove_node (pos) minetest.remove_node (pos)

View File

@@ -87,7 +87,6 @@ local function unit_on_blast (pos, intensity)
end end
end end
on_destruct (pos)
minetest.remove_node (pos) minetest.remove_node (pos)
else -- intensity < 1.0 else -- intensity < 1.0
@@ -113,9 +112,7 @@ local function unit_on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
on_destruct (pos)
minetest.remove_node (pos) minetest.remove_node (pos)
end end
end end
@@ -200,20 +197,6 @@ local consolidation_interval = 20
local function unescape_description (description)
if description:sub (1, 4) == string.char (27, 40, 84, 64) then
local last = description:find (")", 5, true)
if last then
description = description:sub (last + 1, -1)
end
end
return description:gsub (string.char (27, 70), ""):gsub (string.char (27, 69), "")
end
local function unit_inventory (pos, owner, inv_list) local function unit_inventory (pos, owner, inv_list)
local node = utils.get_far_node (pos) local node = utils.get_far_node (pos)
@@ -326,22 +309,21 @@ local function get_stock_list (pos)
for k, v in pairs (inv_list) do for k, v in pairs (inv_list) do
local stack = ItemStack (k) local stack = ItemStack (k)
local name = stack:get_name () local name = stack:get_name ()
local description = nil local description
local custom = false local custom = false
local pallet_index = nil local pallet_index = nil
local tstack = stack:to_table () local tstack = stack:to_table ()
if tstack and tstack.meta and count_table_keys (tstack.meta) > 0 then if tstack and tstack.meta and count_table_keys (tstack.meta) > 0 then
custom = true custom = true
if stack:get_meta ():get_string ("description") ~= "" then
description = stack:get_meta ():get_string ("description")
end
pallet_index = tstack.meta.palette_index pallet_index = tstack.meta.palette_index
end end
if not description then if stack:get_short_description () ~= "" then
description = stack:get_short_description ()
elseif stack:get_description () ~= "" then
description = stack:get_description ()
else
description = name description = name
local def = utils.find_item_def (name) local def = utils.find_item_def (name)
@@ -358,7 +340,7 @@ local function get_stock_list (pos)
list[#list + 1] = list[#list + 1] =
{ {
name = stack:get_name (), name = stack:get_name (),
description = unescape_description (description), description = utils.unescape_description (description),
id = k, id = k,
count = v.count, count = v.count,
custom = custom, custom = custom,
@@ -719,10 +701,11 @@ local function get_formspec_list (pos)
for k, v in pairs (inv_list) do for k, v in pairs (inv_list) do
local description = k local description = k
local stack = ItemStack (k) local stack = ItemStack (k)
local smeta = stack:get_meta ()
if smeta and smeta:get_string ("description") ~= "" then if stack:get_short_description () ~= "" then
description = smeta:get_string ("description") description = stack:get_short_description ()
elseif stack:get_description () ~= "" then
description = stack:get_description ()
else else
local def = utils.find_item_def (stack:get_name ()) local def = utils.find_item_def (stack:get_name ())
@@ -738,7 +721,7 @@ local function get_formspec_list (pos)
list[#list + 1] = list[#list + 1] =
{ {
item = k, item = k,
description = unescape_description (description), description = utils.unescape_description (description),
count = v.count count = v.count
} }
end end
@@ -954,7 +937,6 @@ local function indexer_on_blast (pos, intensity)
end end
end end
on_destruct (pos)
minetest.remove_node (pos) minetest.remove_node (pos)
else -- intensity < 1.0 else -- intensity < 1.0
@@ -990,9 +972,7 @@ local function indexer_on_blast (pos, intensity)
local stack = ItemStack (items[1]) local stack = ItemStack (items[1])
if stack then if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos) utils.item_drop (stack, nil, pos)
on_destruct (pos)
minetest.remove_node (pos) minetest.remove_node (pos)
end end
end end

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 932 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -1,4 +1,4 @@
local utils, mod_storage = ... local utils = ...
@@ -225,6 +225,40 @@ end
function utils.table_equal (t1, t2)
for k, v in pairs (t1) do
if type (t2[k]) ~= type (v) then
return false
end
if type (v) == "table" then
if not utils.table_equal (v, t2[k]) then
return false
end
elseif v ~= t2[k] then
return false
end
end
for k, v in pairs (t2) do
if type (t1[k]) ~= type (v) then
return false
end
if type (v) == "table" then
if not utils.table_equal (v, t1[k]) then
return false
end
elseif v ~= t1[k] then
return false
end
end
return true
end
function utils.is_same_item (item1, item2) function utils.is_same_item (item1, item2)
local copy1 = ItemStack (item1) local copy1 = ItemStack (item1)
local copy2 = ItemStack (item2) local copy2 = ItemStack (item2)
@@ -233,7 +267,42 @@ function utils.is_same_item (item1, item2)
copy1:set_count (1) copy1:set_count (1)
copy2:set_count (1) copy2:set_count (1)
return copy1:to_string () == copy2:to_string () return utils.table_equal (copy1:to_table (), copy2:to_table ())
end
return false
end
function utils.unescape_description (description)
description = description:gsub (string.char (27, 70), ""):
gsub (string.char (27, 69), ""):
gsub ("\n", " ")
local first = description:find (string.char (27, 40, 84, 64), 1, true)
while first do
local last = description:find (")", first + 4, true)
if not last then
last = first + 3
end
description = description:sub (1, first - 1)..description:sub (last + 1)
first = description:find (string.char (27, 40, 84, 64), 1, true)
end
return description
end
function utils.is_drop (obj)
if obj then
local entity = obj.get_luaentity and obj:get_luaentity ()
return (entity and entity.name and entity.name == "__builtin:item")
end end
return false return false