Compare commits

...

12 Commits

Author SHA1 Message Date
loosewheel
7b6b0176a7 Add files via upload 2021-11-14 00:17:20 +10:00
loosewheel
f475b498e5 Add files via upload 2021-11-14 00:16:22 +10:00
loosewheel
3adc0fcf70 Add files via upload 2021-11-13 23:12:12 +10:00
loosewheel
7ed06d7e94 Add files via upload 2021-11-13 23:11:13 +10:00
loosewheel
35ec093f88 Add files via upload 2021-11-13 23:09:34 +10:00
loosewheel
32df0b8420 Add files via upload 2021-11-12 14:40:43 +10:00
loosewheel
b3d0f4ebce Delete foo 2021-11-10 01:01:52 +10:00
loosewheel
a17e128f79 Add files via upload 2021-11-10 01:01:36 +10:00
loosewheel
44a3d9f80f Create foo 2021-11-10 01:01:02 +10:00
loosewheel
d027b10c21 Add files via upload 2021-11-10 00:59:52 +10:00
loosewheel
1aed7e8b78 Add files via upload 2021-11-10 00:58:25 +10:00
loosewheel
2b90c573eb Add files via upload 2021-11-10 00:57:32 +10:00
32 changed files with 2108 additions and 55 deletions

View File

@@ -1,3 +1,24 @@
v 0.1.0 v 0.1.0
* initial release * initial release
v0.1.1
* Fixed receiving digilines message on "" channel.
* Added siren.
* Made digilines optional for solid conductor blocks.
* Fixed lighting
* Added puncher
v0.1.2
* Added support for hopper as optional dependency for droppers, dispensers
and collectors.
* Added digilines message to punchers when something is punched.
v0.1.3
* Added hp and height info from detector.
* Added dispensers spawn if spawner with optional dependency on mobs mod.
If mobs:egg is dispensed 10% change a chicken is dispensed instead.
* Added player_button.

View File

