Compare commits

..

16 Commits

Author SHA1 Message Date
loosewheel
46d8b2fcff Update readme.txt 2021-11-24 19:53:05 +10:00
loosewheel
2dabff4239 Add files via upload 2021-11-24 19:36:15 +10:00
loosewheel
b931c3105c Add files via upload 2021-11-24 19:35:15 +10:00
loosewheel
61825c93af Add files via upload 2021-11-24 19:33:57 +10:00
loosewheel
bd75cddfc8 Add files via upload 2021-11-24 19:31:55 +10:00
loosewheel
1c2486c938 Add files via upload 2021-11-24 19:30:03 +10:00
loosewheel
a45734b65a Add files via upload 2021-11-24 19:28:47 +10:00
loosewheel
16db2b969f Add files via upload 2021-11-24 19:28:07 +10:00
loosewheel
e845b002b4 Create lwcomponents_cannon_barrel.obj 2021-11-24 19:27:35 +10:00
loosewheel
17d23114fc Add files via upload 2021-11-23 04:48:27 +10:00
loosewheel
de9638b85b Add files via upload 2021-11-21 02:12:13 +10:00
loosewheel
f728c4d246 Add files via upload 2021-11-21 02:10:31 +10:00
loosewheel
92138ff625 Add files via upload 2021-11-21 02:09:17 +10:00
loosewheel
09dc9951ab Add files via upload 2021-11-19 10:37:11 +10:00
loosewheel
b3604d044d Add files via upload 2021-11-19 10:36:28 +10:00
loosewheel
d91c820ac9 Add files via upload 2021-11-19 10:34:48 +10:00
41 changed files with 4012 additions and 236 deletions

View File

@@ -2,7 +2,7 @@ local utils = ...
-- function (spawn_pos, itemstack, owner, spawner_pos, spawner_dir)
-- function (spawn_pos, itemstack, owner, spawner_pos, spawner_dir, force)
function lwcomponents.register_spawner (itemname, spawn_func)
return utils.register_spawner (itemname, spawn_func)
end

View File

