Compare commits

...

65 Commits

Author SHA1 Message Date
loosewheel
85e5a877c6 Add files via upload 2022-05-23 20:01:18 +10:00
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
loosewheel
e4b3ae935d Add files via upload 2022-02-27 10:03:39 +10:00
loosewheel
914bdbbe30 Add files via upload 2022-02-27 10:01:16 +10:00
loosewheel
86362bbc86 Add files via upload 2022-02-27 09:58:15 +10:00
loosewheel
6ade6a84a2 Add files via upload 2022-02-27 09:57:07 +10:00
loosewheel
c26d7a86ca Add files via upload 2022-02-27 09:56:09 +10:00
loosewheel
729947a4dc Add files via upload 2022-02-24 08:32:23 +10:00
loosewheel
493167998d Add files via upload 2022-02-24 08:28:38 +10:00
loosewheel
9a118751e4 Add files via upload 2022-02-24 08:26:34 +10:00
loosewheel
0de1dfd620 Add files via upload 2022-02-24 08:24:13 +10:00
loosewheel
b2ac93d3d5 Add files via upload 2022-02-24 08:23:23 +10:00
loosewheel
14202a3a2e Add files via upload 2022-02-24 08:22:17 +10:00
loosewheel
3150c50312 Add files via upload 2022-02-22 14:38:06 +10:00
loosewheel
e507646519 Add files via upload 2022-02-22 14:04:04 +10:00
loosewheel
2f99a60cbd Add files via upload 2022-02-22 14:02:10 +10:00
loosewheel
e9cf28a648 Add files via upload 2022-02-22 13:59:52 +10:00
loosewheel
ebe1720922 Add files via upload 2022-02-22 13:58:38 +10:00
loosewheel
61e20f57ed Add files via upload 2022-02-22 13:58:03 +10:00
loosewheel
eaf6a679c3 Add files via upload 2022-02-19 14:08:26 +10:00
loosewheel
f41ab00398 Add files via upload 2022-02-19 14:06:27 +10:00
loosewheel
7f42fde4a0 Add files via upload 2022-02-19 14:04:44 +10:00
loosewheel
6f8a194042 Add files via upload 2022-02-16 01:49:12 +10:00
loosewheel
84ddc82c95 Add files via upload 2022-02-16 01:46:56 +10:00
loosewheel
36aaf42d9a Add files via upload 2022-02-15 07:14:40 +10:00
loosewheel
c879735c84 Add files via upload 2022-02-15 07:06:04 +10:00
loosewheel
76a8d37edb Add files via upload 2022-02-15 06:31:00 +10:00
loosewheel
1a450bdc2a Add files via upload 2022-02-15 06:28:44 +10:00
loosewheel
c11eb22f31 Add files via upload 2022-02-15 06:26:14 +10:00
loosewheel
e4aabe5ebe Add files via upload 2022-02-15 06:25:24 +10:00
loosewheel
3cfd9adb1f Add files via upload 2022-02-15 06:24:40 +10:00
loosewheel
51ab3bdc3c Add files via upload 2022-02-05 02:14:40 +10:00
loosewheel
f873bb551f Add files via upload 2022-02-05 02:08:42 +10:00
loosewheel
326275cea6 Add files via upload 2022-02-05 02:07:16 +10:00
loosewheel
f869a4c40b Add files via upload 2022-02-05 02:05:18 +10:00
loosewheel
37488db8b9 Add files via upload 2022-02-05 02:04:35 +10:00
loosewheel
cf54a3d548 Add files via upload 2022-02-05 02:03:48 +10:00
loosewheel
9519eae026 Add files via upload 2022-01-20 17:58:09 +10:00
loosewheel
5caa7b6408 Add files via upload 2022-01-08 20:03:32 +10:00
loosewheel
6d4369ee91 Add files via upload 2022-01-07 18:55:19 +10:00
loosewheel
c7ec545ef7 Add files via upload 2022-01-07 18:53:39 +10:00
loosewheel
923faa59a3 Add files via upload 2022-01-07 18:50:47 +10:00
loosewheel
201c01131f Add files via upload 2022-01-07 18:49:57 +10:00
loosewheel
a0c9dd1d0c Add files via upload 2022-01-07 18:49:14 +10:00
loosewheel
c43dab66d7 Add files via upload 2021-12-06 21:15:05 +10:00
loosewheel
ca31c40d8b Add files via upload 2021-12-05 01:24:47 +10:00
loosewheel
2b61dfb872 Add files via upload 2021-11-29 11:29:56 +10:00
loosewheel
1459dc2029 Add files via upload 2021-11-29 11:27:33 +10:00
loosewheel
a3f6a4d203 Add files via upload 2021-11-29 11:25:24 +10:00
loosewheel
6c8a60c3f7 Add files via upload 2021-11-29 11:24:38 +10:00
loosewheel
be384872dd Add files via upload 2021-11-29 11:22:46 +10:00
101 changed files with 11331 additions and 581 deletions

27
.luacheckrc Normal file
View File

