Upload files to "lwcomponents"

This commit is contained in:
Mavori 2025-06-27 17:52:11 +02:00
commit 68a94d636e
5 changed files with 2102 additions and 0 deletions

1038
lwcomponents/force_field.lua Normal file

File diff suppressed because it is too large Load diff

423
lwcomponents/hologram.lua Normal file
View file

@ -0,0 +1,423 @@
local utils = ...
local S = utils.S
if utils.digilines_supported then
local hologram_block =
{
black = {
node = "lwcomponents:hologram_black",
image = "lwhologram_black.png",
color = { a = 128, r = 0, g = 0, b = 0 } },
orange = {
node = "lwcomponents:hologram_orange",
image = "lwhologram_orange.png",
color = { a = 128, r = 255, g = 128, b = 0 } },
magenta = {
node = "lwcomponents:hologram_magenta",
image = "lwhologram_magenta.png",
color = { a = 128, r = 255, g = 0, b = 255 } },
sky = {
node = "lwcomponents:hologram_sky",
image = "lwhologram_sky.png",
color = { a = 128, r = 0, g = 128, b = 255 } },
yellow = {
node = "lwcomponents:hologram_yellow",
image = "lwhologram_yellow.png",
color = { a = 128, r = 255, g = 255, b = 0 } },
pink = {
node = "lwcomponents:hologram_pink",
image = "lwhologram_pink.png",
color = { a = 128, r = 255, g = 128, b = 128 } },
cyan = {
node = "lwcomponents:hologram_cyan",
image = "lwhologram_cyan.png",
color = { a = 128, r = 0, g = 255, b = 255 } },
gray = {
node = "lwcomponents:hologram_gray",
image = "lwhologram_gray.png",
color = { a = 128, r = 128, g = 128, b = 128 } },
silver = {
node = "lwcomponents:hologram_silver",
image = "lwhologram_silver.png",
color = { a = 128, r = 192, g = 192, b = 192 } },
red = {
node = "lwcomponents:hologram_red",
image = "lwhologram_red.png",
color = { a = 128, r = 255, g = 0, b = 0 } },
green = {
node = "lwcomponents:hologram_green",
image = "lwhologram_green.png",
color = { a = 128, r = 0, g = 128, b = 0 } },
blue = {
node = "lwcomponents:hologram_blue",
image = "lwhologram_blue.png",
color = { a = 128, r = 0, g = 0, b = 255 } },
brown = {
node = "lwcomponents:hologram_brown",
image = "lwhologram_brown.png",
color = { a = 128, r = 128, g = 64, b = 0 } },
lime = {
node = "lwcomponents:hologram_lime",
image = "lwhologram_lime.png",
color = { a = 128, r = 0, g = 255, b = 0 } },
purple = {
node = "lwcomponents:hologram_purple",
image = "lwhologram_purple.png",
color = { a = 128, r = 128, g = 0, b = 128 } },
white = {
node = "lwcomponents:hologram_white",
image = "lwhologram_white.png",
color = { a = 128, r = 255, g = 255, b = 255 } },
}
local function rotate_to_dir (center, param2, point)
local base = vector.subtract (point, center)
if param2 == 1 then
base = vector.rotate (base, { x = 0, y = (math.pi * 1.5), z = 0 })
elseif param2 == 2 then
base = vector.rotate (base, { x = 0, y = math.pi, z = 0 })
elseif param2 == 3 then
base = vector.rotate (base, { x = 0, y = (math.pi * 0.5), z = 0 })
end
return vector.add (base, center)
end
local function draw_map (pos, map)
local meta = minetest.get_meta (pos)
local holonode = minetest.get_node (pos)
if meta and holonode and type (map) == "table" then
local id = meta:get_int ("block_id")
for y = 1, 15 do
local layer = (type (map[y]) == "table" and map[y]) or { }
for x = 1, 15 do
local line = (type (layer[x]) == "table" and layer[x]) or { }
for z = 1, 15 do
local map_point = { x = z + pos.x - 8, y = y + pos.y + 1, z = (16 - x) + pos.z - 8 }
local holopos = rotate_to_dir (pos, holonode.param2, map_point)
local node = utils.get_far_node (holopos)
local draw = false
if node and node.name ~= "air" then
if node.name:sub (1, 22) == "lwcomponents:hologram_" then
local nodemeta = minetest.get_meta (holopos)
if nodemeta and nodemeta:get_int ("block_id") == id then
draw = true
end
end
else
draw = true
end
if draw then
local colornode = hologram_block[line[z]]
if node then
utils.destroy_node (holopos)
end
if colornode then
minetest.set_node (holopos, { name = colornode.node })
local nodemeta = minetest.get_meta (holopos)
if nodemeta then
nodemeta:set_int ("block_id", id)
end
end
end
end
end
end
end
end
local function clear_map (pos)
draw_map (pos, { })
end
local function on_destruct (pos)
clear_map (pos)
end
local function after_place_node (pos, placer, itemstack, pointed_thing)
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]"
local id = math.random (1000000)
meta:set_string ("formspec", spec)
meta:set_int ("block_id", id)
-- 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", "Hologram (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
local meta = minetest.get_meta(pos)
if fields.submit then
meta:set_string ("channel", fields.channel)
end
end
local function on_blast (pos, intensity)
local meta = minetest.get_meta (pos)
if meta then
if intensity >= 1.0 then
clear_map (pos)
minetest.remove_node (pos)
else -- intensity < 1.0
clear_map (pos)
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 can_dig (pos, player)
if not utils.can_interact_with_node (pos, player) then
return false
end
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
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
if type (msg) == "string" then
local m = { }
for w in string.gmatch(msg, "[^%s]+") do
m[#m + 1] = w
end
if m[1] == "clear" then
clear_map (pos)
end
elseif type (msg) == "table" then
draw_map (pos, msg)
end
end
end
end,
}
}
end
return nil
end
minetest.register_node("lwcomponents:hologram", {
description = S("Hologram"),
tiles = { "lwhologram.png", "lwhologram.png", "lwhologram.png",
"lwhologram.png", "lwhologram.png", "lwhologram_face.png"},
is_ground_content = false,
groups = { cracky = 3 },
--sounds = default.node_sound_stone_defaults (),
paramtype = "light",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
floodable = false,
_digistuff_channelcopier_fieldname = "channel",
digiline = digilines_support (),
on_destruct = on_destruct,
after_place_node = after_place_node,
on_receive_fields = on_receive_fields,
on_blast = on_blast,
can_dig = can_dig,
on_rightclick = on_rightclick
})
minetest.register_node("lwcomponents:hologram_locked", {
description = S("Hologram (locked)"),
tiles = { "lwhologram.png", "lwhologram.png", "lwhologram.png",
"lwhologram.png", "lwhologram.png", "lwhologram_face.png"},
is_ground_content = false,
groups = { cracky = 3 },
--sounds = default.node_sound_stone_defaults (),
paramtype = "light",
param1 = 0,
paramtype2 = "facedir",
param2 = 1,
floodable = false,
_digistuff_channelcopier_fieldname = "channel",
digiline = digilines_support (),
on_destruct = on_destruct,
after_place_node = after_place_node_locked,
on_receive_fields = on_receive_fields,
on_blast = on_blast,
can_dig = can_dig,
on_rightclick = on_rightclick
})
local function register_hologram_block (block)
local bc = hologram_block[block]
minetest.register_node(bc.node, {
description = S("Hologram "..block),
tiles = { bc.image },
drawtype = "glasslike",
light_source = 7,
use_texture_alpha = "blend",
sunlight_propagates = true,
walkable = false,
pointable = false,
diggable = false,
climbable = false,
buildable_to = true,
floodable = true,
is_ground_content = false,
groups = { not_in_creative_inventory = 1 },
paramtype = "light",
param1 = 255,
post_effect_color = bc.color,
})
end
register_hologram_block ("black")
register_hologram_block ("orange")
register_hologram_block ("magenta")
register_hologram_block ("sky")
register_hologram_block ("yellow")
register_hologram_block ("pink")
register_hologram_block ("cyan")
register_hologram_block ("gray")
register_hologram_block ("silver")
register_hologram_block ("red")
register_hologram_block ("green")
register_hologram_block ("blue")
register_hologram_block ("brown")
register_hologram_block ("lime")
register_hologram_block ("purple")
register_hologram_block ("white")
end -- utils.digilines_supported