@@ -37,7 +37,27 @@ end
local function send_break_message (pos, action, name)
local function get_break_pos (pos, param2, range)
local breakpos = { x = pos.x, y = pos.y, z = pos.z }
for i = 1, range do
breakpos = get_breaker_side (breakpos, param2, "front")
if i < range then
local node = minetest.get_node_or_nil (breakpos)
if not node or node.name ~= "air" then
return nil
end
end
end
return breakpos
end
local function send_break_message (pos, action, name, range)
if utils.digilines_supported then
local meta = minetest.get_meta (pos)
@@ -49,7 +69,8 @@ local function send_break_message (pos, action, name)
utils.digilines_default_rules,
channel,
{ action = action,
name = name })
name = name,
range = range })
end
end
end
@@ -105,21 +126,11 @@ end
local function play_dug_sound (pos, nodename)
local def = utils.find_item_def (nodename)
if def and def.sounds and def.sounds.dug then
minetest.sound_play (def.sounds.dug, { pos = pos })
end
end
local function can_break_node (pos)
local function can_break_node (pos, breakpos)
local node = minetest.get_node (pos)
if node then
local dig_node = minetest.get_node (get_breaker_side (pos, node.param2, "front"))
local dig_node = minetest.get_node_or_nil (breakpos)
if dig_node and dig_node.name ~= "air" then
local node_def = minetest.registered_nodes[dig_node.name]
@@ -160,40 +171,85 @@ end
local function break_node (pos)
local diggable, tool, wear = can_break_node (pos)
local node = minetest.get_node (pos)
local function dig_node (pos, toolname)
local node = minetest.get_node_or_nil (pos)
local dig = false
local drops = nil
if diggable and node then
local break_pos = get_breaker_side (pos, node.param2, "front")
local break_node = minetest.get_node (break_pos)
if toolname == true then
dig = true
toolname = nil
end
if break_node then
local items = minetest.get_node_drops (break_node, tool)
local break_name = break_node.name
if node and node.name ~= "air" and node.name ~= "ignore" then
local def = utils.find_item_def (node.name)
if not dig then
if def and def.can_dig then
local result, can_dig = pcall (def.can_dig, pos)
dig = ((not result) or (result and (can_dig == nil or can_dig == true)))
else
dig = true
end
end
if dig then
local items = minetest.get_node_drops (node, toolname)
if items then
local eject_pos = get_breaker_side (pos, node.param2, "back")
drops = { }
for i = 1, #items do
local stack = ItemStack (items[i])
drops[i] = ItemStack (items[i])
end
if stack and not stack:is_empty () then
local item_def = utils.find_item_def (stack:get_name ())
if item_def and item_def.preserve_metadata then
item_def.preserve_metadata (pos, node, minetest.get_meta (pos), { stack })
end
utils.item_drop (stack, nil, eject_pos)
end
if def and def.preserve_metadata then
def.preserve_metadata (pos, node, minetest.get_meta (pos), drops)
end
end
minetest.remove_node (break_pos)
play_dug_sound (break_pos, break_name)
add_wear (pos, wear)
send_break_message (pos, "break", break_name)
if def and def.sounds and def.sounds.dug then
pcall (minetest.sound_play, def.sounds.dug, { pos = pos })
end
minetest.remove_node (pos)
end
end
return drops
end
local function break_node (pos, range)
local node = minetest.get_node_or_nil (pos)
if node then
local breakpos = get_break_pos (pos, node.param2, range)
if breakpos then
local diggable, toolname, wear = can_break_node (pos, breakpos)
if diggable then
local breaknode = minetest.get_node_or_nil (breakpos)
if breaknode and breaknode.name ~= "air" then
local drops = dig_node (breakpos, toolname)
if drops then
local break_name = breaknode.name
local eject_pos = get_breaker_side (pos, node.param2, "back")
for i = 1, #drops do
utils.item_drop (drops[i], nil, eject_pos)
end
add_wear (pos, wear)
send_break_message (pos, "break", break_name, range)
end
end
end
end
end
end
@@ -222,22 +278,24 @@ end
local function breaker_on (pos)
local function breaker_on (pos, range)
local node = minetest.get_node (pos)
if node then
range = tonumber (range) or 1
if node and range < 6 and range > 0 then
if node.name == "lwcomponents:breaker" then
node.name = "lwcomponents:breaker_on"
minetest.swap_node (pos, node)
break_node (pos)
break_node (pos, range)
minetest.get_node_timer (pos):start (break_interval)
elseif node.name == "lwcomponents:breaker_locked" then
node.name = "lwcomponents:breaker_locked_on"
minetest.swap_node (pos, node)
break_node (pos)
break_node (pos, range)
minetest.get_node_timer (pos):start (break_interval)
end
@@ -298,7 +356,7 @@ local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos)
meta:set_string ("owner", placer:get_player_name ())
meta:set_string ("infotext", "Dropper (owned by "..placer:get_player_name ()..")")
meta:set_string ("infotext", "Breaker (owned by "..placer:get_player_name ()..")")
end
-- If return true no item is taken from itemstack
@@ -480,7 +538,7 @@ local function digilines_support ()
end
if m[1] == "break" then
breaker_on (pos)
breaker_on (pos, m[2])
elseif m[1] == "eject" then
eject_tool (pos, m[2])
@@ -508,7 +566,7 @@ local function mesecon_support ()
action_on = function (pos, node)
-- do something to turn the effector on
breaker_on (pos)
breaker_on (pos, 1)
end,
}
}
@@ -522,7 +580,7 @@ end
minetest.register_node("lwcomponents:breaker", {
description = S("Breaker"),
tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png",
"lwbreaker.png", "lwbreaker.png", "lwbreaker_face.png"},
"lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face.png"},
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
@@ -551,7 +609,7 @@ minetest.register_node("lwcomponents:breaker", {
minetest.register_node("lwcomponents:breaker_locked", {
description = S("Breaker (locked)"),
tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png",
"lwbreaker.png", "lwbreaker.png", "lwbreaker_face.png"},
"lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face.png"},
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
@@ -581,7 +639,7 @@ minetest.register_node("lwcomponents:breaker_locked", {
minetest.register_node("lwcomponents:breaker_on", {
description = S("Breaker"),
tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png",
"lwbreaker.png", "lwbreaker.png", "lwbreaker_face_on.png"},
"lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face_on.png"},
is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
@@ -611,7 +669,7 @@ minetest.register_node("lwcomponents:breaker_on", {
minetest.register_node("lwcomponents:breaker_locked_on", {
description = S("Breaker (locked)"),
tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png",
"lwbreaker.png", "lwbreaker.png", "lwbreaker_face_on.png"},
"lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face_on.png"},
is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),

1021
cannon.lua Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -37,3 +37,28 @@ v0.1.6
* Added holograms.
* Added breakers.
* Added fans.
v0.1.7
* Fixed fan description.
* Breakers can break nodes up to 5 forward with digilines message.
* Added deployers.
v0.1.8
* Changed detector digilines message to single message with list of
detected items.
* Added conduits.
* Fixed fans not blowing upward.
* Made changes to lwcomponents.register_spawner api - called function
must now set velocity, can use force parameter.
* Removed spawning from this mod. Created lwcomponents_spawners to
register spawers.
v0.1.9
* Fixed infotext on various nodes.
v0.1.10
* Added cannons.

748
conduit.lua Normal file
View File

@@ -0,0 +1,748 @@
local utils, mod_storage = ...
local S = utils.S
if utils.digilines_supported or utils.mesecon_supported then
local transfer_rate = 0.1
local conduit_interval = 1.0
local conduit_connections = utils.connections:new (mod_storage, "conduit_connections")
local function get_target_list (pos)
local tlist = conduit_connections:get_connected_ids (pos)
local list = { }
for i = 1, #tlist do
if tlist[i].pos.x ~= pos.x or
tlist[i].pos.y ~= pos.y or
tlist[i].pos.y ~= pos.y then
list[#list + 1] = tlist[i].id
end
end
return list
end
local function send_targets_message (pos)
if utils.digilines_supported then
local meta = minetest.get_meta (pos)
if meta then
local channel = meta:get_string ("channel")
if channel:len () > 0 then
utils.digilines_receptor_send (pos,
utils.digilines_default_rules,
channel,
{ action = "targets",
targets = get_target_list (pos) })
end
end
end
end
local function deliver_slot (pos, slot)
local meta = minetest.get_meta (pos)
if meta then
local inv = meta:get_inventory ()
local transfer_data = minetest.deserialize (meta:get_string ("transfer_data"))
if inv then
local item = inv:get_stack ("transfer", slot)
if transfer_data[slot] and item and not item:is_empty () then
local tmeta = minetest.get_meta (transfer_data[slot].pos)
if tmeta then
local tinv = tmeta:get_inventory ()
if tinv then
tinv:add_item ("main", item)
--send_conduit_message (pos, target, slot)
end
end
end
transfer_data[slot] = nil
meta:set_string ("transfer_data", minetest.serialize (transfer_data))
inv:set_stack ("transfer", slot, nil)
end
end
end
local function run_deliveries (pos)
local meta = minetest.get_meta (pos)
if meta then
local inv = meta:get_inventory ()
local transfer_data = minetest.deserialize (meta:get_string ("transfer_data")) or { }
if inv then
local slots = inv:get_size ("transfer")
local tm = minetest.get_us_time ()
for i = 1, slots do
if transfer_data[i] and
(transfer_data[i].due <= tm or
tm < (transfer_data[i].due - 1000000000)) then
deliver_slot (pos, i)
end
end
end
return not inv:is_empty ("transfer")
end
return false
end
local function deliver_all (pos)
local meta = minetest.get_meta (pos)
if meta then
local inv = meta:get_inventory ()
if inv then
local slots = inv:get_size ("transfer")
for i = 1, slots do
local item = inv:get_stack ("transfer", i)
if item and not item:is_empty () then
deliver_slot (pos, i)
end
end
end
meta:set_string ("transfer_data", minetest.serialize({ }))
inv:set_list ("transfer", { })
end
end
local function delivered_earliest (pos)
local meta = minetest.get_meta (pos)
if meta then
local inv = meta:get_inventory ()
local transfer_data = minetest.deserialize (meta:get_string ("transfer_data")) or { }
if inv then
local slots = inv:get_size ("transfer")
local slot = 0
local tm = 0
for i = 1, slots do
if transfer_data[i] and transfer_data[i].due < tm then
slot = i
tm = transfer_data[i].due
end
end
if slot > 0 then
deliver_slot (pos, slot)
end
end
end
end
local function get_transfer_free_slot (pos)
local meta = minetest.get_meta (pos)
if meta then
local inv = meta:get_inventory ()
if inv then
local slots = inv:get_size ("transfer")
for i = 1, slots do
local item = inv:get_stack ("transfer", i)
if not item or item:is_empty () then
return i
end
end
end
end
return 0
end
local function add_to_send_list (pos, item, destpos, distance)
local slot = get_transfer_free_slot (pos)
while slot < 1 do
delivered_earliest (pos)
end
local meta = minetest.get_meta (pos)
if meta then
local inv = meta:get_inventory ()
local transfer_data = minetest.deserialize (meta:get_string ("transfer_data")) or { }
if inv then
transfer_data[slot] =
{
pos = destpos,
due = minetest.get_us_time () + (transfer_rate * 1000000 * distance)
}
inv:add_item ("transfer", item)
meta:set_string ("transfer_data", minetest.serialize (transfer_data))
local timer = minetest.get_node_timer (pos)
if not timer:is_started () then
timer:start (conduit_interval)
end
end
end
end
local function send_to_target (pos, target, slot)
local meta = minetest.get_meta (pos)
if meta then
local inv = meta:get_inventory ()
target = (target and tostring (target)) or meta:get_string ("target")
if inv and target:len () > 0 then
if not slot then
local slots = inv:get_size ("main")
for i = 1, slots do
local stack = inv:get_stack ("main", i)
if not stack:is_empty () and stack:get_count () > 0 then
slot = i
break
end
end
elseif type (slot) == "string" then
local name = slot
slot = nil
local slots = inv:get_size ("main")
for i = 1, slots do
local stack = inv:get_stack ("main", i)
if not stack:is_empty () and stack:get_count () > 0 then
if name == stack:get_name () then
slot = i
break
end
end
end
else
slot = tonumber (slot)
end
if slot then
local stack = inv:get_stack ("main", slot)
if not stack:is_empty () and stack:get_count () > 0 then
local name = stack:get_name ()
local item = ItemStack (stack)
if item then
item:set_count (1)
local tpos, distance = conduit_connections:is_connected (pos, target)
if tpos then
local tmeta = minetest.get_meta (tpos)
if tmeta then
local tinv = tmeta:get_inventory ()
if tinv and tinv:room_for_item ("main", item) then
add_to_send_list (pos, item, tpos, distance)
stack:set_count (stack:get_count () - 1)
inv:set_stack ("main", slot, stack)
--send_conduit_message (pos, target, slot)
return true, target, slot
end
end
end
end
end
end
end
end
return false
end
local function run_conduit (pos)
local meta = minetest.get_meta (pos)
local automatic = false
if meta then
automatic = meta:get_string ("automatic") == "true"
end
if automatic then
send_to_target (pos)
end
return run_deliveries (pos) or automatic
end
local function get_formspec (pos)
local meta = minetest.get_meta (pos)
local automatic = "false"
if meta then
automatic = meta:get_string ("automatic")
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
local function on_construct (pos)
conduit_connections:add_node (pos)
end
local function on_destruct (pos)
deliver_all (pos)
conduit_connections:remove_node (pos)
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos)
local spec =
"formspec_version[3]"..
"size[7.0,3.8]"..
"field[0.5,1.0;6.0,0.8;channel;Channel;${channel}]"..
"button[2.0,2.3;3.0,0.8;setchannel;Set]"
meta:set_string ("inventory", "{ main = { }, transfer = { } }")
meta:set_string ("formspec", spec)
meta:set_string ("transfer_data", minetest.serialize({ }))
meta:set_string ("automatic", "false")
local inv = meta:get_inventory ()
inv:set_size ("main", 16)
inv:set_width ("main", 4)
inv:set_size ("transfer", 32)
inv:set_width ("transfer", 8)
-- If return true no item is taken from itemstack
return false
end
local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
after_place_node (pos, placer, itemstack, pointed_thing)
if placer and placer:is_player () then
local meta = minetest.get_meta (pos)
meta:set_string ("owner", placer:get_player_name ())
meta:set_string ("infotext", "Conduit (owned by "..placer:get_player_name ()..")")
end
-- If return true no item is taken from itemstack
return false
end
local function can_dig (pos, player)
if not utils.can_interact_with_node (pos, player) then
return false
end
local meta = minetest.get_meta (pos)
if meta then
local inv = meta:get_inventory ()
if inv then
if not inv:is_empty ("main") then
return false
end
end
end
return true
end
local function on_receive_fields (pos, formname, fields, sender)
if not utils.can_interact_with_node (pos, sender) then
return
end
if fields.setchannel then
local meta = minetest.get_meta (pos)
if meta then
if tostring (fields.channel):len () > 0 then
if meta:get_string ("channel"):len () < 1 then
meta:set_string ("formspec", get_formspec (pos))
end
meta:set_string ("channel", fields.channel)
conduit_connections:set_id (pos, tostring (fields.channel))
elseif meta:get_string ("channel"):len () > 0 then
if can_dig (pos, sender) ~= false then
local spec =
"formspec_version[3]"..
"size[7.0,3.8]"..
"field[0.5,1.0;6.0,0.8;channel;Channel;${channel}]"..
"button[2.0,2.3;3.0,0.8;setchannel;Set]"
meta:set_string ("channel", fields.channel)
meta:set_string ("formspec", spec)
conduit_connections:set_id (pos, nil)
elseif sender and sender:is_player () then
fields.channel = meta:get_string ("channel")
local spec =
"formspec_version[3]"..
"size[8.0,4.0,false]"..
"label[2.5,1.0;Conduit not empty]"..
"button_exit[3.0,2.0;2.0,1.0;close;Close]"
minetest.show_formspec (sender:get_player_name (),
"lwcomponents:conduit_not_empty",
spec)
end
end
end
end
if fields.settarget then
local meta = minetest.get_meta (pos)
if meta then
meta:set_string ("target", fields.target)
end
end
if fields.automatic then
local meta = minetest.get_meta (pos)
if meta then
meta:set_string ("automatic", fields.automatic)
meta:set_string ("formspec", get_formspec (pos))
local timer = minetest.get_node_timer (pos)
if not timer:is_started () then
timer:start (conduit_interval)
end
end
end
end
local function on_blast (pos, intensity)
local meta = minetest.get_meta (pos)
if meta then
if intensity >= 1.0 then
local inv = meta:get_inventory ()
if inv then
local slots = inv:get_size ("main")
for slot = 1, slots do
local stack = inv:get_stack ("main", slot)
if stack and not stack:is_empty () then
if math.floor (math.random (0, 5)) == 3 then
utils.item_drop (stack, nil, pos)
else
utils.on_destroy (stack)
end
end
end
end
on_destruct (pos)
minetest.remove_node (pos)
else -- intensity < 1.0
local inv = meta:get_inventory ()
if inv then
local slots = inv:get_size ("main")
for slot = 1, slots do
local stack = inv:get_stack ("main", slot)
if stack and not stack:is_empty () then
utils.item_drop (stack, nil, pos)
end
end
end
local node = minetest.get_node_or_nil (pos)
if node then
local items = minetest.get_node_drops (node, nil)
if items and #items > 0 then
local stack = ItemStack (items[1])
if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos)
on_destruct (pos)
minetest.remove_node (pos)
end
end
end
end
end
end
local function on_rightclick (pos, node, clicker, itemstack, pointed_thing)
if not utils.can_interact_with_node (pos, clicker) then
if clicker and clicker:is_player () then
local owner = "<unknown>"
local meta = minetest.get_meta (pos)
if meta then
owner = meta:get_string ("owner")
end
local spec =
"formspec_version[3]"..
"size[8.0,4.0,false]"..
"label[1.0,1.0;Owned by "..minetest.formspec_escape (owner).."]"..
"button_exit[3.0,2.0;2.0,1.0;close;Close]"
minetest.show_formspec (clicker:get_player_name (),
"lwcomponents:component_privately_owned",
spec)
end
end
return itemstack
end
local function on_timer (pos, elapsed)
return run_conduit (pos)
end
local function digilines_support ()
if utils.digilines_supported then
return
{
wire =
{
rules = utils.digilines_default_rules,
},
effector =
{
action = function (pos, node, channel, msg)
local meta = minetest.get_meta(pos)
if meta then
local this_channel = meta:get_string ("channel")
if this_channel ~= "" and this_channel == channel then
if type (msg) == "string" then
local m = { }
for w in string.gmatch(msg, "[^%s]+") do
m[#m + 1] = w
end
if m[1] == "target" then
meta:set_string ("target", (m[2] and tostring (m[2])) or "")
elseif m[1] == "targets" then
send_targets_message (pos)
elseif m[1] == "transfer" then
send_to_target (pos)
end
elseif type (msg) == "table" then
if msg.action and tostring (msg.action) == "transfer" then
send_to_target (pos, msg.target, msg.slot or msg.item)
end
end
end
end
end,
}
}
end
return nil
end
local function mesecon_support ()
if utils.mesecon_supported then
return
{
effector =
{
rules = utils.mesecon_flat_rules,
action_on = function (pos, node)
send_to_target (pos)
end
}
}
end
return nil
end
minetest.register_node("lwcomponents:conduit", {
description = S("Conduit"),
drawtype = "glasslike_framed",
tiles = { "lwconduit_edge.png", "lwconduit.png" },
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "none",
param2 = 0,
floodable = false,
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_construct = on_construct,
on_destruct = on_destruct,
on_receive_fields = on_receive_fields,
after_place_node = after_place_node,
can_dig = can_dig,
on_blast = on_blast,
on_timer = on_timer,
on_rightclick = on_rightclick
})
minetest.register_node("lwcomponents:conduit_locked", {
description = S("Conduit (locked)"),
drawtype = "glasslike_framed",
tiles = { "lwconduit_edge.png", "lwconduit.png" },
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "none",
param2 = 0,
floodable = false,
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_construct = on_construct,
on_destruct = on_destruct,
on_receive_fields = on_receive_fields,
after_place_node = after_place_node_locked,
can_dig = can_dig,
on_blast = on_blast,
on_timer = on_timer,
on_rightclick = on_rightclick
})
utils.hopper_add_container({
{"top", "lwcomponents:conduit", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:conduit", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:conduit", "main"}, -- insert items from hopper at side
})
utils.hopper_add_container({
{"top", "lwcomponents:conduit_locked", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:conduit_locked", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:conduit_locked", "main"}, -- insert items from hopper at side
})
end -- utils.digilines_supported or utils.mesecon_supported

300
connections.lua Normal file
View File

@@ -0,0 +1,300 @@
local connections = { }
function connections:new (mod_storage, name)
local obj = { }
setmetatable (obj, self)
self.__index = self
obj.connector_list = { }
obj.name = tostring (name)
obj.storage = mod_storage
if mod_storage then
local stored = mod_storage:get_string (obj.name)
if stored == "" then
stored = "{ }"
end
obj.connector_list = minetest.deserialize (stored)
if not obj.connector_list then
obj.connector_list = { }
end
end
return obj
end
function connections:load ()
if self.storage then
local stored = self.storage:get_string (self.name)
if stored == "" then
stored = "{ }"
end
self.connector_list = minetest.deserialize (stored)
end
end
function connections:store ()
if self.storage then
self.storage:set_string (self.name, minetest.serialize (self.connector_list))
end
end
function connections:add_node (pos, id)
self.connector_list[minetest.pos_to_string (pos, 0)] =
{
id = (id and tostring (id)) or nil,
checked = false
}
self:store ()
end
function connections:remove_node (pos)
self.connector_list[minetest.pos_to_string (pos, 0)] = nil
self:store ()
end
function connections:set_id (pos, id)
local con = self.connector_list[minetest.pos_to_string (pos, 0)]
if con then
con.id = (id and tostring (id)) or nil
self:store ()
return true
end
return false
end
local function is_connected (self, pos, id, tally, test_coords)
if not id then
return nil
end
local con = self.connector_list[minetest.pos_to_string (pos, 0)]
if con and not con.checked then
con.checked = true
if con.id == id then
con.checked = false
return pos, tally
end
for i = 1, #test_coords do
local result, agg = is_connected (self,
{
x = pos.x + test_coords[i].x,
y = pos.y + test_coords[i].y,
z = pos.z + test_coords[i].z
},
id,
tally,
test_coords)
if result then
con.checked = false
return result, (tally + agg + 1)
end
end
con.checked = false
end
return nil, 0
end
function connections:is_connected (pos, id)
return is_connected (self,
pos,
tostring (id),
0,
{
{ x = 1, y = 0, z = 0 },
{ x = -1, y = 0, z = 0 },
{ x = 0, y = 0, z = 1 },
{ x = 0, y = 0, z = -1 },
{ x = 0, y = 1, z = 0 },
{ x = 0, y = -1, z = 0 }
})
end
function connections:is_connected_horizontal (pos, id)
return is_connected (self,
pos,
tostring (id),
0,
{
{ x = 1, y = 0, z = 0 },
{ x = -1, y = 0, z = 0 },
{ x = 0, y = 0, z = 1 },
{ x = 0, y = 0, z = -1 }
})
end
function connections:is_connected_vertical (pos, id)
return is_connected (self,
pos,
tostring (id),
0,
{
{ x = 0, y = 1, z = 0 },
{ x = 0, y = -1, z = 0 }
})
end
local function get_connected_ids (self, pos, test_coords, list)
local con = self.connector_list[minetest.pos_to_string (pos, 0)]
if con and not con.checked then
con.checked = true
if con.id then
list[#list + 1] =
{
pos = { x = pos.x, y = pos.y, z = pos.z },
id = con.id
}
end
for i = 1, #test_coords do
get_connected_ids (self,
{
x = pos.x + test_coords[i].x,
y = pos.y + test_coords[i].y,
z = pos.z + test_coords[i].z
},
test_coords,
list)
end
con.checked = false
end
return list
end
function connections:get_connected_ids (pos)
local list = get_connected_ids (self,
pos,
{
{ x = 1, y = 0, z = 0 },
{ x = -1, y = 0, z = 0 },
{ x = 0, y = 0, z = 1 },
{ x = 0, y = 0, z = -1 },
{ x = 0, y = 1, z = 0 },
{ x = 0, y = -1, z = 0 }
},
{ })
for i = #list, 1, -1 do
for j = 1, i - 1, 1 do
if list[i].pos.x == list[j].pos.x and
list[i].pos.y == list[j].pos.y and
list[i].pos.z == list[j].pos.z then
list[i] = nil
break
end
end
end
return list
end
function connections:get_connected_ids_horizontal (pos)
return get_connected_ids (self,
pos,
{
{ x = 1, y = 0, z = 0 },
{ x = -1, y = 0, z = 0 },
{ x = 0, y = 0, z = 1 },
{ x = 0, y = 0, z = -1 }
},
{ })
end
function connections:get_connected_ids_vertical (pos)
return get_connected_ids (self,
pos,
{
{ x = 0, y = 1, z = 0 },
{ x = 0, y = -1, z = 0 }
},
{ })
end
function connections:get_connected_ids_north_south (pos)
return get_connected_ids (self,
pos,
{
{ x = 0, y = 0, z = 1 },
{ x = 0, y = 0, z = -1 }
},
{ })
end
function connections:get_connected_ids_east_west (pos)
return get_connected_ids (self,
pos,
{
{ x = 1, y = 0, z = 0 },
{ x = -1, y = 0, z = 0 }
},
{ })
end
return connections
--

View File

@@ -3,6 +3,27 @@ local S = utils.S
minetest.register_craft( {
output = "lwcomponents:cannon",
recipe = {
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
{ "default:chest", "default:wood", "" },
{ "default:copper_ingot", "default:stone", "" },
},
})
minetest.register_craft( {
output = "lwcomponents:cannon_locked",
recipe = {
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
{ "default:chest_locked", "default:wood", "" },
{ "default:copper_ingot", "default:stone", "" },
},
})
if utils.digilines_supported or utils.mesecon_supported then
minetest.register_craft( {
@@ -113,6 +134,24 @@ minetest.register_craft( {
})
minetest.register_craft( {
output = "lwcomponents:deployer",
recipe = {
{ "default:chest", "group:wood" },
{ "default:copper_ingot", "default:steel_ingot" },
},
})
minetest.register_craft( {
output = "lwcomponents:deployer_locked",
recipe = {
{ "default:chest_locked", "group:wood" },
{ "default:copper_ingot", "default:steel_ingot" },
},
})
minetest.register_craft( {
output = "lwcomponents:fan",
recipe = {
@@ -130,6 +169,26 @@ 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" },
},
})
end -- utils.digilines_supported or utils.mesecon_supported

View File

@@ -5,5 +5,4 @@ digilines?
unifieddyes?
intllib?
hopper?
mobs?
digistuff?

679
deployer.lua Normal file
View File

@@ -0,0 +1,679 @@
local utils = ...
local S = utils.S
if utils.digilines_supported or utils.mesecon_supported then
local deploy_interval = 1.0
local function send_deploy_message (pos, slot, name, range)
if utils.digilines_supported then
local meta = minetest.get_meta (pos)
if meta then
local channel = meta:get_string ("channel")
if channel:len () > 0 then
utils.digilines_receptor_send (pos,
utils.digilines_default_rules,
channel,
{ action = "deploy",
name = name,
slot = slot,
range = range })
end
end
end
end
local function deployer_front (pos, param2)
if param2 == 0 then
return { x = pos.x, y = pos.y, z = pos.z - 1 }
elseif param2 == 1 then
return { x = pos.x - 1, y = pos.y, z = pos.z }
elseif param2 == 2 then
return { x = pos.x, y = pos.y, z = pos.z + 1 }
elseif param2 == 3 then
return { x = pos.x + 1, y = pos.y, z = pos.z }
else
return { x = pos.x, y = pos.y, z = pos.z }
end
end
local function get_deploy_pos (pos, param2, range)
local deploypos = { x = pos.x, y = pos.y, z = pos.z }
for i = 1, range do
deploypos = deployer_front (deploypos, param2)
if i < range then
local node = minetest.get_node_or_nil (deploypos)
if not node or node.name ~= "air" then
local nodedef = utils.find_item_def (node.name)
if not nodedef or not nodedef.buildable_to then
return nil
end
end
end
end
return deploypos
end
local function place_node (itemname, pos)
local node = minetest.get_node_or_nil ({ x = pos.x, y = pos.y - 1, z = pos.z })
if not node then
return false
end
local nodedef = utils.find_item_def (node.name)
if node.name == "air" or not nodedef or (nodedef and nodedef.buildable_to) then
return false
end
node = minetest.get_node_or_nil (pos)
if not node then
return false
end
nodedef = utils.find_item_def (node.name)
if node.name ~= "air" then
if not nodedef or not nodedef.buildable_to or minetest.is_protected (pos, "") then
return false
end
end
local stack = ItemStack (itemname)
local itemdef = utils.find_item_def (itemname)
if stack and itemdef then
local placed = false
local pointed_thing =
{
type = "node",
under = { x = pos.x, y = pos.y - 1, z = pos.z },
above = pos,
}
if node.name ~= "air" and nodedef and nodedef.buildable_to then
pointed_thing =
{
type = "node",
under = pos,
above = { x = pos.x, y = pos.y + 1, z = pos.z },
}
end
if itemdef and itemdef.on_place then
local result, msg = pcall (itemdef.on_place, stack, nil, pointed_thing)
placed = result
if not placed then
if utils.settings.alert_handler_errors then
minetest.log ("error", "on_place handler for "..itemname.." crashed - "..msg)
end
end
end
if not placed then
if not minetest.registered_nodes[itemname] then
return false
end
minetest.set_node (pos, { name = itemname, param1 = 0, param2 = 0 })
if itemdef and itemdef.after_place_node then
local result, msg = pcall (itemdef.after_place_node, pos, nil, stack, pointed_thing)
if not result then
if utils.settings.alert_handler_errors then
minetest.log ("error", "after_place_node handler for "..nodename.." crashed - "..msg)
end
end
end
if itemdef and itemdef.sounds and itemdef.sounds.place then
pcall (minetest.sound_play, itemdef.sounds.place, { pos = pos })
end
end
end
return true
end
-- slot:
-- nil - next item, no drop if empty
-- number - 1 item from slot, no drop if empty
-- string - name of item to drop, no drop if none
-- range:
-- 1 - 5 from front of deployer
local function deploy_item (pos, node, slot, range)
local meta = minetest.get_meta (pos)
range = math.min (math.max (tonumber (range) or 1, 1), 5)
if meta then
local inv = meta:get_inventory ()
if inv then
if not slot then
local slots = inv:get_size ("main")
for i = 1, slots do
local stack = inv:get_stack ("main", i)
if not stack:is_empty () and stack:get_count () > 0 then
slot = i
break
end
end
elseif type (slot) == "string" then
local name = slot
slot = nil
local slots = inv:get_size ("main")
for i = 1, slots do
local stack = inv:get_stack ("main", i)
if not stack:is_empty () and stack:get_count () > 0 then
if name == stack:get_name () then
slot = i
break
end
end
end
else
slot = tonumber (slot)
end
if slot then
local stack = inv:get_stack ("main", slot)
if not stack:is_empty () and stack:get_count () > 0 then
local name = stack:get_name ()
local item = ItemStack (stack)
local deploypos = get_deploy_pos (pos, node.param2, range)
if item and deploypos then
if place_node (name, deploypos) then
stack:set_count (stack:get_count () - 1)
inv:set_stack ("main", slot, stack)
send_deploy_message (pos, slot, name, range)
return true, slot, name, range
end
end
end
end
end
end
return false
end
local function deployer_off (pos)
local node = minetest.get_node (pos)
if node then
if node.name == "lwcomponents:deployer_on" then
node.name = "lwcomponents:deployer"
minetest.get_node_timer (pos):stop ()
minetest.swap_node (pos, node)
elseif node.name == "lwcomponents:deployer_locked_on" then
node.name = "lwcomponents:deployer_locked"
minetest.get_node_timer (pos):stop ()
minetest.swap_node (pos, node)
end
end
end
local function deployer_on (pos, node, slot, range)
local node = minetest.get_node (pos)
range = tonumber (range) or 1
if slot and tostring (slot) == "nil" then
slot = nil
end
if node and range < 6 and range > 0 then
if node.name == "lwcomponents:deployer" then
node.name = "lwcomponents:deployer_on"
minetest.swap_node (pos, node)
deploy_item (pos, node, slot, range)
minetest.get_node_timer (pos):start (deploy_interval)
elseif node.name == "lwcomponents:deployer_locked" then
node.name = "lwcomponents:deployer_locked_on"
minetest.swap_node (pos, node)
deploy_item (pos, node, slot, range)
minetest.get_node_timer (pos):start (deploy_interval)
end
end
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos)
local spec =
"formspec_version[3]\n"..
"size[11.75,13.75;true]\n"..
"field[1.0,1.0;4.0,0.8;channel;Channel;${channel}]\n"..
"button[5.5,1.0;2.0,0.8;setchannel;Set]\n"..
"list[context;main;3.5,2.5;4,4;]\n"..
"list[current_player;main;1.0,8.0;8,4;]\n"..
"listring[]"
meta:set_string ("inventory", "{ main = { } }")
meta:set_string ("formspec", spec)
local inv = meta:get_inventory ()
inv:set_size ("main", 16)
inv:set_width ("main", 4)
-- If return true no item is taken from itemstack
return false
end
local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
after_place_node (pos, placer, itemstack, pointed_thing)
if placer and placer:is_player () then
local meta = minetest.get_meta (pos)
meta:set_string ("owner", placer:get_player_name ())
meta:set_string ("infotext", "Deployer (owned by "..placer:get_player_name ()..")")
end
-- If return true no item is taken from itemstack
return false
end
local function on_receive_fields (pos, formname, fields, sender)
if not utils.can_interact_with_node (pos, sender) then
return
end
if fields.setchannel then
local meta = minetest.get_meta (pos)
if meta then
meta:set_string ("channel", fields.channel)
end
end
end
local function can_dig (pos, player)
if not utils.can_interact_with_node (pos, player) then
return false
end
local meta = minetest.get_meta (pos)
if meta then
local inv = meta:get_inventory ()
if inv then
if not inv:is_empty ("main") then
return false
end
end
end
return true
end
local function on_blast (pos, intensity)
local meta = minetest.get_meta (pos)
if meta then
if intensity >= 1.0 then
local inv = meta:get_inventory ()
if inv then
local slots = inv:get_size ("main")
for slot = 1, slots do
local stack = inv:get_stack ("main", slot)
if stack and not stack:is_empty () then
if math.floor (math.random (0, 5)) == 3 then
utils.item_drop (stack, nil, pos)
else
utils.on_destroy (stack)
end
end
end
end
minetest.remove_node (pos)
else -- intensity < 1.0
local inv = meta:get_inventory ()
if inv then
local slots = inv:get_size ("main")
for slot = 1, slots do
local stack = inv:get_stack ("main", slot)
if stack and not stack:is_empty () then
utils.item_drop (stack, nil, pos)
end
end
end
local node = minetest.get_node_or_nil (pos)
if node then
local items = minetest.get_node_drops (node, nil)
if items and #items > 0 then
local stack = ItemStack (items[1])
if stack then
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos)
minetest.remove_node (pos)
end
end
end
end
end
end
local function on_rightclick (pos, node, clicker, itemstack, pointed_thing)
if not utils.can_interact_with_node (pos, clicker) then
if clicker and clicker:is_player () then
local owner = "<unknown>"
local meta = minetest.get_meta (pos)
if meta then
owner = meta:get_string ("owner")
end
local spec =
"formspec_version[3]"..
"size[8.0,4.0,false]"..
"label[1.0,1.0;Owned by "..minetest.formspec_escape (owner).."]"..
"button_exit[3.0,2.0;2.0,1.0;close;Close]"
minetest.show_formspec (clicker:get_player_name (),
"lwcomponents:component_privately_owned",
spec)
end
end
return itemstack
end
local function on_timer (pos, elapsed)
deployer_off (pos)
end
local function digilines_support ()
if utils.digilines_supported then
return
{
wire =
{
rules = utils.digilines_default_rules,
},
effector =
{
action = function (pos, node, channel, msg)
local meta = minetest.get_meta(pos)
if meta then
local this_channel = meta:get_string ("channel")
if this_channel ~= "" and this_channel == channel and
type (msg) == "string" then
local m = { }
for w in string.gmatch(msg, "[^%s]+") do
m[#m + 1] = w
end
if m[1] == "deploy" then
if tostring (m[2]) == nil then
m[2] = "nil"
elseif m[2] and tonumber (m[2]) then
m[2] = tonumber (m[2])
end
deployer_on (pos, node, m[2], m[3])
end
end
end
end,
}
}
end
return nil
end
local function mesecon_support ()
if utils.mesecon_supported then
return
{
effector =
{
rules = utils.mesecon_flat_rules,
action_on = function (pos, node)
deployer_on (pos, node, "nil", 1)
end
}
}
end
return nil
end
minetest.register_node("lwcomponents:deployer", {
description = S("Deployer"),
tiles = { "lwdeployer.png", "lwdeployer.png", "lwdeployer.png",
"lwdeployer.png", "lwdeployer.png", "lwdeployer_face.png"},
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
floodable = false,
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_receive_fields = on_receive_fields,
after_place_node = after_place_node,
can_dig = can_dig,
on_blast = on_blast,
on_timer = on_timer,
on_rightclick = on_rightclick
})
minetest.register_node("lwcomponents:deployer_locked", {
description = S("Deployer (locked)"),
tiles = { "lwdeployer.png", "lwdeployer.png", "lwdeployer.png",
"lwdeployer.png", "lwdeployer.png", "lwdeployer_face.png"},
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
floodable = false,
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_receive_fields = on_receive_fields,
after_place_node = after_place_node_locked,
can_dig = can_dig,
on_blast = on_blast,
on_timer = on_timer,
on_rightclick = on_rightclick
})
minetest.register_node("lwcomponents:deployer_on", {
description = S("Deployer"),
tiles = { "lwdeployer.png", "lwdeployer.png", "lwdeployer.png",
"lwdeployer.png", "lwdeployer.png", "lwdeployer_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,
light_source = 3,
floodable = false,
drop = "lwcomponents:deployer",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
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:deployer_locked_on", {
description = S("Deployer (locked)"),
tiles = { "lwdeployer.png", "lwdeployer.png", "lwdeployer.png",
"lwdeployer.png", "lwdeployer.png", "lwdeployer_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,
light_source = 3,
floodable = false,
drop = "lwcomponents:deployer_locked",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
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
})
utils.hopper_add_container({
{"top", "lwcomponents:deployer", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:deployer", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:deployer", "main"}, -- insert items from hopper at side
})
utils.hopper_add_container({
{"top", "lwcomponents:deployer_locked", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:deployer_locked", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:deployer_locked", "main"}, -- insert items from hopper at side
})
utils.hopper_add_container({
{"top", "lwcomponents:deployer_on", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:deployer_on", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:deployer_on", "main"}, -- insert items from hopper at side
})
utils.hopper_add_container({
{"top", "lwcomponents:deployer_locked_on", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:deployer_locked_on", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:deployer_locked_on", "main"}, -- insert items from hopper at side
})
end -- utils.digilines_supported or utils.mesecon_supported
--

View File

@@ -60,7 +60,7 @@ end
local function send_detect_message (pos, item_type, name, label, item_pos, count, hp, height)
local function send_detect_message (pos, detected_list)
if utils.digilines_supported then
local meta = minetest.get_meta (pos)
@@ -72,13 +72,7 @@ local function send_detect_message (pos, item_type, name, label, item_pos, count
utils.digilines_default_rules,
channel,
{ action = "detect",
type = item_type,
name = name,
label = label,
pos = to_relative_coords (pos, item_pos),
count = count,
hp = hp,
height = height })
detected = detected_list })
end
end
end
@@ -169,6 +163,7 @@ local function detect (pos)
local radius = meta:get_int ("radius")
local mode = meta:get_int ("mode")
local object = minetest.get_objects_inside_radius (pos, radius + 0.5)
local detected_list = { }
for i = 1, #object do
if object[i]:is_player () then
@@ -177,14 +172,16 @@ local function detect (pos)
if meta:get_string ("players") == "true" and
filter_item (pos, mode, object[i]:get_pos ()) then
send_detect_message (pos,
"player",
object[i]:get_player_name (),
object[i]:get_player_name (),
object[i]:get_pos (),
1,
object[i]:get_hp (),
get_entity_height (object[i]))
detected_list[#detected_list + 1] =
{
type = "player",
name = object[i]:get_player_name (),
label = object[i]:get_player_name (),
pos = to_relative_coords (pos, object[i]:get_pos ()),
count = 1,
hp = object[i]:get_hp (),
height = get_entity_height (object[i])
}
detected = true
end
@@ -200,14 +197,17 @@ local function detect (pos)
local stack = ItemStack (object[i]:get_luaentity ().itemstring or "")
if stack and not stack:is_empty () then
send_detect_message (pos,
"drop",
stack:get_name (),
stack:get_name (),
object[i]:get_pos (),
stack:get_count (),
0,
0)
detected_list[#detected_list + 1] =
{
type = "drop",
name = stack:get_name (),
label = stack:get_name (),
pos = to_relative_coords (pos, object[i]:get_pos ()),
count = stack:get_count (),
hp = 0,
height = 0
}
detected = true
end
@@ -231,14 +231,16 @@ local function detect (pos)
object[i]:get_luaentity () and
object[i]:get_luaentity ().name) or ""
send_detect_message (pos,
"entity",
name,
label,
object[i]:get_pos (),
1,
object[i]:get_hp (),
get_entity_height (object[i]))
detected_list[#detected_list + 1] =
{
type = "entity",
name = name,
label = label,
pos = to_relative_coords (pos, object[i]:get_pos ()),
count = 1,
hp = object[i]:get_hp (),
height = get_entity_height (object[i])
}
detected = true
@@ -258,14 +260,16 @@ local function detect (pos)
if node and node.name ~= "air" and node.name ~= "ignore" and
filter_item (pos, mode, testpos) then
send_detect_message (pos,
"node",
node.name,
node.name,
testpos,
1,
0,
0)
detected_list[#detected_list + 1] =
{
type = "node",
name = node.name,
label = node.name,
pos = testpos,
count = 1,
hp = 0,
height = 0
}
detected = true
end
@@ -276,6 +280,8 @@ local function detect (pos)
if detected then
mesecons_on (pos)
send_detect_message (pos, detected_list)
else
mesecons_off (pos)
end

View File

@@ -7,6 +7,10 @@ if utils.digilines_supported or utils.mesecon_supported then
local dispenser_force = 25
local function dispense_dir (node)
if node.param2 == 0 then
return { x = 0, y = 0, z = -1 }
@@ -40,18 +44,17 @@ end
local function dispense_velocity (node)
local force = 25 --math.random (30 , 35)
local tilt = (math.random (1 , 2001) - 1001) / 1000
local sway = (math.random (1 , 4001) - 2001) / 1000
if node.param2 == 0 then
return { x = sway, y = tilt, z = -force }
return { x = sway, y = tilt, z = -dispenser_force }
elseif node.param2 == 1 then
return { x = -force, y = tilt, z = sway }
return { x = -dispenser_force, y = tilt, z = sway }
elseif node.param2 == 2 then
return { x = sway, y = tilt, z = force }
return { x = sway, y = tilt, z = dispenser_force }
elseif node.param2 == 3 then
return { x = force, y = tilt, z = sway }
return { x = dispenser_force, y = tilt, z = sway }
else
return { x = 0, y = 0, z = 0 }
end
@@ -80,73 +83,6 @@ end
local function try_spawn (pos, node, item, owner)
if utils.mobs_supported and utils.settings.spawn_mobs then
local mob = item:get_name ()
local item_def = minetest.registered_craftitems[mob]
local spawn_pos = dispense_pos (pos, node)
if item_def and item_def.groups and item_def.groups.spawn_egg then
if mob:sub (mob:len () - 3) == "_set" then
mob = mob:sub (1, mob:len () - 4)
if minetest.registered_entities[mob] then
local data = item:get_metadata ()
local smob = minetest.add_entity (spawn_pos, mob, data)
local ent = smob and smob:get_luaentity ()
if ent then
-- set owner if not a monster
if owner:len () > 0 and ent.type ~= "monster" then
ent.owner = owner
ent.tamed = true
end
end
return smob
end
else
if minetest.registered_entities[mob] then
local smob = minetest.add_entity (spawn_pos, mob)
local ent = smob and smob:get_luaentity ()
if ent then
-- set owner if not a monster
if owner:len () > 0 and ent.type ~= "monster" then
ent.owner = owner
ent.tamed = true
end
end
return smob
end
end
elseif mob == "mobs:egg" then
if math.random (1, 10) == 1 then
local smob = minetest.add_entity (spawn_pos, "mobs_animal:chicken")
local ent = smob and smob:get_luaentity ()
if ent then
-- set owner if not a monster
if owner:len () > 0 and ent.type ~= "monster" then
ent.owner = owner
ent.tamed = true
end
end
return smob
end
end
end
return nil
end
-- slot:
-- nil - next item, no dispense if empty
-- number - 1 item from slot, no dispense if empty
@@ -203,29 +139,31 @@ local function dispense_item (pos, node, slot)
item:set_count (1)
local spawn_pos = dispense_pos (pos, node)
local owner = meta:get_string ("owner")
local obj, cancel = nil, false
local obj, cancel = utils.spawn_registered (name,
spawn_pos,
item,
owner,
pos,
dispense_dir (node))
if utils.settings.spawn_mobs then
obj, cancel = utils.spawn_registered (name,
spawn_pos,
item,
owner,
pos,
dispense_dir (node),
dispenser_force)
if obj == nil and cancel then
return false
end
if not obj then
obj = try_spawn (pos, node, item, owner)
if obj == nil and cancel then
return false
end
end
if not obj then
obj = minetest.add_item (spawn_pos, item)
if obj then
obj:set_velocity (dispense_velocity (node))
end
end
if obj then
obj:set_velocity (dispense_velocity (node))
stack:set_count (stack:get_count () - 1)
inv:set_stack ("main", slot, stack)

View File

@@ -13,7 +13,7 @@ lwcomponents.register_spawner (itemname, spawn_func)
spawn_func:
The function to call to spawn the mob of the form -
spawn_func (spawn_pos, itemstack, owner, spawner_pos, spawner_dir)
spawn_func (spawn_pos, itemstack, owner, spawner_pos, spawner_dir, force)
spawn_pos:
The position the entity should be spawned at.
@@ -32,9 +32,13 @@ lwcomponents.register_spawner (itemname, spawn_func)
A single unit vector of the direction the spawner block is facing.
eg. { x = -1, y = 0, z = 0 }
force:
Recommended force (for velocity) of spawned entity.
Can use vector.multiply (spawner_dir, force).
This function should return the ObjectRef of the spawned entity or
nil. If this function returns nil for ObjectRef a second boolean
value should be returned for weather to cancel the action.
value should be returned for whether to cancel the action.
eg. If too many mobs:
return nil, true

View File

@@ -2,11 +2,12 @@ Breaker
-------
* This block is only available if digilines and/or mesecons are loaded.
Breakers dig the node directly in front of them and drop the item at the
back of them. The node is only dug if the breaker has a tool that can
dig it, of if it can be dug by hand. The tool is worn if used. Also acts
as a digilines conductor. If the hopper mod is loaded, will take tools
from the top and sides.
Breakers dig the node up to 5 nodes directly in front of them and drop
the item at the back of them. The node is only dug if the breaker has a
tool that can dig it or if it can be dug by hand, and there are no nodes
before of it. ie. cannot dig 2nd node if 1st node has something in it.
The tool is worn if used. Also acts as a digilines conductor. If the
hopper mod is loaded, will take tools from the top and sides.
Only the owner can dig or access the form of the locked version.
@@ -17,23 +18,26 @@ Top 1 slot inventory - tool to use.
Bottom 32 slot inventory - player's inventory.
Mesecons
Digs the node in front when power is turned on, if it can.
Digs the node in front (always the 1st node position) when power is
turned on, if it can.
Digilines messages
"break"
Digs the node in front when power is turned on, if it can.
"break n"
Digs the node at n nodes in front when power is turned on, if it can.
n should be a number between 1 and 5. If omitted 1 is assumed.
"eject side"
Drop the tool in the tool slot at the given side. Valid sides are "left",
"right", "back", "front". If side is omitted or invalid "front" is used.
When a breaker digs a node or wears out the tool a digilines message is
sent with the puncher's channel. The message is a table with the following
sent with the breaker's channel. The message is a table with the following
keys:
{
action = "<action>",
name = "<name>"
name = "<name>",
range = <number>
}
action
@@ -42,3 +46,7 @@ action
name
For "break" action the registered node name of what was dug.
For "tool" action the registered tool name of the tool that wore out.
range
For "break" action the nodes forward that was dug.
For "tool" action always nil.

63
docs/cannon.txt Normal file
View File

@@ -0,0 +1,63 @@
Cannon
------
This item is available without digilines or mesecons as it can be used
manually.
Contains a single inventory slot and shoots an item on command.
If the hopper mod is loaded, will take items from the top and sides, and
release them from the bottom.
Cannon rotation range:
side to side - +/-60 degrees (- = left, + = right)
down to up: -20 to 50 degrees (- = down, + = up)
To spawn entities from cannons include the lwcomponents_spawners mod.
Only the owner can dig or access the form of the locked version.
UI
Channel - digilines channel of cannon.
Hide - hides the form so the cannon can be used manually, double right click
any other face besides the rear to bring up the form.
Controller - digistuff game controller digilines channel.
Top 1 slot inventory - storage of items to shoot.
Bottom 32 slot inventory - player's inventory.
Manual control
Place some items in the single slot, and click the Hide button. On the
rear panel their are 4 gray buttons. Right clicking them turns the barrel
in that direction 10 degrees. aux + right click turns 1 degree. Clicking
the red button fires an item. To bring up the form again double right click
any other face besides the rear.
Digistuff game controller
Connect a game controller to the cannon with digilines cable. Enter the
game controller's channel in the Controller field of the cannon's form
(click Set). Your turning movements turn the cannon's barrel in the
direction the cannon is facing. The movements have an increased sensitivity
(x3) to try and keep the target in your view. Punching shoots an item.
The game controller updates every 0.2 seconds, so a quick punch may not
register. A locked cannon can only be controlled by it's owner with a game
controller.
Mesecons
Shoots an item when power is turned on.
Digilines messages
"pitch <n>"
Sets the pitch of the barrel. n should be between -20 to 50, and will
be clipped to this range.
eg. "pitch 22"
"rotation <n>"
Sets the rotation of the barrel. n should be between -60 to 60, and will
be clipped to this range.
eg. "rotation 45"
"fire"
Shoots an item.
* Note: turning the barrel is animated and takes 0.1 seconds per 10
degrees of movement. A fire command while moving is ignored.

66
docs/conduit.txt Normal file
View File

@@ -0,0 +1,66 @@
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
inventory to another conduit in the same circuit.
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
conduit within the circuit. A conduit does not have to be given a name.
Most of them are just used to connect other conduits together.
Transfer of items takes 0.1 seconds per conduit node moved.
Also acts as a digilines conductor. If the hopper mod is loaded, will
take items from the top and sides, and release them from the bottom.
Only the owner can dig or access the form of the locked version.
UI
Channel - digilines channel/target id of circuit.
Target - target id/channel of circuit this circuit will transfer to.
Automatic - if checked transfers next item every second without command.
Top right 16 slot inventory - storage of items.
Bottom 32 slot inventory - player's inventory.
Mesecons
Transfers the next item when power is turned on to the target circuit.
Digilines messages
"target <id>"
Set the target of the conduit. id should be the channel of another
conduit on the same circiut. This takes a moment to take effect, so
delay any transfers.
"targets"
Conduit will send a digilines message with its own channel in the form:
{
action = "targets",
targets = { ... } -- list of string channels of all other conduits
-- with a channel on the same circuit.
}
"transfer"
Simple transfer. Transfers the next item in the inventory to the target
circuit (same as mesecons power).
table message
{
action = "transfer",
target = "<channel>",
slot = <number>,
item = "<itemname>"
}
If target is not given, the circuit's set target is used.
slot should be a number between 1 to 16. If the slot is empty nothing
is transferred.
item should be the registered item name. If the circuit's inventory
does not contain any nothing is transferred.
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.

57
docs/deployer.txt Normal file
View File

@@ -0,0 +1,57 @@
Deployer
-------
* This block is only available if digilines and/or mesecons are loaded.
Deployers place the node up to 5 nodes directly in front of them. The
node is only placed if there are no nodes before of it which are not
replaceable. ie. cannot place 2nd node if 1st node has something in it.
Also acts as a digilines conductor. If the hopper mod is loaded, will
take items from the top and sides, and release them from the bottom.
Only the owner can dig or access the form of the locked version.
UI
Channel - digilines channel of breaker.
Top 16 slot inventory - storage of items to place.
Bottom 32 slot inventory - player's inventory.
Mesecons
Places the node in front (always the 1st node position) when power is
turned on, if it can.
Digilines messages
"deploy <slot or itemname> <n>"
Places the node at n nodes in front when power is turned on, if it can.
n should be a number between 1 and 5. If omitted 1 is assumed.
If slot is a number, places an item from that slot. No placement if
slot is empty.
eg. "deploy 7"
If itemname is given, places the item of the name given. No placement
if deployer does not contain the item.
eg. "deploy default:stone"
If n is given with no slot/itemname use "nil".
eg. "deploy nil 3"
When a deployer places a node a digilines message is sent with the
deployer's channel. The message is a table with the following
keys:
{
action = "deploy",
name = "<name>",
slot = <slot>,
range = <number>
}
action
Will be "deploy".
name
The registered node name of what was placed.
range
The nodes forward that was placed.

View File

@@ -59,8 +59,14 @@ Digilines messages
When items or entities are detected a digilines message is sent with the
detector's channel. A message is sent for each found item/entity. The
message is a table with the following keys:
{
action = "detect",
detected = table
}
The detected field is a list of detected items. Each entry is of the form:
{
type = "<type>", -- will be "entity", "player", "drop" or "node"
name = "<name>",
label = "<label>",

View File

@@ -6,11 +6,7 @@ Contains an inventory and dispenses (with velocity) an item on command.
Also acts as a digilines conductor. If the hopper mod is loaded, will take
items from the top and sides, and release them from the bottom.
Dispensers support mobs mod if loaded and Spawn mobs setting is enabled.
Will spawn the entity from an 'egg' if possible, or the 'egg' is dispensed.
If a chicken egg is dispensed a 10% chance a chicken is dispensed instead.
If the spawned entity can be owned (or tamed) and the dispenser is owned
the owner of the dispenser is set as the owner of the entity.
To spawn entities from dispensers include the lwcomponents_spawners mod.
Only the owner can dig or access the form of the locked version.

80
fan.lua
View File

@@ -13,17 +13,33 @@ local fan_force = 15.0
local function direction_vector (node)
if node.param2 == 0 then
return { x = 0, y = 0, z = -1 }
elseif node.param2 == 1 then
return { x = -1, y = 0, z = 0 }
elseif node.param2 == 2 then
return { x = 0, y = 0, z = 1 }
elseif node.param2 == 3 then
return { x = 1, y = 0, z = 0 }
else
return { x = 0, y = 0, z = 0 }
local axis = math.floor (node.param2 / 4)
local rotate = node.param2 % 4
local vec = { x = 0, y = 0, z = 0 }
if rotate == 0 then
vec = { x = 0, y = 0, z = -1 }
elseif rotate == 1 then
vec = { x = -1, y = 0, z = 0 }
elseif rotate == 2 then
vec = { x = 0, y = 0, z = 1 }
elseif rotate == 3 then
vec = { x = 1, y = 0, z = 0 }
end
if axis == 1 then
vec = vector.rotate (vec, { x = math.pi / -2, y = 0, z = 0 })
elseif axis == 2 then
vec = vector.rotate (vec, { x = math.pi / 2, y = 0, z = 0 })
elseif axis == 3 then
vec = vector.rotate (vec, { x = 0, y = 0, z = math.pi / 2 })
elseif axis == 4 then
vec = vector.rotate (vec, { x = 0, y = 0, z = math.pi / -2 })
elseif axis == 5 then
vec = vector.rotate (vec, { x = math.pi, y = 0, z = 0 })
end
return vec
end
@@ -39,11 +55,15 @@ local function blow (pos)
local tnode = minetest.get_node_or_nil (tpos)
if tnode and tnode.name ~= "air" then
return
local def = utils.find_item_def (tnode.name)
if def and def.walkable then
return
end
end
local object = minetest.get_objects_inside_radius (tpos, 1.5)
local vel = vector.multiply (dir, fan_force)
local vel = vector.multiply (dir, (dir.y > 0 and fan_force / 2) or fan_force)
for i = 1, #object do
if object[i].add_velocity then
@@ -113,6 +133,20 @@ end
local function on_place (itemstack, placer, pointed_thing)
local param2 = 0
if placer and placer:is_player () then
param2 = minetest.dir_to_facedir (placer:get_look_dir (), true)
elseif pointed_thing and pointed_thing.type == "node" then
param2 = minetest.dir_to_facedir (vector.subtract (pointed_thing.under, pointed_thing.above), true)
end
return minetest.item_place (itemstack, placer, pointed_thing, param2)
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos)
@@ -136,7 +170,7 @@ local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos)
meta:set_string ("owner", placer:get_player_name ())
meta:set_string ("infotext", "Hologram (owned by "..placer:get_player_name ()..")")
meta:set_string ("infotext", "Fan (owned by "..placer:get_player_name ()..")")
end
-- If return true no item is taken from itemstack
@@ -309,7 +343,7 @@ end
minetest.register_node("lwcomponents:fan", {
description = S("Breaker"),
description = S("Fan"),
tiles = { "lwfan.png", "lwfan.png", "lwfan.png",
"lwfan.png", "lwfan.png", "lwfan_face.png"},
is_ground_content = false,
@@ -318,7 +352,7 @@ minetest.register_node("lwcomponents:fan", {
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
param2 = 0,
floodable = false,
drop = "lwcomponents:fan",
_digistuff_channelcopier_fieldname = "channel",
@@ -326,6 +360,7 @@ minetest.register_node("lwcomponents:fan", {
mesecons = mesecon_support (),
digiline = digilines_support (),
on_place = on_place,
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node,
@@ -336,7 +371,7 @@ minetest.register_node("lwcomponents:fan", {
minetest.register_node("lwcomponents:fan_locked", {
description = S("Breaker (locked)"),
description = S("Fan (locked)"),
tiles = { "lwfan.png", "lwfan.png", "lwfan.png",
"lwfan.png", "lwfan.png", "lwfan_face.png"},
is_ground_content = false,
@@ -345,7 +380,7 @@ minetest.register_node("lwcomponents:fan_locked", {
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
param2 = 0,
floodable = false,
drop = "lwcomponents:fan_locked",
_digistuff_channelcopier_fieldname = "channel",
@@ -353,6 +388,7 @@ minetest.register_node("lwcomponents:fan_locked", {
mesecons = mesecon_support (),
digiline = digilines_support (),
on_place = on_place,
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node_locked,
@@ -363,7 +399,7 @@ minetest.register_node("lwcomponents:fan_locked", {
minetest.register_node("lwcomponents:fan_on", {
description = S("Breaker"),
description = S("Fan"),
tiles = { "lwfan.png", "lwfan.png", "lwfan.png",
"lwfan.png", "lwfan.png", "lwfan_face_on.png"},
is_ground_content = false,
@@ -372,7 +408,7 @@ minetest.register_node("lwcomponents:fan_on", {
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
param2 = 0,
floodable = false,
drop = "lwcomponents:fan",
_digistuff_channelcopier_fieldname = "channel",
@@ -380,6 +416,7 @@ minetest.register_node("lwcomponents:fan_on", {
mesecons = mesecon_support (),
digiline = digilines_support (),
on_place = on_place,
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node,
@@ -391,7 +428,7 @@ minetest.register_node("lwcomponents:fan_on", {
minetest.register_node("lwcomponents:fan_locked_on", {
description = S("Breaker (locked)"),
description = S("Fan (locked)"),
tiles = { "lwfan.png", "lwfan.png", "lwfan.png",
"lwfan.png", "lwfan.png", "lwfan_face_on.png"},
is_ground_content = false,
@@ -400,7 +437,7 @@ minetest.register_node("lwcomponents:fan_locked_on", {
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
param2 = 0,
floodable = false,
drop = "lwcomponents:fan_locked",
_digistuff_channelcopier_fieldname = "channel",
@@ -408,6 +445,7 @@ minetest.register_node("lwcomponents:fan_locked_on", {
mesecons = mesecon_support (),
digiline = digilines_support (),
on_place = on_place,
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node_locked,

View File

@@ -1,4 +1,4 @@
local version = "0.1.6"
local version = "0.1.10"
local mod_storage = minetest.get_mod_storage ()
@@ -18,6 +18,7 @@ local modpath = minetest.get_modpath ("lwcomponents")
loadfile (modpath.."/utils.lua") (utils, mod_storage)
loadfile (modpath.."/settings.lua") (utils)
loadfile (modpath.."/api.lua") (utils)
utils.connections = loadfile (modpath.."/connections.lua") ()
loadfile (modpath.."/dropper.lua") (utils)
loadfile (modpath.."/collector.lua") (utils)
loadfile (modpath.."/dispenser.lua") (utils)
@@ -27,7 +28,10 @@ loadfile (modpath.."/puncher.lua") (utils)
loadfile (modpath.."/player_button.lua") (utils)
loadfile (modpath.."/hologram.lua") (utils)
loadfile (modpath.."/breaker.lua") (utils)
loadfile (modpath.."/deployer.lua") (utils)
loadfile (modpath.."/fan.lua") (utils)
loadfile (modpath.."/conduit.lua") (utils, mod_storage)
loadfile (modpath.."/cannon.lua") (utils)
loadfile (modpath.."/extras.lua") (utils)
loadfile (modpath.."/digiswitch.lua") (utils)
loadfile (modpath.."/movefloor.lua") (utils)

View File

@@ -69,6 +69,8 @@ public domain.
player button images derived from mesecons button image.
cannon firing sound from tnt, released under CC BY-SA 3.0 and CC0 1.0
All other media, or media not covered by a licence, is licensed
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)

View File

@@ -3,4 +3,4 @@ description = Various components for mesecons and digilines.
title = LWComponents
name = lwcomponents
depends = default
optional_depends = lwdrops, mesecons, digilines, unifieddyes, intllib, hopper, mobs, digistuff
optional_depends = lwdrops, mesecons, digilines, unifieddyes, intllib, hopper, digistuff

View File

@@ -0,0 +1,625 @@
# Blender v2.82 (sub 7) OBJ File: 'canon.blend'
# www.blender.org
mtllib lwcomponents_cannon_barrel.mtl
o Canon
v 0.999994 -2.037148 -0.790288
v 0.999994 -0.938179 -2.111386
v 0.999994 -1.251549 1.868645
v 0.999994 -2.145818 0.243561
v 0.999994 -1.824579 1.232245
v 0.999994 -1.517369 -1.690576
v -0.837650 -1.110379 -1.986275
v -0.999994 -1.517369 -1.690576
v -0.999994 -0.938179 -2.111386
v -0.437400 -1.222309 -1.904956
v 0.000000 -1.344629 -1.816076
v 0.437400 -1.222309 -1.904956
v 0.837650 -1.110379 -1.986275
v -0.999994 -2.037148 -0.790289
v -0.999994 -2.145818 0.243560
v -0.999994 -1.824579 1.232244
v -0.000000 -1.538639 1.549804
v 0.089079 -1.516209 1.574724
v 0.947191 -1.300109 1.814725
v -0.089079 -1.516209 1.574724
v -0.947191 -1.300109 1.814724
v -0.999994 -1.251549 1.868644
v 1.673030 -0.625437 3.499885
v 1.414210 0.340481 4.396455
v 1.224740 -0.366620 4.396455
v 1.673030 1.306400 3.499885
v 1.931850 0.340481 3.499885
v -0.517635 0.340481 4.914094
v -0.448284 0.599299 4.914094
v -1.414210 0.340481 4.396455
v 1.673030 1.306400 2.464605
v 0.749998 1.639521 -5.027746
v 0.965919 2.013511 2.464605
v 1.299040 1.090479 -5.027746
v -0.000000 2.272331 2.464605
v 0.965919 -1.332548 3.499884
v -0.000000 -1.591369 2.464605
v 0.965919 -1.332548 2.464605
v -0.000000 -1.591369 3.499884
v -1.673030 -0.625437 3.499884
v -1.224740 -0.366620 4.396455
v -0.000000 -1.073729 4.396455
v 0.258818 -0.107803 4.914094
v -0.000000 -0.177154 4.914094
v -0.965919 2.013511 3.499884
v -0.000000 1.754691 4.396455
v -0.000000 2.272331 3.499884
v -1.299040 -0.409517 -5.027746
v -1.673030 -0.625437 2.464605
v -0.749998 -0.958559 -5.027746
v -0.965919 -1.332548 2.464605
v 1.500000 0.340481 -5.027746
v 1.931850 0.340481 2.464605
v 1.299040 -0.409517 -5.027746
v 1.224740 1.047583 4.396455
v -1.500000 0.340481 -5.027746
v -1.931850 0.340481 2.464605
v -1.299040 1.090479 -5.027746
v 0.965919 2.013511 3.499884
v -0.965919 2.013511 2.464605
v -0.749998 1.639521 -5.027746
v -0.258818 -0.107803 4.914094
v 0.448284 0.081663 4.914094
v -0.965919 -1.332548 3.499884
v -0.707102 -0.884259 4.396455
v 0.000000 1.840482 -5.027746
v -1.673030 1.306400 2.464605
v 0.448284 0.599299 4.914094
v 0.707102 1.565221 4.396455
v -1.673030 1.306400 3.499884
v -0.999994 0.340481 -5.027746
v -0.866022 0.840474 -5.027746
v -0.499992 1.206504 -5.027746
v 0.000000 1.340475 -5.027746
v 0.499992 1.206504 -5.027746
v 0.866022 0.840474 -5.027746
v 0.999994 0.340481 -5.027746
v -0.866022 -0.159511 -5.027746
v -0.499992 -0.525541 -5.027746
v 0.000000 -0.659513 -5.027746
v 0.000000 -1.159519 -5.027746
v 0.499992 -0.525541 -5.027746
v 0.749998 -0.958559 -5.027746
v 0.866022 -0.159511 -5.027746
v 0.258818 0.788765 4.914094
v -0.707102 1.565221 4.396455
v -1.224740 1.047583 4.396455
v -0.258818 0.788765 4.914094
v 0.707102 -0.884259 4.396455
v 1.673030 -0.625437 2.464605
v -0.448284 0.081663 4.914094
v -1.931850 0.340481 3.499884
v -0.000000 0.858117 4.914094
v 0.517635 0.340481 4.914094
v 0.499992 1.206504 -0.017755
v 0.000000 1.340475 -0.017755
v -0.866022 -0.159511 -0.017756
v -0.999994 0.340481 -0.017756
v 0.999994 0.340481 -0.017755
v 0.866022 -0.159511 -0.017755
v 0.000000 -0.659513 -0.017755
v 0.499992 -0.525541 -0.017755
v -0.866022 0.840474 -0.017756
v -0.499992 1.206504 -0.017756
v -0.499992 -0.525541 -0.017756
v 0.866022 0.840474 -0.017755
vt 0.898722 0.101473
vt 0.949058 0.000000
vt 0.949058 0.291647
vt 0.897343 0.177359
vt 0.917533 0.247935
vt 0.921432 0.033397
vt 0.644810 0.718620
vt 0.656466 0.688883
vt 0.656466 0.731202
vt 0.938458 0.774110
vt 0.917273 0.733004
vt 0.946494 0.744866
vt 0.929676 0.806070
vt 0.917273 0.879136
vt 0.938458 0.838029
vt 0.946494 0.867274
vt 0.958858 0.879136
vt 0.720513 0.816705
vt 0.809535 0.875496
vt 0.700708 0.883794
vt 0.829340 0.808407
vt 0.720513 0.741037
vt 0.829340 0.732739
vt 0.829340 0.985218
vt 0.900553 0.888939
vt 0.900554 1.000000
vt 0.829340 0.874157
vt 1.000000 0.879136
vt 0.979470 0.806070
vt 1.000000 0.733004
vt 0.977860 0.812578
vt 0.962344 0.875278
vt 0.958858 0.879136
vt 0.977860 0.799561
vt 0.962344 0.736862
vt 0.333921 0.730752
vt 0.330130 0.692431
vt 0.333921 0.688883
vt 0.900071 0.556676
vt 0.950406 0.658149
vt 0.922781 0.624752
vt 0.950406 0.366502
vt 0.898691 0.480790
vt 0.918881 0.410213
vt 0.255350 0.066011
vt 0.224399 0.000000
vt 0.267734 0.000231
vt 0.463512 0.067703
vt 0.499410 0.000000
vt 0.525690 0.066413
vt 0.258332 0.815437
vt 0.267951 0.798482
vt 0.303850 0.861759
vt 0.463512 0.143300
vt 0.399738 0.689322
vt 0.391714 0.143300
vt 0.455487 0.689322
vt 0.656641 0.142072
vt 0.718822 0.143213
vt 0.728112 0.689215
vt 0.196154 0.065695
vt 0.326930 0.066054
vt 0.391714 0.141456
vt 0.326930 0.141696
vt 0.391714 0.065814
vt 0.584886 0.622872
vt 0.597270 0.688652
vt 0.553935 0.688883
vt 0.442482 0.882141
vt 0.461064 0.811564
vt 0.474668 0.825408
vt 0.062178 0.621619
vt 0.026280 0.689322
vt 0.000000 0.622909
vt 0.595217 0.000034
vt 0.636204 0.213000
vt 0.584886 0.547230
vt 0.650796 0.000000
vt 0.653098 0.222127
vt 0.650827 0.503665
vt 0.656466 0.547187
vt 0.655974 0.499724
vt 0.219718 0.688604
vt 0.196154 0.141337
vt 0.265682 0.688849
vt 0.453892 0.000944
vt 0.174230 0.001002
vt 0.196154 0.547312
vt 0.125951 0.000000
vt 0.656466 0.066476
vt 0.682592 0.000000
vt 0.718647 0.067616
vt 0.062178 0.546022
vt 0.000000 0.547312
vt 0.070203 0.000000
vt 0.493250 0.830475
vt 0.405317 0.740987
vt 0.456085 0.792653
vt 0.391714 0.792653
vt 0.172450 0.755310
vt 0.129645 0.690784
vt 0.177048 0.689322
vt 0.525690 0.547546
vt 0.549254 0.000279
vt 0.679831 0.688329
vt 0.525690 0.142010
vt 0.503765 0.688320
vt 0.133976 0.546022
vt 0.493250 0.895984
vt 0.442482 0.703166
vt 0.474668 0.759899
vt 0.728112 0.000835
vt 0.021924 0.001002
vt 0.133976 0.621619
vt 0.571208 0.835015
vt 0.540118 0.853282
vt 0.525690 0.798482
vt 0.579538 0.893399
vt 0.561589 0.798483
vt 0.540119 0.743682
vt 0.571208 0.761949
vt 0.579538 0.703566
vt 0.597488 0.735205
vt 0.633386 0.725417
vt 0.633386 0.688883
vt 0.107696 0.908522
vt 0.071797 0.862198
vt 0.107697 0.871988
vt 0.053848 0.893838
vt 0.045518 0.835455
vt 0.597487 0.861759
vt 0.633386 0.908082
vt 0.633386 0.871549
vt 0.071798 0.735645
vt 0.107696 0.689322
vt 0.107696 0.725856
vt 0.053848 0.704005
vt 0.045519 0.762388
vt 0.014429 0.744121
vt 0.035899 0.798922
vt 0.000000 0.798922
vt 0.014428 0.853721
vt 0.303850 0.715627
vt 0.241672 0.752160
vt 0.258332 0.688883
vt 0.401333 0.000944
vt 0.391714 0.067703
vt 0.330130 0.761949
vt 0.330130 0.815437
vt 0.267951 0.778904
vt 0.071797 0.688378
vt 0.124357 0.688378
vt 0.649670 0.688620
vt 0.656466 0.622829
vt 0.405317 0.844319
vt 0.169874 0.689322
vt 0.306668 0.475883
vt 0.321261 0.688883
vt 0.255350 0.141653
vt 0.321291 0.185217
vt 0.323562 0.466756
vt 0.326439 0.189159
vt 0.320134 0.000263
vt 0.367559 0.000087
vt 0.493250 0.689322
vt 0.493250 0.754831
vt 0.383346 0.206474
vt 0.389253 0.208272
vt 0.350625 0.460717
vt 0.371562 0.688696
vt 0.380200 0.454116
vt 0.114908 0.899599
vt 0.110220 0.832906
vt 0.120752 0.897599
vt 0.391714 0.690986
vt 0.362403 0.918008
vt 0.341454 0.688883
vt 0.391714 0.925731
vt 0.205773 0.888503
vt 0.241672 0.825226
vt 0.258333 0.888503
vt 0.222434 0.825226
vt 0.196154 0.622909
vt 0.525690 0.623188
vt 0.107697 0.757308
vt 0.174974 0.830908
vt 0.258332 0.761949
vt 0.461064 0.773742
vt 0.205773 0.815437
vt 0.196154 0.798482
vt 0.196154 0.778904
vt 0.222434 0.752160
vt 0.205773 0.761949
vt 0.177048 0.878327
vt 0.335581 0.910942
vt 0.982592 0.366176
vt 0.949058 0.000000
vt 0.982592 0.000124
vt 0.949058 0.366052
vt 0.861526 0.366502
vt 0.829340 0.733004
vt 0.829340 0.367170
vt 0.861526 0.732336
vt 0.760297 0.000668
vt 0.728112 0.365834
vt 0.728112 0.000000
vt 0.760297 0.366502
vt 0.829648 0.365834
vt 0.797463 0.000668
vt 0.829648 0.000000
vt 0.797463 0.366502
vt 0.798698 0.366524
vt 0.761646 0.732553
vt 0.761646 0.366502
vt 0.798699 0.732576
vt 0.829340 0.366688
vt 0.829340 0.732739
vt 0.982592 0.733004
vt 0.950406 0.366502
vt 0.982592 0.367170
vt 0.950406 0.732336
vt 0.898691 0.366502
vt 0.898691 0.732336
vt 0.728112 0.366626
vt 0.728112 0.732678
vt 0.649940 0.784405
vt 0.668522 0.854981
vt 0.649940 0.822226
vt 0.668523 0.751650
vt 0.700708 0.873892
vt 0.700708 0.732739
vt 0.917273 0.874157
vt 0.880109 0.733004
vt 0.917273 0.733004
vt 0.880109 0.874156
vt 0.847923 0.751914
vt 0.847923 0.855245
vt 0.829340 0.784669
vt 0.829340 0.822491
vt 0.866701 0.000163
vt 0.829648 0.366237
vt 0.829648 0.000186
vt 0.866701 0.366215
vt 0.897343 0.000000
vt 0.897343 0.366052
vn 1.0000 0.0000 0.0000
vn -0.0000 -0.5878 -0.8090
vn 0.0000 -0.8660 -0.5000
vn 0.0000 -0.9945 -0.1045
vn -0.0000 -0.9511 0.3090
vn -0.0000 -0.7431 0.6691
vn -0.0000 -0.7432 0.6691
vn 0.0001 -0.7431 0.6691
vn -0.0001 -0.7431 0.6691
vn -1.0000 -0.0000 -0.0000
vn 0.8436 -0.2260 0.4871
vn 0.8436 0.2260 0.4871
vn -0.4956 0.1328 0.8584
vn 0.7060 0.7060 -0.0556
vn 0.2584 0.9644 -0.0556
vn 0.2588 -0.9659 0.0000
vn -0.8436 -0.2260 0.4871
vn 0.1328 -0.4956 0.8584
vn -0.2260 0.8436 0.4871
vn -0.7060 -0.7060 -0.0556
vn 0.9644 -0.2584 -0.0556
vn -0.9644 0.2584 -0.0556
vn 0.2260 0.8436 0.4871
vn -0.2584 0.9644 -0.0556
vn -0.1328 -0.4956 0.8584
vn 0.4956 -0.1328 0.8584
vn -0.2260 -0.8436 0.4871
vn -0.9644 -0.2584 -0.0556
vn 0.9644 0.2584 -0.0556
vn -0.7060 0.7060 -0.0556
vn 0.2588 0.9659 0.0000
vn 0.4956 0.1328 0.8584
vn -0.7071 0.7071 -0.0000
vn 0.9659 0.2588 0.0000
vn 0.0000 0.0000 -1.0000
vn -0.2588 0.9659 0.0000
vn 0.1328 0.4956 0.8584
vn 0.6176 0.6176 0.4871
vn -0.3628 0.3628 0.8584
vn -0.1328 0.4956 0.8584
vn -0.6176 0.6176 0.4871
vn -0.6176 -0.6176 0.4871
vn 0.3628 -0.3628 0.8584
vn -0.8436 0.2260 0.4871
vn 0.7060 -0.7060 -0.0556
vn 0.2260 -0.8436 0.4871
vn 0.9659 -0.2588 0.0000
vn 0.7071 0.7071 0.0000
vn 0.3628 0.3628 0.8584
vn 0.2584 -0.9644 -0.0556
vn -0.2584 -0.9644 -0.0556
vn -0.3628 -0.3628 0.8584
vn -0.4956 -0.1328 0.8584
vn -0.9659 0.2588 -0.0000
vn -0.9659 -0.2588 -0.0000
vn 0.7071 -0.7071 -0.0000
vn 0.6176 -0.6176 0.4871
vn -0.2588 -0.9659 -0.0000
vn 0.0000 0.0000 1.0000
vn -0.7071 -0.7071 0.0000
usemtl None
s off
f 1/1/1 2/2/1 3/3/1
f 4/4/1 3/3/1 5/5/1
f 2/2/1 1/1/1 6/6/1
f 3/3/1 4/4/1 1/1/1
f 7/7/2 8/8/2 9/9/2
f 10/10/2 8/11/2 7/12/2
f 11/13/2 8/11/2 10/10/2
f 11/13/2 6/14/2 8/11/2
f 12/15/2 6/14/2 11/13/2
f 13/16/2 6/14/2 12/15/2
f 6/14/2 13/16/2 2/17/2
f 1/18/3 8/19/3 6/20/3
f 8/19/3 1/18/3 14/21/3
f 4/22/4 14/21/4 1/18/4
f 14/21/4 4/22/4 15/23/4
f 5/24/5 15/25/5 4/26/5
f 15/25/5 5/24/5 16/27/5
f 5/28/6 17/29/6 16/30/6
f 5/28/7 18/31/7 17/29/7
f 5/28/6 19/32/6 18/31/6
f 19/32/8 5/28/8 3/33/8
f 20/34/7 16/30/7 17/29/7
f 21/35/6 16/30/6 20/34/6
f 16/36/9 21/37/9 22/38/9
f 14/39/10 9/40/10 8/41/10
f 9/40/10 14/39/10 22/42/10
f 15/43/10 22/42/10 14/39/10
f 22/42/10 15/43/10 16/44/10
f 23/45/11 24/46/11 25/47/11
f 26/48/12 24/49/12 27/50/12
f 28/51/13 29/52/13 30/53/13
f 31/54/14 32/55/14 33/56/14
f 32/55/14 31/54/14 34/57/14
f 35/58/15 33/59/15 32/60/15
f 27/61/11 24/46/11 23/45/11
f 36/62/16 37/63/16 38/64/16
f 37/63/16 36/62/16 39/65/16
f 40/66/17 41/67/17 30/68/17
f 42/69/18 43/70/18 44/71/18
f 45/72/19 46/73/19 47/74/19
f 48/75/20 9/76/20 49/77/20
f 50/78/20 9/76/20 48/75/20
f 9/76/20 50/78/20 7/79/20
f 22/80/20 49/77/20 9/76/20
f 22/80/20 51/81/20 49/77/20
f 51/81/20 22/80/20 21/82/20
f 52/83/21 53/84/21 54/85/21
f 55/86/12 24/49/12 26/48/12
f 56/87/22 57/88/22 58/89/22
f 47/90/23 46/91/23 59/92/23
f 60/93/24 35/94/24 61/95/24
f 42/69/25 44/71/25 62/96/25
f 24/97/26 63/98/26 25/99/26
f 64/100/27 42/101/27 65/102/27
f 48/75/28 57/103/28 56/104/28
f 66/105/15 35/58/15 32/60/15
f 34/57/29 53/106/29 52/107/29
f 60/93/30 58/89/30 67/108/30
f 58/89/30 60/93/30 61/95/30
f 47/90/31 33/59/31 35/58/31
f 33/59/31 47/90/31 59/92/31
f 42/69/25 62/96/25 65/109/25
f 55/110/32 68/111/32 24/97/32
f 46/91/23 69/112/23 59/92/23
f 61/95/24 35/94/24 66/113/24
f 67/108/33 45/72/33 60/93/33
f 45/72/33 67/108/33 70/114/33
f 27/50/34 31/54/34 26/48/34
f 31/54/34 27/50/34 53/106/34
f 31/54/29 53/106/29 34/57/29
f 71/115/35 56/116/35 58/117/35
f 56/116/35 71/115/35 48/118/35
f 58/117/35 72/119/35 71/115/35
f 61/120/35 72/119/35 58/117/35
f 61/120/35 73/121/35 72/119/35
f 66/122/35 73/121/35 61/120/35
f 66/122/35 74/123/35 73/121/35
f 66/122/35 75/124/35 74/123/35
f 32/125/35 75/124/35 66/122/35
f 32/126/35 76/127/35 75/128/35
f 34/129/35 76/127/35 32/126/35
f 76/127/35 34/129/35 77/130/35
f 78/131/35 48/118/35 71/115/35
f 78/131/35 50/132/35 48/118/35
f 79/133/35 50/132/35 78/131/35
f 80/134/35 50/135/35 79/136/35
f 80/134/35 81/137/35 50/135/35
f 82/138/35 81/137/35 80/134/35
f 82/138/35 83/139/35 81/137/35
f 84/140/35 83/139/35 82/138/35
f 54/141/35 84/140/35 77/130/35
f 52/142/35 77/130/35 34/129/35
f 84/140/35 54/141/35 83/139/35
f 77/130/35 52/142/35 54/141/35
f 45/72/36 35/94/36 60/93/36
f 35/94/36 45/72/36 47/74/36
f 46/143/37 85/144/37 69/145/37
f 69/146/38 26/48/38 59/147/38
f 26/48/38 69/146/38 55/86/38
f 29/52/39 86/148/39 87/149/39
f 86/148/39 29/52/39 88/150/39
f 86/148/40 88/150/40 46/143/40
f 86/151/19 46/73/19 45/72/19
f 70/114/41 86/151/41 45/72/41
f 86/151/41 70/114/41 87/152/41
f 40/66/42 65/153/42 41/67/42
f 65/153/42 40/66/42 64/154/42
f 89/155/43 63/98/43 43/70/43
f 63/98/43 89/155/43 25/99/43
f 30/53/13 29/52/13 87/149/13
f 30/156/44 87/152/44 70/114/44
f 54/85/45 2/157/45 83/158/45
f 90/159/45 2/157/45 54/85/45
f 2/157/45 90/159/45 3/160/45
f 83/158/45 2/157/45 13/161/45
f 3/160/45 38/64/45 19/162/45
f 38/64/45 3/160/45 90/159/45
f 36/62/46 89/163/46 42/164/46
f 54/85/21 53/84/21 90/159/21
f 23/45/47 53/84/47 27/61/47
f 53/84/47 23/45/47 90/159/47
f 26/48/48 33/56/48 59/147/48
f 33/56/48 26/48/48 31/54/48
f 68/111/49 69/165/49 85/166/49
f 69/165/49 68/111/49 55/110/49
f 18/167/50 37/63/50 17/168/50
f 12/169/50 81/170/50 83/158/50
f 81/170/50 12/169/50 11/171/50
f 17/172/51 37/173/51 20/174/51
f 81/175/51 10/176/51 50/177/51
f 10/176/51 81/175/51 11/178/51
f 65/179/52 91/180/52 41/181/52
f 91/180/52 65/179/52 62/182/52
f 30/53/53 91/180/53 28/51/53
f 92/183/44 30/156/44 70/114/44
f 37/63/50 19/162/50 38/64/50
f 19/162/50 37/63/50 18/167/50
f 13/161/50 12/169/50 83/158/50
f 89/155/18 43/70/18 42/69/18
f 41/181/53 91/180/53 30/53/53
f 57/88/54 70/114/54 67/108/54
f 70/114/54 57/88/54 92/183/54
f 57/88/22 67/108/22 58/89/22
f 49/77/55 92/184/55 57/103/55
f 92/184/55 49/77/55 40/66/55
f 40/66/17 30/68/17 92/184/17
f 36/62/56 90/159/56 23/45/56
f 90/159/56 36/62/56 38/64/56
f 89/163/57 23/45/57 25/47/57
f 23/45/57 89/163/57 36/62/57
f 39/185/58 51/186/58 37/173/58
f 51/186/58 39/185/58 64/100/58
f 93/187/37 85/144/37 46/143/37
f 68/111/32 94/188/32 24/97/32
f 88/150/40 93/187/40 46/143/40
f 48/75/28 49/77/28 57/103/28
f 36/62/46 42/164/46 39/65/46
f 39/185/27 42/101/27 64/100/27
f 91/180/59 29/52/59 28/51/59
f 62/182/59 29/52/59 91/180/59
f 62/182/59 88/150/59 29/52/59
f 44/189/59 88/150/59 62/182/59
f 44/189/59 93/187/59 88/150/59
f 43/190/59 93/187/59 44/189/59
f 43/190/59 85/144/59 93/187/59
f 63/191/59 85/144/59 43/190/59
f 63/191/59 68/192/59 85/144/59
f 68/192/59 63/191/59 94/193/59
f 24/97/26 94/188/26 63/98/26
f 51/81/60 40/66/60 49/77/60
f 40/66/60 51/81/60 64/154/60
f 37/173/51 21/194/51 20/174/51
f 21/194/51 37/173/51 51/186/51
f 50/177/51 10/176/51 7/195/51
f 95/196/58 74/197/58 75/198/58
f 74/197/58 95/196/58 96/199/58
f 97/200/34 71/201/34 98/202/34
f 71/201/34 97/200/34 78/203/34
f 84/204/54 99/205/54 77/206/54
f 99/205/54 84/204/54 100/207/54
f 101/208/36 82/209/36 80/210/36
f 82/209/36 101/208/36 102/211/36
f 103/212/56 73/213/56 104/214/56
f 73/213/56 103/212/56 72/215/56
f 98/216/47 72/215/47 103/212/47
f 72/215/47 98/216/47 71/217/47
f 105/218/31 80/219/31 79/220/31
f 80/219/31 105/218/31 101/221/31
f 105/222/48 78/203/48 97/200/48
f 78/203/48 105/222/48 79/223/48
f 96/224/16 73/213/16 74/225/16
f 73/213/16 96/224/16 104/214/16
f 82/209/33 100/207/33 84/204/33
f 100/207/33 82/209/33 102/211/33
f 103/226/35 97/227/35 98/228/35
f 104/229/35 97/227/35 103/226/35
f 104/229/35 105/230/35 97/227/35
f 96/231/35 105/230/35 104/229/35
f 96/232/35 101/233/35 105/234/35
f 95/235/35 101/233/35 96/232/35
f 95/235/35 102/236/35 101/233/35
f 106/237/35 102/236/35 95/235/35
f 106/237/35 100/238/35 102/236/35
f 100/238/35 106/237/35 99/239/35
f 76/240/60 95/241/60 75/242/60
f 95/241/60 76/240/60 106/243/60
f 77/244/55 106/243/55 76/240/55
f 106/243/55 77/244/55 99/245/55

View File

@@ -13,7 +13,7 @@ CC BY-SA 3.0
Version
=======
0.1.6
0.1.10
Minetest Version
@@ -34,7 +34,6 @@ digilines
unifieddyes
intllib
hopper
mobs
digistuff
@@ -59,12 +58,19 @@ Various components for mesecons and digilines.
* Siren, plays a sound repeatedly while active.
* Puncher, punches players or entities within a given reach.
* Player button, sends digilines message with player name.
* Breaker, digs the node directly in front.
* Breaker, digs the nodes directly in front.
* Deployers, places the nodes directly in front.
* Hologram, projects a hologram above the hologram node.
* Fan, blows any entity, player or drop in front of the fan.
* Conduit, connected in a circuit to move items.
* Cannon, shoots an item on command with directional aiming.
* Digiswitch, digilines controlled mesecons power.
* Movefloor, similar to vertical mesecons movestone.
* Solid color conductor blocks, same as Solid Color Block but also mesecons and digilines conductor.
* Solid color conductor blocks, same as Solid Color Block but also mesecons
and digilines conductor.
To spawn entities from dispensers and cannons include the
lwcomponents_spawners mod.
See the docs folder for details on each item.
@@ -77,4 +83,16 @@ the relevant mod is loaded.
The mod supports the following settings:
Spawn mobs
Allow dispensers and cannons to spawn mobs instead of spawners.
Default: true
Alert handler errors
Issue errors when handler's of other mods fail.
Default: true
------------------------------------------------------------------------

View File

@@ -6,6 +6,9 @@ utils.settings = { }
utils.settings.spawn_mobs =
minetest.settings:get_bool ("lwcomponents_spawn_mobs", true)
utils.settings.alert_handler_errors =
minetest.settings:get_bool ("lwcomponents_alert_handler_errors", true)
--

View File

@@ -1,2 +1,5 @@
# Allow dispensers to spawn mobs instead of spawners.
# Allow dispensers and cannons to spawn mobs instead of spawners.
lwcomponents_spawn_mobs (Spawn mobs) bool true
# Issue errors when handler's of other mods fail.
lwcomponents_alert_handler_errors (Alert handler errors) bool true

View File

@@ -269,7 +269,7 @@ local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos)
meta:set_string ("owner", placer:get_player_name ())
meta:set_string ("infotext", "Detector (owned by "..placer:get_player_name ()..")")
meta:set_string ("infotext", "Siren (owned by "..placer:get_player_name ()..")")
end
-- If return true no item is taken from itemstack

BIN
sounds/lwcannon.ogg Normal file

Binary file not shown.

BIN
textures/lwbreaker_rear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
textures/lwcannon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
textures/lwcannon_face.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
textures/lwcannon_item.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
textures/lwcannon_top.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
textures/lwconduit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
textures/lwconduit_edge.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
textures/lwdeployer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -129,15 +129,6 @@ end
-- check for mobs
if minetest.global_exists ("mobs") then
utils.mobs_supported = true
else
utils.mobs_supported = false
end
-- check for digistuff
if minetest.global_exists ("digistuff") then
utils.digistuff_supported = true
@@ -259,17 +250,18 @@ end
function utils.spawn_registered (itemname, spawn_pos, itemstack, owner, spawner_pos, spawner_dir)
function utils.spawn_registered (itemname, spawn_pos, itemstack, owner, spawner_pos, spawner_dir, force)
local func = utils.registered_spawners[itemname]
if func then
local result, obj, cancel = pcall (func, spawn_pos, itemstack, owner, spawner_pos, spawner_dir)
local result, obj, cancel = pcall (func, spawn_pos, itemstack, owner, spawner_pos, spawner_dir, force)
if result and (obj == nil or type (obj) == "userdata") then
if result and (obj == nil or type (obj) == "userdata" or type (obj) == "table") then
return obj, cancel
end
minetest.log ("error", "lwcomponents.register_spawner spawner function for "..itemname.." failed")
minetest.log ("error", "lwcomponents.register_spawner spawner function for "..itemname.." failed "..
((type (obj) == "string" and obj) or ""))
return nil, true
end
@@ -279,4 +271,62 @@ end
function utils.can_place (pos)
local node = minetest.get_node_or_nil (pos)
if node and node.name ~= "air" then
local def = minetest.registered_nodes[node.name]
if not def or not def.buildable_to then
return false
end
end
return true
end
function utils.is_protected (pos, player)
local name = (player and player:get_player_name ()) or ""
return minetest.is_protected (pos, name)
end
function utils.get_on_rightclick (pos, player)
local node = minetest.get_node_or_nil (pos)
if node then
local def = minetest.registered_nodes[node.name]
if def and def.on_rightclick and
not (player and player:is_player () and
player:get_player_control ().sneak) then
return def.on_rightclick
end
end
return nil
end
function utils.is_creative (player)
if minetest.settings:get_bool ("creative_mode") then
return true
end
if player and player:is_player () then
return minetest.is_creative_enabled (player:get_player_name ()) or
minetest.check_player_privs (placer, "creative")
end
return false
end
--