@@ -0,0 +1,27 @@
unused_args = false
allow_defined_top = true
max_comment_line_length = 999
read_globals = {
"DIR_DELIM",
"minetest", "core",
"unpack",
"dump",
table = { fields = { "copy", "getn" } },
"vector", "nodeupdate",
"VoxelManip", "VoxelArea",
"PseudoRandom", "ItemStack",
"default",
"lwcomponents",
"intllib",
"mesecon",
"digiline",
"digilines",
"hopper",
"pipeworks",
"unifieddyes",
"digistuff",
}
globals = {
}

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 ()]
@@ -222,6 +222,35 @@ end
local function eject_item (pos, stack, eject_pos)
if utils.pipeworks_supported then
local node = utils.get_far_node (eject_pos)
if node and minetest.get_item_group (node.name, "tube") > 0 then
local owner = nil
local meta = minetest.get_meta (pos)
if meta then
local o = meta:get_string ("owner")
if o ~= "" then
owner = o
end
end
local vel = vector.subtract (eject_pos, pos)
pipeworks.tube_inject_item (pos, pos, vel, stack, owner)
return
end
end
utils.item_drop (stack, nil, eject_pos)
end
local function break_node (pos, range) local function break_node (pos, range)
local node = minetest.get_node_or_nil (pos) local node = minetest.get_node_or_nil (pos)
@@ -242,7 +271,7 @@ local function break_node (pos, range)
local eject_pos = get_breaker_side (pos, node.param2, "back") local eject_pos = get_breaker_side (pos, node.param2, "back")
for i = 1, #drops do for i = 1, #drops do
utils.item_drop (drops[i], nil, eject_pos) eject_item (pos, drops[i], eject_pos)
end end
add_wear (pos, wear) add_wear (pos, wear)
@@ -324,7 +353,7 @@ end
local function after_place_node (pos, placer, itemstack, pointed_thing) local function after_place_base (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
local spec = local spec =
"formspec_version[3]\n".. "formspec_version[3]\n"..
@@ -342,6 +371,13 @@ local function after_place_node (pos, placer, itemstack, pointed_thing)
inv:set_size ("tool", 1) inv:set_size ("tool", 1)
inv:set_width ("tool", 1) inv:set_width ("tool", 1)
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
after_place_base (pos, placer, itemstack, pointed_thing)
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
@@ -350,7 +386,7 @@ end
local function after_place_node_locked (pos, placer, itemstack, pointed_thing) local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
after_place_node (pos, placer, itemstack, pointed_thing) after_place_base (pos, placer, itemstack, pointed_thing)
if placer and placer:is_player () then if placer and placer:is_player () then
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
@@ -359,6 +395,8 @@ local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
meta:set_string ("infotext", "Breaker (owned by "..placer:get_player_name ()..")") meta:set_string ("infotext", "Breaker (owned by "..placer:get_player_name ()..")")
end end
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
end end
@@ -478,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
@@ -577,12 +614,126 @@ end
local function pipeworks_support ()
if utils.pipeworks_supported then
return
{
priority = 100,
input_inventory = "tool",
connect_sides = { left = 1, right = 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
return inv:add_item ("tool", stack)
end
return stack
end,
can_insert = function (pos, node, stack, direction)
if stack and not stack:is_empty () then
local def = utils.find_item_def (stack:get_name ())
if def and def.tool_capabilities then
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
if inv then
return inv:room_for_item ("tool", stack)
end
end
end
return false
end,
can_remove = function (pos, node, stack, dir)
-- returns the maximum number of items of that stack that can be removed
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
if inv then
local slots = inv:get_size ("tool")
for i = 1, slots, 1 do
local s = inv:get_stack ("tool", i)
if s and not s:is_empty () and utils.is_same_item (stack, s) then
return s:get_count ()
end
end
end
return 0
end,
remove_items = function (pos, node, stack, dir, count)
-- removes count items and returns them
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
local left = count
if inv then
local slots = inv:get_size ("tool")
for i = 1, slots, 1 do
local s = inv:get_stack ("tool", i)
if s and not s:is_empty () and utils.is_same_item (s, stack) then
if s:get_count () > left then
s:set_count (s:get_count () - left)
inv:set_stack ("tool", i, s)
left = 0
else
left = left - s:get_count ()
inv:set_stack ("tool", i, nil)
end
end
if left == 0 then
break
end
end
end
local result = ItemStack (stack)
result:set_count (count - left)
return result
end
}
end
return nil
end
local breaker_groups = { cracky = 3, wires_connect = 1 }
if utils.pipeworks_supported then
breaker_groups.tubedevice = 1
breaker_groups.tubedevice_receiver = 1
end
local breaker_on_groups = { cracky = 3, not_in_creative_inventory = 1, wires_connect = 1 }
if utils.pipeworks_supported then
breaker_on_groups.tubedevice = 1
breaker_on_groups.tubedevice_receiver = 1
end
minetest.register_node("lwcomponents:breaker", { minetest.register_node("lwcomponents:breaker", {
description = S("Breaker"), description = S("Breaker"),
tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png", tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png",
"lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face.png"}, "lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = table.copy (breaker_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -594,9 +745,11 @@ minetest.register_node("lwcomponents:breaker", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
after_place_node = after_place_node, after_place_node = after_place_node,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, on_timer = on_timer,
@@ -611,7 +764,7 @@ minetest.register_node("lwcomponents:breaker_locked", {
tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png", tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png",
"lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face.png"}, "lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = table.copy (breaker_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -623,9 +776,11 @@ minetest.register_node("lwcomponents:breaker_locked", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
after_place_node = after_place_node_locked, after_place_node = after_place_node_locked,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, on_timer = on_timer,
@@ -641,7 +796,7 @@ minetest.register_node("lwcomponents:breaker_on", {
tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png", tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png",
"lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face_on.png"}, "lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = table.copy (breaker_on_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -654,9 +809,11 @@ minetest.register_node("lwcomponents:breaker_on", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
after_place_node = after_place_node, after_place_node = after_place_node,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, on_timer = on_timer,
@@ -671,7 +828,7 @@ minetest.register_node("lwcomponents:breaker_locked_on", {
tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png", tiles = { "lwbreaker.png", "lwbreaker.png", "lwbreaker.png",
"lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face_on.png"}, "lwbreaker.png", "lwbreaker_rear.png", "lwbreaker_face_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = table.copy (breaker_on_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -684,9 +841,11 @@ minetest.register_node("lwcomponents:breaker_locked_on", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
after_place_node = after_place_node_locked, after_place_node = after_place_node_locked,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, on_timer = on_timer,

439
camera.lua Normal file
View File

@@ -0,0 +1,439 @@
local utils = ...
local S = utils.S
if utils.digilines_supported then
local function get_entity_dims (obj)
local dims = { -0.5, 0, -0.5, 0.5, 2, 0.5 }
local found = false
if obj.get_luaentity then
local entity = obj:get_luaentity ()
if entity and entity.name then
local def = minetest.registered_entities[entity.name]
if def and type (def.collisionbox) == "table" then
dims = { def.collisionbox[1] or -0.5,
def.collisionbox[2] or -0.5,
def.collisionbox[3] or -0.5,
def.collisionbox[4] or 0.5,
def.collisionbox[5] or 0.5,
def.collisionbox[6] or 0.5 }
found = true
end
end
end
if not found then
local props = obj:get_properties ()
if props and props.collisionbox and type (props.collisionbox) == "table" then
dims = { props.collisionbox[1] or -0.5,
props.collisionbox[2] or -0.5,
props.collisionbox[3] or -0.5,
props.collisionbox[4] or 0.5,
props.collisionbox[5] or 0.5,
props.collisionbox[6] or 0.5 }
end
end
dims[1] = math.min (dims[1], dims[3])
dims[3] = dims[1]
dims[4] = math.max (dims[4], dims[6])
dims[6] = dims[4]
if (dims[3] - dims[1]) < 1 then
dims[1] = -0.5
dims[3] = -0.5
dims[4] = 0.5
dims[6] = 0.5
end
return dims
end
local function get_entity (pos)
local objects = minetest.get_objects_inside_radius (pos, 2.0)
if #objects > 0 then
for _, obj in ipairs (objects) do
if obj.get_pos then
if obj:is_player () then
local epos = vector.round (obj:get_pos ())
if epos.x == pos.x and epos.z == pos.z and
(epos.y == pos.y or epos.y == pos.y - 1) then
return 1
end
end
if not utils.is_drop (obj) then
local epos = vector.new (obj:get_pos ())
local dims = get_entity_dims (obj)
if pos.x >= (epos.x + dims[1]) and pos.x <= (epos.x + dims[4]) and
pos.y >= (epos.y + dims[2]) and pos.y <= (epos.y + dims[5]) and
pos.z >= (epos.z + dims[3]) and pos.z <= (epos.z + dims[6]) then
return 2
end
end
end
end
end
return nil
end
local function camera_scan (pos, resolution, distance)
local node = utils.get_far_node (pos)
local image = { }
for y = 1, resolution, 1 do
image[y] = { }
for x = 1, resolution, 1 do
image[y][x] = "000000"
end
end
if node then
local dir = vector.multiply (minetest.facedir_to_dir (node.param2), -1)
local last_pos = nil
local last_color = "000000"
local view = (distance * 1.414213562) / resolution
for dist = distance, 1, -1 do
local scale = dist / distance
for y = 1, resolution, 1 do
for x = 1, resolution, 1 do
local horz = (x - (resolution / 2)) * scale * view
local vert = (y - (resolution / 2)) * scale * view
local tpos
if dir.x ~= 0 then
tpos = vector.round ({ x = (dist * dir.x) + pos.x, y = pos.y - vert, z = horz + pos.z })
else
tpos = vector.round ({ x = horz + pos.x, y = pos.y - vert, z = (dist * dir.z) + pos.z })
end
if last_pos and vector.equals (last_pos, tpos) then
if last_color then
image[y][x] = last_color
end
else
local entity = get_entity (tpos)
if entity == 1 then
local color = (((distance - dist) / distance) * 98) + 30
last_color = string.format ("00%02X00", color)
image[y][x] = last_color
elseif entity == 2 then
local color = (((distance - dist) / distance) * 98) + 30
last_color = string.format ("0000%02X", color)
image[y][x] = last_color
else
local tnode = utils.get_far_node (tpos)
if tnode and tnode.name ~= "air" then
local color = (((distance - dist) / distance) * 98) + 30
last_color = string.format ("%02X%02X%02X", color, color, color)
image[y][x] = last_color
else
last_color = nil
end
end
end
last_pos = tpos
end
end
end
end
return image
end
local function send_scan (pos)
local meta = minetest.get_meta (pos)
if meta then
local channel = meta:get_string ("channel")
if channel:len () > 0 then
local image = camera_scan (pos,
tonumber (meta:get_string ("resolution")),
tonumber (meta:get_string ("distance")))
utils.digilines_receptor_send (pos,
utils.digilines_default_rules,
channel,
image)
end
end
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos)
local spec =
"formspec_version[3]"..
"size[8.5,5.5;true]"..
"field[1.0,1.0;4.0,0.8;channel;Channel;${channel}]"..
"button[5.5,1.0;2.0,0.8;setchannel;Set]"..
"field[1.0,2.5;4.0,0.8;distance;Distance;${distance}]"..
"button[5.5,2.5;2.0,0.8;setdistance;Set]"..
"field[1.0,4.0;4.0,0.8;resolution;Resolution;${resolution}]"..
"button[5.5,4.0;2.0,0.8;setresolution;Set]"
meta:set_string ("formspec", spec)
meta:set_string ("distance", "5")
meta:set_string ("resolution", "16")
-- 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", "Camera (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
if fields.setdistance then
local meta = minetest.get_meta (pos)
if meta then
local distance = math.min (math.max (tonumber (fields.distance) or 1, 1), 16)
fields.distance = tostring (distance)
meta:set_string ("distance", tostring (distance))
end
end
if fields.setresolution then
local meta = minetest.get_meta (pos)
if meta then
local resolution = math.min (math.max (tonumber (fields.resolution) or 1, 1), 128)
fields.resolution = tostring (resolution)
meta:set_string ("resolution", tostring (resolution))
end
end
end
local function can_dig (pos, player)
if not utils.can_interact_with_node (pos, player) then
return false
end
return true
end
local function on_blast (pos, intensity)
local meta = minetest.get_meta (pos)
if meta then
if intensity >= 1.0 then
minetest.remove_node (pos)
else -- intensity < 1.0
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
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 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] == "scan" then
send_scan (pos)
elseif m[1] == "distance" then
local distance = math.min (math.max (tonumber (m[2] or 5) or 5, 1), 16)
meta:set_string ("distance", tostring (distance))
elseif m[1] == "resolution" then
local resolution = math.min (math.max (tonumber (m[2] or 16) or 16, 1), 128)
meta:set_string ("resolution", tostring (resolution))
end
end
end
end,
}
}
end
return nil
end
minetest.register_node("lwcomponents:camera", {
description = S("Camera"),
tiles = { "lwcamera.png", "lwcamera.png", "lwcamera.png",
"lwcamera.png", "lwcamera.png", "lwcamera_lens.png"},
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 0,
floodable = false,
drop = "lwcomponents:camera",
_digistuff_channelcopier_fieldname = "channel",
digiline = digilines_support (),
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node,
on_blast = on_blast,
on_rightclick = on_rightclick
})
minetest.register_node("lwcomponents:camera_locked", {
description = S("Camera (locked)"),
tiles = { "lwcamera.png", "lwcamera.png", "lwcamera.png",
"lwcamera.png", "lwcamera.png", "lwcamera_lens.png"},
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 0,
floodable = false,
drop = "lwcomponents:camera_locked",
_digistuff_channelcopier_fieldname = "channel",
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_rightclick = on_rightclick
})
end -- utils.digilines_supported
--

View File

@@ -5,7 +5,7 @@ local S = utils.S
local cannon_force = 20 local cannon_force = 20
local min_pitch = -20 local min_pitch = -20
local max_pitch = 50 local max_pitch = 70
local min_rotation = -60 local min_rotation = -60
local max_rotation = 60 local max_rotation = 60
@@ -15,7 +15,7 @@ local function get_cannon_barrel (pos)
local barrel_pos = { x = pos.x, y = pos.y + 0.65, z = pos.z } local barrel_pos = { x = pos.x, y = pos.y + 0.65, z = pos.z }
local objects = minetest.get_objects_inside_radius (barrel_pos, 0.1) local objects = minetest.get_objects_inside_radius (barrel_pos, 0.1)
for i = 1, #objects do for i = 1, #objects, 1 do
if not objects[i]:is_player () then if not objects[i]:is_player () then
if objects[i].get_luaentity and objects[i]:get_luaentity () and if objects[i].get_luaentity and objects[i]:get_luaentity () and
objects[i]:get_luaentity ().name and objects[i]:get_luaentity ().name and
@@ -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 }
@@ -298,6 +283,7 @@ local function process_controller_input (pos, input)
local pitch = input.pitch * -180 / math.pi local pitch = input.pitch * -180 / math.pi
local node_rot = vector.dir_to_rotation (minetest.facedir_to_dir ((node.param2 + 2) % 4)) local node_rot = vector.dir_to_rotation (minetest.facedir_to_dir ((node.param2 + 2) % 4))
local rot = (input.yaw - node_rot.y) * 180 / math.pi local rot = (input.yaw - node_rot.y) * 180 / math.pi
local sensitivity = (meta:get_string ("sensitive") == "true" and 3) or 1
while rot > 180 do while rot > 180 do
rot = rot - 360 rot = rot - 360
@@ -311,8 +297,8 @@ local function process_controller_input (pos, input)
rot = -rot rot = -rot
end end
set_barrel_pitch (pos, pitch * 3) set_barrel_pitch (pos, pitch * sensitivity)
set_barrel_rotation (pos, rot * 3) set_barrel_rotation (pos, rot * sensitivity)
if input.dig then if input.dig then
fire_cannon (pos) fire_cannon (pos)
@@ -323,15 +309,19 @@ end
local function get_formspec () local function get_formspec (pos)
local meta = minetest.get_meta (pos)
local sensitive = (meta and meta:get_string ("sensitive")) or "false"
return return
"formspec_version[3]\n".. "formspec_version[3]\n"..
"size[11.75,10.75;true]\n".. "size[11.75,10.75;true]\n"..
"field[1.0,1.0;4.0,0.8;channel;Channel;${channel}]\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".. "button[5.5,1.0;2.0,0.8;setchannel;Set]\n"..
"button[8.5,1.0;2.0,0.8;hide;Hide]\n".. "button[8.5,1.0;2.0,0.8;hide;Hide]\n"..
"field[1.0,3.0;4.0,0.8;controller;Controller;${controller}]\n".. "field[1.0,2.6;4.0,0.8;controller;Controller;${controller}]\n"..
"button[5.5,3.0;2.0,0.8;setcontroller;Set]\n".. "button[5.5,2.6;2.0,0.8;setcontroller;Set]\n"..
"checkbox[1.3,3.8;sensitive;Sensitive;"..sensitive.."]\n"..
"list[context;main;9.0,2.75;1,1;]\n".. "list[context;main;9.0,2.75;1,1;]\n"..
"list[current_player;main;1.0,5.0;8,4;]\n".. "list[current_player;main;1.0,5.0;8,4;]\n"..
"listring[]" "listring[]"
@@ -365,6 +355,7 @@ local function on_construct (pos)
if barrel then if barrel then
set_barrel_rotation (pos, 0) set_barrel_rotation (pos, 0)
set_barrel_pitch (pos, 0) set_barrel_pitch (pos, 0)
barrel:set_armor_groups ({ immortal = 1 })
end end
minetest.set_node (blank_pos, { name = "lwcomponents:cannon_blank" }) minetest.set_node (blank_pos, { name = "lwcomponents:cannon_blank" })
@@ -389,17 +380,26 @@ end
local function after_place_node (pos, placer, itemstack, pointed_thing) local function after_place_base (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
meta:set_string ("sensitive", "true")
meta:set_string ("inventory", "{ main = { } }") meta:set_string ("inventory", "{ main = { } }")
meta:set_string ("formspec", get_formspec ())
local inv = meta:get_inventory () local inv = meta:get_inventory ()
inv:set_size ("main", 1) inv:set_size ("main", 1)
inv:set_width ("main", 1) inv:set_width ("main", 1)
meta:set_string ("formspec", get_formspec (pos))
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
after_place_base (pos, placer, itemstack, pointed_thing)
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
end end
@@ -407,7 +407,7 @@ end
local function after_place_node_locked (pos, placer, itemstack, pointed_thing) local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
after_place_node (pos, placer, itemstack, pointed_thing) after_place_base (pos, placer, itemstack, pointed_thing)
if placer and placer:is_player () then if placer and placer:is_player () then
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
@@ -416,6 +416,8 @@ local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
meta:set_string ("infotext", "Cannon (owned by "..placer:get_player_name ()..")") meta:set_string ("infotext", "Cannon (owned by "..placer:get_player_name ()..")")
end end
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
end end
@@ -447,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
@@ -482,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
@@ -542,6 +544,15 @@ local function on_receive_fields (pos, formname, fields, sender)
meta:set_string ("formspec", "") meta:set_string ("formspec", "")
end end
end end
if fields.sensitive ~= nil then
local meta = minetest.get_meta (pos)
if meta then
meta:set_string ("sensitive", fields.sensitive)
meta:set_string ("formspec", get_formspec (pos))
end
end
end end
@@ -595,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)
@@ -660,29 +670,26 @@ local function on_rightclick (pos, node, clicker, itemstack, pointed_thing)
if hz == 0.5 and hy >= -0.5 and hy <= 0.2 then if hz == 0.5 and hy >= -0.5 and hy <= 0.2 then
local angle = get_barrel_angle (pos) local angle = get_barrel_angle (pos)
if hx >= -0.5 and hx <= -0.25 and hy >= -0.25 and hy <= -0.0625 then if angle then
-- left if hx >= -0.5 and hx <= -0.25 and hy >= -0.25 and hy <= -0.0625 then
set_barrel_rotation (pos, angle.y + inc) -- left
set_barrel_rotation (pos, angle.y + inc)
elseif hx >= 0.25 and hx <= 0.5 and hy >= -0.25 and hy <= -0.0625 then elseif hx >= 0.25 and hx <= 0.5 and hy >= -0.25 and hy <= -0.0625 then
-- right -- right
set_barrel_rotation (pos, angle.y - inc) set_barrel_rotation (pos, angle.y - inc)
elseif hx >= -0.125 and hx <= 0.125 and hy >= 0.0 and hy <= 0.1875 then
elseif hx >= -0.125 and hx <= 0.125 and hy >= 0.0 and hy <= 0.1875 then -- up
-- up set_barrel_pitch (pos, angle.x + inc)
set_barrel_pitch (pos, angle.x + inc) elseif hx >= -0.125 and hx <= 0.125 and hy >= -0.5 and hy <= -0.3125 then
-- down
elseif hx >= -0.125 and hx <= 0.125 and hy >= -0.5 and hy <= -0.3125 then set_barrel_pitch (pos, angle.x - inc)
-- down elseif hx >= -0.125 and hx <= 0.125 and hy >= -0.25 and hy <= -0.0625 then
set_barrel_pitch (pos, angle.x - inc) -- fire
fire_cannon (pos)
elseif hx >= -0.125 and hx <= 0.125 and hy >= -0.25 and hy <= -0.0625 then end
-- fire
fire_cannon (pos)
end end
else else
meta:set_string ("formspec", get_formspec ()) meta:set_string ("formspec", get_formspec (pos))
end end
end end
end end
@@ -824,6 +831,106 @@ end
local function pipeworks_support ()
if utils.pipeworks_supported then
return
{
priority = 100,
input_inventory = "main",
connect_sides = { left = 1, right = 1, front = 1, back = 1, bottom = 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
return inv:add_item ("main", 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 ("main", 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
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
if inv then
local slots = inv:get_size ("main")
for i = 1, slots, 1 do
local s = inv:get_stack ("main", i)
if s and not s:is_empty () and utils.is_same_item (stack, s) then
return s:get_count ()
end
end
end
return 0
end,
remove_items = function (pos, node, stack, dir, count)
-- removes count items and returns them
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
local left = count
if inv then
local slots = inv:get_size ("main")
for i = 1, slots, 1 do
local s = inv:get_stack ("main", i)
if s and not s:is_empty () and utils.is_same_item (s, stack) then
if s:get_count () > left then
s:set_count (s:get_count () - left)
inv:set_stack ("main", i, s)
left = 0
else
left = left - s:get_count ()
inv:set_stack ("main", i, nil)
end
end
if left == 0 then
break
end
end
end
local result = ItemStack (stack)
result:set_count (count - left)
return result
end
}
end
return nil
end
local cannon_groups = { cracky = 3, wires_connect = 1 }
if utils.pipeworks_supported then
cannon_groups.tubedevice = 1
cannon_groups.tubedevice_receiver = 1
end
minetest.register_node("lwcomponents:cannon_blank", { minetest.register_node("lwcomponents:cannon_blank", {
description = S("Cannon blank"), description = S("Cannon blank"),
drawtype = "airlike", drawtype = "airlike",
@@ -839,6 +946,8 @@ minetest.register_node("lwcomponents:cannon_blank", {
drop = "", drop = "",
groups = { not_in_creative_inventory = 1 }, groups = { not_in_creative_inventory = 1 },
paramtype = "light", paramtype = "light",
-- unaffected by explosions
on_blast = function() end,
}) })
@@ -858,6 +967,8 @@ minetest.register_node("lwcomponents:cannon_blank_fire", {
drop = "", drop = "",
groups = { not_in_creative_inventory = 1 }, groups = { not_in_creative_inventory = 1 },
paramtype = "light", paramtype = "light",
-- unaffected by explosions
on_blast = function() end,
}) })
@@ -877,7 +988,7 @@ minetest.register_node("lwcomponents:cannon", {
type = "fixed", type = "fixed",
fixed = { fixed = {
{ -0.09, 0, -0.09, 0.09, 0.5, 0.09 }, { -0.09, 0, -0.09, 0.09, 0.5, 0.09 },
{ -0.5, -0.1875, -0.5, 0.5, 0.125, 0.5 }, { -0.5, -0.25, -0.5, 0.5, 0.125, 0.5 },
{ -0.4375, -0.1875, -0.4375, 0.4375, 0.1875, 0.5 }, { -0.4375, -0.1875, -0.4375, 0.4375, 0.1875, 0.5 },
{ -0.5, -0.5, 0.3125, 0.5, 0.125, 0.5 }, { -0.5, -0.5, 0.3125, 0.5, 0.125, 0.5 },
{ -0.5, -0.5, -0.5, -0.3125, 0.125, -0.3125 }, { -0.5, -0.5, -0.5, -0.3125, 0.125, -0.3125 },
@@ -899,7 +1010,7 @@ minetest.register_node("lwcomponents:cannon", {
wield_image = "lwcannon_item.png", wield_image = "lwcannon_item.png",
inventory_image = "lwcannon_item.png", inventory_image = "lwcannon_item.png",
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = table.copy (cannon_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
@@ -910,12 +1021,14 @@ minetest.register_node("lwcomponents:cannon", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_construct = on_construct, on_construct = on_construct,
on_destruct = on_destruct, on_destruct = on_destruct,
on_place = on_place, on_place = on_place,
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
after_place_node = after_place_node, after_place_node = after_place_node,
on_blast = on_blast, on_blast = on_blast,
on_rightclick = on_rightclick, on_rightclick = on_rightclick,
@@ -939,7 +1052,7 @@ minetest.register_node("lwcomponents:cannon_locked", {
type = "fixed", type = "fixed",
fixed = { fixed = {
{ -0.09, 0, -0.09, 0.09, 0.5, 0.09 }, { -0.09, 0, -0.09, 0.09, 0.5, 0.09 },
{ -0.5, -0.1875, -0.5, 0.5, 0.125, 0.5 }, { -0.5, -0.25, -0.5, 0.5, 0.125, 0.5 },
{ -0.4375, -0.1875, -0.4375, 0.4375, 0.1875, 0.5 }, { -0.4375, -0.1875, -0.4375, 0.4375, 0.1875, 0.5 },
{ -0.5, -0.5, 0.3125, 0.5, 0.125, 0.5 }, { -0.5, -0.5, 0.3125, 0.5, 0.125, 0.5 },
{ -0.5, -0.5, -0.5, -0.3125, 0.125, -0.3125 }, { -0.5, -0.5, -0.5, -0.3125, 0.125, -0.3125 },
@@ -961,7 +1074,7 @@ minetest.register_node("lwcomponents:cannon_locked", {
wield_image = "lwcannon_item.png", wield_image = "lwcannon_item.png",
inventory_image = "lwcannon_item.png", inventory_image = "lwcannon_item.png",
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = table.copy (cannon_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
@@ -972,12 +1085,14 @@ minetest.register_node("lwcomponents:cannon_locked", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_construct = on_construct, on_construct = on_construct,
on_destruct = on_destruct, on_destruct = on_destruct,
on_place = on_place_locked, on_place = on_place_locked,
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
after_place_node = after_place_node_locked, after_place_node = after_place_node_locked,
on_blast = on_blast, on_blast = on_blast,
on_rightclick = on_rightclick, on_rightclick = on_rightclick,
@@ -1023,6 +1138,10 @@ minetest.register_entity ("lwcomponents:cannon_barrel", {
on_punch = function (self, puncher, time_from_last_punch, tool_capabilities, dir) on_punch = function (self, puncher, time_from_last_punch, tool_capabilities, dir)
return true return true
end, end,
on_blast = function (self, damage)
return false, false, nil
end,
}) })

297
cannon_shell.lua Normal file
View File

@@ -0,0 +1,297 @@
local utils = ...
local S = utils.S
--[[
on_step info
info.touching_ground = bool
info.standing_on_object = bool
info.collides = bool
info.collisions[n].type = "node"
info.collisions[n].node_pos = vector
info.collisions[n].old_velocity = vector
info.collisions[n].now_velocity = vector
info.collisions[n].axis = "x" | "y" | "z" - axis hit
or
info.collisions[n].type = "object"
info.collisions[n].object = userdata
info.collisions[n].old_velocity = vector
info.collisions[n].now_velocity = vector
info.collisions[n].axis = "x" | "y" | "z" - axis hit
]]
local function get_adjacent_node (collision_info, spawn_pos)
if vector.equals (collision_info.node_pos, spawn_pos) then
return collision_info.node_pos
end
local adj = { x = 0, y = 0, z = 0 }
if collision_info.axis == "x" then
adj.x = (collision_info.old_velocity.x > 0 and -1) or 1
elseif collision_info.axis == "y" then
adj.y = (collision_info.old_velocity.y > 0 and -1) or 1
elseif collision_info.axis == "z" then
adj.z = (collision_info.old_velocity.z > 0 and -1) or 1
end
local pos = vector.new (collision_info.node_pos)
local node = utils.get_far_node (pos)
local def = minetest.registered_nodes[node and node.name or nil]
while (node and node.name ~= "air") and (def and not def.buildable_to) do
local next_pos = vector.add (pos, adj)
if vector.equals (next_pos, spawn_pos) then
return pos
end
pos = next_pos
node = utils.get_far_node (pos)
def = minetest.registered_nodes[node and node.name or nil]
end
return pos
end
local function register_shell (name, description, texture, inventory_image,
stack_max, shell_speed, explode_func)
minetest.register_entity (name.."_entity", {
initial_properties = {
physical = true,
collide_with_objects = true,
collisionbox = { -0.25, -0.125, -0.25, 0.25, 0.125, 0.25 },
pointable = false,
visual_size = { x = 0.7, y = 0.7, z = 0.7 },
visual = "mesh",
mesh = "lwcomponents_shell.obj",
textures = { texture },
use_texture_alpha = false,
is_visible = true,
makes_footstep_sound = false,
automatic_face_movement_dir = false,
automatic_face_movement_max_rotation_per_sec = false,
automatic_rotate = 0,
backface_culling = true,
damage_texture_modifier = "",
glow = 0,
static_save = false,
shaded = true,
show_on_minimap = false,
},
on_activate = function (self, staticdata, dtime_s)
if not self.spawn_pos then
self.spawn_pos = vector.new (self.object:get_pos ())
end
if not self.time_lived then
self.time_lived = 0
end
if not self.shell_speed then
self.shell_speed = shell_speed
end
self.staticdata = staticdata
end,
get_staticdata = function (self)
return self.staticdata
end,
on_step = function (self, dtime, info)
local explode_pos = nil
self.object:set_rotation (vector.dir_to_rotation (self.object:get_velocity ()))
if self.time_lived then
self.time_lived = self.time_lived + dtime
if self.time_lived > self.shell_speed then
self.object:remove ()
return
end
end
if info.collides then
--For each collision that was found in reverse order
for i = #info.collisions, 1, -1 do
local c = info.collisions[i]
if c.type == "node" then
local node = utils.get_far_node (c.node_pos)
if node and node.name ~= "air" then
local def = minetest.registered_nodes[node.name]
if def and def.walkable then
-- adjacent for explosion
explode_pos = get_adjacent_node (c, self.spawn_pos)
--minetest.log ("action", "Shell on node "..node.name.." at "..minetest.pos_to_string (explode_pos)..
--" node at "..minetest.pos_to_string (c.node_pos))
break
end
end
if not explode_pos then
self.object:set_velocity (c.old_velocity)
end
elseif c.type == "object" then
local c_name = (c.object.get_luaentity and
c.object:get_luaentity () and
c.object:get_luaentity ().name) or ""
local s_name = (self.name) or ""
-- explode at this pos
if c.object:get_armor_groups ().immortal or s_name == c_name then
self.object:set_velocity (c.old_velocity)
else
explode_pos = vector.new (c.object:get_pos ())
--minetest.log ("action", "Shell on entity "..c.object:get_luaentity ().name.." at "..minetest.pos_to_string (explode_pos))
break
end
end
end
end
if explode_pos then
self.object:remove ()
explode_func (explode_pos)
end
end,
on_punch = function (self, puncher, time_from_last_punch, tool_capabilities, dir)
return true
end,
})
minetest.register_craftitem (name, {
description = description,
short_description = description,
groups = { },
inventory_image = inventory_image,
wield_image = inventory_image,
stack_max = stack_max,
})
lwcomponents.register_spawner (name,
function (spawn_pos, itemstack, owner, spawner_pos, spawner_dir, force)
if not itemstack:is_empty() then
local def = minetest.registered_entities[name.."_entity"]
if def then
local obj = minetest.add_entity (spawn_pos, name.."_entity")
if obj then
obj:set_acceleration ({ x = 0, y = -9.81, z = 0 })
obj:set_rotation (vector.dir_to_rotation (vector.multiply (spawner_dir, shell_speed)))
obj:set_velocity (vector.multiply (spawner_dir, shell_speed))
local luaent = obj:get_luaentity ()
if luaent then
luaent.spawn_pos = { x = spawn_pos.x, y = spawn_pos.y, z = spawn_pos.z }
luaent.time_lived = 0
luaent.shell_speed = shell_speed
end
return obj, false
end
end
end
return nil, false
end)
end
register_shell ("lwcomponents:cannon_shell",
S("Shell"),
"lwcannon_shell.png",
"lwcannon_shell_item.png",
99,
25,
function (pos)
utils.boom (pos,
2, -- node_radius
70, -- node_chance in 100
2, -- fire_radius
5, -- fire_chance in 100
4, -- entity_radius
20, -- entity_damage
false, -- disable_drops
nil, -- node_filter
false, -- burn_all
nil) -- sound
end)
register_shell ("lwcomponents:cannon_soft_shell",
S("Soft Shell"),
"lwcannon_soft_shell.png",
"lwcannon_soft_shell_item.png",
99,
25,
function (pos)
utils.boom (pos,
2, -- node_radius
50, -- node_chance in 100
2, -- fire_radius
5, -- fire_chance in 100
4, -- entity_radius
20, -- entity_damage
false, -- disable_drops
{
buildable_to = true,
buildable_to_undefined = false,
}, -- node_filter
false, -- burn_all
nil) -- sound
end)
if minetest.global_exists ("fire") then
register_shell ("lwcomponents:cannon_fire_shell",
S("Fire Shell"),
"lwcannon_fire_shell.png",
"lwcannon_fire_shell_item.png",
99,
25,
function (pos)
utils.boom (pos,
2, -- node_radius
0, -- node_chance in 100
2, -- fire_radius
70, -- fire_chance in 100
4, -- entity_radius
20, -- entity_damage
false, -- disable_drops
nil, -- node_filter
true, -- burn_all
nil) -- sound
end)
end
--

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
@@ -67,3 +67,107 @@ v0.1.10
v0.1.11 v0.1.11
* Fix to breakers (?). * Fix to breakers (?).
* Added position aiming to cannons. * Added position aiming to cannons.
v0.1.12
* Added sensitivity option for game controller in cannons.
* Added cannon shells.
* Fixed bug in utils.is_creative.
* Increased cannon pitch to -20 to 70.
v0.1.13
* Removed optional dependency lwdrops.
v0.1.14
* Calls on_drop when item is dropped.
v0.1.15
* Fixed bug call to clear_map in fan on_blast.
* Added pistons.
v0.1.16
* Fixed piston interaction with non-walkable nodes.
v0.1.17
* Fixed unintended global variable in pistons.lua.
v0.1.18
* Added mesecons through wire.
v0.1.19
* Added camera.
v0.1.20
* Valid distance and resolution for camera set by digilines message.
* Imposed maximum resolution of 128 for cameras.
v0.1.21
* Minor bug fix, movefloor global.
* Fixed movefloor so player doesn't fall through floor.
* Transfer timer in moved nodes for pistons.
v0.1.22
* Added storage.
v0.1.23
* Fixed storage indexer not taking items from storage properly.
* Added pipeworks support for:
Storage Indexer
Dropper
Collector
Dispenser
Breaker
Deployer
Cannon
Conduit
* Conduits now work in unloaded blocks.
* Fixed conduits sending items in groups.
* Fixed player attached to controller moving forever when they get blown up.
* Fixed pistons being powered from the pusher side.
v0.1.24
* Limited requested count from storage indexer from digilines message to max stack.
* Fixed receptor state in detector.
* Fixed receptor state in digiswitch.
* Fixed bug in utils.is_same_item ().
* Added force field generators.
* 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.
v0.1.28
* Added support for lwwires. Wires will not connect to conduits.

View File

@@ -148,7 +148,7 @@ end
local function after_place_node (pos, placer, itemstack, pointed_thing) local function after_place_base (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
local is_off = itemstack and (itemstack:get_name () == "lwcomponents:collector" or local is_off = itemstack and (itemstack:get_name () == "lwcomponents:collector" or
itemstack:get_name () == "lwcomponents:collector_locked") itemstack:get_name () == "lwcomponents:collector_locked")
@@ -162,6 +162,13 @@ local function after_place_node (pos, placer, itemstack, pointed_thing)
inv:set_width ("main", 4) inv:set_width ("main", 4)
inv:set_size ("filter", 8) inv:set_size ("filter", 8)
inv:set_width ("filter", 2) inv:set_width ("filter", 2)
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
after_place_base (pos, placer, itemstack, pointed_thing)
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
@@ -170,7 +177,7 @@ end
local function after_place_node_locked (pos, placer, itemstack, pointed_thing) local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
after_place_node (pos, placer, itemstack, pointed_thing) after_place_base (pos, placer, itemstack, pointed_thing)
if placer and placer:is_player () then if placer and placer:is_player () then
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
@@ -179,6 +186,8 @@ local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
meta:set_string ("infotext", "Collector (owned by "..placer:get_player_name ()..")") meta:set_string ("infotext", "Collector (owned by "..placer:get_player_name ()..")")
end end
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
end end
@@ -307,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)
@@ -427,12 +435,120 @@ end
local function pipeworks_support ()
if utils.pipeworks_supported then
return
{
priority = 100,
input_inventory = "main",
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
return inv:add_item ("main", 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 ("main", 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
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
if inv then
local slots = inv:get_size ("main")
for i = 1, slots, 1 do
local s = inv:get_stack ("main", i)
if s and not s:is_empty () and utils.is_same_item (stack, s) then
return s:get_count ()
end
end
end
return 0
end,
remove_items = function (pos, node, stack, dir, count)
-- removes count items and returns them
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
local left = count
if inv then
local slots = inv:get_size ("main")
for i = 1, slots, 1 do
local s = inv:get_stack ("main", i)
if s and not s:is_empty () and utils.is_same_item (s, stack) then
if s:get_count () > left then
s:set_count (s:get_count () - left)
inv:set_stack ("main", i, s)
left = 0
else
left = left - s:get_count ()
inv:set_stack ("main", i, nil)
end
end
if left == 0 then
break
end
end
end
local result = ItemStack (stack)
result:set_count (count - left)
return result
end
}
end
return nil
end
local collector_groups = { cracky = 3 }
if utils.pipeworks_supported then
collector_groups.tubedevice = 1
collector_groups.tubedevice_receiver = 1
end
local collector_on_groups = { cracky = 3, not_in_creative_inventory = 1 }
if utils.pipeworks_supported then
collector_on_groups.tubedevice = 1
collector_on_groups.tubedevice_receiver = 1
end
minetest.register_node("lwcomponents:collector", { minetest.register_node("lwcomponents:collector", {
description = S("Collector"), description = S("Collector"),
tiles = { "lwcollector.png", "lwcollector.png", "lwcollector.png", tiles = { "lwcollector.png", "lwcollector.png", "lwcollector.png",
"lwcollector.png", "lwcollector.png", "lwcollector.png"}, "lwcollector.png", "lwcollector.png", "lwcollector.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = table.copy (collector_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -441,11 +557,13 @@ minetest.register_node("lwcomponents:collector", {
_digistuff_channelcopier_fieldname = "channel", _digistuff_channelcopier_fieldname = "channel",
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_destruct = on_destruct, on_destruct = on_destruct,
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
after_place_node = after_place_node, after_place_node = after_place_node,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, on_timer = on_timer,
on_rightclick = on_rightclick on_rightclick = on_rightclick
@@ -458,7 +576,7 @@ minetest.register_node("lwcomponents:collector_locked", {
tiles = { "lwcollector.png", "lwcollector.png", "lwcollector.png", tiles = { "lwcollector.png", "lwcollector.png", "lwcollector.png",
"lwcollector.png", "lwcollector.png", "lwcollector.png"}, "lwcollector.png", "lwcollector.png", "lwcollector.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = table.copy (collector_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -467,11 +585,13 @@ minetest.register_node("lwcomponents:collector_locked", {
_digistuff_channelcopier_fieldname = "channel", _digistuff_channelcopier_fieldname = "channel",
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_destruct = on_destruct, on_destruct = on_destruct,
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
after_place_node = after_place_node_locked, after_place_node = after_place_node_locked,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, on_timer = on_timer,
on_rightclick = on_rightclick on_rightclick = on_rightclick
@@ -484,7 +604,7 @@ minetest.register_node("lwcomponents:collector_on", {
tiles = { "lwcollector_on.png", "lwcollector_on.png", "lwcollector_on.png", tiles = { "lwcollector_on.png", "lwcollector_on.png", "lwcollector_on.png",
"lwcollector_on.png", "lwcollector_on.png", "lwcollector_on.png"}, "lwcollector_on.png", "lwcollector_on.png", "lwcollector_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = table.copy (collector_on_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -493,11 +613,13 @@ minetest.register_node("lwcomponents:collector_on", {
_digistuff_channelcopier_fieldname = "channel", _digistuff_channelcopier_fieldname = "channel",
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_destruct = on_destruct, on_destruct = on_destruct,
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
after_place_node = after_place_node, after_place_node = after_place_node,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, on_timer = on_timer,
on_rightclick = on_rightclick on_rightclick = on_rightclick
@@ -510,7 +632,7 @@ minetest.register_node("lwcomponents:collector_locked_on", {
tiles = { "lwcollector_on.png", "lwcollector_on.png", "lwcollector_on.png", tiles = { "lwcollector_on.png", "lwcollector_on.png", "lwcollector_on.png",
"lwcollector_on.png", "lwcollector_on.png", "lwcollector_on.png"}, "lwcollector_on.png", "lwcollector_on.png", "lwcollector_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = table.copy (collector_on_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -519,11 +641,13 @@ minetest.register_node("lwcomponents:collector_locked_on", {
_digistuff_channelcopier_fieldname = "channel", _digistuff_channelcopier_fieldname = "channel",
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_destruct = on_destruct, on_destruct = on_destruct,
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
after_place_node = after_place_node_locked, after_place_node = after_place_node_locked,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, on_timer = on_timer,
on_rightclick = on_rightclick on_rightclick = on_rightclick

View File

@@ -3,15 +3,15 @@ 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
local run_initialize = nil
local function get_target_list (pos) local function get_target_list (pos)
local tlist = conduit_connections:get_connected_ids (pos) local tlist = conduit_connections:get_connected_ids (pos)
@@ -51,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)
@@ -62,15 +90,18 @@ local function deliver_slot (pos, slot)
local item = inv:get_stack ("transfer", slot) local item = inv:get_stack ("transfer", slot)
if transfer_data[slot] and item and not item:is_empty () then if transfer_data[slot] and item and not item:is_empty () then
local tmeta = minetest.get_meta (transfer_data[slot].pos) local tnode = utils.get_far_node (transfer_data[slot].pos)
if tmeta then if tnode and (tnode.name == "lwcomponents:conduit" or
local tinv = tmeta:get_inventory () tnode.name == "lwcomponents:conduit_locked") then
local tmeta = minetest.get_meta (transfer_data[slot].pos)
if tinv then if tmeta then
tinv:add_item ("main", item) local tinv = tmeta:get_inventory ()
--send_conduit_message (pos, target, slot) if tinv then
tinv:add_item ("main", item)
end
end end
end end
end end
@@ -138,7 +169,7 @@ end
local function delivered_earliest (pos) local function deliver_earliest (pos)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
if meta then if meta then
@@ -194,7 +225,8 @@ local function add_to_send_list (pos, item, destpos, distance)
local slot = get_transfer_free_slot (pos) local slot = get_transfer_free_slot (pos)
while slot < 1 do while slot < 1 do
delivered_earliest (pos) deliver_earliest (pos)
slot = get_transfer_free_slot (pos)
end end
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
@@ -210,15 +242,11 @@ local function add_to_send_list (pos, item, destpos, distance)
due = minetest.get_us_time () + (transfer_rate * 1000000 * distance) due = minetest.get_us_time () + (transfer_rate * 1000000 * distance)
} }
inv:add_item ("transfer", item) inv:set_stack ("transfer", slot, item)
meta:set_string ("transfer_data", minetest.serialize (transfer_data)) meta:set_string ("transfer_data", minetest.serialize (transfer_data))
local timer = minetest.get_node_timer (pos) run_initialize (pos)
if not timer:is_started () then
timer:start (conduit_interval)
end
end end
end end
end end
@@ -231,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")
@@ -241,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
@@ -271,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)
@@ -292,8 +322,6 @@ local function send_to_target (pos, target, slot)
stack:set_count (stack:get_count () - 1) stack:set_count (stack:get_count () - 1)
inv:set_stack ("main", slot, stack) inv:set_stack ("main", slot, stack)
--send_conduit_message (pos, target, slot)
return true, target, slot return true, target, slot
end end
end end
@@ -309,42 +337,173 @@ 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 function get_formspec (pos)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
local automatic = "false" local automatic = "false"
local filters = ""
if meta then if meta then
automatic = meta:get_string ("automatic") automatic = meta:get_string ("automatic")
end 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 return
"formspec_version[3]\n".. "formspec_version[3]"..
"size[11.75,12.25;true]\n".. "size[18.4,12.25;true]"..
"field[1.0,1.5;3.0,0.8;channel;Channel;${channel}]\n".. "field[1.0,1.5;3.0,0.8;channel;Channel;${channel}]"..
"button[4.2,1.5;1.5,0.8;setchannel;Set]\n".. "button[4.2,1.5;1.5,0.8;setchannel;Set]"..
"field[1.0,3.0;3.0,0.8;target;Target;${target}]\n".. "field[1.0,3.0;3.0,0.8;target;Target;${target}]"..
"button[4.2,3.0;1.5,0.8;settarget;Set]\n".. "button[4.2,3.0;1.5,0.8;settarget;Set]"..
"checkbox[1.0,4.5;automatic;Automatic;"..automatic.."]\n".. "checkbox[1.0,4.5;automatic;Automatic;"..automatic.."]"..
"list[context;main;6.0,1.0;4,4;]\n".. "list[context;main;6.0,1.0;4,4;]"..
"list[current_player;main;1.0,6.5;8,4;]\n".. "list[current_player;main;1.0,6.5;8,4;]"..
"listring[]" "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 node = utils.get_far_node (pos)
if node then
if node.name == "lwcomponents:conduit" or
node.name == "lwcomponents:conduit_locked" then
local meta = minetest.get_meta (pos)
if meta and id == meta:get_int ("conduit_id") then
local automatic = meta:get_string ("automatic") == "true"
if automatic then
send_to_target (pos)
end
if run_deliveries (pos) or automatic then
minetest.after (conduit_interval, run_conduit, pos, id)
else
meta:set_int ("run_active", 0)
end
end
else
conduit_connections:remove_node (pos)
end
end
end
run_initialize = function (pos)
local meta = minetest.get_meta (pos)
if meta then
if meta:get_int ("run_active") == 0 then
meta:set_int ("run_active", 1)
minetest.after (conduit_interval, run_conduit, pos, meta:get_int ("conduit_id"))
end
end
end
local function count_table_keys (t)
local count = 0
for k, v in pairs (t) do
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 end
@@ -362,7 +521,7 @@ end
local function after_place_node (pos, placer, itemstack, pointed_thing) local function after_place_base (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
local spec = local spec =
"formspec_version[3]".. "formspec_version[3]"..
@@ -370,10 +529,11 @@ local function after_place_node (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")
meta:set_int ("conduit_id", math.random (1000000))
local inv = meta:get_inventory () local inv = meta:get_inventory ()
@@ -383,6 +543,16 @@ local function after_place_node (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
local function after_place_node (pos, placer, itemstack, pointed_thing)
after_place_base (pos, placer, itemstack, pointed_thing)
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
end end
@@ -390,7 +560,7 @@ end
local function after_place_node_locked (pos, placer, itemstack, pointed_thing) local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
after_place_node (pos, placer, itemstack, pointed_thing) after_place_base (pos, placer, itemstack, pointed_thing)
if placer and placer:is_player () then if placer and placer:is_player () then
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
@@ -399,6 +569,8 @@ local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
meta:set_string ("infotext", "Conduit (owned by "..placer:get_player_name ()..")") meta:set_string ("infotext", "Conduit (owned by "..placer:get_player_name ()..")")
end end
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
end end
@@ -492,10 +664,22 @@ 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))
local timer = minetest.get_node_timer (pos) if fields.automatic == "true" then
meta:set_int ("run_active", 0)
end
if not timer:is_started () then run_initialize (pos)
timer:start (conduit_interval) 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 end
@@ -552,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)
@@ -592,8 +775,83 @@ end
local function on_timer (pos, elapsed) local function allow_metadata_inventory_put (pos, listname, index, stack, player)
return run_conduit (pos) 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 end
@@ -631,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
@@ -671,14 +932,151 @@ end
local function pipeworks_support ()
if utils.pipeworks_supported then
return
{
priority = 100,
input_inventory = "main",
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
return inv:add_item ("main", 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 ("main", 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
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
if inv then
local slots = inv:get_size ("main")
for i = 1, slots, 1 do
local s = inv:get_stack ("main", i)
if s and not s:is_empty () and utils.is_same_item (stack, s) then
return s:get_count ()
end
end
end
return 0
end,
remove_items = function (pos, node, stack, dir, count)
-- removes count items and returns them
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
local left = count
if inv then
local slots = inv:get_size ("main")
for i = 1, slots, 1 do
local s = inv:get_stack ("main", i)
if s and not s:is_empty () and utils.is_same_item (s, stack) then
if s:get_count () > left then
s:set_count (s:get_count () - left)
inv:set_stack ("main", i, s)
left = 0
else
left = left - s:get_count ()
inv:set_stack ("main", i, nil)
end
end
if left == 0 then
break
end
end
end
local result = ItemStack (stack)
result:set_count (count - left)
return result
end
}
end
return nil
end
local conduit_groups = { cracky = 3, wires_connect = 1 }
if utils.pipeworks_supported then
conduit_groups.tubedevice = 1
conduit_groups.tubedevice_receiver = 1
end
minetest.register_node("lwcomponents:conduit", { minetest.register_node("lwcomponents:conduit", {
description = S("Conduit"), description = S("Conduit"),
drawtype = "glasslike_framed", short_description = S("Conduit"),
tiles = { "lwconduit_edge.png", "lwconduit.png" }, tiles = { "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 = { cracky = 3 }, 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,
@@ -687,27 +1085,69 @@ minetest.register_node("lwcomponents:conduit", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_construct = on_construct, on_construct = on_construct,
on_destruct = on_destruct, on_destruct = on_destruct,
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
after_place_node = after_place_node, after_place_node = after_place_node,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, 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", short_description = S("Conduit (locked)"),
tiles = { "lwconduit_edge.png", "lwconduit.png" }, tiles = { "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 = { cracky = 3 }, 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,
@@ -716,15 +1156,19 @@ minetest.register_node("lwcomponents:conduit_locked", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_construct = on_construct, on_construct = on_construct,
on_destruct = on_destruct, on_destruct = on_destruct,
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
after_place_node = after_place_node_locked, after_place_node = after_place_node_locked,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, 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
}) })
@@ -745,4 +1189,79 @@ utils.hopper_add_container({
end -- utils.digilines_supported or utils.mesecon_supported -- legacy code v0.1.23 (24-2-22)
local function convert_conduits ()
local list = conduit_connections:get_full_list ()
for _, data in ipairs (list) do
local node = utils.get_far_node (data.pos)
if node and (node.name == "lwcomponents:conduit" or
node.name == "lwcomponents:conduit_locked") then
local meta = minetest.get_meta (data.pos)
if meta then
if meta:get_int ("conduit_id") == 0 then
meta:set_int ("conduit_id", math.random (1000000))
if meta:get_string ("automatic") == "true" then
meta:set_int ("run_active", 1)
else
local inv = meta:get_inventory ()
if inv and not inv:is_empty ("transfer") then
meta:set_int ("run_active", 1)
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
local function restart_conduits ()
convert_conduits ()
local list = conduit_connections:get_id_list ()
for _, data in ipairs (list) do
local meta = minetest.get_meta (data.pos)
if meta and meta:get_int ("run_active") ~= 0 then
minetest.after (conduit_interval + (math.random (10) / 10),
run_conduit, data.pos, meta:get_int ("conduit_id"))
end
end
end
minetest.register_on_mods_loaded (function ()
minetest.after (3.0, restart_conduits)
end)
--

View File

@@ -293,6 +293,40 @@ end
function connections:get_id_list ()
local list = { }
for spos, data in pairs (self.connector_list) do
if data.id then
list[#list + 1] =
{
pos = minetest.string_to_pos (spos),
id = data.id
}
end
end
return list
end
function connections:get_full_list ()
local list = { }
for spos, data in pairs (self.connector_list) do
list[#list + 1] =
{
pos = minetest.string_to_pos (spos),
id = data.id
}
end
return list
end
return connections return connections

View File

@@ -1,5 +1,4 @@
local utils = ... local utils = ...
local S = utils.S
@@ -23,6 +22,151 @@ minetest.register_craft( {
}) })
minetest.register_craft( {
output = "lwcomponents:storage_unit 2",
recipe = {
{ "default:steel_ingot", "group:wood", "group:wood" },
{ "group:wood", "", "group:wood" },
{ "group:wood", "group:wood", "default:chest" },
},
})
minetest.register_craft( {
output = "lwcomponents:storage_unit_locked 2",
recipe = {
{ "default:steel_ingot", "group:wood", "group:wood" },
{ "group:wood", "", "group:wood" },
{ "group:wood", "group:wood", "default:chest_locked" },
},
})
minetest.register_craft( {
output = "lwcomponents:storage_indexer",
recipe = {
{ "default:steel_ingot", "group:wood" },
{ "group:wood", "default:chest" }
},
})
minetest.register_craft( {
output = "lwcomponents:storage_indexer_locked",
recipe = {
{ "default:steel_ingot", "group:wood" },
{ "group:wood", "default:chest_locked" }
},
})
minetest.register_craft( {
output = "lwcomponents:force_field",
recipe = {
{ "default:steel_ingot", "default:mese_crystal", "group:wood" },
{ "default:mese_crystal", "default:diamondblock", "default:mese_crystal" },
{ "default:stone", "default:mese_crystal", "default:chest" }
},
})
minetest.register_craft( {
output = "lwcomponents:force_field_locked",
recipe = {
{ "default:steel_ingot", "default:mese_crystal", "group:wood" },
{ "default:mese_crystal", "default:diamondblock", "default:mese_crystal" },
{ "default:stone", "default:mese_crystal", "default:chest_locked" }
},
})
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( {
output = "lwcomponents:cannon_shell 10",
recipe = {
{ "default:steel_ingot", "default:steel_ingot" },
{ "", "default:coalblock" },
},
})
minetest.register_craft( {
output = "lwcomponents:cannon_soft_shell 10",
recipe = {
{ "default:steel_ingot", "default:steel_ingot" },
{ "default:copper_lump", "default:coalblock" },
},
})
if minetest.global_exists ("fire") then
minetest.register_craft( {
output = "lwcomponents:cannon_fire_shell 10",
recipe = {
{ "default:steel_ingot", "default:steel_ingot" },
{ "default:iron_lump", "default:coalblock" },
},
})
end -- minetest.global_exists ("fire")
if utils.mesecon_supported then
minetest.register_craft( {
output = "lwcomponents:through_wire_off 2",
recipe = {
{ "", "mesecons:wire_00000000_off" },
{ "mesecons:wire_00000000_off", "" },
},
})
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
@@ -170,25 +314,25 @@ minetest.register_craft( {
}) })
minetest.register_craft( { minetest.register_craft({
output = "lwcomponents:conduit 5", output = "lwcomponents:piston 2",
recipe = { recipe = {
{ "default:stone", "", "default:stone" }, { "group:wood", "group:wood", "group:wood" },
{ "", "default:chest", "" }, { "default:cobble", "default:steel_ingot", "default:cobble" },
{ "default:stone", "default:steel_ingot", "default:stone" }, { "default:stone", "default:copper_ingot", "default:stone" },
}, }
}) })
minetest.register_craft( { minetest.register_craft({
output = "lwcomponents:conduit_locked 5", output = "lwcomponents:piston_sticky",
recipe = { recipe = {
{ "default:stone", "", "default:stone" }, {"group:sapling"},
{ "", "default:chest_locked", "" }, {"lwcomponents:piston"},
{ "default:stone", "default:steel_ingot", "default:stone" }, }
},
}) })
end -- utils.digilines_supported or utils.mesecon_supported end -- utils.digilines_supported or utils.mesecon_supported
@@ -232,6 +376,24 @@ minetest.register_craft( {
}, },
}) })
minetest.register_craft( {
output = "lwcomponents:camera",
recipe = {
{ "default:copper_ingot", "default:iron_lump" },
{ "default:chest", "default:stone" },
},
})
minetest.register_craft( {
output = "lwcomponents:camera_locked",
recipe = {
{ "default:copper_ingot", "default:iron_lump" },
{ "default:chest_locked", "default:stone" },
},
})
end -- utils.digilines_supported end -- utils.digilines_supported
@@ -251,7 +413,7 @@ end -- utils.digilines_supported and utils.digistuff_supported
if utils.mesecon_supported and mesecon.mvps_push then if utils.mesecon_supported then
minetest.register_craft ({ minetest.register_craft ({
output = "lwcomponents:movefloor", output = "lwcomponents:movefloor",
@@ -262,7 +424,7 @@ minetest.register_craft ({
} }
}) })
end -- utils.mesecon_supported and mesecon.mvps_push end -- utils.mesecon_supported
@@ -284,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" },
@@ -293,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

@@ -1,8 +1,9 @@
default default
lwdrops?
mesecons? mesecons?
digilines? digilines?
unifieddyes? unifieddyes?
intllib? intllib?
hopper? hopper?
digistuff? digistuff?
pipeworks?
lwwires?

View File

@@ -73,7 +73,7 @@ end
local function place_node (itemname, pos) local function place_node (item, pos)
local node = minetest.get_node_or_nil ({ x = pos.x, y = pos.y - 1, z = pos.z }) local node = minetest.get_node_or_nil ({ x = pos.x, y = pos.y - 1, z = pos.z })
if not node then if not node then
@@ -100,8 +100,8 @@ local function place_node (itemname, pos)
end end
end end
local stack = ItemStack (itemname) local stack = ItemStack (item)
local itemdef = utils.find_item_def (itemname) local itemdef = utils.find_item_def (stack:get_name ())
if stack and itemdef then if stack and itemdef then
local placed = false local placed = false
@@ -122,30 +122,30 @@ local function place_node (itemname, pos)
end end
if itemdef and itemdef.on_place then if itemdef and itemdef.on_place then
local result, msg = pcall (itemdef.on_place, stack, nil, pointed_thing) local result, leftover = pcall (itemdef.on_place, stack, nil, pointed_thing)
placed = result placed = result
if not placed then if not placed then
if utils.settings.alert_handler_errors then if utils.settings.alert_handler_errors then
minetest.log ("error", "on_place handler for "..itemname.." crashed - "..msg) minetest.log ("error", "on_place handler for "..stack:get_name ().." crashed - "..leftover)
end end
end end
end end
if not placed then if not placed then
if not minetest.registered_nodes[itemname] then if not minetest.registered_nodes[stack:get_name ()] then
return false return false
end end
minetest.set_node (pos, { name = itemname, param1 = 0, param2 = 0 }) minetest.set_node (pos, { name = stack:get_name (), param1 = 0, param2 = 0 })
if itemdef and itemdef.after_place_node then if itemdef and itemdef.after_place_node then
local result, msg = pcall (itemdef.after_place_node, pos, nil, stack, pointed_thing) local result, msg = pcall (itemdef.after_place_node, pos, nil, stack, pointed_thing)
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
@@ -154,9 +154,11 @@ local function place_node (itemname, pos)
pcall (minetest.sound_play, itemdef.sounds.place, { pos = pos }) pcall (minetest.sound_play, itemdef.sounds.place, { pos = pos })
end end
end end
return true
end end
return true return false
end end
@@ -219,7 +221,7 @@ local function deploy_item (pos, node, slot, range)
local deploypos = get_deploy_pos (pos, node.param2, range) local deploypos = get_deploy_pos (pos, node.param2, range)
if item and deploypos then if item and deploypos then
if place_node (name, deploypos) then if place_node (stack, deploypos) then
stack:set_count (stack:get_count () - 1) stack:set_count (stack:get_count () - 1)
inv:set_stack ("main", slot, stack) inv:set_stack ("main", slot, stack)
@@ -260,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
@@ -290,7 +292,7 @@ end
local function after_place_node (pos, placer, itemstack, pointed_thing) local function after_place_base (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
local spec = local spec =
"formspec_version[3]\n".. "formspec_version[3]\n"..
@@ -308,6 +310,13 @@ local function after_place_node (pos, placer, itemstack, pointed_thing)
inv:set_size ("main", 16) inv:set_size ("main", 16)
inv:set_width ("main", 4) inv:set_width ("main", 4)
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
after_place_base (pos, placer, itemstack, pointed_thing)
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
@@ -316,7 +325,7 @@ end
local function after_place_node_locked (pos, placer, itemstack, pointed_thing) local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
after_place_node (pos, placer, itemstack, pointed_thing) after_place_base (pos, placer, itemstack, pointed_thing)
if placer and placer:is_player () then if placer and placer:is_player () then
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
@@ -325,6 +334,8 @@ local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
meta:set_string ("infotext", "Deployer (owned by "..placer:get_player_name ()..")") meta:set_string ("infotext", "Deployer (owned by "..placer:get_player_name ()..")")
end end
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
end end
@@ -417,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
@@ -528,12 +538,120 @@ end
local function pipeworks_support ()
if utils.pipeworks_supported then
return
{
priority = 100,
input_inventory = "main",
connect_sides = { left = 1, right = 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
return inv:add_item ("main", 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 ("main", 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
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
if inv then
local slots = inv:get_size ("main")
for i = 1, slots, 1 do
local s = inv:get_stack ("main", i)
if s and not s:is_empty () and utils.is_same_item (stack, s) then
return s:get_count ()
end
end
end
return 0
end,
remove_items = function (pos, node, stack, dir, count)
-- removes count items and returns them
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
local left = count
if inv then
local slots = inv:get_size ("main")
for i = 1, slots, 1 do
local s = inv:get_stack ("main", i)
if s and not s:is_empty () and utils.is_same_item (s, stack) then
if s:get_count () > left then
s:set_count (s:get_count () - left)
inv:set_stack ("main", i, s)
left = 0
else
left = left - s:get_count ()
inv:set_stack ("main", i, nil)
end
end
if left == 0 then
break
end
end
end
local result = ItemStack (stack)
result:set_count (count - left)
return result
end
}
end
return nil
end
local deployer_groups = { cracky = 3, wires_connect = 1 }
if utils.pipeworks_supported then
deployer_groups.tubedevice = 1
deployer_groups.tubedevice_receiver = 1
end
local deployer_on_groups = { cracky = 3, not_in_creative_inventory = 1, wires_connect = 1 }
if utils.pipeworks_supported then
deployer_on_groups.tubedevice = 1
deployer_on_groups.tubedevice_receiver = 1
end
minetest.register_node("lwcomponents:deployer", { minetest.register_node("lwcomponents:deployer", {
description = S("Deployer"), description = S("Deployer"),
tiles = { "lwdeployer.png", "lwdeployer.png", "lwdeployer.png", tiles = { "lwdeployer.png", "lwdeployer.png", "lwdeployer.png",
"lwdeployer.png", "lwdeployer.png", "lwdeployer_face.png"}, "lwdeployer.png", "lwdeployer.png", "lwdeployer_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = table.copy (deployer_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -544,10 +662,12 @@ minetest.register_node("lwcomponents:deployer", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
after_place_node = after_place_node, after_place_node = after_place_node,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, on_timer = on_timer,
on_rightclick = on_rightclick on_rightclick = on_rightclick
@@ -560,7 +680,7 @@ minetest.register_node("lwcomponents:deployer_locked", {
tiles = { "lwdeployer.png", "lwdeployer.png", "lwdeployer.png", tiles = { "lwdeployer.png", "lwdeployer.png", "lwdeployer.png",
"lwdeployer.png", "lwdeployer.png", "lwdeployer_face.png"}, "lwdeployer.png", "lwdeployer.png", "lwdeployer_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = table.copy (deployer_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -571,10 +691,12 @@ minetest.register_node("lwcomponents:deployer_locked", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
after_place_node = after_place_node_locked, after_place_node = after_place_node_locked,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, on_timer = on_timer,
on_rightclick = on_rightclick on_rightclick = on_rightclick
@@ -588,7 +710,7 @@ minetest.register_node("lwcomponents:deployer_on", {
tiles = { "lwdeployer.png", "lwdeployer.png", "lwdeployer.png", tiles = { "lwdeployer.png", "lwdeployer.png", "lwdeployer.png",
"lwdeployer.png", "lwdeployer.png", "lwdeployer_face_on.png"}, "lwdeployer.png", "lwdeployer.png", "lwdeployer_face_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = table.copy (deployer_on_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -601,9 +723,11 @@ minetest.register_node("lwcomponents:deployer_on", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
after_place_node = after_place_node, after_place_node = after_place_node,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, on_timer = on_timer,
@@ -617,7 +741,7 @@ minetest.register_node("lwcomponents:deployer_locked_on", {
tiles = { "lwdeployer.png", "lwdeployer.png", "lwdeployer.png", tiles = { "lwdeployer.png", "lwdeployer.png", "lwdeployer.png",
"lwdeployer.png", "lwdeployer.png", "lwdeployer_face_on.png"}, "lwdeployer.png", "lwdeployer.png", "lwdeployer_face_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = table.copy (deployer_on_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -630,9 +754,11 @@ minetest.register_node("lwcomponents:deployer_locked_on", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
after_place_node = after_place_node_locked, after_place_node = after_place_node_locked,
on_blast = on_blast, on_blast = on_blast,
on_timer = on_timer, on_timer = on_timer,

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

@@ -18,6 +18,17 @@ local function mesecons_on (pos)
if meta:get_int ("power_on") == 0 then if meta:get_int ("power_on") == 0 then
utils.mesecon_receptor_on (pos, utils.mesecon_default_rules) utils.mesecon_receptor_on (pos, utils.mesecon_default_rules)
meta:set_int ("power_on", 1) meta:set_int ("power_on", 1)
local node = utils.get_far_node (pos)
if node then
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)
end
end end
end end
end end
@@ -31,6 +42,17 @@ local function mesecons_off (pos)
if meta:get_int ("power_on") ~= 0 then if meta:get_int ("power_on") ~= 0 then
utils.mesecon_receptor_off (pos, utils.mesecon_default_rules) utils.mesecon_receptor_off (pos, utils.mesecon_default_rules)
meta:set_int ("power_on", 0) meta:set_int ("power_on", 0)
local node = utils.get_far_node (pos)
if node then
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)
end
end end
end end
end end
@@ -130,10 +152,10 @@ end
local function get_entity_height (objref) local function get_entity_height (objref)
if objref.get_luaentity then if objref.get_luaentity then
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
@@ -165,7 +187,7 @@ local function detect (pos)
local object = minetest.get_objects_inside_radius (pos, radius + 0.5) local object = minetest.get_objects_inside_radius (pos, radius + 0.5)
local detected_list = { } local detected_list = { }
for i = 1, #object do for i = 1, #object, 1 do
if object[i]:is_player () then if object[i]:is_player () then
-- player -- player
@@ -331,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
@@ -364,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
@@ -410,7 +416,6 @@ local function after_place_node (pos, placer, itemstack, pointed_thing)
local is_off = itemstack and (itemstack:get_name () == "lwcomponents:detector" or local is_off = itemstack and (itemstack:get_name () == "lwcomponents:detector" or
itemstack:get_name () == "lwcomponents:detector_locked") itemstack:get_name () == "lwcomponents:detector_locked")
meta:set_string ("inventory", "{ main = { }, filter = { } }")
meta:set_string ("formspec", get_form_spec (is_off, 1, 0, 0, 0, 0, 1)) meta:set_string ("formspec", get_form_spec (is_off, 1, 0, 0, 0, 0, 1))
meta:set_string ("entities", "false") meta:set_string ("entities", "false")
@@ -554,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)
@@ -687,7 +691,24 @@ end
local function mesecon_support () local function mesecon_support_on ()
if utils.mesecon_supported then
return
{
receptor =
{
state = utils.mesecon_state_on,
rules = utils.mesecon_default_rules
}
}
end
return nil
end
local function mesecon_support_off ()
if utils.mesecon_supported then if utils.mesecon_supported then
return return
{ {
@@ -709,7 +730,7 @@ minetest.register_node("lwcomponents:detector", {
tiles = { "lwdetector_face.png", "lwdetector_face.png", "lwdetector.png", tiles = { "lwdetector_face.png", "lwdetector_face.png", "lwdetector.png",
"lwdetector.png", "lwdetector.png", "lwdetector_face.png"}, "lwdetector.png", "lwdetector.png", "lwdetector_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -719,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,
@@ -738,7 +759,7 @@ minetest.register_node("lwcomponents:detector_locked", {
tiles = { "lwdetector_face.png", "lwdetector_face.png", "lwdetector.png", tiles = { "lwdetector_face.png", "lwdetector_face.png", "lwdetector.png",
"lwdetector.png", "lwdetector.png", "lwdetector_face.png"}, "lwdetector.png", "lwdetector.png", "lwdetector_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -748,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,
@@ -767,7 +788,7 @@ minetest.register_node("lwcomponents:detector_on", {
tiles = { "lwdetector_face_on.png", "lwdetector_face_on.png", "lwdetector.png", tiles = { "lwdetector_face_on.png", "lwdetector_face_on.png", "lwdetector.png",
"lwdetector.png", "lwdetector.png", "lwdetector_face_on.png"}, "lwdetector.png", "lwdetector.png", "lwdetector_face_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -777,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,
@@ -796,7 +817,7 @@ minetest.register_node("lwcomponents:detector_locked_on", {
tiles = { "lwdetector_face_on.png", "lwdetector_face_on.png", "lwdetector.png", tiles = { "lwdetector_face_on.png", "lwdetector_face_on.png", "lwdetector.png",
"lwdetector.png", "lwdetector.png", "lwdetector_face_on.png"}, "lwdetector.png", "lwdetector.png", "lwdetector_face_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -806,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, wires_connect = 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, wires_connect = 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,12 +8,10 @@ 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
return { { x = 0, y = -1, z = 0 } } -- down doesn't work return { { x = 0, y = -1, z = 0 } }
elseif side == "red" then elseif side == "red" then
return { { x = -1, y = 0, z = 0 } } return { { x = -1, y = 0, z = 0 } }
elseif side == "green" then elseif side == "green" then
@@ -32,13 +30,154 @@ local function get_mesecon_rule_for_side (side)
{ x = 0, y = 0, z = 1 }, { x = 0, y = 0, z = 1 },
{ x = 0, y = 0, z = -1 }, { x = 0, y = 0, z = -1 },
{ x = 0, y = 1, z = 0 }, { x = 0, y = 1, z = 0 },
{ x = 0, y = -1, z = 0 }, -- down doesn't work { x = 0, y = -1, z = 0 },
} }
end end
end end
local side_bits =
{
["white"] = 0,
["black"] = 1,
["red"] = 2,
["green"] = 3,
["blue"] = 4,
["yellow"] = 5
}
local function get_side_bit (side)
if side then
if side == "switch" then
return 64
end
local bit = side_bits[side]
if bit then
return math.pow (2, bit)
end
end
return 63
end
local function is_side_on (bits, side)
local bit = get_side_bit (side)
for i = 0, 6, 1 do
if (bit % 2) == 1 and (bits % 2) ~= 1 then
return false
end
bit = math.floor (bit / 2)
bits = math.floor (bits / 2)
end
return true
end
local function set_side_bit (bits, side, on)
local bit = get_side_bit (side)
local result = 0
for i = 0, 6, 1 do
if (bit % 2) == 1 then
if on then
result = result + math.pow (2, i)
end
elseif (bits % 2) == 1 then
result = result + math.pow (2, i)
end
bit = math.floor (bit / 2)
bits = math.floor (bits / 2)
end
return result
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)
utils.mesecon_receptor_on (pos, get_mesecon_rule_for_side (side))
local node = utils.get_far_node (pos)
if node then
node.param1 = set_side_bit (node.param1, side, true)
node.name = get_node_name (node)
minetest.swap_node (pos, node)
end
end
local function switch_off (pos, side)
utils.mesecon_receptor_off (pos, get_mesecon_rule_for_side (side))
local node = utils.get_far_node (pos)
if node then
node.param1 = set_side_bit (node.param1, side, false)
node.name = get_node_name (node)
minetest.swap_node (pos, node)
end
end
local function digilines_support () local function digilines_support ()
return return
{ {
@@ -80,9 +219,9 @@ local function digilines_support ()
end end
if words[1] == "on" then if words[1] == "on" then
utils.mesecon_receptor_on (pos, get_mesecon_rule_for_side (words[2])) switch_on (pos, words[2])
elseif words[1] == "off" then elseif words[1] == "off" then
utils.mesecon_receptor_off (pos, get_mesecon_rule_for_side (words[2])) switch_off (pos, words[2])
end end
end end
end end
@@ -102,12 +241,20 @@ local function mesecon_support ()
state = mesecon.state.off, state = mesecon.state.off,
rules = rules =
{ {
{ x = 0, y = 0, z = -1 },
{ x = 1, y = 0, z = 0 }, { x = 1, y = 0, z = 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 = 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 },
{ x = 0, y = -1, z = 0 }, -- down doesn't work { x = 0, y = -1, z = 0 }
} }
}, },
} }
@@ -115,6 +262,19 @@ end
local function mesecon_support_on ()
return
{
receptor =
{
state = mesecon.state.on,
rules = get_powered_rules
},
}
end
local function on_construct (pos) local function on_construct (pos)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
@@ -124,7 +284,7 @@ local function on_construct (pos)
local formspec = local formspec =
"formspec_version[3]\n".. "formspec_version[3]\n"..
"size[6.0,4.0]\n".. "size[6.0,4.0]\n"..
"field[1.0,0.8;4.0,1.0;channel;Channel;]\n".. "field[1.0,0.8;4.0,1.0;channel;Channel;${channel}]\n"..
"button_exit[2.0,2.5;2.0,1.0;set;Set]\n" "button_exit[2.0,2.5;2.0,1.0;set;Set]\n"
meta:set_string ("formspec", formspec) meta:set_string ("formspec", formspec)
@@ -134,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
@@ -145,14 +313,6 @@ local function on_receive_fields (pos, formname, fields, sender)
if meta then if meta then
meta:set_string ("channel", fields.channel or "") meta:set_string ("channel", fields.channel or "")
local formspec =
"formspec_version[3]\n"..
"size[6.0,4.0]\n"..
"field[1.0,0.8;4.0,1.0;channel;Channel;"..minetest.formspec_escape (meta:get_string ("channel")).."]\n"..
"button_exit[2.0,2.5;2.0,1.0;set;Set]\n"
meta:set_string ("formspec", formspec)
end end
end end
end end
@@ -172,7 +332,9 @@ minetest.register_node ("lwcomponents:digiswitch", {
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
} }
}, },
groups = { cracky = 2, oddly_breakable_by_hand = 2 }, paramtype = "none",
param1 = 0,
groups = { cracky = 2, oddly_breakable_by_hand = 2, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
@@ -185,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, wires_connect = 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,
@@ -182,7 +183,7 @@ end
local function after_place_node (pos, placer, itemstack, pointed_thing) local function after_place_base (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
local spec = local spec =
"formspec_version[3]\n".. "formspec_version[3]\n"..
@@ -200,6 +201,13 @@ local function after_place_node (pos, placer, itemstack, pointed_thing)
inv:set_size ("main", 16) inv:set_size ("main", 16)
inv:set_width ("main", 4) inv:set_width ("main", 4)
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
after_place_base (pos, placer, itemstack, pointed_thing)
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
@@ -208,7 +216,7 @@ end
local function after_place_node_locked (pos, placer, itemstack, pointed_thing) local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
after_place_node (pos, placer, itemstack, pointed_thing) after_place_base (pos, placer, itemstack, pointed_thing)
if placer and placer:is_player () then if placer and placer:is_player () then
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
@@ -217,6 +225,8 @@ local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
meta:set_string ("infotext", "Dispenser (owned by "..placer:get_player_name ()..")") meta:set_string ("infotext", "Dispenser (owned by "..placer:get_player_name ()..")")
end end
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
end end
@@ -309,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
@@ -412,12 +421,112 @@ end
local function pipeworks_support ()
if utils.pipeworks_supported then
return
{
priority = 100,
input_inventory = "main",
connect_sides = { left = 1, right = 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
return inv:add_item ("main", 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 ("main", 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
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
if inv then
local slots = inv:get_size ("main")
for i = 1, slots, 1 do
local s = inv:get_stack ("main", i)
if s and not s:is_empty () and utils.is_same_item (stack, s) then
return s:get_count ()
end
end
end
return 0
end,
remove_items = function (pos, node, stack, dir, count)
-- removes count items and returns them
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
local left = count
if inv then
local slots = inv:get_size ("main")
for i = 1, slots, 1 do
local s = inv:get_stack ("main", i)
if s and not s:is_empty () and utils.is_same_item (s, stack) then
if s:get_count () > left then
s:set_count (s:get_count () - left)
inv:set_stack ("main", i, s)
left = 0
else
left = left - s:get_count ()
inv:set_stack ("main", i, nil)
end
end
if left == 0 then
break
end
end
end
local result = ItemStack (stack)
result:set_count (count - left)
return result
end
}
end
return nil
end
local dispenser_groups = { cracky = 3, wires_connect = 1 }
if utils.pipeworks_supported then
dispenser_groups.tubedevice = 1
dispenser_groups.tubedevice_receiver = 1
end
minetest.register_node("lwcomponents:dispenser", { minetest.register_node("lwcomponents:dispenser", {
description = S("Dispenser"), description = S("Dispenser"),
tiles = { "lwdispenser.png", "lwdispenser.png", "lwdispenser.png", tiles = { "lwdispenser.png", "lwdispenser.png", "lwdispenser.png",
"lwdispenser.png", "lwdispenser.png", "lwdispenser_face.png"}, "lwdispenser.png", "lwdispenser.png", "lwdispenser_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = table.copy (dispenser_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -428,10 +537,12 @@ minetest.register_node("lwcomponents:dispenser", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
after_place_node = after_place_node, after_place_node = after_place_node,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_rightclick = on_rightclick on_rightclick = on_rightclick
}) })
@@ -443,7 +554,7 @@ minetest.register_node("lwcomponents:dispenser_locked", {
tiles = { "lwdispenser.png", "lwdispenser.png", "lwdispenser.png", tiles = { "lwdispenser.png", "lwdispenser.png", "lwdispenser.png",
"lwdispenser.png", "lwdispenser.png", "lwdispenser_face.png"}, "lwdispenser.png", "lwdispenser.png", "lwdispenser_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = table.copy (dispenser_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -454,10 +565,12 @@ minetest.register_node("lwcomponents:dispenser_locked", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
after_place_node = after_place_node_locked, after_place_node = after_place_node_locked,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_rightclick = on_rightclick on_rightclick = on_rightclick
}) })

View File

@@ -3,11 +3,13 @@ Breaker
* This block is only available if digilines and/or mesecons are loaded. * This block is only available if digilines and/or mesecons are loaded.
Breakers dig the node up to 5 nodes directly in front of them and drop 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 the item at the back of them, or into a pipeworks tube if one is placed
tool that can dig it or if it can be dug by hand, and there are no nodes behind it. The node is only dug if the breaker has a tool that can dig it
before of it. ie. cannot dig 2nd node if 1st node has something in it. or if it can be dug by hand, and there are no nodes before of it. ie.
The tool is worn if used. Also acts as a digilines conductor. If the cannot dig 2nd node if 1st node has something in it. The tool is worn if
hopper mod is loaded, will take tools from the top and sides. used. Also acts as a digilines conductor. If the hopper mod is loaded,
will take tools from the top and sides. Pipeworks tubes can push items
into and pull items from the inventory.
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.

41
docs/camera.txt Normal file
View File

@@ -0,0 +1,41 @@
Camera
------
* This block is only available if digilines is loaded.
Cameras take an image in the direction they are facing. The colors in the
image represent what is being viewed. Nodes are gray, entities are blue and
players are green. The closer they are to the camera the brighter the color.
The viewing distance of the camera is 1 to 16 nodes. Also acts as a
digilines conductor.
Only the owner can dig or access the form of the locked version.
UI
Channel - digilines channel of camera.
Distance - the viewing distance forward from the camera (1 to 16).
Resolution - the image resolution (for both width and height, 1 to 128).
Digilines messages
"scan"
Sends a digilines message with the camera's channel and a table of the
image as the message (see below).
"distance n"
Sets the viewing distance of the camera. Will be clipped between 1 and
16.
"resolution n"
Sets the image resolution of the camera.
The image is an indexed table of indexed tables. Each inner table is one
line of the image ordered top to bottom. There are resolution number of
lines. Each line has a string value for each pixel of that line left to
right. The string is a hex color string eg. "00FF00". There are resolution
number of pixels per line.
The image format is compatible with digistuff's digiscreens and lwcomputers'
digiscreens and digipanels. It is best to set the resolution of the camera
to the resolution of the display, then the image from the camera can be sent
straight to the display device.

View File

@@ -5,11 +5,12 @@ manually.
Contains a single inventory slot and shoots an item on command. 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 If the hopper mod is loaded, will take items from the top and sides, and
release them from the bottom. release them from the bottom. Pipeworks tubes can push items into and pull
items from the inventory.
Cannon rotation range: Cannon rotation range:
side to side - +/-60 degrees (- = left, + = right) side to side - +/-60 degrees (- = left, + = right)
down to up: -20 to 50 degrees (- = down, + = up) down to up: -20 to 70 degrees (- = down, + = up)
To spawn entities from cannons include the lwcomponents_spawners mod. To spawn entities from cannons include the lwcomponents_spawners mod.
@@ -21,6 +22,7 @@ Channel - digilines channel of cannon.
Hide - hides the form so the cannon can be used manually, double right click 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. any other face besides the rear to bring up the form.
Controller - digistuff game controller digilines channel. Controller - digistuff game controller digilines channel.
Sensitive - if checked game controller movements have a x3 sensitivity.
Top 1 slot inventory - storage of items to shoot. Top 1 slot inventory - storage of items to shoot.
Bottom 32 slot inventory - player's inventory. Bottom 32 slot inventory - player's inventory.
@@ -35,11 +37,11 @@ Digistuff game controller
Connect a game controller to the cannon with digilines cable. Enter the 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 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 (click Set). Your turning movements turn the cannon's barrel in the
direction the cannon is facing. The movements have an increased sensitivity direction the cannon is facing. If Sensitive is checked the movements
(x3) to try and keep the target in your view. Punching shoots an item. have an increased sensitivity (x3) to try and keep the target in your view,
The game controller updates every 0.2 seconds, so a quick punch may not otherwise x1. Punching shoots an item. The game controller updates every
register. A locked cannon can only be controlled by it's owner with a game 0.2 seconds, so a quick punch may not register. A locked cannon can only
controller. be controlled by it's owner with a game controller.
Mesecons Mesecons
Shoots an item when power is turned on. Shoots an item when power is turned on.
@@ -47,7 +49,7 @@ Mesecons
Digilines messages Digilines messages
"pitch <n>" "pitch <n>"
Sets the pitch of the barrel. n should be between -20 to 50, and will Sets the pitch of the barrel. n should be between -20 to 70, and will
be clipped to this range. be clipped to this range.
eg. "pitch 22" eg. "pitch 22"
@@ -56,8 +58,47 @@ Digilines messages
be clipped to this range. be clipped to this range.
eg. "rotation 45" eg. "rotation 45"
table - aim position
{
action = "aim",
aim = { x, y, z }
}
x is the horizontal left (negative) to right. 0 is straight ahead.
y is the vertical down (negative) to up. 0 is straight ahead.
z is the depth. Must be > 0 or ignored. 1 is the position directly in
front of the cannon.
* The cannon barrel's height is 0.65 above the cannon's placed position.
When aiming for height, if the cannon's base height is taken as -0.5,
and consider height from there. This allows for the barrel height
and a little drop in the projectile at close range.
"fire" "fire"
Shoots an item. Shoots an item.
* Note: turning the barrel is animated and takes 0.1 seconds per 10 * Note: turning the barrel is animated and takes 0.1 seconds per 10
degrees of movement. A fire command while moving is ignored. degrees of movement. A fire command while moving is ignored.
Three shells are provided for cannons.
Shell
This shell has a 70% chance of destroying a node within a radius of 2 from
the impact, a 5% chance a flammable node will be set on fire within a
radius of 2 (if fire is installed), and damages players and entities within
a radius of 4 with a maximum of 20 damage points.
Soft Shell
This shell has a 50% chance of destroying only soft (buildable_to) nodes,
such as grass, within a radius of 2 from the impact, a 5% chance a flammable
node will be set on fire within a radius of 2 (if fire is installed), and
damages players and entities within a radius of 4 with a maximum of 20
damage points.
Fire Shell
* This item is only available if fire is installed.
This shell does not destroying nodes, has a 70% chance of setting a node
on fire, whether its flammable or not within a radius of 2, and damages
players and entities within a radius of 4 with a maximum of 20 damage
points.

View File

@@ -4,7 +4,8 @@ Collector
Picks up dropped items in adjacent block, with optional filtering. Also Picks up dropped items in adjacent block, with optional filtering. Also
acts as a digilines conductor. If the hopper mod is loaded, will take items 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. from the top and sides, and release them from the bottom. Pipeworks tubes
can push items into and pull items from the inventory.
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.

View File

@@ -1,32 +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. Transfer of items takes 0.1 seconds per conduit node moved, and will work
in unloaded blocks.
Filtering of items can be done by placing an item into a filter slot and
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.
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.
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. 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>"
@@ -44,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
{ {
@@ -54,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.

View File

@@ -7,6 +7,7 @@ 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. 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 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. take items from the top and sides, and release them from the bottom.
Pipeworks tubes can push items into and pull items from the inventory.
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.

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.

View File

@@ -4,7 +4,8 @@ Dispenser
Contains an inventory and dispenses (with velocity) an item on command. 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 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. items from the top and sides, and release them from the bottom. Pipeworks
tubes can push items into and pull items from the inventory.
To spawn entities from dispensers include the lwcomponents_spawners mod. To spawn entities from dispensers include the lwcomponents_spawners mod.

View File

@@ -4,7 +4,8 @@ Dropper
Contains an inventory and drops an item on command. Also acts as a Contains an inventory and drops an item on command. Also acts as a
digilines conductor. If the hopper mod is loaded, will take items from the digilines conductor. If the hopper mod is loaded, will take items from the
top and sides, and release them from the bottom. top and sides, and release them from the bottom. Pipeworks tubes can push
items into and pull items from the inventory.
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.

View File

@@ -0,0 +1,67 @@
Force Field Generator
---------------------
Force field generators repel players and mobs within a given radius from
the generator. The radius can be 5 to 25 and is in all directions. An
'electric dome' appears marking the field. The generator consumes fuel
relative to the radius. A radius of 25 uses 1 coal in 10 seconds, 5 uses
1 coal in 50 seconds. Each time an entity is repelled it cost 1 fuel value
(1/40 of a coal). Any players or mobs permitted inside the field can be
added to the Permit list. Each entry must be on a new line with no extra
spaces. Empty lines (not even a space) are ignored. The mob's registered
name or tag can be used. The owner of a locked generator will not be
repelled. When something is repelled it takes a small amount of damage.
Only the owner can dig or access the form of the locked version.
UI
Channel - digilines channel of generator.
Radius - the node radius to repel, in every direction. 5 to 25.
Permit - list of players or mobs to allow within field. Mobs can be registered
entity name or tag.
Start/Stop button - starts and stops the field.
Fuel - single slot inventory.
Player inventor - 32 slot inventory at bottom.
Mesecons
Turns the generator on and off.
Digilines messages
"start"
Start the generator.
"stop"
Stop the generator.
"radius n"
Set the radius to n, where n is a number between 5 to 25.
"add <name>"
Add a name to the permit list.
"remove <name>"
Remove a name from the permit list.
"status"
Query the status of the generator. The generator will send a digilines
message with its own channel as the following table:
{
action = "status",
state = "on" | "off",
radius = n, -- radius as number
permit =
{
<list of names>
},
fuel =
{
name = name, -- eg. "default:coal_lump", will be "" if empty
count = n, -- count of fuel
}
}
Hoppers and pipeworks tubes can be used to push or pull the fuel.

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

@@ -1,6 +1,6 @@
MoveFloor MoveFloor
--------- ---------
* This block is only available if mesecons and mesecons_mvps is loaded. * This block is only available if mesecons is loaded.
The MoveFloor block responds to a mesecons power source in the 4 horizontal The MoveFloor block responds to a mesecons power source in the 4 horizontal
directions. If the power source is one higher the MoveFloor moves up to directions. If the power source is one higher the MoveFloor moves up to

43
docs/pistons.txt Normal file
View File

@@ -0,0 +1,43 @@
Pistons and sticky pistons
--------------------------
* These blocks are only available if digilines and/or mesecons are loaded.
Pistons push up to the setting Maximum piston nodes (default 15) in front
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
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
Channel - digilines channel of piston.
Single move - pusher extends 1 node if checked, otherwise 2 nodes.
Mesecons
Piston extends while power is turned on.
Digilines messages
"extend n"
Extends the piston pusher to extent n (0, 1 or 2). If n is not given
pusher extends to maximum extent. 0 is retracted.
"retract"
Same as 'extend 0'.
"single"
Sets piston to single move mode.
"double"
Sets piston to double move mode.

105
docs/storage.txt Normal file
View File

@@ -0,0 +1,105 @@
Storage
-------
Storage is accommodated with two nodes, Storage Unit and Storage Indexer.
Storage units can be interacted with like a basic chest, each with 32 slots,
and visually join together when placed adjacent to each other. Units are
generally accessed via indexers, which action all adjoining units as a
single storage block. Multiple indexers can action a single storage block.
Only the owner can dig or access the form of the locked versions.
Unowned indexers can only access unowned units. Owned indexers can access
units of the same owner or unowned units.
UI
Search - top left.
List - left.
Channel - digilines channel of indexer.
Input - middle.
Output - top right.
Filter - center right.
Player inventor - lower right.
When the UI is accessed the storage is scanned, and its contents are
displayed in the list. The list contains the following columns:
Item button - pressing will place one of these items from storage into the
output.
10 button - pressing will place 10 of the item.
<stack> button - pressing places a full stack.
Count - the total number of this item in storage.
Description - description of the item.
Note that the 10 and stack buttons may vary in number or not appear
depending on the requirements of that item.
The form does not update while open. A request for more items than in
storage will only deliver the amount in storage.
Terms can be entered into the search field, and when enter is pressed or
the Search button is pressed, only items whose description contains these
terms are shown in the list. That is if they match any of the space
separated terms.
Any items placed into the input are placed into storage. If the filter
is clear all items are accepted. If the filter contains items only these
items will be accepted. Any items not accepted or that do not fit into
storage are placed into the output.
When items are placed into the filter a copy is used and the item returns
to where it was taken from. When items are removed from the filter they
are disposed of.
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.
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
output.
Every 20 inputs the storage is consolidated to minimize fragmentation.
Digilines messages
"output <item> <count>"
or
{
action = "output",
item = "<item>",
count = <count>
}
Moves the item/s to the output. If count is omitted defaults to 1. If
the requested amount is greater than in storage, only the stored amount
is moved. If the requested amount is greater than a full stack of the
item a full stack is moved.
"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 storage. 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
id -- string, unique id of the item in storage
}
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 output 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 output message and set the item
field with the id field for the item from a returned inventory.

7
docs/through_wire.txt Normal file
View File

@@ -0,0 +1,7 @@
Mesecons Through Wire
---------------------
* This block is only available if mesecons is loaded.
Will transmit mesecons power when placed one to two blocks apart opposing
each other, through solid blocks or open space. Can also be used as a mesecons
crossover.

View File

@@ -118,7 +118,7 @@ end
local function after_place_node (pos, placer, itemstack, pointed_thing) local function after_place_base (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
local spec = local spec =
"formspec_version[3]\n".. "formspec_version[3]\n"..
@@ -136,6 +136,13 @@ local function after_place_node (pos, placer, itemstack, pointed_thing)
inv:set_size ("main", 16) inv:set_size ("main", 16)
inv:set_width ("main", 4) inv:set_width ("main", 4)
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
after_place_base (pos, placer, itemstack, pointed_thing)
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
@@ -144,7 +151,7 @@ end
local function after_place_node_locked (pos, placer, itemstack, pointed_thing) local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
after_place_node (pos, placer, itemstack, pointed_thing) after_place_base (pos, placer, itemstack, pointed_thing)
if placer and placer:is_player () then if placer and placer:is_player () then
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
@@ -153,6 +160,8 @@ local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
meta:set_string ("infotext", "Dropper (owned by "..placer:get_player_name ()..")") meta:set_string ("infotext", "Dropper (owned by "..placer:get_player_name ()..")")
end end
utils.pipeworks_after_place (pos)
-- If return true no item is taken from itemstack -- If return true no item is taken from itemstack
return false return false
end end
@@ -245,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
@@ -348,12 +356,112 @@ end
local function pipeworks_support ()
if utils.pipeworks_supported then
return
{
priority = 100,
input_inventory = "main",
connect_sides = { left = 1, right = 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
return inv:add_item ("main", 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 ("main", 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
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
if inv then
local slots = inv:get_size ("main")
for i = 1, slots, 1 do
local s = inv:get_stack ("main", i)
if s and not s:is_empty () and utils.is_same_item (stack, s) then
return s:get_count ()
end
end
end
return 0
end,
remove_items = function (pos, node, stack, dir, count)
-- removes count items and returns them
local meta = minetest.get_meta (pos)
local inv = (meta and meta:get_inventory ()) or nil
local left = count
if inv then
local slots = inv:get_size ("main")
for i = 1, slots, 1 do
local s = inv:get_stack ("main", i)
if s and not s:is_empty () and utils.is_same_item (s, stack) then
if s:get_count () > left then
s:set_count (s:get_count () - left)
inv:set_stack ("main", i, s)
left = 0
else
left = left - s:get_count ()
inv:set_stack ("main", i, nil)
end
end
if left == 0 then
break
end
end
end
local result = ItemStack (stack)
result:set_count (count - left)
return result
end
}
end
return nil
end
local dropper_groups = { cracky = 3, wires_connect = 1 }
if utils.pipeworks_supported then
dropper_groups.tubedevice = 1
dropper_groups.tubedevice_receiver = 1
end
minetest.register_node("lwcomponents:dropper", { minetest.register_node("lwcomponents:dropper", {
description = S("Dropper"), description = S("Dropper"),
tiles = { "lwdropper.png", "lwdropper.png", "lwdropper.png", tiles = { "lwdropper.png", "lwdropper.png", "lwdropper.png",
"lwdropper.png", "lwdropper.png", "lwdropper_face.png"}, "lwdropper.png", "lwdropper.png", "lwdropper_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = table.copy (dropper_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -364,10 +472,12 @@ minetest.register_node("lwcomponents:dropper", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
after_place_node = after_place_node, after_place_node = after_place_node,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_rightclick = on_rightclick on_rightclick = on_rightclick
}) })
@@ -379,7 +489,7 @@ minetest.register_node("lwcomponents:dropper_locked", {
tiles = { "lwdropper.png", "lwdropper.png", "lwdropper.png", tiles = { "lwdropper.png", "lwdropper.png", "lwdropper.png",
"lwdropper.png", "lwdropper.png", "lwdropper_face.png"}, "lwdropper.png", "lwdropper.png", "lwdropper_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = table.copy (dropper_groups),
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -390,10 +500,12 @@ minetest.register_node("lwcomponents:dropper_locked", {
mesecons = mesecon_support (), mesecons = mesecon_support (),
digiline = digilines_support (), digiline = digilines_support (),
tube = pipeworks_support (),
on_receive_fields = on_receive_fields, on_receive_fields = on_receive_fields,
after_place_node = after_place_node_locked, after_place_node = after_place_node_locked,
can_dig = can_dig, can_dig = can_dig,
after_dig_node = utils.pipeworks_after_dig,
on_blast = on_blast, on_blast = on_blast,
on_rightclick = on_rightclick on_rightclick = on_rightclick
}) })

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

517
explode.lua Normal file
View File

@@ -0,0 +1,517 @@
local utils = ...
local S = utils.S
local explode = { }
if minetest.global_exists ("fire") then
explode.fire_supported = true
function explode.set_fire (pos, burn_all)
local node = utils.get_far_node (pos)
if not node then
return
end
if node.name ~= "air" then
local def = minetest.registered_nodes[node.name]
if not def or not def.buildable_to then
return
end
end
local dirs =
{
{ x = 0, y = -1, z = 0 },
{ x = -1, y = 0, z = 0 },
{ x = 0, y = 0, z = -1 },
{ x = 1, y = 0, z = 0 },
{ x = 0, y = 0, z = 1 }
}
for i = 1, #dirs do
node = utils.get_far_node (vector.add (pos, dirs[i]))
if node and node.name ~= "air" and node.name ~= "fire:basic_flame" then
local def = minetest.registered_nodes[node.name]
if def and def.liquidtype == "none" then
if (def.groups and def.groups.flammable) or burn_all then
minetest.set_node (pos, { name = "fire:basic_flame" })
return
end
end
end
end
end
else
explode.fire_supported = false
function explode.set_fire (pos, burn_all)
end
end
local function dig_node (pos, toolname)
local node = utils.get_far_node (pos)
local dig = false
local drops = nil
if toolname == true then
dig = true
toolname = nil
end
if node and node.name ~= "air" 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
drops = { }
for i = 1, #items do
drops[i] = ItemStack (items[i])
end
if def and def.preserve_metadata then
def.preserve_metadata (pos, node, minetest.get_meta (pos), drops)
end
end
minetest.remove_node (pos)
end
end
return drops
end
local function add_drops (drops, drop)
if drops and drop then
for i = 1, #drop do
local item = ItemStack (drop[i])
if item and not item:is_empty () then
local existing = drops[item:get_name ()]
if existing and utils.is_same_item (item, existing) then
existing:set_count (existing:get_count () + item:get_count ())
else
drops[item:get_name ()] = item
end
end
end
end
end
local function explode_node (pos, dig_chance, intensity, drops, filter)
if not utils.is_protected (pos, nil) then
dig_chance = math.min (math.max (dig_chance, 0), 100)
if math.random (100) <= dig_chance then
local node = utils.get_far_node (pos)
local blasted = false
if node and node.name ~= "air" then
local def = minetest.registered_nodes[node.name]
if def then
if def.diggable == false then
return false
end
for k, v in pairs (filter) do
if def[k] == nil then
if filter[k.."_undefined"] == false then
return false
end
elseif def[k] ~= v then
return false
end
end
if def.on_blast then
def.on_blast (pos, intensity)
blasted = true
end
end
if not blasted then
local drop = dig_node (pos, true)
add_drops (drops, drop)
end
minetest.check_for_falling ({ x = pos.x, y = pos.y + 1, z = pos.z })
return true
end
end
end
return false
end
local function burn_node (pos, fire_chance, burn_all)
if not utils.is_protected (pos, nil) then
fire_chance = math.min (math.max (fire_chance, 0), 100)
if math.random (100) <= fire_chance then
explode.set_fire (pos, burn_all)
end
end
end
local function entity_is_drop (obj)
return obj.get_luaentity and obj:get_luaentity () and
obj:get_luaentity ().name and
obj:get_luaentity ().name == "__builtin:item"
end
local function explode_entities (pos, radius, damage, drops)
local objs = minetest.get_objects_inside_radius (pos, radius)
for _, obj in ipairs (objs) do
-- could be detached player from controller
if obj.get_pos and obj:get_pos () then
local obj_pos = obj:get_pos ()
local dir = vector.direction (pos, obj_pos)
local dist = vector.length (vector.subtract (obj_pos, pos))
local vel = vector.multiply (dir, ((radius + 1) - dist) / (radius + 1) * damage * 5)
if entity_is_drop (obj) then
obj:add_velocity (vel)
elseif not obj:get_armor_groups ().immortal then
local ent_damage = ((radius - dist) / radius * damage / 2) + (damage / 2)
local reason = { type = "set_hp", from = "lwcomponents" }
if obj:is_player() then
local parent = obj:get_attach ()
if parent then
obj:set_detach ()
end
obj:add_velocity (vel)
obj:set_hp (obj:get_hp () - ent_damage, reason)
else
local luaobj = obj:get_luaentity ()
-- object might have disappeared somehow
if luaobj then
if luaobj.name == "digistuff:controller_entity" then
for _, child in ipairs (obj:get_children ()) do
if child:is_player () then
local def = utils.find_item_def ("digistuff:controller_programmed")
if def and def.on_rightclick then
def.on_rightclick (obj:get_pos (), ItemStack (), child)
child:add_velocity (vel)
child:set_hp (child:get_hp () - ent_damage, reason)
end
end
end
else
local do_damage = true
local do_knockback = true
local entity_drops = {}
local objdef = minetest.registered_entities[luaobj.name]
if objdef and objdef.on_blast then
do_damage, do_knockback, entity_drops = objdef.on_blast (luaobj, ent_damage)
end
if do_knockback then
obj:add_velocity (vel)
end
if do_damage then
obj:set_hp (obj:get_hp() - ent_damage, reason)
end
add_drops (drops, entity_drops)
end
end
end
end
end
end
end
local function spray_drops (pos, drops, damage)
local max_vel = damage * 2.5
for k, stack in pairs (drops) do
local vel =
{
x = math.random (max_vel) - (max_vel / 2),
y = math.random (max_vel) - (max_vel / 2),
z = math.random (max_vel) - (max_vel / 2)
}
local drop = minetest.add_item (pos, stack)
if drop then
drop:set_velocity (vel)
end
end
end
local function add_effects (pos, radius, drops)
minetest.add_particle ({
pos = pos,
velocity = vector.new (),
acceleration = vector.new (),
expirationtime = 0.4,
size = 30, -- radius * 10,
collisiondetection = false,
vertical = false,
texture = "lwcomponents_boom.png",
glow = 14,
})
minetest.add_particlespawner ({
amount = 64,
time = 0.5,
minpos = vector.subtract (pos, radius / 2),
maxpos = vector.add (pos, radius / 2),
minvel = {x = -10, y = -10, z = -10},
maxvel = {x = 10, y = 10, z = 10},
minacc = vector.new (),
maxacc = vector.new (),
minexptime = 1,
maxexptime = 2.5,
minsize = 9, -- radius * 3,
maxsize = 15, -- radius * 5,
texture = "lwcomponents_smoke.png",
})
-- we just dropped some items. Look at the items entities and pick
-- one of them to use as texture
local texture = "lwcomponents_blast.png" --fallback texture
local node
local most = 0
if drops then
for name, stack in pairs (drops) do
local count = stack:get_count()
if count > most then
most = count
local def = minetest.registered_nodes[name]
if def then
node = { name = name }
end
if def and def.tiles and def.tiles[1] then
if type (def.tiles[1]) == "table" then
texture = def.tiles[1].name or "lwcomponents_blast.png"
elseif type (def.tiles[1]) == "string" then
texture = def.tiles[1]
end
end
end
end
end
minetest.add_particlespawner ({
amount = 64,
time = 0.1,
minpos = vector.subtract (pos, radius / 2),
maxpos = vector.add (pos, radius / 2),
minvel = {x = -3, y = 0, z = -3},
maxvel = {x = 3, y = 5, z = 3},
minacc = {x = 0, y = -10, z = 0},
maxacc = {x = 0, y = -10, z = 0},
minexptime = 0.8,
maxexptime = 2.0,
minsize = 1, -- radius * 0.33,
maxsize = 3, -- radius,
texture = texture,
-- ^ only as fallback for clients without support for `node` parameter
node = node,
collisiondetection = true,
})
end
function utils.boom (pos, -- center of explosion
node_radius, node_chance, -- radius and chance in 100
fire_radius, fire_chance, -- radius and chance in 100
entity_radius, entity_damage, -- radius and max damage applied
disable_drops, -- true to disable drops
node_filter, -- node filter table as { buildable_to = true, buildable_to_undefined = false, ... }
burn_all, -- true to set fire to anything, otherwise only flammable
sound) -- sound on blast, if nil plays default
pos = vector.round (pos)
node_radius = math.floor (node_radius or 1)
fire_radius = math.floor (fire_radius or node_radius)
entity_radius = math.floor (entity_radius or node_radius * 2)
node_chance = node_chance or 80
fire_chance = fire_chance or 30
entity_damage = math.floor (entity_damage or entity_radius)
disable_drops = disable_drops == true
node_filter = node_filter or { }
burn_all = burn_all == true
sound = sound or "lwcannon"
local drops = { }
local effects_radius = (node_radius > 0 and node_radius) or entity_radius
local center_free = false
if not utils.is_protected (pos, nil) then
local center_node = utils.get_far_node (pos)
if not center_node or center_node.name == "air" then
center_free = true
end
end
if node_radius > 0 and node_chance > 0 then
local extents = node_radius * 2
for y = -extents, extents, 1 do
for z = -extents, extents, 1 do
for x = -extents, extents, 1 do
local node_pos = { x = x + pos.x, y = y + pos.y, z = z + pos.z }
local length = vector.length ({ x = x, y = y, z = z })
if node_chance > 0 and length <= node_radius then
if explode_node (node_pos, node_chance, 1.0, drops, node_filter) then
if vector.equals (pos, node_pos) then
center_free = true
end
end
end
end
end
end
end
if fire_radius > 0 and fire_chance > 0 then
local extents = fire_radius * 2
for y = -extents, extents, 1 do
for z = -extents, extents, 1 do
for x = -extents, extents, 1 do
local node_pos = { x = x + pos.x, y = y + pos.y, z = z + pos.z }
local length = vector.length ({ x = x, y = y, z = z })
if fire_chance > 0 and length <= fire_radius then
burn_node (node_pos, fire_chance, burn_all)
end
end
end
end
end
minetest.sound_play (sound,
{
pos = pos,
gain = 2.5,
max_hear_distance = math.min (effects_radius * 20, 128)
},
true)
if center_free then
minetest.set_node (pos, { name = "lwcomponents:boom" })
end
explode_entities (pos, entity_radius, entity_damage, drops)
if not disable_drops then
spray_drops (pos, drops, entity_damage)
end
add_effects (pos, effects_radius, drops)
minetest.log ("action", "A Shell explosion occurred at " .. minetest.pos_to_string (pos) ..
" with radius " .. entity_radius)
end
minetest.register_node ("lwcomponents:boom", {
description = S("Boom"),
drawtype = "airlike",
tiles = { "lwcomponents_boom.png" },
inventory_image = "lwcomponents_boom.png",
wield_image = "lwcomponents_boom.png",
light_source = default.LIGHT_MAX,
use_texture_alpha = "blend",
sunlight_propagates = true,
walkable = false,
pointable = false,
diggable = false,
climbable = false,
buildable_to = true,
floodable = true,
is_ground_content = false,
drop = "",
paramtype = "light",
param1 = 255,
post_effect_color = { a = 128, r = 255, g = 0, b = 0 },
groups = { dig_immediate = 3, not_in_creative_inventory = 1 },
on_construct = function (pos)
minetest.get_node_timer (pos):start (0.5)
end,
on_timer = function (pos, elapsed)
minetest.remove_node (pos)
return false
end,
-- unaffected by explosions
on_blast = function() end,
})
--

14
fan.lua
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
@@ -199,14 +198,10 @@ local function on_blast (pos, intensity)
if meta then if meta then
if intensity >= 1.0 then if intensity >= 1.0 then
clear_map (pos)
minetest.remove_node (pos) minetest.remove_node (pos)
else -- intensity < 1.0 else -- intensity < 1.0
clear_map (pos)
local node = minetest.get_node_or_nil (pos) local node = minetest.get_node_or_nil (pos)
if node then if node then
local items = minetest.get_node_drops (node, nil) local items = minetest.get_node_drops (node, nil)
@@ -215,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
@@ -347,7 +341,7 @@ minetest.register_node("lwcomponents:fan", {
tiles = { "lwfan.png", "lwfan.png", "lwfan.png", tiles = { "lwfan.png", "lwfan.png", "lwfan.png",
"lwfan.png", "lwfan.png", "lwfan_face.png"}, "lwfan.png", "lwfan.png", "lwfan_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -375,7 +369,7 @@ minetest.register_node("lwcomponents:fan_locked", {
tiles = { "lwfan.png", "lwfan.png", "lwfan.png", tiles = { "lwfan.png", "lwfan.png", "lwfan.png",
"lwfan.png", "lwfan.png", "lwfan_face.png"}, "lwfan.png", "lwfan.png", "lwfan_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -403,7 +397,7 @@ minetest.register_node("lwcomponents:fan_on", {
tiles = { "lwfan.png", "lwfan.png", "lwfan.png", tiles = { "lwfan.png", "lwfan.png", "lwfan.png",
"lwfan.png", "lwfan.png", "lwfan_face_on.png"}, "lwfan.png", "lwfan.png", "lwfan_face_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -432,7 +426,7 @@ minetest.register_node("lwcomponents:fan_locked_on", {
tiles = { "lwfan.png", "lwfan.png", "lwfan.png", tiles = { "lwfan.png", "lwfan.png", "lwfan.png",
"lwfan.png", "lwfan.png", "lwfan_face_on.png"}, "lwfan.png", "lwfan.png", "lwfan_face_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,

1038
force_field.lua Normal file

File diff suppressed because it is too large Load Diff

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.11" local version = "0.1.28"
local mod_storage = minetest.get_mod_storage () local mod_storage = minetest.get_mod_storage ()
@@ -15,8 +15,10 @@ end
local utils = { } local utils = { }
local modpath = minetest.get_modpath ("lwcomponents") local modpath = minetest.get_modpath ("lwcomponents")
loadfile (modpath.."/utils.lua") (utils, mod_storage)
loadfile (modpath.."/settings.lua") (utils) loadfile (modpath.."/settings.lua") (utils)
utils.get_dummy_player = loadfile (modpath.."/dummy_player.lua") ()
loadfile (modpath.."/utils.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") ()
loadfile (modpath.."/dropper.lua") (utils) loadfile (modpath.."/dropper.lua") (utils)
@@ -31,7 +33,15 @@ 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.."/pistons.lua") (utils)
loadfile (modpath.."/through_wire.lua") (utils)
loadfile (modpath.."/camera.lua") (utils)
loadfile (modpath.."/storage.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

@@ -13,6 +13,10 @@ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
See the GNU Lesser General Public License for more details: See the GNU Lesser General Public License for more details:
https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
Mesecons through wire code was adapted from mesecons_receiver.
Fragments of code were gleaned from tnt mod.
lwsiren-buzz.ogg lwsiren-buzz.ogg
@@ -59,6 +63,24 @@ https://creativecommons.org/licenses/by/4.0/
lwmovefloor.ogg
---------------
https://www.freesoundslibrary.com/elevator-sound-effect-elevator-ride-doors-closing-and-opening/
License: Attribution 4.0 International (CC BY 4.0). You are allowed to use
sound effects free of charge and royalty free in your multimedia projects
for commercial or non-commercial purposes.
lwforce_field_zap.ogg
---------------------
https://orangefreesounds.com/electricity-zap/
Licence: The sound effect is permitted for non-commercial use under license
Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
Media license Media license
------------- -------------
siren images derived from images from https://openclipart.org, which is siren images derived from images from https://openclipart.org, which is
@@ -67,9 +89,20 @@ public domain.
fan images derived from images from https://openclipart.org, which is fan images derived from images from https://openclipart.org, which is
public domain. public domain.
camera lens images derived from images from https://openclipart.org, which
is public domain.
storage nodes images derived from images from https://openclipart.org, which
is public domain.
player button images derived from mesecons button image. player button images derived from mesecons button image.
cannon firing sound from tnt, released under CC BY-SA 3.0 and CC0 1.0 cannon firing and explosion sound from tnt (TumeniNodes/steveygos93),
released under CC0 1.0 (originally from https://freesound.org/s/80401/)
boom image from tnt, released under CC BY-SA 3.0.
Piston images and sounds from mesecons_pistons, released under CC-BY-SA 3.0.
All other media, or media not covered by a licence, is licensed All other media, or media not covered by a licence, is licensed
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) 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 title = LWComponents
name = lwcomponents name = lwcomponents
depends = default depends = default
optional_depends = lwdrops, mesecons, digilines, unifieddyes, intllib, hopper, digistuff optional_depends = mesecons, digilines, unifieddyes, intllib, hopper, digistuff, pipeworks, lwwires

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,162 @@
# Blender v2.82 (sub 7) OBJ File: 'shell.blend'
# www.blender.org
mtllib shell.mtl
o Sell
v 1.188815 0.386266 -2.500000
v 1.188815 -0.386266 -0.000000
v 1.188815 -0.386266 -2.500000
v -1.188815 -0.386266 0.000000
v -1.188815 0.386266 -2.500000
v -1.188815 -0.386266 -2.500000
v 1.188815 0.386266 -0.000000
v 0.951055 -0.309014 0.499997
v 0.734730 -1.011265 -0.000000
v -0.734730 -1.011265 -2.500000
v -0.734730 -1.011265 0.000000
v -0.951055 0.309014 0.499997
v -1.188815 0.386266 0.000000
v 0.237761 -0.077252 2.000000
v 0.440836 -0.606760 1.000000
v 0.713290 -0.231762 1.000000
v 0.734730 1.011265 -2.500000
v 0.146942 0.202250 2.000000
v 0.146942 -0.202250 2.000000
v 0.951055 0.309014 0.499997
v -0.000000 -1.250000 -2.500000
v 0.000000 -1.250000 0.000000
v -0.587785 -0.809015 0.499997
v -0.734730 1.011265 0.000000
v -0.587785 0.809015 0.499997
v 0.000000 1.250000 0.000000
v 0.734730 -1.011265 -2.500000
v 0.734730 1.011265 -0.000000
v -0.000000 1.250000 -2.500000
v -0.146942 -0.202250 2.000000
v -0.237760 -0.077252 2.000000
v -0.951055 -0.309014 0.499997
v -0.734730 1.011265 -2.500000
v -0.237760 0.077252 2.000000
v 0.000000 -0.249996 2.000000
v -0.440836 -0.606760 1.000000
v 0.587785 -0.809015 0.499997
v 0.713290 0.231762 1.000000
v 0.237761 0.077252 2.000000
v 0.587785 0.809015 0.499997
v 0.440836 0.606760 1.000000
v -0.713290 0.231762 1.000000
v -0.440836 0.606760 1.000000
v -0.713290 -0.231762 1.000000
v 0.000000 0.249996 2.000000
v -0.146942 0.202250 2.000000
vn 1.0000 0.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.7306 -0.5308 0.4294
vn -0.8090 -0.5878 0.0000
vn -0.9031 0.0000 0.4294
vn 0.8090 0.5878 0.0000
vn 0.0000 0.0000 1.0000
vn 0.9031 0.0000 0.4294
vn 0.0000 0.0000 -1.0000
vn -0.2791 -0.8589 0.4294
vn -0.2791 0.8589 0.4294
vn -0.3090 -0.9511 0.0000
vn 0.7306 0.5308 0.4294
vn 0.3090 0.9511 0.0000
vn -0.8090 0.5878 0.0000
vn -0.3090 0.9511 0.0000
vn 0.3090 -0.9511 0.0000
vn -0.7306 -0.5308 0.4294
vn 0.2791 -0.8589 0.4294
vn 0.8090 -0.5878 0.0000
vn 0.2791 0.8589 0.4294
vn -0.7306 0.5308 0.4294
usemtl None
s off
f 1//1 2//1 3//1
f 4//2 5//2 6//2
f 7//1 2//1 1//1
f 2//3 8//3 9//3
f 4//4 10//4 11//4
f 4//5 12//5 13//5
f 14//3 15//3 16//3
f 1//6 17//6 7//6
f 14//7 18//7 19//7
f 8//8 20//8 16//8
f 10//9 5//9 21//9
f 6//4 10//4 4//4
f 22//10 23//10 11//10
f 24//11 25//11 26//11
f 3//9 5//9 1//9
f 21//9 5//9 27//9
f 11//12 10//12 22//12
f 28//13 20//13 7//13
f 17//14 26//14 28//14
f 7//6 17//6 28//6
f 29//14 26//14 17//14
f 24//15 5//15 13//15
f 29//16 24//16 26//16
f 22//17 27//17 9//17
f 30//7 18//7 31//7
f 11//18 32//18 4//18
f 33//15 5//15 24//15
f 29//9 5//9 33//9
f 31//7 18//7 34//7
f 15//19 19//19 35//19
f 33//16 24//16 29//16
f 27//9 5//9 3//9
f 22//12 10//12 21//12
f 21//17 27//17 22//17
f 13//2 5//2 4//2
f 6//9 5//9 10//9
f 2//20 27//20 3//20
f 9//20 27//20 2//20
f 31//18 36//18 30//18
f 32//5 12//5 4//5
f 17//9 5//9 29//9
f 1//9 5//9 17//9
f 35//7 18//7 30//7
f 16//3 37//3 9//3
f 14//8 38//8 39//8
f 26//21 40//21 28//21
f 41//13 18//13 39//13
f 24//22 42//22 25//22
f 25//11 43//11 26//11
f 31//5 34//5 44//5
f 30//10 36//10 35//10
f 34//22 43//22 42//22
f 44//18 32//18 11//18
f 45//21 18//21 41//21
f 16//8 38//8 14//8
f 9//3 8//3 16//3
f 22//19 15//19 35//19
f 15//3 37//3 16//3
f 16//8 20//8 38//8
f 38//13 20//13 28//13
f 32//5 42//5 12//5
f 13//22 12//22 24//22
f 12//22 42//22 24//22
f 42//22 43//22 25//22
f 46//22 43//22 34//22
f 26//21 45//21 41//21
f 14//3 19//3 15//3
f 35//10 36//10 22//10
f 22//19 37//19 15//19
f 9//19 37//19 22//19
f 44//5 34//5 42//5
f 39//7 18//7 14//7
f 2//8 20//8 8//8
f 7//8 20//8 2//8
f 38//13 41//13 39//13
f 41//21 40//21 26//21
f 44//5 42//5 32//5
f 19//7 18//7 35//7
f 34//7 18//7 46//7
f 46//7 18//7 45//7
f 44//18 36//18 31//18
f 36//10 23//10 22//10
f 38//13 40//13 41//13
f 28//13 40//13 38//13
f 44//18 23//18 36//18
f 11//18 23//18 44//18
f 45//11 43//11 46//11
f 26//11 43//11 45//11

143
models/piston_normal_1.obj Normal file
View File

@@ -0,0 +1,143 @@
# Blender v2.82 (sub 7) OBJ File: ''
# www.blender.org
mtllib piston_normal_1.mtl
o cube
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.312500
v 0.500000 -0.500000 -0.312500
v 0.500000 0.500000 0.500000
v 0.500000 0.500000 -0.312500
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.312500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.333333 0.333333
vt 0.666667 0.333333
vt 0.666667 0.666667
vt 0.333333 0.666667
vt 0.333333 0.666667
vt 0.666667 1.000000
vt 0.333333 1.000000
vn 0.0000 -1.0000 0.0000
vn 1.0000 -0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 -0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 -0.0000 1.0000
usemtl m_7
s 1
f 1/1/1 2/2/1 3/3/1 4/4/1
f 5/5/2 1/6/2 4/7/2 6/8/2
f 7/9/3 5/10/3 6/11/3 8/12/3
f 2/13/4 7/14/4 8/15/4 3/16/4
f 8/17/5 6/18/5 4/19/5 3/20/5
f 2/21/6 1/1/6 5/22/6 7/23/6
o cube.000
v 0.500000 -0.500000 -1.312500
v -0.500000 -0.500000 -1.312500
v -0.500000 -0.500000 -1.500000
v 0.500000 -0.500000 -1.500000
v 0.500000 0.500000 -1.312500
v 0.500000 0.500000 -1.500000
v -0.500000 0.500000 -1.312500
v -0.500000 0.500000 -1.500000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.333333 0.000000
vt 0.666667 0.000000
vt 0.666667 0.333333
vt 0.333333 0.333333
vt 0.666667 0.333333
vt 1.000000 0.333333
vt 1.000000 0.666667
vt 0.666667 0.666667
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_7
s 1
f 9/24/7 10/25/7 11/26/7 12/27/7
f 13/28/8 9/29/8 12/30/8 14/31/8
f 15/32/9 13/33/9 14/34/9 16/35/9
f 10/36/10 15/37/10 16/38/10 11/39/10
f 16/40/11 14/41/11 12/42/11 11/43/11
f 10/44/12 9/45/12 13/46/12 15/47/12
o cube.001
v 0.125000 -0.125000 0.375000
v -0.125000 -0.125000 0.375000
v -0.125000 -0.125000 -1.375000
v 0.125000 -0.125000 -1.375000
v 0.125000 0.125000 0.375000
v 0.125000 0.125000 -1.375000
v -0.125000 0.125000 0.375000
v -0.125000 0.125000 -1.375000
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.458333 0.130208
vt 0.541667 0.130208
vt 0.541667 0.213542
vt 0.458333 0.213542
vt 0.791667 0.463542
vt 0.875000 0.463542
vt 0.875000 0.546875
vt 0.791667 0.546875
vn 0.0000 -1.0000 -0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_7
s 1
f 17/48/13 18/49/13 19/50/13 20/51/13
f 21/52/14 17/53/14 20/54/14 22/55/14
f 23/56/15 21/57/15 22/58/15 24/59/15
f 18/60/16 23/61/16 24/62/16 19/63/16
f 24/64/17 22/65/17 20/66/17 19/67/17
f 18/68/18 17/69/18 21/70/18 23/71/18

143
models/piston_normal_2.obj Normal file
View File

@@ -0,0 +1,143 @@
# Blender v2.82 (sub 7) OBJ File: ''
# www.blender.org
mtllib piston_normal_2.mtl
o cube.011
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.312500
v 0.500000 -0.500000 -0.312500
v 0.500000 0.500000 0.500000
v 0.500000 0.500000 -0.312500
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.312500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.333333 0.333333
vt 0.666667 0.333333
vt 0.666667 0.666667
vt 0.333333 0.666667
vt 0.333333 0.666667
vt 0.666667 1.000000
vt 0.333333 1.000000
vn 0.0000 -1.0000 0.0000
vn 1.0000 -0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 -0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 -0.0000 1.0000
usemtl m_0.001
s 1
f 1/1/1 2/2/1 3/3/1 4/4/1
f 5/5/2 1/6/2 4/7/2 6/8/2
f 7/9/3 5/10/3 6/11/3 8/12/3
f 2/13/4 7/14/4 8/15/4 3/16/4
f 8/17/5 6/18/5 4/19/5 3/20/5
f 2/21/6 1/1/6 5/22/6 7/23/6
o cube.012
v 0.500000 -0.500000 -2.312500
v -0.500000 -0.500000 -2.312500
v -0.500000 -0.500000 -2.500000
v 0.500000 -0.500000 -2.500000
v 0.500000 0.500000 -2.312500
v 0.500000 0.500000 -2.500000
v -0.500000 0.500000 -2.312500
v -0.500000 0.500000 -2.500000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.333333 0.000000
vt 0.666667 0.000000
vt 0.666667 0.333333
vt 0.333333 0.333333
vt 0.666667 0.333333
vt 1.000000 0.333333
vt 1.000000 0.666667
vt 0.666667 0.666667
vn 0.0000 -1.0000 -0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_0.001
s 1
f 9/24/7 10/25/7 11/26/7 12/27/7
f 13/28/8 9/29/8 12/30/8 14/31/8
f 15/32/9 13/33/9 14/34/9 16/35/9
f 10/36/10 15/37/10 16/38/10 11/39/10
f 16/40/11 14/41/11 12/42/11 11/43/11
f 10/44/12 9/45/12 13/46/12 15/47/12
o cube.013
v 0.125000 -0.125000 0.375000
v -0.125000 -0.125000 0.375000
v -0.125000 -0.125000 -2.375000
v 0.125000 -0.125000 -2.375000
v 0.125000 0.125000 0.375000
v 0.125000 0.125000 -2.375000
v -0.125000 0.125000 0.375000
v -0.125000 0.125000 -2.375000
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.562500 0.229167
vt 0.458333 0.229167
vt 0.458333 0.125000
vt 0.562500 0.125000
vt 0.875000 0.458333
vt 0.791667 0.458333
vt 0.791667 0.541667
vt 0.875000 0.541667
vn 0.0000 -1.0000 -0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_0.001
s 1
f 17/48/13 18/49/13 19/50/13 20/51/13
f 21/52/14 17/53/14 20/54/14 22/55/14
f 23/56/15 21/57/15 22/58/15 24/59/15
f 18/60/16 23/61/16 24/62/16 19/63/16
f 24/64/17 22/65/17 20/66/17 19/67/17
f 18/68/18 17/69/18 21/70/18 23/71/18

143
models/piston_sticky_1.obj Normal file
View File

@@ -0,0 +1,143 @@
# Blender v2.82 (sub 7) OBJ File: ''
# www.blender.org
mtllib piston_sticky_1.mtl
o cube.002
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.312500
v 0.500000 -0.500000 -0.312500
v 0.500000 0.500000 0.500000
v 0.500000 0.500000 -0.312500
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.312500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.333333 0.333333
vt 0.666667 0.333333
vt 0.666667 0.666667
vt 0.333333 0.666667
vt 0.333333 0.666667
vt 0.666667 1.000000
vt 0.333333 1.000000
vn 0.0000 -1.0000 0.0000
vn 1.0000 -0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 -0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 -0.0000 1.0000
usemtl m_7.001
s 1
f 1/1/1 2/2/1 3/3/1 4/4/1
f 5/5/2 1/6/2 4/7/2 6/8/2
f 7/9/3 5/10/3 6/11/3 8/12/3
f 2/13/4 7/14/4 8/15/4 3/16/4
f 8/17/5 6/18/5 4/19/5 3/20/5
f 2/21/6 1/1/6 5/22/6 7/23/6
o cube.003
v 0.500000 -0.500000 -1.312500
v -0.500000 -0.500000 -1.312500
v -0.500000 -0.500000 -1.500000
v 0.500000 -0.500000 -1.500000
v 0.500000 0.500000 -1.312500
v 0.500000 0.500000 -1.500000
v -0.500000 0.500000 -1.312500
v -0.500000 0.500000 -1.500000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.000000
vt 1.000000 0.000000
vt 1.000000 0.333333
vt 0.666667 0.333333
vt 0.666667 0.333333
vt 1.000000 0.333333
vt 1.000000 0.666667
vt 0.666667 0.666667
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_7.001
s 1
f 9/24/7 10/25/7 11/26/7 12/27/7
f 13/28/8 9/29/8 12/30/8 14/31/8
f 15/32/9 13/33/9 14/34/9 16/35/9
f 10/36/10 15/37/10 16/38/10 11/39/10
f 16/40/11 14/41/11 12/42/11 11/43/11
f 10/44/12 9/45/12 13/46/12 15/47/12
o cube.004
v 0.125000 -0.125000 0.375000
v -0.125000 -0.125000 0.375000
v -0.125000 -0.125000 -1.375000
v 0.125000 -0.125000 -1.375000
v 0.125000 0.125000 0.375000
v 0.125000 0.125000 -1.375000
v -0.125000 0.125000 0.375000
v -0.125000 0.125000 -1.375000
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.354167
vt 0.208333 0.354167
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.458333 0.130208
vt 0.541667 0.130208
vt 0.541667 0.213542
vt 0.458333 0.213542
vt 0.791667 0.463542
vt 0.875000 0.463542
vt 0.875000 0.546875
vt 0.791667 0.546875
vn 0.0000 -1.0000 -0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_7.001
s 1
f 17/48/13 18/49/13 19/50/13 20/51/13
f 21/52/14 17/53/14 20/54/14 22/55/14
f 23/56/15 21/57/15 22/58/15 24/59/15
f 18/60/16 23/61/16 24/62/16 19/63/16
f 24/64/17 22/65/17 20/66/17 19/67/17
f 18/68/18 17/69/18 21/70/18 23/71/18

143
models/piston_sticky_2.obj Normal file
View File

@@ -0,0 +1,143 @@
# Blender v2.82 (sub 7) OBJ File: ''
# www.blender.org
mtllib piston_sticky_2.mtl
o cube.008
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.312500
v 0.500000 -0.500000 -0.312500
v 0.500000 0.500000 0.500000
v 0.500000 0.500000 -0.312500
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.312500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.666667 0.666667
vt 1.000000 0.666667
vt 1.000000 0.937500
vt 0.666667 0.937500
vt 0.333333 0.333333
vt 0.666667 0.333333
vt 0.666667 0.666667
vt 0.333333 0.666667
vt 0.333333 0.666667
vt 0.666667 1.000000
vt 0.333333 1.000000
vn 0.0000 -1.0000 0.0000
vn 1.0000 -0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 -0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 -0.0000 1.0000
usemtl m_0
s 1
f 1/1/1 2/2/1 3/3/1 4/4/1
f 5/5/2 1/6/2 4/7/2 6/8/2
f 7/9/3 5/10/3 6/11/3 8/12/3
f 2/13/4 7/14/4 8/15/4 3/16/4
f 8/17/5 6/18/5 4/19/5 3/20/5
f 2/21/6 1/1/6 5/22/6 7/23/6
o cube.009
v 0.500000 -0.500000 -2.312500
v -0.500000 -0.500000 -2.312500
v -0.500000 -0.500000 -2.500000
v 0.500000 -0.500000 -2.500000
v 0.500000 0.500000 -2.312500
v 0.500000 0.500000 -2.500000
v -0.500000 0.500000 -2.312500
v -0.500000 0.500000 -2.500000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.937500
vt 1.000000 0.937500
vt 1.000000 1.000000
vt 0.666667 1.000000
vt 0.666667 0.000000
vt 1.000000 0.000000
vt 1.000000 0.333333
vt 0.666667 0.333333
vt 0.666667 0.333333
vt 1.000000 0.333333
vt 1.000000 0.666667
vt 0.666667 0.666667
vn 0.0000 -1.0000 -0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_0
s 1
f 9/24/7 10/25/7 11/26/7 12/27/7
f 13/28/8 9/29/8 12/30/8 14/31/8
f 15/32/9 13/33/9 14/34/9 16/35/9
f 10/36/10 15/37/10 16/38/10 11/39/10
f 16/40/11 14/41/11 12/42/11 11/43/11
f 10/44/12 9/45/12 13/46/12 15/47/12
o cube.010
v 0.125000 -0.125000 0.375000
v -0.125000 -0.125000 0.375000
v -0.125000 -0.125000 -2.375000
v 0.125000 -0.125000 -2.375000
v 0.125000 0.125000 0.375000
v 0.125000 0.125000 -2.375000
v -0.125000 0.125000 0.375000
v -0.125000 0.125000 -2.375000
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.125000 0.020833
vt 0.208333 0.020833
vt 0.208333 0.979167
vt 0.125000 0.979167
vt 0.562500 0.229167
vt 0.458333 0.229167
vt 0.458333 0.125000
vt 0.562500 0.125000
vt 0.875000 0.458333
vt 0.791667 0.458333
vt 0.791667 0.541667
vt 0.875000 0.541667
vn 0.0000 -1.0000 -0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl m_0
s 1
f 17/48/13 18/49/13 19/50/13 20/51/13
f 21/52/14 17/53/14 20/54/14 22/55/14
f 23/56/15 21/57/15 22/58/15 24/59/15
f 18/60/16 23/61/16 24/62/16 19/63/16
f 24/64/17 22/65/17 20/66/17 19/67/17
f 18/68/18 17/69/18 21/70/18 23/71/18

View File

@@ -3,7 +3,7 @@ local S = utils.S
if utils.mesecon_supported and mesecon.mvps_push then if utils.mesecon_supported then
@@ -21,14 +21,10 @@ local mesecon_rules =
-- use mesecons movestone settings
local timer_interval = 1 / mesecon.setting ("movestone_speed", 3)
local max_push = 3 local max_push = 3
local max_pull = 3
-- helper functions:
local function get_movefloor_direction (rulename) local function get_movefloor_direction (rulename)
if rulename.y > 0 then if rulename.y > 0 then
return { x = 0, y = 1, z = 0 } return { x = 0, y = 1, z = 0 }
@@ -38,6 +34,7 @@ local function get_movefloor_direction (rulename)
end end
local function add_movefloor_list (pos, list) local function add_movefloor_list (pos, list)
for i = 1, #list do for i = 1, #list do
if list[i].x == pos.x and if list[i].x == pos.x and
@@ -76,10 +73,289 @@ end
-- copied from mesecons movestone local function get_node_height (node)
local function movefloor_move (pos, node, rulename, is_sticky) local height = 0
local def = minetest.registered_nodes[node.name]
if def and type (def.collision_box) == "table" then
if def.collision_box.type and def.collision_box.type == "regular" then
height = 1
else
for _, box in pairs (def.collision_box) do
if type (box) == "table" then
if type (box[5]) == "number" then
height = box[5]
else
for _, b in ipairs (box) do
if type (b[5]) == "number" and b[5] > height then
height = b[5]
end
end
end
end
end
end
end
return height
end
local function get_affected_nodes (floor_list)
local list = { }
local max_height = 0
local protected = false
for _, fpos in ipairs (floor_list) do
for y = 0, max_push, 1 do
local npos = vector.add (fpos, { x = 0, y = y, z = 0 })
local node = utils.get_far_node (npos)
if node and node.name ~= "air" then
local meta = minetest.get_meta (npos)
local timer = minetest.get_node_timer (npos)
local h = get_node_height (node) + npos.y - fpos.y - 0.5
list[#list + 1] =
{
pos = npos,
node = node,
meta = (meta and meta:to_table ()),
timeout = (timer and timer:get_timeout ()) or 0,
elapsed = (timer and timer:get_elapsed ()) or 0
}
if h > max_height then
max_height = h
end
if utils.is_protected (npos, nil) then
protected = true
end
end
end
end
return list, math.ceil (max_height), protected
end
local function get_entity_height (obj, base)
local height = 0
if obj.get_pos then
local pos = obj:get_pos ()
if obj.get_luaentity then
local entity = obj:get_luaentity ()
if entity and entity.name then
local def = minetest.registered_entities[entity.name]
if def and type (def.collisionbox) == "table" and
type (def.collisionbox[5]) == "number" then
height = def.collisionbox[5] + pos.y - base
end
end
end
local props = obj:get_properties ()
if props and props.collisionbox and type (props.collisionbox) == "table" and
type (props.collisionbox[5]) == "number" then
if props.collisionbox[5] > height then
height = props.collisionbox[5] + pos.y - base
end
end
end
return height
end
local function get_affected_entities (floor_list)
local list = { }
local max_height = 0
for _, fpos in pairs (floor_list) do
local min_pos = vector.subtract (fpos, { x = 0.4999, y = 0.4999, z = 0.4999 })
local max_pos = vector.add (fpos, { x = 0.4999, y = max_push + 0.4999, z = 0.4999 })
local objects = minetest.get_objects_in_area (min_pos, max_pos)
for _, obj in ipairs (objects) do
local h = get_entity_height (obj, fpos.y + 0.5)
list[#list + 1] =
{
pos = obj:get_pos (),
obj = obj
}
if h > max_height then
max_height = h
end
end
end
return list, math.ceil (max_height)
end
local function is_obstructed (floor_list, height)
for _, fpos in pairs (floor_list) do
local npos = vector.add (fpos, { x = 0, y = height, z = 0 })
if utils.is_protected (npos, nil) then
return true
end
local node = utils.get_far_node (npos)
if node and node.name ~= "air" then
local def = minetest.registered_nodes[node.name]
if not def or not def.buildable_to then
return true
end
end
end
return false
end
local function move_entities (list, move, players)
for _, entry in ipairs (list) do
if entry.obj then
if players or not entry.obj:is_player () then
local pos
if entry.obj:is_player () then
pos = vector.add (entry.pos, { x = move.x, y = move.y + 0.1, z = move.z })
else
pos = vector.add (entry.pos, move)
end
if entry.obj.move_to then
entry.obj:move_to (pos)
elseif entry.set_pos then
entry.obj:set_pos (pos)
end
end
end
end
end
local function update_player_position (list)
for _, entry in ipairs (list) do
local player = minetest.get_player_by_name (entry.name)
if player then
local pos = player:get_pos ()
if pos.y < entry.pos.y then
pos.y = entry.pos.y + 0.1
player:set_pos (pos)
end
end
end
end
local function queue_player_update (list, move)
local players = { }
for _, entry in ipairs (list) do
if entry.obj and entry.obj:is_player () then
players[#players + 1] =
{
pos = vector.add (entry.pos, move),
name = entry.obj:get_player_name ()
}
end
end
if #players > 0 then
minetest.after(0.1, update_player_position, players)
end
end
local function move_nodes (list, move)
if move.y > 0 then
for i = #list, 1, -1 do
local pos = vector.add (list[i].pos, move)
minetest.remove_node (list[i].pos)
minetest.set_node (pos, list[i].node)
if list[i].meta then
local meta = minetest.get_meta (pos)
if meta then
meta:from_table (list[i].meta)
end
end
if list[i].timeout > 0 then
local timer = minetest.get_node_timer (pos)
if timer then
timer:set (list[i].timeout, list[i].elapsed)
end
end
end
else
for i = 1, #list, 1 do
local pos = vector.add (list[i].pos, move)
minetest.remove_node (list[i].pos)
minetest.set_node (pos, list[i].node)
if list[i].meta then
local meta = minetest.get_meta (pos)
if meta then
meta:from_table (list[i].meta)
end
end
if list[i].timeout > 0 then
local timer = minetest.get_node_timer (pos)
if timer then
timer:set (list[i].timeout, list[i].elapsed)
end
end
end
end
end
local function check_for_falling (list)
for _, pos in ipairs (list) do
minetest.check_for_falling (vector.add (pos, { x = 0, y = max_push + 1, z = 0 }))
end
end
local function movefloor_move (pos, node, rulename)
local direction = get_movefloor_direction (rulename) local direction = get_movefloor_direction (rulename)
local play_sound = false
local list = local list =
{ {
@@ -88,68 +364,34 @@ local function movefloor_move (pos, node, rulename, is_sticky)
find_adjoining_movefloor (pos, list) find_adjoining_movefloor (pos, list)
for i = 1, #list do local nodes, height, protected = get_affected_nodes (list)
local frontpos = vector.add (list[i], direction)
local meta = minetest.get_meta (list[i])
local owner = meta:get_string ("owner")
local continue = true
-- ### Step 1: Push nodes in front ### if protected then
local success, stack, oldstack = mesecon.mvps_push (frontpos, direction, max_push, owner)
if not success then
if stack == "protected" then
meta:set_string ("infotext", "Can't move: protected area on the way")
else
minetest.get_node_timer (list[i]):start (timer_interval)
continue = false
end
end
if continue then
mesecon.mvps_move_objects (frontpos, direction, oldstack)
-- ### Step 2: Move the movestone ###
minetest.set_node (frontpos, node)
local meta2 = minetest.get_meta (frontpos)
meta2:set_string ("owner", owner)
minetest.remove_node (list[i])
mesecon.on_dignode (list[i], node)
mesecon.on_placenode (frontpos, node)
minetest.get_node_timer (frontpos):start (timer_interval)
play_sound = true
-- ### Step 3: If sticky, pull stack behind ###
if is_sticky and direction.y < 0 then
local backpos = vector.subtract (list[i], direction)
success, stack, oldstack = mesecon.mvps_pull_all (backpos, direction, max_pull, owner)
if success then
mesecon.mvps_move_objects (backpos, vector.multiply (direction, -1), oldstack, -1)
end
end
-- ### Step 4: Let things fall ###
minetest.check_for_falling (vector.add (list[i], { x = 0, y = 1, z = 0 }))
end
end
if play_sound then
minetest.sound_play("movestone", { pos = list[i], max_hear_distance = 20, gain = 0.5 }, true)
end
end
local function on_timer (pos, elapsed)
local sourcepos = mesecon.is_powered (pos)
if not sourcepos then
return return
end end
local rulename = vector.subtract (sourcepos[1], pos) local entities, h = get_affected_entities (list)
mesecon.activate (pos, minetest.get_node (pos), rulename, 0) if h > height then
height = h
end
if is_obstructed (list, (direction.y > 0 and height + 1) or -1) then
return
end
if direction.y > 0 then
move_entities (entities, direction, true)
move_nodes (nodes, direction)
queue_player_update (entities, direction)
else
move_nodes (nodes, direction)
move_entities (entities, direction, false)
check_for_falling (list)
queue_player_update (entities, direction)
end
minetest.sound_play ("lwmovefloor", { pos = pos, max_hear_distance = 10, gain = 1.0 }, true)
end end
@@ -164,8 +406,8 @@ local function mesecon_support ()
action_on = function (pos, node, rulename) action_on = function (pos, node, rulename)
-- do something to turn the effector on -- do something to turn the effector on
if rulename and not minetest.get_node_timer (pos):is_started () then if rulename then
movefloor_move (pos, node, rulename, true) movefloor_move (pos, node, rulename)
end end
end end
} }
@@ -190,8 +432,6 @@ minetest.register_node("lwcomponents:movefloor", {
groups = { cracky = 2 }, groups = { cracky = 2 },
sounds = default.node_sound_wood_defaults (), sounds = default.node_sound_wood_defaults (),
mesecons = mesecon_support (), mesecons = mesecon_support (),
on_timer = on_timer,
}) })

1348
pistons.lua Normal file

File diff suppressed because it is too large Load Diff

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",
@@ -226,7 +225,9 @@ minetest.register_node ("lwcomponents:player_button_on", {
}, },
after_destruct = digistuff.remove_receiver, after_destruct = digistuff.remove_receiver,
-- on_rightclick = player_button_push, on_rightclick = function (pos, node, clicker, itemstack, pointed_thing)
-- so clicking when depressed doesn't place node
end,
on_timer = player_button_turnoff, on_timer = player_button_turnoff,
}) })

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
@@ -506,7 +482,7 @@ minetest.register_node("lwcomponents:puncher", {
tiles = { "lwpuncher_face.png", "lwpuncher_face.png", "lwpuncher.png", tiles = { "lwpuncher_face.png", "lwpuncher_face.png", "lwpuncher.png",
"lwpuncher.png", "lwpuncher.png", "lwpuncher_face.png"}, "lwpuncher.png", "lwpuncher.png", "lwpuncher_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -533,7 +509,7 @@ minetest.register_node("lwcomponents:puncher_locked", {
tiles = { "lwpuncher_face.png", "lwpuncher_face.png", "lwpuncher.png", tiles = { "lwpuncher_face.png", "lwpuncher_face.png", "lwpuncher.png",
"lwpuncher.png", "lwpuncher.png", "lwpuncher_face.png"}, "lwpuncher.png", "lwpuncher.png", "lwpuncher_face.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -560,7 +536,7 @@ minetest.register_node("lwcomponents:puncher_on", {
tiles = { "lwpuncher_face_on.png", "lwpuncher_face_on.png", "lwpuncher.png", tiles = { "lwpuncher_face_on.png", "lwpuncher_face_on.png", "lwpuncher.png",
"lwpuncher.png", "lwpuncher.png", "lwpuncher_face_on.png"}, "lwpuncher.png", "lwpuncher.png", "lwpuncher_face_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -587,7 +563,7 @@ minetest.register_node("lwcomponents:puncher_locked_on", {
tiles = { "lwpuncher_face_on.png", "lwpuncher_face_on.png", "lwpuncher.png", tiles = { "lwpuncher_face_on.png", "lwpuncher_face_on.png", "lwpuncher.png",
"lwpuncher.png", "lwpuncher.png", "lwpuncher_face_on.png"}, "lwpuncher.png", "lwpuncher.png", "lwpuncher_face_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,

View File

@@ -13,7 +13,7 @@ CC BY-SA 3.0
Version Version
======= =======
0.1.11 0.1.28
Minetest Version Minetest Version
@@ -28,13 +28,14 @@ default
Optional Dependencies Optional Dependencies
===================== =====================
lwdrops
mesecons mesecons
digilines digilines
unifieddyes unifieddyes
intllib intllib
hopper hopper
digistuff digistuff
pipeworks
lwwires
Installation Installation
@@ -59,13 +60,20 @@ 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. * Cannon, shoots an item on command with directional aiming (plus 3 shells).
* Digiswitch, digilines controlled mesecons power. * Double (optionally single) reach pistons and sticky pistons.
* Digilines Switch, digilines controlled mesecons power.
* Movefloor, similar to vertical mesecons movestone. * Movefloor, similar to vertical mesecons movestone.
* Camera, takes a representative image.
* Storage, indexed storage units.
* Hoppers, that are more compatible with this mod.
* Force Field Generator, repels players and mobs within a radius.
* 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
and digilines conductor. and digilines conductor.
@@ -93,6 +101,9 @@ Alert handler errors
Issue errors when handler's of other mods fail. Issue errors when handler's of other mods fail.
Default: true Default: true
Maximum piston nodes
Maximum nodes a piston can push.
Default: 15
------------------------------------------------------------------------ ------------------------------------------------------------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 84 KiB

View File

@@ -9,6 +9,12 @@ utils.settings.spawn_mobs =
utils.settings.alert_handler_errors = utils.settings.alert_handler_errors =
minetest.settings:get_bool ("lwcomponents_alert_handler_errors", true) minetest.settings:get_bool ("lwcomponents_alert_handler_errors", true)
utils.settings.max_piston_nodes =
tonumber (minetest.settings:get ("lwcomponents_max_piston_nodes") or 15)
utils.settings.default_stack_max =
tonumber (minetest.settings:get ("default_stack_max")) or 99
-- --

View File

@@ -3,3 +3,6 @@ lwcomponents_spawn_mobs (Spawn mobs) bool true
# Issue errors when handler's of other mods fail. # Issue errors when handler's of other mods fail.
lwcomponents_alert_handler_errors (Alert handler errors) bool true lwcomponents_alert_handler_errors (Alert handler errors) bool true
# Maximum nodes a piston can push.
lwcomponents_max_piston_nodes (Maximum piston nodes) int 15

129
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)
@@ -528,7 +491,7 @@ minetest.register_node("lwcomponents:siren", {
tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren.png", tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren.png",
"lwsiren.png", "lwsiren.png", "lwsiren.png"}, "lwsiren.png", "lwsiren.png", "lwsiren.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -555,7 +518,7 @@ minetest.register_node("lwcomponents:siren_locked", {
tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren.png", tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren.png",
"lwsiren.png", "lwsiren.png", "lwsiren.png"}, "lwsiren.png", "lwsiren.png", "lwsiren.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -582,7 +545,7 @@ minetest.register_node("lwcomponents:siren_on", {
tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren_on.png", tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren_on.png",
"lwsiren_on.png", "lwsiren_on.png", "lwsiren_on.png"}, "lwsiren_on.png", "lwsiren_on.png", "lwsiren_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -609,7 +572,7 @@ minetest.register_node("lwcomponents:siren_locked_on", {
tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren_on.png", tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren_on.png",
"lwsiren_on.png", "lwsiren_on.png", "lwsiren_on.png"}, "lwsiren_on.png", "lwsiren_on.png", "lwsiren_on.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -636,7 +599,7 @@ minetest.register_node("lwcomponents:siren_alarm", {
tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren_alarm.png", tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren_alarm.png",
"lwsiren_alarm.png", "lwsiren_alarm.png", "lwsiren_alarm.png"}, "lwsiren_alarm.png", "lwsiren_alarm.png", "lwsiren_alarm.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,
@@ -664,7 +627,7 @@ minetest.register_node("lwcomponents:siren_locked_alarm", {
tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren_alarm.png", tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren_alarm.png",
"lwsiren_alarm.png", "lwsiren_alarm.png", "lwsiren_alarm.png"}, "lwsiren_alarm.png", "lwsiren_alarm.png", "lwsiren_alarm.png"},
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1, wires_connect = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "none", paramtype = "none",
param1 = 0, param1 = 0,

View File

@@ -35,6 +35,7 @@ mesecon.register_node (":lwcomponents:solid_conductor",
groups = { groups = {
dig_immediate = 2, dig_immediate = 2,
ud_param2_colorable = 1, ud_param2_colorable = 1,
wires_connect = 1
}, },
}, },
{ {
@@ -51,7 +52,8 @@ mesecon.register_node (":lwcomponents:solid_conductor",
groups = { groups = {
dig_immediate = 2, dig_immediate = 2,
ud_param2_colorable = 1, ud_param2_colorable = 1,
not_in_creative_inventory = 1 not_in_creative_inventory = 1,
wires_connect = 1
}, },
} }
) )
@@ -101,6 +103,7 @@ mesecon.register_node (":lwcomponents:solid_horizontal_conductor",
groups = { groups = {
dig_immediate = 2, dig_immediate = 2,
ud_param2_colorable = 1, ud_param2_colorable = 1,
wires_connect = 1
}, },
}, },
{ {
@@ -117,7 +120,8 @@ mesecon.register_node (":lwcomponents:solid_horizontal_conductor",
groups = { groups = {
dig_immediate = 2, dig_immediate = 2,
ud_param2_colorable = 1, ud_param2_colorable = 1,
not_in_creative_inventory = 1 not_in_creative_inventory = 1,
wires_connect = 1
}, },
} }
) )

Binary file not shown.

BIN
sounds/lwmovefloor.ogg Normal file

Binary file not shown.

BIN
sounds/lwpiston_extend.ogg Normal file

Binary file not shown.

BIN
sounds/lwpiston_retract.ogg Normal file

Binary file not shown.

1432
storage.lua Normal file

File diff suppressed because it is too large Load Diff

BIN
textures/lwcamera.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

BIN
textures/lwcamera_lens.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
textures/lwcannon_shell.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

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: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 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.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 723 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 857 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

80
through_wire.lua Normal file
View File

@@ -0,0 +1,80 @@
local utils = ...
local S = utils.S
if utils.mesecon_supported then
local through_wire_get_rules = function (node)
local rules = { {x = -1, y = 0, z = 0},
{x = 2, y = 0, z = 0},
{x = 3, y = 0, z = 0} }
if node.param2 == 2 then
rules = mesecon.rotate_rules_left(rules)
elseif node.param2 == 3 then
rules = mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules))
elseif node.param2 == 0 then
rules = mesecon.rotate_rules_right(rules)
end
return rules
end
mesecon.register_node ("lwcomponents:through_wire", {
description = S("Mesecons Through Wire"),
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
on_rotate = false,
selection_box = {
type = "fixed",
fixed = { -3/16, -8/16, -8/16, 3/16, 3/16, 8/16 }
},
node_box = {
type = "fixed",
fixed = {
{ -3/16, -3/16, 13/32 , 3/16, 3/16 , 8/16 }, -- the smaller bump
{ -1/32, -1/32, 1/2 , 1/32, 1/32 , 3/2 }, -- the wire through the block
{ -2/32, -1/2 , 0.5002-3/32 , 2/32, 0 , 0.5 }, -- the vertical wire bit
{ -2/32, -1/2 , -16/32+0.001 , 2/32, -14/32, 7/16+0.002 } -- the horizontal wire
}
},
drop = "lwcomponents:through_wire_off",
sounds = default.node_sound_defaults(),
}, {
tiles = { "mesecons_wire_off.png" },
groups = { dig_immediate = 3 },
mesecons = {
conductor = {
state = mesecon.state.off,
rules = through_wire_get_rules,
onstate = "lwcomponents:through_wire_on"
}
}
}, {
tiles = { "mesecons_wire_on.png" },
groups = { dig_immediate = 3, not_in_creative_inventory = 1 },
mesecons = {
conductor = {
state = mesecon.state.on,
rules = through_wire_get_rules,
offstate = "lwcomponents:through_wire_off"
}
}
})
end -- utils.mesecon_supported
--

Some files were not shown because too many files have changed in this diff Show More