@@ -20,7 +20,7 @@ local function send_collect_message (pos, name, count)
if channel:len () > 0 then if channel:len () > 0 then
utils.digilines_receptor_send (pos, utils.digilines_receptor_send (pos,
digiline.rules.default, utils.digilines_default_rules,
channel, channel,
{ action = "collect", { action = "collect",
name = name, name = name,
@@ -389,7 +389,7 @@ local function digilines_support ()
{ {
wire = wire =
{ {
rules = digiline.rules.default, rules = utils.digilines_default_rules,
}, },
effector = effector =
@@ -400,7 +400,7 @@ local function digilines_support ()
if meta then if meta then
local this_channel = meta:get_string ("channel") local this_channel = meta:get_string ("channel")
if this_channel == channel then if this_channel ~= "" and this_channel == channel then
local m = { } local m = { }
for w in string.gmatch(msg, "[^%s]+") do for w in string.gmatch(msg, "[^%s]+") do
m[#m + 1] = w m[#m + 1] = w
@@ -432,7 +432,7 @@ minetest.register_node("lwcomponents:collector", {
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "none",
param1 = 0, param1 = 0,
floodable = false, floodable = false,
drop = "lwcomponents:collector", drop = "lwcomponents:collector",
@@ -458,7 +458,7 @@ minetest.register_node("lwcomponents:collector_locked", {
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "none",
param1 = 0, param1 = 0,
floodable = false, floodable = false,
drop = "lwcomponents:collector_locked", drop = "lwcomponents:collector_locked",
@@ -484,7 +484,7 @@ minetest.register_node("lwcomponents:collector_on", {
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "none",
param1 = 0, param1 = 0,
floodable = false, floodable = false,
drop = "lwcomponents:collector", drop = "lwcomponents:collector",
@@ -510,7 +510,7 @@ minetest.register_node("lwcomponents:collector_locked_on", {
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "none",
param1 = 0, param1 = 0,
floodable = false, floodable = false,
drop = "lwcomponents:collector_locked", drop = "lwcomponents:collector_locked",
@@ -529,6 +529,38 @@ minetest.register_node("lwcomponents:collector_locked_on", {
utils.hopper_add_container({
{"top", "lwcomponents:collector", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:collector", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:collector", "main"}, -- insert items from hopper at side
})
utils.hopper_add_container({
{"top", "lwcomponents:collector_locked", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:collector_locked", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:collector_locked", "main"}, -- insert items from hopper at side
})
utils.hopper_add_container({
{"top", "lwcomponents:collector_on", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:collector_on", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:collector_on", "main"}, -- insert items from hopper at side
})
utils.hopper_add_container({
{"top", "lwcomponents:collector_locked_on", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:collector_locked_on", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:collector_locked_on", "main"}, -- insert items from hopper at side
})
end -- utils.digilines_supported end -- utils.digilines_supported

View File

@@ -58,6 +58,42 @@ minetest.register_craft( {
}, },
}) })
minetest.register_craft( {
output = "lwcomponents:siren",
recipe = {
{ "group:wood", "default:chest" },
{ "default:copper_ingot", "default:steel_ingot" },
},
})
minetest.register_craft( {
output = "lwcomponents:siren_locked",
recipe = {
{ "group:wood", "default:chest_locked" },
{ "default:copper_ingot", "default:steel_ingot" },
},
})
minetest.register_craft( {
output = "lwcomponents:puncher",
recipe = {
{ "default:chest", "default:sword_stone" },
{ "default:copper_ingot", "default:steel_ingot" },
},
})
minetest.register_craft( {
output = "lwcomponents:puncher_locked",
recipe = {
{ "default:chest_locked", "default:sword_stone" },
{ "default:copper_ingot", "default:steel_ingot" },
},
})
end -- utils.digilines_supported or utils.mesecon_supported end -- utils.digilines_supported or utils.mesecon_supported
@@ -85,6 +121,21 @@ end -- utils.digilines_supported
if utils.digilines_supported and utils.digistuff_supported then
minetest.register_craft({
output = "lwcomponents:player_button",
recipe = {
{ "mesecons_button:button_off", "digilines:wire_std_00000000" }
},
})
end -- utils.digilines_supported and utils.digistuff_supported
if utils.mesecon_supported and mesecon.mvps_push then if utils.mesecon_supported and mesecon.mvps_push then
minetest.register_craft ({ minetest.register_craft ({
@@ -115,7 +166,7 @@ end -- utils.digilines_supported and utils.mesecon_supported
if utils.unifieddyes_supported and utils.mesecon_supported and utils.digilines_supported then if utils.unifieddyes_supported and utils.mesecon_supported then
minetest.register_craft ({ minetest.register_craft ({
output = "lwcomputers:solid_conductor_off 3", output = "lwcomputers:solid_conductor_off 3",
@@ -134,7 +185,7 @@ minetest.register_craft ({
}, },
}) })
end -- utils.unifieddyes_supported and utils.mesecon_supported and utils.digilines_supported then end -- utils.unifieddyes_supported and utils.mesecon_supported then

View File

@@ -4,3 +4,6 @@ mesecons?
digilines? digilines?
unifieddyes? unifieddyes?
intllib? intllib?
hopper?
mobs?
digistuff?

View File

@@ -60,7 +60,7 @@ end
local function send_detect_message (pos, item_type, name, label, item_pos, count) local function send_detect_message (pos, item_type, name, label, item_pos, count, hp, height)
if utils.digilines_supported then if utils.digilines_supported then
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
@@ -69,14 +69,16 @@ local function send_detect_message (pos, item_type, name, label, item_pos, count
if channel:len () > 0 then if channel:len () > 0 then
utils.digilines_receptor_send (pos, utils.digilines_receptor_send (pos,
digiline.rules.default, utils.digilines_default_rules,
channel, channel,
{ action = "detect", { action = "detect",
type = item_type, type = item_type,
name = name, name = name,
label = label, label = label,
pos = to_relative_coords (pos, item_pos), pos = to_relative_coords (pos, item_pos),
count = count }) count = count,
hp = hp,
height = height })
end end
end end
end end
@@ -132,6 +134,33 @@ end
local function get_entity_height (objref)
if objref.get_luaentity then
entity = objref:get_luaentity ()
if entity and entity.name then
def = minetest.registered_entities[entity.name]
if def and type (def.collisionbox) == "table" and
type (def.collisionbox[5]) == "number" then
return def.collisionbox[5]
end
end
end
local props = objref:get_properties ()
if props and props.collisionbox and type (props.collisionbox) == "table" and
type (props.collisionbox[5]) == "number" then
return props.collisionbox[5]
end
return 0
end
local function detect (pos) local function detect (pos)
local meta = minetest.get_meta (pos) local meta = minetest.get_meta (pos)
local detected = false local detected = false
@@ -153,7 +182,9 @@ local function detect (pos)
object[i]:get_player_name (), object[i]:get_player_name (),
object[i]:get_player_name (), object[i]:get_player_name (),
object[i]:get_pos (), object[i]:get_pos (),
1) 1,
object[i]:get_hp (),
get_entity_height (object[i]))
detected = true detected = true
end end
@@ -174,7 +205,9 @@ local function detect (pos)
stack:get_name (), stack:get_name (),
stack:get_name (), stack:get_name (),
object[i]:get_pos (), object[i]:get_pos (),
stack:get_count ()) stack:get_count (),
0,
0)
detected = true detected = true
end end
@@ -203,7 +236,9 @@ local function detect (pos)
name, name,
label, label,
object[i]:get_pos (), object[i]:get_pos (),
1) 1,
object[i]:get_hp (),
get_entity_height (object[i]))
detected = true detected = true
@@ -228,7 +263,9 @@ local function detect (pos)
node.name, node.name,
node.name, node.name,
testpos, testpos,
1) 1,
0,
0)
detected = true detected = true
end end
@@ -565,7 +602,7 @@ local function digilines_support ()
{ {
wire = wire =
{ {
rules = digiline.rules.default, rules = utils.digilines_default_rules,
}, },
effector = effector =
@@ -576,7 +613,7 @@ local function digilines_support ()
if meta then if meta then
local this_channel = meta:get_string ("channel") local this_channel = meta:get_string ("channel")
if this_channel == channel then if this_channel ~= "" and this_channel == channel then
local m = { } local m = { }
for w in string.gmatch(msg, "[^%s]+") do for w in string.gmatch(msg, "[^%s]+") do
m[#m + 1] = w m[#m + 1] = w
@@ -666,7 +703,7 @@ minetest.register_node("lwcomponents:detector", {
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "none",
param1 = 0, param1 = 0,
paramtype2 = "facedir", paramtype2 = "facedir",
param2 = 1, param2 = 1,
@@ -695,7 +732,7 @@ minetest.register_node("lwcomponents:detector_locked", {
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "none",
param1 = 0, param1 = 0,
paramtype2 = "facedir", paramtype2 = "facedir",
param2 = 1, param2 = 1,
@@ -724,7 +761,7 @@ minetest.register_node("lwcomponents:detector_on", {
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "none",
param1 = 0, param1 = 0,
paramtype2 = "facedir", paramtype2 = "facedir",
param2 = 1, param2 = 1,
@@ -753,7 +790,7 @@ minetest.register_node("lwcomponents:detector_locked_on", {
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 }, groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "none",
param1 = 0, param1 = 0,
paramtype2 = "facedir", paramtype2 = "facedir",
param2 = 1, param2 = 1,

View File

@@ -71,7 +71,7 @@ local function digilines_support ()
if meta then if meta then
local mychannel = meta:get_string ("channel") local mychannel = meta:get_string ("channel")
if mychannel == channel then if mychannel ~= "" and mychannel == channel then
if type (msg) == "string" then if type (msg) == "string" then
local words = { } local words = { }

View File

@@ -52,7 +52,7 @@ local function send_dispense_message (pos, slot, name)
if channel:len () > 0 then if channel:len () > 0 then
utils.digilines_receptor_send (pos, utils.digilines_receptor_send (pos,
digiline.rules.default, utils.digilines_default_rules,
channel, channel,
{ action = "dispense", { action = "dispense",
name = name, name = name,
@@ -64,6 +64,90 @@ end
local function try_spawn (pos, node, item)
if utils.mobs_supported then
local mob = item:get_name ()
local item_def = minetest.registered_craftitems[mob]
local spawn_pos = dispense_pos (pos, node)
if item_def and item_def.groups and item_def.groups.spawn_egg then
if mob:sub (mob:len () - 4) == "_set" then
mob = mob:sub (1, mob:len () - 5)
if minetest.registered_entities[mob] then
local data = item:get_metadata ()
local smob = minetest.add_entity (spawn_pos, mob, data)
local ent = smob and smob:get_luaentity ()
if ent then
local meta = minetest.get_meta (pos)
if meta then
local owner = meta:get_string ("owner")
-- set owner if not a monster
if owner:len () > 0 and ent.type ~= "monster" then
ent.owner = owner
ent.tamed = true
end
end
end
return smob
end
else
if minetest.registered_entities[mob] then
local smob = minetest.add_entity (spawn_pos, mob)
local ent = smob and smob:get_luaentity ()
if ent then
local meta = minetest.get_meta (pos)
if meta then
local owner = meta:get_string ("owner")
-- set owner if not a monster
if owner:len () > 0 and ent.type ~= "monster" then
ent.owner = owner
ent.tamed = true
end
end
end
return smob
end
end
elseif mob == "mobs:egg" then
if math.random (1, 10) == 1 then
local smob = minetest.add_entity (spawn_pos, "mobs_animal:chicken")
local ent = smob and smob:get_luaentity ()
if ent then
local meta = minetest.get_meta (pos)
if meta then
local owner = meta:get_string ("owner")
-- set owner if not a monster
if owner:len () > 0 and ent.type ~= "monster" then
ent.owner = owner
ent.tamed = true
end
end
end
return smob
end
end
end
return nil
end
-- slot: -- slot:
-- nil - next item, no dispense if empty -- nil - next item, no dispense if empty
-- number - 1 item from slot, no dispense if empty -- number - 1 item from slot, no dispense if empty
@@ -119,7 +203,11 @@ local function dispense_item (pos, node, slot)
if item then if item then
item:set_count (1) item:set_count (1)
local obj = minetest.add_item (dispense_pos (pos, node), item) local obj = try_spawn (pos, node, item)
if not obj then
obj = minetest.add_item (dispense_pos (pos, node), item)
end
if obj then if obj then
obj:set_velocity (dispense_velocity (node)) obj:set_velocity (dispense_velocity (node))
@@ -314,7 +402,7 @@ local function digilines_support ()
{ {
wire = wire =
{ {
rules = digiline.rules.default, rules = utils.digilines_default_rules,
}, },
effector = effector =
@@ -325,7 +413,7 @@ local function digilines_support ()
if meta then if meta then
local this_channel = meta:get_string ("channel") local this_channel = meta:get_string ("channel")
if this_channel == channel then if this_channel ~= "" and this_channel == channel then
local m = { } local m = { }
for w in string.gmatch(msg, "[^%s]+") do for w in string.gmatch(msg, "[^%s]+") do
m[#m + 1] = w m[#m + 1] = w
@@ -377,7 +465,7 @@ minetest.register_node("lwcomponents:dispenser", {
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "none",
param1 = 0, param1 = 0,
paramtype2 = "facedir", paramtype2 = "facedir",
param2 = 1, param2 = 1,
@@ -403,7 +491,7 @@ minetest.register_node("lwcomponents:dispenser_locked", {
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "none",
param1 = 0, param1 = 0,
paramtype2 = "facedir", paramtype2 = "facedir",
param2 = 1, param2 = 1,
@@ -422,6 +510,22 @@ minetest.register_node("lwcomponents:dispenser_locked", {
utils.hopper_add_container({
{"top", "lwcomponents:dispenser", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:dispenser", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:dispenser", "main"}, -- insert items from hopper at side
})
utils.hopper_add_container({
{"top", "lwcomponents:dispenser_locked", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:dispenser_locked", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:dispenser_locked", "main"}, -- insert items from hopper at side
})
end -- utils.digilines_supported or utils.mesecon_supported end -- utils.digilines_supported or utils.mesecon_supported

View File

@@ -32,7 +32,7 @@ local function send_drop_message (pos, slot, name)
if channel:len () > 0 then if channel:len () > 0 then
utils.digilines_receptor_send (pos, utils.digilines_receptor_send (pos,
digiline.rules.default, utils.digilines_default_rules,
channel, channel,
{ action = "drop", { action = "drop",
name = name, name = name,
@@ -290,7 +290,7 @@ local function digilines_support ()
{ {
wire = wire =
{ {
rules = digiline.rules.default, rules = utils.digilines_default_rules,
}, },
effector = effector =
@@ -301,7 +301,7 @@ local function digilines_support ()
if meta then if meta then
local this_channel = meta:get_string ("channel") local this_channel = meta:get_string ("channel")
if this_channel == channel then if this_channel ~= "" and this_channel == channel then
local m = { } local m = { }
for w in string.gmatch(msg, "[^%s]+") do for w in string.gmatch(msg, "[^%s]+") do
m[#m + 1] = w m[#m + 1] = w
@@ -353,7 +353,7 @@ minetest.register_node("lwcomponents:dropper", {
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "none",
param1 = 0, param1 = 0,
paramtype2 = "facedir", paramtype2 = "facedir",
param2 = 1, param2 = 1,
@@ -379,7 +379,7 @@ minetest.register_node("lwcomponents:dropper_locked", {
is_ground_content = false, is_ground_content = false,
groups = { cracky = 3 }, groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (), sounds = default.node_sound_stone_defaults (),
paramtype = "light", paramtype = "none",
param1 = 0, param1 = 0,
paramtype2 = "facedir", paramtype2 = "facedir",
param2 = 1, param2 = 1,
@@ -398,6 +398,21 @@ minetest.register_node("lwcomponents:dropper_locked", {
utils.hopper_add_container({
{"top", "lwcomponents:dropper", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:dropper", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:dropper", "main"}, -- insert items from hopper at side
})
utils.hopper_add_container({
{"top", "lwcomponents:dropper_locked", "main"}, -- take items from above into hopper below
{"bottom", "lwcomponents:dropper_locked", "main"}, -- insert items below from hopper above
{"side", "lwcomponents:dropper_locked", "main"}, -- insert items from hopper at side
})
end -- utils.digilines_supported or utils.mesecon_supported end -- utils.digilines_supported or utils.mesecon_supported

View File

@@ -1,4 +1,4 @@
local version = "0.1.0" local version = "0.1.3"
local mod_storage = minetest.get_mod_storage () local mod_storage = minetest.get_mod_storage ()
@@ -20,6 +20,9 @@ loadfile (modpath.."/dropper.lua") (utils)
loadfile (modpath.."/collector.lua") (utils) loadfile (modpath.."/collector.lua") (utils)
loadfile (modpath.."/dispenser.lua") (utils) loadfile (modpath.."/dispenser.lua") (utils)
loadfile (modpath.."/detector.lua") (utils) loadfile (modpath.."/detector.lua") (utils)
loadfile (modpath.."/siren.lua") (utils)
loadfile (modpath.."/puncher.lua") (utils)
loadfile (modpath.."/player_button.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

@@ -14,8 +14,59 @@ 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
lwsiren-buzz.ogg
----------------
derived from https://www.freesoundslibrary.com/alarm-sound-effect/
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.
https://creativecommons.org/licenses/by/4.0/
lwsiren-horn.ogg
----------------
derived from https://www.freesoundslibrary.com/ahooga-horn/
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.
https://creativecommons.org/licenses/by/4.0/
lwsiren-siren.ogg
------------------
https://www.freesoundslibrary.com/cop-siren/
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.
https://creativecommons.org/licenses/by/4.0/
lwsiren-raid.ogg
-----------------
derived from https://www.freesoundslibrary.com/space-ship-siren-sound/
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.
https://creativecommons.org/licenses/by/4.0/
Media license Media license
------------- -------------
siren images derived from images from https://openclipart.org, which is
public domain.
player button images derived from mesecons button image.
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)
You are free to: You are free to:

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 optional_depends = lwdrops, mesecons, digilines, unifieddyes, intllib, hopper, mobs, digistuff

232
player_button.lua Normal file
View File

@@ -0,0 +1,232 @@
local utils = ...
local S = utils.S
if utils.digilines_supported and utils.digistuff_supported then
local function on_contruct (pos)
local meta = minetest.get_meta(pos)
local spec =
"size[7.5,3]"..
"field[1,1;6,2;channel;Channel;${channel}]"..
"button_exit[2.5,2;3,1;submit;Set]"
meta:set_string("formspec", spec)
end
local function on_receive_fields (pos, formname, fields, sender)
local meta = minetest.get_meta(pos)
if fields.submit then
if fields.channel ~= "" then
meta:set_string ("channel", fields.channel)
meta:set_string ("formspec", "")
minetest.swap_node (pos, { name = "lwcomponents:player_button_off",
param2 = minetest.get_node(pos).param2 })
else
minetest.chat_send_player (sender:get_player_name(), "Please set a channel!")
end
end
end
local function player_button_push (pos, node, player)
local meta = minetest.get_meta (pos)
if player and player:is_player () then
local channel = meta:get_string ("channel")
local formspec = meta:get_string ("formspec")
if channel:len () > 0 and formspec:len () == 0 then
utils.digilines_receptor_send (pos,
digistuff.button_get_rules (node),
channel,
{ action = "player",
name = player:get_player_name () })
end
end
if node.name == "lwcomponents:player_button_off" then
node.name = "lwcomponents:player_button_on"
minetest.swap_node(pos, node)
if digistuff.mesecons_installed then
minetest.sound_play ("mesecons_button_push", { pos = pos })
end
minetest.get_node_timer (pos):start (0.25)
end
end
local function player_button_turnoff (pos)
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos)
if node.name == "lwcomponents:player_button_on" then
node.name = "lwcomponents:player_button_off"
minetest.swap_node (pos, node)
if digistuff.mesecons_installed then
minetest.sound_play ("mesecons_button_pop", { pos = pos })
end
end
end
minetest.register_node ("lwcomponents:player_button", {
description = "Player Button",
drawtype = "nodebox",
tiles = {
"lwplayer_button_side.png",
"lwplayer_button_side.png",
"lwplayer_button_side.png",
"lwplayer_button_side.png",
"lwplayer_button_side.png",
"lwplayer_button.png"
},
paramtype = "light",
paramtype2 = "facedir",
legacy_wallmounted = true,
walkable = false,
sunlight_propagates = true,
drop = "lwcomponents:player_button",
selection_box = {
type = "fixed",
fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 }
},
node_box = {
type = "fixed",
fixed = {
{ -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 }, -- the thin plate behind the button
{ -4/16, -2/16, 4/16, 4/16, 2/16, 6/16 } -- the button itself
}
},
groups = { dig_immediate = 2, digiline_receiver = 1 },
_digistuff_channelcopier_fieldname = "channel",
sounds = default and default.node_sound_stone_defaults(),
digiline =
{
receptor = {},
wire = {
rules = digistuff.button_get_rules,
},
},
on_construct = on_contruct,
after_place_node = digistuff.place_receiver,
after_destruct = digistuff.remove_receiver,
on_receive_fields = on_receive_fields,
})
minetest.register_node ("lwcomponents:player_button_off", {
description = "Player Button",
drawtype = "nodebox",
tiles = {
"lwplayer_button_side.png",
"lwplayer_button_side.png",
"lwplayer_button_side.png",
"lwplayer_button_side.png",
"lwplayer_button_side.png",
"lwplayer_button.png"
},
paramtype = "light",
paramtype2 = "facedir",
legacy_wallmounted = true,
walkable = false,
sunlight_propagates = true,
drop = "lwcomponents:player_button",
selection_box = {
type = "fixed",
fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 }
},
node_box = {
type = "fixed",
fixed = {
{ -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 }, -- the thin plate behind the button
{ -4/16, -2/16, 4/16, 4/16, 2/16, 6/16 } -- the button itself
}
},
groups = { dig_immediate = 2, digiline_receiver = 1, not_in_creative_inventory = 1 },
_digistuff_channelcopier_fieldname = "channel",
sounds = default and default.node_sound_stone_defaults(),
digiline =
{
receptor = {},
wire = {
rules = digistuff.button_get_rules,
},
effector = {
action = digistuff.button_handle_digilines,
},
},
after_destruct = digistuff.remove_receiver,
on_rightclick = player_button_push,
})
minetest.register_node ("lwcomponents:player_button_on", {
description = "Player Button",
drawtype = "nodebox",
tiles = {
"lwplayer_button_side.png",
"lwplayer_button_side.png",
"lwplayer_button_side.png",
"lwplayer_button_side.png",
"lwplayer_button_side.png",
"lwplayer_button_on.png"
},
paramtype = "light",
paramtype2 = "facedir",
legacy_wallmounted = true,
walkable = false,
sunlight_propagates = true,
light_source = 7,
drop = "lwcomponents:player_button",
selection_box = {
type = "fixed",
fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 }
},
node_box = {
type = "fixed",
fixed = {
{ -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 },
{ -4/16, -2/16, 11/32, 4/16, 2/16, 6/16 }
}
},
groups = { dig_immediate = 2, digiline_receiver = 1, not_in_creative_inventory = 1 },
_digistuff_channelcopier_fieldname = "channel",
sounds = default and default.node_sound_stone_defaults(),
digiline =
{
receptor = {},
wire = {
rules = digistuff.button_get_rules,
},
},
after_destruct = digistuff.remove_receiver,
-- on_rightclick = player_button_push,
on_timer = player_button_turnoff,
})
end -- utils.digilines_supported and utils.digistuff_supported

614
puncher.lua Normal file
View File

@@ -0,0 +1,614 @@
local utils = ...
local S = utils.S
if utils.digilines_supported or utils.mesecon_supported then
local function send_punch_message (pos, item_type, name, label)
if utils.digilines_supported then
local meta = minetest.get_meta (pos)
if meta then
local channel = meta:get_string ("channel")
if channel:len () > 0 then
utils.digilines_receptor_send (pos,
utils.digilines_default_rules,
channel,
{ action = "punch",
type = item_type,
name = name,
label = label })
end
end
end
end
local function direction_vector (pos)
local meta = minetest.get_meta (pos)
if meta then
local mode = meta:get_int ("mode")
if mode == 2 then
return { x = 0, y = 1, z = 0 }
elseif mode == 3 then
return { x = 0, y = -1, z = 0 }
else
local node = minetest.get_node (pos)
if node then
if node.param2 == 0 then
return { x = 0, y = 0, z = -1 }
elseif node.param2 == 1 then
return { x = -1, y = 0, z = 0 }
elseif node.param2 == 2 then
return { x = 0, y = 0, z = 1 }
elseif node.param2 == 3 then
return { x = 1, y = 0, z = 0 }
end
end
end
end
return { x = 0, y = 0, z = 0 }
end
local function punch (pos)
local meta = minetest.get_meta (pos)
local node = minetest.get_node (pos)
if meta and node and
(node.name == "lwcomponents:puncher_on" or
node.name == "lwcomponents:puncher_locked_on") then
local reach = tonumber (meta:get_string ("reach")) or 1
local dir = direction_vector (pos)
local punched = false
for r = 1, reach do
local tpos = vector.add (pos, vector.multiply (dir, r))
local object = minetest.get_objects_inside_radius (tpos, 0.68)
for i = 1, #object do
if object[i]:is_player () then
-- player
if meta:get_string ("players") == "true" then
object[i]:punch (object[i],
1.0,
{ full_punch_interval = 1.0,
damage_groups = { fleshy = 4 } },
vector.direction (pos, object[i]:get_pos ()))
send_punch_message (pos,
"player",
object[i]:get_player_name (),
object[i]:get_player_name ())
punched = true
end
elseif object[i].get_luaentity and object[i]:get_luaentity () and
object[i]:get_luaentity ().name and
object[i]:get_luaentity ().name == "__builtin:item" then
-- don't punch drops
elseif object[i].get_pos and object[i]:get_pos () then
-- entity
if meta:get_string ("entities") == "true" then
local name = object[i]:get_nametag_attributes ()
local label = ""
if type (name) == "table" then
label = tostring (name.text or "")
end
name = (object[i].get_luaentity and
object[i]:get_luaentity () and
object[i]:get_luaentity ().name) or ""
object[i]:punch (object[i],
1.0,
{ full_punch_interval = 1.0,
damage_groups = { fleshy = 4 } },
vector.direction (pos, object[i]:get_pos ()))
send_punch_message (pos,
"entity",
name,
label)
punched = true
end
end
end
if punched then
break
end
end
end
end
local function get_form_spec (is_off, mode, entities, players)
return
"formspec_version[3]\n"..
"size[11.75,7.0;true]\n"..
"field[1.0,1.0;4.0,0.8;channel;Channel;${channel}]\n"..
"button[5.5,1.0;2.0,0.8;setchannel;Set]\n"..
"button[8.25,1.0;2.5,0.8;"..((is_off and "start;Start") or "stop;Stop").."]\n"..
"field[1.0,2.5;4.0,0.8;reach;Reach;${reach}]\n"..
"button[5.5,2.5;2.0,0.8;setreach;Set]\n"..
"checkbox[1.0,4.4;entities;Entities;"..entities.."]\n"..
"checkbox[1.0,5.4;players;Players;"..players.."]\n"..
"textlist[4.875,4.0;5.875,2.0;mode;Forward,Up,Down;"..tostring (mode)..";false]"
end
local function update_form_spec (pos)
local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then
local is_off = node.name == "lwcomponents:puncher" or
node.name == "lwcomponents:puncher_locked"
meta:set_string ("formspec", get_form_spec (is_off,
meta:get_int ("mode"),
meta:get_string ("entities"),
meta:get_string ("players")))
end
end
local function start_puncher (pos)
local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then
if node.name == "lwcomponents:puncher" then
local meta = minetest.get_meta (pos)
if meta then
node.name = "lwcomponents:puncher_on"
minetest.swap_node (pos, node)
update_form_spec (pos)
end
elseif node.name == "lwcomponents:puncher_locked" then
local meta = minetest.get_meta (pos)
if meta then
node.name = "lwcomponents:puncher_locked_on"
minetest.swap_node (pos, node)
update_form_spec (pos)
end
end
end
end
local function stop_puncher (pos)
local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then
if node.name == "lwcomponents:puncher_on" then
local meta = minetest.get_meta (pos)
if meta then
node.name = "lwcomponents:puncher"
minetest.swap_node (pos, node)
update_form_spec (pos)
end
elseif node.name == "lwcomponents:puncher_locked_on" then
local meta = minetest.get_meta (pos)
if meta then
node.name = "lwcomponents:puncher_locked"
minetest.swap_node (pos, node)
update_form_spec (pos)
end
end
end
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos)
local is_off = itemstack and (itemstack:get_name () == "lwcomponents:puncher" or
itemstack:get_name () == "lwcomponents:puncher_locked")
meta:set_string ("formspec", get_form_spec (is_off, 1, "false", "false"))
meta:set_string ("reach", "1")
meta:set_int ("mode", 1)
meta:set_string ("entities", "false")
meta:set_string ("players", "false")
-- 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", "Puncher (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.setreach then
local meta = minetest.get_meta (pos)
if meta then
local reach = math.min (math.max (tonumber (fields.reach) or 1, 1), 5)
meta:set_string ("reach", tostring (reach))
end
end
if fields.start then
start_puncher (pos)
end
if fields.stop then
stop_puncher (pos)
end
if fields.entities ~= nil then
local meta = minetest.get_meta (pos)
if meta then
meta:set_string ("entities", fields.entities)
update_form_spec (pos)
end
end
if fields.players ~= nil then
local meta = minetest.get_meta (pos)
if meta then
meta:set_string ("players", fields.players)
update_form_spec (pos)
end
end
if fields.mode then
local event = minetest.explode_textlist_event (fields.mode)
if event.type == "CHG" then
local meta = minetest.get_meta (pos)
if meta then
meta:set_int ("mode", event.index)
update_form_spec (pos)
end
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
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos)
minetest.remove_node (pos)
end
end
end
end
end
end
local function on_rightclick (pos, node, clicker, itemstack, pointed_thing)
if not utils.can_interact_with_node (pos, clicker) then
if clicker and clicker:is_player () then
local owner = "<unknown>"
local meta = minetest.get_meta (pos)
if meta then
owner = meta:get_string ("owner")
end
local spec =
"formspec_version[3]"..
"size[8.0,4.0,false]"..
"label[1.0,1.0;Owned by "..minetest.formspec_escape (owner).."]"..
"button_exit[3.0,2.0;2.0,1.0;close;Close]"
minetest.show_formspec (clicker:get_player_name (),
"lwcomponents:component_privately_owned",
spec)
end
end
return itemstack
end
local function digilines_support ()
if utils.digilines_supported then
return
{
wire =
{
rules = utils.digilines_default_rules,
},
effector =
{
action = function (pos, node, channel, msg)
local meta = minetest.get_meta(pos)
if meta then
local this_channel = meta:get_string ("channel")
if this_channel ~= "" and this_channel == channel then
local m = { }
for w in string.gmatch(msg, "[^%s]+") do
m[#m + 1] = w
end
if m[1] == "start" then
start_puncher (pos)
elseif m[1] == "stop" then
stop_puncher (pos)
elseif m[1] == "reach" then
local reach = math.min (math.max (tonumber (m[2]) or 1, 1), 5)
meta:set_string ("reach", tostring (reach))
elseif m[1] == "entities" then
meta:set_string ("entities", ((m[2] == "true") and "true") or "false")
update_form_spec (pos)
elseif m[1] == "players" then
meta:set_string ("players", ((m[2] == "true") and "true") or "false")
update_form_spec (pos)
elseif m[1] == "mode" then
if m[2] == "forward" then
meta:set_int ("mode", 1)
update_form_spec (pos)
elseif m[2] == "up" then
meta:set_int ("mode", 2)
update_form_spec (pos)
elseif m[2] == "down" then
meta:set_int ("mode", 3)
update_form_spec (pos)
end
elseif m[1] == "punch" then
punch (pos)
end
end
end
end,
}
}
end
return nil
end
local function mesecon_support ()
if utils.mesecon_supported then
return
{
effector =
{
rules = utils.mesecon_default_rules,
action_on = function (pos, node)
-- do something to turn the effector on
punch (pos)
end
}
}
end
return nil
end
minetest.register_node("lwcomponents:puncher", {
description = S("Puncher"),
tiles = { "lwpuncher_face.png", "lwpuncher_face.png", "lwpuncher.png",
"lwpuncher.png", "lwpuncher.png", "lwpuncher_face.png"},
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
floodable = false,
drop = "lwcomponents:puncher",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node,
on_blast = on_blast,
on_rightclick = on_rightclick
})
minetest.register_node("lwcomponents:puncher_locked", {
description = S("Puncher (locked)"),
tiles = { "lwpuncher_face.png", "lwpuncher_face.png", "lwpuncher.png",
"lwpuncher.png", "lwpuncher.png", "lwpuncher_face.png"},
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
floodable = false,
drop = "lwcomponents:puncher_locked",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node_locked,
on_blast = on_blast,
on_rightclick = on_rightclick
})
minetest.register_node("lwcomponents:puncher_on", {
description = S("Puncher"),
tiles = { "lwpuncher_face_on.png", "lwpuncher_face_on.png", "lwpuncher.png",
"lwpuncher.png", "lwpuncher.png", "lwpuncher_face_on.png"},
is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
floodable = false,
drop = "lwcomponents:puncher",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node,
on_blast = on_blast,
on_rightclick = on_rightclick
})
minetest.register_node("lwcomponents:puncher_locked_on", {
description = S("Puncher (locked)"),
tiles = { "lwpuncher_face_on.png", "lwpuncher_face_on.png", "lwpuncher.png",
"lwpuncher.png", "lwpuncher.png", "lwpuncher_face_on.png"},
is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
floodable = false,
drop = "lwcomponents:puncher_locked",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
digiline = digilines_support (),
on_receive_fields = on_receive_fields,
can_dig = can_dig,
after_place_node = after_place_node_locked,
on_blast = on_blast,
on_rightclick = on_rightclick
})
end -- utils.digilines_supported or utils.mesecon_supported
--

View File

@@ -13,7 +13,7 @@ CC BY-SA 3.0
Version Version
======= =======
0.1.0 0.1.3
Minetest Version Minetest Version
@@ -33,6 +33,9 @@ mesecons
digilines digilines
unifieddyes unifieddyes
intllib intllib
hopper
mobs
digistuff
Installation Installation
@@ -56,7 +59,8 @@ Dropper
* This block is only available if digilines and/or mesecons are loaded. * This block is only available if digilines and/or mesecons are loaded.
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. digilines conductor. If the hopper mod is loaded, will take items from the
top and sides, and release them from the bottom.
UI UI
@@ -96,7 +100,14 @@ Dispenser
* This block is only available if digilines and/or mesecons are loaded. * This block is only available if digilines and/or mesecons are loaded.
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. Also acts as a digilines conductor. If the hopper mod is loaded, will take
items from the top and sides, and release them from the bottom.
Dispensers support mobs mod if loaded. Will spawn the entity from an 'egg'
if possible, or the 'egg' is dispensed. If a chicken egg is dispensed a
10% chance a chicken is dispensed instead. If the spawned entity can be
owned (or tamed) and the dispenser is owned the owner of the dispenser is
set as the owner of the entity.
UI UI
@@ -137,7 +148,8 @@ Collector
* This block is only available if digilines is loaded. * This block is only available if digilines is loaded.
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. 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.
UI UI
@@ -230,7 +242,9 @@ message is a table with the following keys:
name = "<name>", name = "<name>",
label = "<label>", label = "<label>",
pos = { x = n, y = n, z = n }, pos = { x = n, y = n, z = n },
count = <count> count = <count>,
hp = <number>,
height = <number>
} }
type type
@@ -261,6 +275,148 @@ pos
count count
The count of items for a "drop", or 1 for everything else. The count of items for a "drop", or 1 for everything else.
hp
Health points for players and entities. Zero for everything else.
height
Height for players and entities. Zero for everything else. This is simply
the top position of the object's collision box.
Siren
-----
* This block is only available if digilines and/or mesecons are loaded.
Plays a sound repeatedly while active. Also acts as a digilines conductor.
UI
Channel - digilines channel of siren.
Distance - block distance the sound can be heard (range 0 to 100).
Volume - volume the sound is played.
Sound - select Buzzer, Horn, Raid or Siren.
Mesecons
Sound plays while mesecons power is applied.
Digilines messages
"start"
Start the siren (turn on).
"stop"
Stop the siren (turn off).
"distance <n>"
Set block distance the sound can be heard. <n> should be a number
from 1 to 100, and is trimmed to this range.
"volume <n>"
Set the sound volume. <n> should be a number from 1 to 100, and is
trimmed to this range.
"sound buzzer"
"sound horn"
"sound raid"
"sound siren"
Set the sound of the siren.
"siren on"
Activate the siren, if its on.
"siren off"
deactivate the siren.
Puncher
-------
* This block is only available if digilines and/or mesecons are loaded.
Punches players or entities within a given reach. Also acts as a
digilines conductor.
UI
Channel - digilines channel of detector.
Reach - block distance from puncher to punch.
Entities - if checked punches entities.
Players - if checked punches players.
mode:
Forward - punches to reach extent directly in front of the puncher (one block high).
Up - detects to reach extent directly above the puncher (one block wide).
Down - detects to reach extent directly below the puncher (one block wide).
Mesecons
Punches the next item when power is turned on.
Digilines messages
"start"
Start the puncher.
"stop"
Stop the puncher.
"reach <n>"
Set reach of the puncher. <n> should be a number from 1 to 5, and is
trimmed to this range.
"entities <true|false>"
Set punching of entities on or off.
"players <true|false>"
Set punching of players on or off.
"mode forward"
"mode up"
"mode down"
Set the puncher's mode.
"punch"
Action a single punch if the puncher is turned on.
When a player or entity is punched a digilines message is sent with the
puncher's channel. The message is a table with the following keys:
{
action = "punch",
type = "<type>", -- will be "entity" or "player"
name = "<name>",
label = "<label>"
}
type
Will be "entity" or "player".
name
For "entity" the registered entity name.
For "player" the player's name.
label
For "entity" the name tag text.
For "player" the player's name.
Player Button
-------------
* This block is only available if both digilines and digistuff are loaded.
When pressed sends a digilines message with the name of the player that
pressed the button.
The first time the button is right clicked a form opens to set the
digilines channel. After that right click presses the button. The
digilines cannot be changed after its set.
When the button is pressed a digilines message is sent with the button's
channel in the form:
{
action = "player",
name = <player name>
}
DigiSwitch DigiSwitch
@@ -309,8 +465,7 @@ the MoveFloor will not move.
Solid Color Conductors Solid Color Conductors
---------------------- ----------------------
* These blocks are only defined if mesecons, digilines, and unifieddyes are * These blocks are only defined if mesecons and unifieddyes are loaded.
loaded.
Provides 2 blocks that can be colored the same as Solid Color Block (with Provides 2 blocks that can be colored the same as Solid Color Block (with
the air brush) and is both a mesecons and digilines conductor. the air brush) and is both a mesecons and digilines conductor.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 70 KiB

692
siren.lua Normal file
View File

@@ -0,0 +1,692 @@
local utils = ...
local S = utils.S
if utils.digilines_supported or utils.mesecon_supported then
local sound_interval = 5.0
local siren_sounds =
{
"lwsiren-buzz",
"lwsiren-horn",
"lwsiren-raid",
"lwsiren-siren",
}
local function start_sound (pos)
local meta = minetest.get_meta (pos)
if meta then
local handle = meta:get_int ("sound_handle")
if handle ~= 0 then
minetest.sound_stop (handle)
meta:set_int ("sound_handle", 0)
end
local sound = siren_sounds[meta:get_int ("sound")]
if sound then
handle = minetest.sound_play (
sound,
{
pos = pos,
max_hear_distance = meta:get_int ("distance"),
gain = meta:get_int ("gain") / 100
})
meta:set_int ("sound_handle", handle)
end
end
end
local function stop_sound (pos)
local meta = minetest.get_meta (pos)
if meta then
local handle = meta:get_int ("sound_handle")
if handle ~= 0 then
minetest.sound_stop (handle)
meta:set_int ("sound_handle", 0)
end
end
end
local function get_form_spec (is_off, distance, gain, sound)
return
"formspec_version[3]\n"..
"size[11.75,6.0;true]\n"..
"field[1.0,1.0;4.0,0.8;channel;Channel;${channel}]\n"..
"button[5.5,1.0;2.0,0.8;setchannel;Set]\n"..
"button[8.25,1.0;2.5,0.8;"..((is_off and "start;Start") or "stop;Stop").."]\n"..
"label[1.0,2.5;Distance]\n"..
"scrollbaroptions[min=0;max=100;smallstep=10;largestep=10;thumbsize=10]\n"..
"scrollbar[1.0,2.9;6.0,0.5;horizontal;distance;"..tostring (distance).."]\n"..
"label[1.0,4.2;Volume]\n"..
"scrollbaroptions[min=0;max=100;smallstep=10;largestep=10;thumbsize=10]\n"..
"scrollbar[1.0,4.5;6.0,0.5;horizontal;gain;"..tostring (gain).."]\n"..
"textlist[7.75,2.25;3.0,2.75;sound;Buzzer,Horn,Raid,Siren;"..tostring (sound)..";false]"
end
local function update_form_spec (pos)
local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then
local is_off = node.name == "lwcomponents:siren" or
node.name == "lwcomponents:siren_locked"
meta:set_string ("formspec",
get_form_spec (is_off,
meta:get_int ("distance"),
meta:get_int ("gain"),
meta:get_int ("sound")))
end
end
local function start_siren (pos)
local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then
if node.name == "lwcomponents:siren" then
local meta = minetest.get_meta (pos)
if meta then
node.name = "lwcomponents:siren_on"
stop_sound (pos)
minetest.swap_node (pos, node)
update_form_spec (pos)
end
elseif node.name == "lwcomponents:siren_locked" then
local meta = minetest.get_meta (pos)
if meta then
node.name = "lwcomponents:siren_locked_on"
stop_sound (pos)
minetest.swap_node (pos, node)
update_form_spec (pos)
end
end
end
end
local function stop_siren (pos)
local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then
if node.name == "lwcomponents:siren_on" or
node.name == "lwcomponents:siren_alarm" then
local meta = minetest.get_meta (pos)
if meta then
node.name = "lwcomponents:siren"
minetest.get_node_timer (pos):stop ()
stop_sound (pos)
minetest.swap_node (pos, node)
update_form_spec (pos)
end
elseif node.name == "lwcomponents:siren_locked_on" or
node.name == "lwcomponents:siren_locked_alarm" then
local meta = minetest.get_meta (pos)
if meta then
node.name = "lwcomponents:siren_locked"
minetest.get_node_timer (pos):stop ()
stop_sound (pos)
minetest.swap_node (pos, node)
update_form_spec (pos)
end
end
end
end
local function start_alarm (pos)
local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then
if node.name == "lwcomponents:siren_on" then
local meta = minetest.get_meta (pos)
if meta then
node.name = "lwcomponents:siren_alarm"
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
local meta = minetest.get_meta (pos)
if meta then
node.name = "lwcomponents:siren_locked_alarm"
minetest.get_node_timer (pos):start (sound_interval)
start_sound (pos)
minetest.swap_node (pos, node)
end
end
end
end
local function stop_alarm (pos)
local node = minetest.get_node (pos)
local meta = minetest.get_meta (pos)
if node and meta then
if node.name == "lwcomponents:siren_alarm" then
local meta = minetest.get_meta (pos)
if meta then
node.name = "lwcomponents:siren_on"
minetest.get_node_timer (pos):stop ()
stop_sound (pos)
minetest.swap_node (pos, node)
end
elseif node.name == "lwcomponents:siren_locked_alarm" then
local meta = minetest.get_meta (pos)
if meta then
node.name = "lwcomponents:siren_locked_on"
minetest.get_node_timer (pos):stop ()
stop_sound (pos)
minetest.swap_node (pos, node)
end
end
end
end
local function on_destruct (pos)
minetest.get_node_timer (pos):stop ()
stop_sound (pos)
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta (pos)
local is_off = itemstack and (itemstack:get_name () == "lwcomponents:siren" or
itemstack:get_name () == "lwcomponents:siren_locked")
meta:set_string ("formspec", get_form_spec (is_off, 10, 50, 1))
meta:set_int ("sound", 1)
meta:set_int ("distance", 10)
meta:set_int ("gain", 50)
meta:set_int ("sound_handle", 0)
-- 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", "Detector (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.start then
start_siren (pos)
end
if fields.stop then
stop_siren (pos)
end
if fields.sound then
local event = minetest.explode_textlist_event (fields.sound)
if event.type == "CHG" then
local meta = minetest.get_meta (pos)
if meta then
meta:set_int ("sound", event.index)
end
end
end
if fields.gain then
local event = minetest.explode_scrollbar_event (fields.gain)
if event.type == "CHG" then
local meta = minetest.get_meta (pos)
if meta then
meta:set_int ("gain", event.value)
end
end
end
if fields.distance then
local event = minetest.explode_scrollbar_event (fields.distance)
if event.type == "CHG" then
local meta = minetest.get_meta (pos)
if meta then
meta:set_int ("distance", event.value)
end
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
on_destruct (pos)
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
preserve_metadata (pos, node, meta, { stack })
utils.item_drop (stack, nil, pos)
on_destruct (pos)
minetest.remove_node (pos)
end
end
end
end
end
end
local function on_timer (pos, elapsed)
start_sound (pos)
return true
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
else
update_form_spec (pos)
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 then
local m = { }
for w in string.gmatch(msg, "[^%s]+") do
m[#m + 1] = w
end
if m[1] == "start" then
start_siren (pos)
elseif m[1] == "stop" then
stop_siren (pos)
elseif m[1] == "siren" then
if m[2] == "on" then
start_alarm (pos)
elseif m[2] == "off" then
stop_alarm (pos)
end
elseif m[1] == "distance" then
local distance = math.min (math.max (tonumber (m[2] or 1) or 1, 1), 100)
meta:set_int ("distance", distance)
elseif m[1] == "volume" then
local volume = math.min (math.max (tonumber (m[2] or 1) or 1, 1), 100)
meta:set_int ("gain", volume)
elseif m[1] == "sound" then
if m[2] == "buzzer" then
meta:set_int ("sound", 1)
update_form_spec (pos)
elseif m[2] == "horn" then
meta:set_int ("sound", 2)
update_form_spec (pos)
elseif m[2] == "raid" then
meta:set_int ("sound", 3)
update_form_spec (pos)
elseif m[2] == "siren" then
meta:set_int ("sound", 4)
update_form_spec (pos)
end
end
end
end
end,
}
}
end
return nil
end
local function mesecon_support ()
if utils.mesecon_supported then
return
{
effector =
{
rules = utils.mesecon_default_rules,
action_on = function (pos, node)
-- do something to turn the effector on
start_alarm (pos)
end,
action_off = function (pos, node)
-- do something to turn the effector off
stop_alarm (pos)
end,
}
}
end
return nil
end
minetest.register_node("lwcomponents:siren", {
description = S("Siren"),
tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren.png",
"lwsiren.png", "lwsiren.png", "lwsiren.png"},
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
floodable = false,
drop = "lwcomponents:siren",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
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:siren_locked", {
description = S("Siren (locked)"),
tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren.png",
"lwsiren.png", "lwsiren.png", "lwsiren.png"},
is_ground_content = false,
groups = { cracky = 3 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
floodable = false,
drop = "lwcomponents:siren_locked",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
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:siren_on", {
description = S("Siren"),
tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren_on.png",
"lwsiren_on.png", "lwsiren_on.png", "lwsiren_on.png"},
is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
floodable = false,
drop = "lwcomponents:siren",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
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:siren_locked_on", {
description = S("Siren (locked)"),
tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren_on.png",
"lwsiren_on.png", "lwsiren_on.png", "lwsiren_on.png"},
is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
floodable = false,
drop = "lwcomponents:siren_locked",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
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:siren_alarm", {
description = S("Siren"),
tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren_alarm.png",
"lwsiren_alarm.png", "lwsiren_alarm.png", "lwsiren_alarm.png"},
is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
light_source = 3,
floodable = false,
drop = "lwcomponents:siren",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
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:siren_locked_alarm", {
description = S("Siren (locked)"),
tiles = { "lwsiren_base.png", "lwsiren_base.png", "lwsiren_alarm.png",
"lwsiren_alarm.png", "lwsiren_alarm.png", "lwsiren_alarm.png"},
is_ground_content = false,
groups = { cracky = 3, not_in_creative_inventory = 1 },
sounds = default.node_sound_stone_defaults (),
paramtype = "none",
param1 = 0,
light_source = 3,
floodable = false,
drop = "lwcomponents:siren_locked",
_digistuff_channelcopier_fieldname = "channel",
mesecons = mesecon_support (),
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
})
end -- utils.digilines_supported or utils.mesecon_supported
--

View File

@@ -3,7 +3,7 @@ local S = utils.S
if utils.unifieddyes_supported and utils.mesecon_supported and utils.digilines_supported then if utils.unifieddyes_supported and utils.mesecon_supported then
@@ -17,7 +17,7 @@ mesecon.register_node (":lwcomponents:solid_conductor",
palette = "unifieddyes_palette_extended.png", palette = "unifieddyes_palette_extended.png",
on_rotate = false, on_rotate = false,
drop = "lwcomponents:solid_conductor_off", drop = "lwcomponents:solid_conductor_off",
digiline = { wire = { rules = mesecon.rules.default } }, digiline = { wire = { rules = utils.digilines_default_rules } },
on_construct = unifieddyes.on_construct, on_construct = unifieddyes.on_construct,
on_dig = unifieddyes.on_dig, on_dig = unifieddyes.on_dig,
}, },
@@ -27,8 +27,8 @@ mesecon.register_node (":lwcomponents:solid_conductor",
{ {
conductor = conductor =
{ {
rules = mesecon.rules.default, rules = utils.mesecon_default_rules,
state = mesecon.state.off, state = utils.mesecon_state_off,
onstate = "lwcomponents:solid_conductor_on", onstate = "lwcomponents:solid_conductor_on",
} }
}, },
@@ -43,8 +43,8 @@ mesecon.register_node (":lwcomponents:solid_conductor",
{ {
conductor = conductor =
{ {
rules = mesecon.rules.default, rules = utils.mesecon_default_rules,
state = mesecon.state.on, state = utils.mesecon_state_on,
offstate = "lwcomponents:solid_conductor_off", offstate = "lwcomponents:solid_conductor_off",
} }
}, },
@@ -83,7 +83,7 @@ mesecon.register_node (":lwcomponents:solid_horizontal_conductor",
palette = "unifieddyes_palette_extended.png", palette = "unifieddyes_palette_extended.png",
on_rotate = false, on_rotate = false,
drop = "lwcomponents:solid_horizontal_conductor_off", drop = "lwcomponents:solid_horizontal_conductor_off",
digiline = { wire = { rules = mesecon.rules.flat } }, digiline = { wire = { rules = utils.digilines_flat_rules } },
on_construct = unifieddyes.on_construct, on_construct = unifieddyes.on_construct,
on_dig = unifieddyes.on_dig, on_dig = unifieddyes.on_dig,
}, },
@@ -93,8 +93,8 @@ mesecon.register_node (":lwcomponents:solid_horizontal_conductor",
{ {
conductor = conductor =
{ {
rules = mesecon.rules.flat, rules = utils.mesecon_flat_rules,
state = mesecon.state.off, state = utils.mesecon_state_off,
onstate = "lwcomponents:solid_horizontal_conductor_on", onstate = "lwcomponents:solid_horizontal_conductor_on",
} }
}, },
@@ -109,8 +109,8 @@ mesecon.register_node (":lwcomponents:solid_horizontal_conductor",
{ {
conductor = conductor =
{ {
rules = mesecon.rules.flat, rules = utils.mesecon_flat_rules,
state = mesecon.state.on, state = utils.mesecon_state_on,
offstate = "lwcomponents:solid_horizontal_conductor_off", offstate = "lwcomponents:solid_horizontal_conductor_off",
} }
}, },
@@ -139,4 +139,4 @@ unifieddyes.register_color_craft ({
end -- utils.unifieddyes_supported and utils.mesecon_supported and utils.digilines_supported then end -- utils.unifieddyes_supported and utils.mesecon_supported then

BIN
sounds/lwsiren-buzz.ogg Normal file

Binary file not shown.

BIN
sounds/lwsiren-horn.ogg Normal file

Binary file not shown.

BIN
sounds/lwsiren-raid.ogg Normal file

Binary file not shown.

BIN
sounds/lwsiren-siren.ogg Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

BIN
textures/lwpuncher.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

BIN
textures/lwpuncher_face.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

BIN
textures/lwsiren.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 B

BIN
textures/lwsiren_alarm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 826 B

BIN
textures/lwsiren_base.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

BIN
textures/lwsiren_on.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 794 B

View File

@@ -47,9 +47,18 @@ end
-- check for digilines -- check for digilines
if minetest.global_exists ("digilines") then if minetest.global_exists ("digilines") then
utils.digilines_supported = true utils.digilines_supported = true
utils.digilines_default_rules = digiline.rules.default
utils.digilines_flat_rules = {
{ x = 1, y = 0, z = 0 },
{ x = -1, y = 0, z = 0 },
{ x = 0, y = 0, z = 1 },
{ x = 0, y = 0, z = -1 },
}
utils.digilines_receptor_send = digilines.receptor_send utils.digilines_receptor_send = digilines.receptor_send
else else
utils.digilines_supported = false utils.digilines_supported = false
utils.digilines_default_rules = { }
utils.digilines_flat_rules = { }
-- dummy -- dummy
utils.digilines_receptor_send = function (pos, rules, channel, msg) utils.digilines_receptor_send = function (pos, rules, channel, msg)
@@ -104,6 +113,40 @@ end
-- check for hopper
if minetest.global_exists ("hopper") then
utils.hopper_supported = true
utils.hopper_add_container = function (list)
hopper:add_container (list)
end
else
utils.hopper_supported = false
utils.hopper_add_container = function (list)
end
end
-- check for mobs
if minetest.global_exists ("mobs") then
utils.mobs_supported = true
else
utils.mobs_supported = false
end
-- check for digistuff
if minetest.global_exists ("digistuff") then
utils.digistuff_supported = true
else
utils.digistuff_supported = false
end
function utils.can_interact_with_node (pos, player) function utils.can_interact_with_node (pos, player)
if not player or not player:is_player () then if not player or not player:is_player () then
return false return false