459
lwcomponents/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

55
lwcomponents/init.lua Normal file
View file

@ -0,0 +1,55 @@
local version = "0.1.36"
local mod_storage = minetest.get_mod_storage ()
lwcomponents = { }
function lwcomponents.version ()
return version
end
local utils = { }
local modpath = minetest.get_modpath ("lwcomponents")
loadfile (modpath.."/settings.lua") (utils)
utils.get_dummy_player = loadfile (modpath.."/dummy_player.lua") ()
loadfile (modpath.."/utils.lua") (utils)
loadfile (modpath.."/long_process.lua") (utils)
loadfile (modpath.."/explode.lua") (utils)
loadfile (modpath.."/api.lua") (utils)
utils.connections = loadfile (modpath.."/connections.lua") ()
loadfile (modpath.."/dropper.lua") (utils)
loadfile (modpath.."/collector.lua") (utils)
loadfile (modpath.."/dispenser.lua") (utils)
loadfile (modpath.."/detector.lua") (utils)
loadfile (modpath.."/siren.lua") (utils)
loadfile (modpath.."/puncher.lua") (utils)
loadfile (modpath.."/player_button.lua") (utils)
loadfile (modpath.."/hologram.lua") (utils)
loadfile (modpath.."/breaker.lua") (utils)
loadfile (modpath.."/deployer.lua") (utils)
loadfile (modpath.."/fan.lua") (utils)
loadfile (modpath.."/conduit.lua") (utils, mod_storage)
loadfile (modpath.."/hopper.lua") (utils, mod_storage)
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.."/crafter.lua") (utils)
loadfile (modpath.."/force_field.lua") (utils)
loadfile (modpath.."/destroyer.lua") (utils)
loadfile (modpath.."/extras.lua") (utils)
loadfile (modpath.."/digiswitch.lua") (utils)
loadfile (modpath.."/movefloor.lua") (utils)
loadfile (modpath.."/solid_conductor.lua") (utils)
loadfile (modpath.."/crafting.lua") (utils)
--

127
lwcomponents/license.txt Normal file
View file

@ -0,0 +1,127 @@
Source code license
-------------------
GNU Lesser General Public License, version 2.1
Copyright (C) 2021 loosewheel
This program is free software; you can redistribute it and/or modify it under the terms
of the GNU Lesser General Public License as published by the Free Software Foundation;
either version 2.1 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details:
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
----------------
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/
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
-------------
siren images derived from images from https://openclipart.org, which is
public domain.
fan images derived from images from https://openclipart.org, which is
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.
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
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
You are free to:
Share — copy and redistribute the material in any medium or format.
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
The licensor cannot revoke these freedoms as long as you follow the license terms.
Under the following terms:
Attribution — You must give appropriate credit, provide a link to the license, and
indicate if changes were made. You may do so in any reasonable manner, but not in any way
that suggests the licensor endorses you or your use.
ShareAlike — If you remix, transform, or build upon the material, you must distribute
your contributions under the same license as the original.
No additional restrictions — You may not apply legal terms or technological measures that
legally restrict others from doing anything the license permits.
See http://creativecommons.org/licenses/by-sa/3.0/