diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..a1b7448 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,13 @@ +DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/menu/header.png b/menu/header.png index 9e44e44..b2e574a 100644 Binary files a/menu/header.png and b/menu/header.png differ diff --git a/mods/areas b/mods/areas new file mode 160000 index 0000000..3666f7d --- /dev/null +++ b/mods/areas @@ -0,0 +1 @@ +Subproject commit 3666f7debb84b919f2e2ba145cb6e530fd10c6b7 diff --git a/mods/default/models/character.png b/mods/default/models/character.png index 0502178..1867974 100644 Binary files a/mods/default/models/character.png and b/mods/default/models/character.png differ diff --git a/mods/default/models/character_18.blend b/mods/default/models/character_18.blend new file mode 100644 index 0000000..f0ff7cf Binary files /dev/null and b/mods/default/models/character_18.blend differ diff --git a/mods/default/models/character_18.blend1 b/mods/default/models/character_18.blend1 new file mode 100644 index 0000000..c6af223 Binary files /dev/null and b/mods/default/models/character_18.blend1 differ diff --git a/mods/default/models/characterf.png b/mods/default/models/characterf.png index 6baa26d..7ccfc10 100644 Binary files a/mods/default/models/characterf.png and b/mods/default/models/characterf.png differ diff --git a/mods/default/models/characterm.png b/mods/default/models/characterm.png index dd3562b..06d34e0 100644 Binary files a/mods/default/models/characterm.png and b/mods/default/models/characterm.png differ diff --git a/mods/item_drop b/mods/item_drop new file mode 160000 index 0000000..a711c07 --- /dev/null +++ b/mods/item_drop @@ -0,0 +1 @@ +Subproject commit a711c073effbcc47ff9e0d49d2c296f2bb2aea3f diff --git a/mods/moreblocks/LICENSE.txt b/mods/moreblocks/LICENSE.txt new file mode 100644 index 0000000..726257d --- /dev/null +++ b/mods/moreblocks/LICENSE.txt @@ -0,0 +1,13 @@ ++---- zlib/libpng license ----+ + +Copyright (c) 2013-2014 Calinou and contributors + +This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/mods/moreblocks/README.txt b/mods/moreblocks/README.txt new file mode 100644 index 0000000..aa99eda --- /dev/null +++ b/mods/moreblocks/README.txt @@ -0,0 +1,12 @@ +More Blocks +========== + +More Blocks for Minetest (http://minetest.net), a free and open source infinite +world block sandbox game. + +To install, just clone this repository into your "mods" directory. + +More Blocks code is under the zlib license, textures are under CC BY-SA 3.0 unported. + +Forum topic: http://forum.minetest.net/viewtopic.php?id=509 + diff --git a/mods/moreblocks/aliases.lua b/mods/moreblocks/aliases.lua new file mode 100644 index 0000000..df820c3 --- /dev/null +++ b/mods/moreblocks/aliases.lua @@ -0,0 +1,75 @@ +-- More Blocks aliases + +minetest.register_alias("sweeper", "moreblocks:sweeper") +minetest.register_alias("circular_saw", "moreblocks:circular_saw") +minetest.register_alias("jungle_stick", "moreblocks:jungle_stick") + +-- Old block/item replacement + +minetest.register_alias("moreblocks:oerkkiblock", "default:mossycobble") +minetest.register_alias("moreblocks:screwdriver", "screwdriver:screwdriver") + +-- Node and item renaming + +minetest.register_alias("moreblocks:stone_bricks", "default:stonebrick") +minetest.register_alias("moreblocks:stonebrick", "default:stonebrick") +minetest.register_alias("moreblocks:junglewood", "default:junglewood") +minetest.register_alias("moreblocks:jungle_wood", "default:junglewood") + +for _, t in pairs(circular_saw.names) do + minetest.register_alias("moreblocks:" ..t[1].. "_jungle_wood" ..t[2], + "moreblocks:" ..t[1].. "_junglewood" ..t[2]) +end +minetest.register_alias("moreblocks:horizontaltree", "moreblocks:horizontal_tree") +minetest.register_alias("moreblocks:horizontaljungletree", "moreblocks:horizontal_jungle_tree") +minetest.register_alias("moreblocks:stonesquare", "moreblocks:stone_tile") +minetest.register_alias("moreblocks:circlestonebrick", "moreblocks:circle_stone_bricks") +minetest.register_alias("moreblocks:ironstonebrick", "moreblocks:iron_stone_bricks") +minetest.register_alias("moreblocks:fence_junglewood", "moreblocks:fence_jungle_wood") +minetest.register_alias("moreblocks:coalstone", "moreblocks:coal_stone") +minetest.register_alias("moreblocks:ironstone", "moreblocks:iron_stone") +minetest.register_alias("moreblocks:woodtile", "moreblocks:wood_tile") +minetest.register_alias("moreblocks:woodtile_full", "moreblocks:wood_tile_full") +minetest.register_alias("moreblocks:woodtile_centered", "moreblocks:wood_tile_centered") +minetest.register_alias("moreblocks:woodtile_up", "moreblocks:wood_tile_up") +minetest.register_alias("moreblocks:woodtile_down", "moreblocks:wood_tile_down") +minetest.register_alias("moreblocks:woodtile_left", "moreblocks:wood_tile_left") +minetest.register_alias("moreblocks:woodtile_right", "moreblocks:wood_tile_right") +minetest.register_alias("moreblocks:coalglass", "moreblocks:coal_glass") +minetest.register_alias("moreblocks:ironglass", "moreblocks:iron_glass") +minetest.register_alias("moreblocks:glowglass", "moreblocks:glow_glass") +minetest.register_alias("moreblocks:superglowglass", "moreblocks:super_glow_glass") +minetest.register_alias("moreblocks:trapglass", "moreblocks:trap_glass") +minetest.register_alias("moreblocks:trapstone", "moreblocks:trap_stone") +minetest.register_alias("moreblocks:cactuschecker", "moreblocks:cactus_checker") +minetest.register_alias("moreblocks:coalchecker", "moreblocks:coal_checker") +minetest.register_alias("moreblocks:ironchecker", "moreblocks:iron_checker") +minetest.register_alias("moreblocks:cactusbrick", "moreblocks:cactus_brick") +minetest.register_alias("moreblocks:cleanglass", "moreblocks:clean_glass") +minetest.register_alias("moreblocks:emptybookshelf", "moreblocks:empty_bookshelf") +minetest.register_alias("moreblocks:junglestick", "moreblocks:jungle_stick") +minetest.register_alias("moreblocks:splitstonesquare","moreblocks:split_stone_tile") +minetest.register_alias("moreblocks:allfacestree","moreblocks:all_faces_tree") + +-- ABM for horizontal trees (fix facedir). + +local horizontal_tree_convert_facedir = {7, 12, 9, 18} + +minetest.register_abm({ + nodenames = {"moreblocks:horizontal_tree","moreblocks:horizontal_jungle_tree"}, + interval = 1, + chance = 1, + action = function(pos, node) + if node.name == "moreblocks:horizontal_tree" then + node.name = "default:tree" + else + node.name = "default:jungletree" + end + node.param2 = node.param2 < 3 and node.param2 or 0 + minetest.set_node(pos, { + name = node.name, + param2 = horizontal_tree_convert_facedir[node.param2 + 1] + }) + end, +}) + diff --git a/mods/moreblocks/circular_saw.lua b/mods/moreblocks/circular_saw.lua new file mode 100644 index 0000000..2af5972 --- /dev/null +++ b/mods/moreblocks/circular_saw.lua @@ -0,0 +1,355 @@ +local S = moreblocks.gettext +circular_saw = {} + +circular_saw.known_stairs = setmetatable({}, { + __newindex = function(k, v) + local modname = minetest.get_current_modname() + print(("WARNING: mod %s tried to add node %s to the circular saw" + .. " manually."):format(modname, v)) + end, +}) + +-- This is populated by stairsplus:register_all: +circular_saw.known_nodes = {} + +-- How many microblocks does this shape at the output inventory cost: +circular_saw.cost_in_microblocks = { + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 3, 2, 4, 2, 4, 5, 6, + 7, 1, 1, 2, 4, 6, 7, 8, + 3, 1, 1, 2, 4, 0, 0, 0, +} + +circular_saw.names = { + {"micro", "_1"}, + {"panel", "_1"}, + {"micro", "_2"}, + {"panel", "_2"}, + {"micro", "_4"}, + {"panel", "_4"}, + {"micro", ""}, + {"panel", ""}, + {"micro", "_12"}, + {"panel", "_12"}, + {"micro", "_14"}, + {"panel", "_14"}, + {"micro", "_15"}, + {"panel", "_15"}, + {"stair", "_outer"}, + {"stair", ""}, + {"stair", "_inner"}, + {"slab", "_1"}, + {"slab", "_2"}, + {"slab", "_quarter"}, + {"slab", ""}, + {"slab", "_three_quarter"}, + {"slab", "_14"}, + {"slab", "_15"}, + {"stair", "_half"}, + {"stair", "_alt_1"}, + {"stair", "_alt_2"}, + {"stair", "_alt_4"}, + {"stair", "_alt"}, +} + +function circular_saw:get_cost(inv, stackname) + for i, item in pairs(inv:get_list("output")) do + if item:get_name() == stackname then + return circular_saw.cost_in_microblocks[i] + end + end +end + +function circular_saw:get_output_inv(modname, material, amount, max) + if (not max or max < 1 or max > 99) then max = 99 end + + local list = {} + -- If there is nothing inside, display empty inventory: + if amount < 1 then + return list + end + + for i, t in ipairs(circular_saw.names) do + local cost = circular_saw.cost_in_microblocks[i] + table.insert(list, modname .. ":" .. t[1] .. "_" .. material .. t[2] + .. " " .. math.min(math.floor(amount/cost), max)) + end + return list +end + + +-- Reset empty circular_saw after last full block has been taken out +-- (or the circular_saw has been placed the first time) +-- Note: max_offered is not reset: +function circular_saw:reset(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + inv:set_list("input", {}) + inv:set_list("micro", {}) + inv:set_list("output", {}) + meta:set_int("anz", 0) + + meta:set_string("infotext", + S("Circular Saw is empty (owned by %s)") + :format(meta:get_string("owner") or "")) +end + + +-- Player has taken something out of the box or placed something inside +-- that amounts to count microblocks: +function circular_saw:update_inventory(pos, amount) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + amount = meta:get_int("anz") + amount + + -- The material is recycled automaticly. + inv:set_list("recycle", {}) + + if amount < 1 then -- If the last block is taken out. + self:reset(pos) + return + end + + local stack = inv:get_stack("input", 1) + -- At least one "normal" block is necessary to see what kind of stairs are requested. + if stack:is_empty() then + -- Any microblocks not taken out yet are now lost. + -- (covers material loss in the machine) + self:reset(pos) + return + + end + local node_name = stack:get_name() or "" + local name_parts = circular_saw.known_nodes[node_name] or "" + local modname = name_parts[1] or "" + local material = name_parts[2] or "" + + inv:set_list("input", { -- Display as many full blocks as possible: + node_name.. " " .. math.floor(amount / 8) + }) + + -- The stairnodes made of default nodes use moreblocks namespace, other mods keep own: + if modname == "default" then + modname = "moreblocks" + end + -- print("circular_saw set to " .. modname .. " : " + -- .. material .. " with " .. (amount) .. " microblocks.") + + -- 0-7 microblocks may remain left-over: + inv:set_list("micro", { + modname .. ":micro_" .. material .. "_bottom " .. (amount % 8) + }) + -- Display: + inv:set_list("output", + self:get_output_inv(modname, material, amount, + meta:get_int("max_offered"))) + -- Store how many microblocks are available: + meta:set_int("anz", amount) + + meta:set_string("infotext", + S("Circular Saw is working on %s (owned by %s)") + :format(material, meta:get_string("owner") or "")) +end + + +-- The amount of items offered per shape can be configured: +function circular_saw.on_receive_fields(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + local max = tonumber(fields.max_offered) + if max and max > 0 then + meta:set_string("max_offered", max) + -- Update to show the correct number of items: + circular_saw:update_inventory(pos, 0) + end +end + + +-- Moving the inventory of the circular_saw around is not allowed because it +-- is a fictional inventory. Moving inventory around would be rather +-- impractical and make things more difficult to calculate: +function circular_saw.allow_metadata_inventory_move( + pos, from_list, from_index, to_list, to_index, count, player) + return 0 +end + + +-- Only input- and recycle-slot are intended as input slots: +function circular_saw.allow_metadata_inventory_put( + pos, listname, index, stack, player) + -- The player is not allowed to put something in there: + if listname == "output" or listname == "micro" then + return 0 + end + + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stackname = stack:get_name() + local count = stack:get_count() + + -- Only alow those items that are offered in the output inventory to be recycled: + if listname == "recycle" then + if not inv:contains_item("output", stackname) then + return 0 + end + local stackmax = stack:get_stack_max() + local instack = inv:get_stack("input", 1) + local microstack = inv:get_stack("micro", 1) + local incount = instack:get_count() + local incost = (incount * 8) + microstack:get_count() + local maxcost = (stackmax * 8) + 7 + local cost = circular_saw:get_cost(inv, stackname) + if (incost + cost) > maxcost then + return math.max((maxcost - incost) / cost, 0) + end + return count + end + + -- Only accept certain blocks as input which are known to be craftable into stairs: + if listname == "input" then + if not inv:is_empty("input") and + inv:get_stack("input", index):get_name() ~= stackname then + return 0 + end + for name, t in pairs(circular_saw.known_nodes) do + if name == stackname and inv:room_for_item("input", stack) then + return count + end + end + return 0 + end +end + +-- Taking is allowed from all slots (even the internal microblock slot). +-- Putting something in is slightly more complicated than taking anything +-- because we have to make sure it is of a suitable material: +function circular_saw.on_metadata_inventory_put( + pos, listname, index, stack, player) + -- We need to find out if the circular_saw is already set to a + -- specific material or not: + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stackname = stack:get_name() + local count = stack:get_count() + + -- Putting something into the input slot is only possible if that had + -- been empty before or did contain something of the same material: + if listname == "input" then + -- Each new block is worth 8 microblocks: + circular_saw:update_inventory(pos, 8 * count) + elseif listname == "recycle" then + -- Lets look which shape this represents: + local cost = circular_saw:get_cost(inv, stackname) + circular_saw:update_inventory(pos, cost * count) + end +end + +function circular_saw.on_metadata_inventory_take( + pos, listname, index, stack, player) + -- If it is one of the offered stairs: find out how many + -- microblocks have to be substracted: + if listname == "output" then + -- We do know how much each block at each position costs: + local cost = circular_saw.cost_in_microblocks[index] + * stack:get_count() + + circular_saw:update_inventory(pos, -cost) + elseif listname == "micro" then + -- Each microblock costs 1 microblock: + circular_saw:update_inventory(pos, -stack:get_count()) + elseif listname == "input" then + -- Each normal (= full) block taken costs 8 microblocks: + circular_saw:update_inventory(pos, 8 * -stack:get_count()) + end + -- The recycle field plays no role here since it is processed immediately. +end + +gui_slots = "listcolors[#606060AA;#808080;#101010;#202020;#FFF]" + +function circular_saw.on_construct(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "size[11,9]" ..gui_slots.. + "label[0,0;" ..S("Input\nmaterial").. "]" .. + "list[current_name;input;1.5,0;1,1;]" .. + "label[0,1;" ..S("Left-over").. "]" .. + "list[current_name;micro;1.5,1;1,1;]" .. + "label[0,2;" ..S("Recycle\noutput").. "]" .. + "list[current_name;recycle;1.5,2;1,1;]" .. + "field[0.3,3.5;1,1;max_offered;" ..S("Max").. ":;${max_offered}]" .. + "button[1,3.2;1,1;Set;" ..S("Set").. "]" .. + "list[current_name;output;2.8,0;8,4;]" .. + "list[current_player;main;1.5,5;8,4;]") + + meta:set_int("anz", 0) -- No microblocks inside yet. + meta:set_string("max_offered", 99) -- How many items of this kind are offered by default? + meta:set_string("infotext", S("Circular Saw is empty")) + + local inv = meta:get_inventory() + inv:set_size("input", 1) -- Input slot for full blocks of material x. + inv:set_size("micro", 1) -- Storage for 1-7 surplus microblocks. + inv:set_size("recycle", 1) -- Surplus partial blocks can be placed here. + inv:set_size("output", 4*8) -- 4x8 versions of stair-parts of material x. + + circular_saw:reset(pos) +end + + +function circular_saw.can_dig(pos,player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if not inv:is_empty("input") or + not inv:is_empty("micro") or + not inv:is_empty("recycle") then + return false + end + -- Can be dug by anyone when empty, not only by the owner: + return true +end + +minetest.register_node("moreblocks:circular_saw", { + description = S("Circular Saw"), + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.4, -0.5, -0.4, -0.25, 0.25, -0.25}, -- Leg + {0.25, -0.5, 0.25, 0.4, 0.25, 0.4}, -- Leg + {-0.4, -0.5, 0.25, -0.25, 0.25, 0.4}, -- Leg + {0.25, -0.5, -0.4, 0.4, 0.25, -0.25}, -- Leg + {-0.5, 0.25, -0.5, 0.5, 0.375, 0.5}, -- Tabletop + {-0.01, 0.4375, -0.125, 0.01, 0.5, 0.125}, -- Saw blade (top) + {-0.01, 0.375, -0.1875, 0.01, 0.4375, 0.1875}, -- Saw blade (bottom) + {-0.25, -0.0625, -0.25, 0.25, 0.25, 0.25}, -- Motor case + }, + }, + tiles = {"moreblocks_circular_saw_top.png", + "moreblocks_circular_saw_bottom.png", + "moreblocks_circular_saw_side.png"}, + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + groups = {choppy = 2,oddly_breakable_by_hand = 2}, + sounds = default.node_sound_wood_defaults(), + on_construct = circular_saw.on_construct, + can_dig = circular_saw.can_dig, + -- Set the owner of this circular saw. + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + local owner = placer and placer:get_player_name() or "" + meta:set_string("owner", owner) + meta:set_string("infotext", + S("Circular Saw is empty (owned by %s)") + :format(owner)) + end, + + -- The amount of items offered per shape can be configured: + on_receive_fields = circular_saw.on_receive_fields, + allow_metadata_inventory_move = circular_saw.allow_metadata_inventory_move, + -- Only input- and recycle-slot are intended as input slots: + allow_metadata_inventory_put = circular_saw.allow_metadata_inventory_put, + -- Taking is allowed from all slots (even the internal microblock slot). Moving is forbidden. + -- Putting something in is slightly more complicated than taking anything because we have to make sure it is of a suitable material: + on_metadata_inventory_put = circular_saw.on_metadata_inventory_put, + on_metadata_inventory_take = circular_saw.on_metadata_inventory_take, +}) diff --git a/mods/moreblocks/config.lua b/mods/moreblocks/config.lua new file mode 100644 index 0000000..7efb539 --- /dev/null +++ b/mods/moreblocks/config.lua @@ -0,0 +1,25 @@ +moreblocks.config = {} + +local function getbool_default(setting, default) + local value = minetest.setting_getbool(setting) + if value == nil then + value = default + end + return value +end + +local function setting(settingtype, name, default) + if settingtype == "bool" then + moreblocks.config[name] = + getbool_default("moreblocks." .. name, default) + else + moreblocks.config[name] = + minetest.setting_get("moreblocks." .. name) or default + end +end + +-- Whether to direct wood based on player posititon when placing the block (true or false): +setting("bool", "wood_facedir", true) + +-- Show stairs/slabs/panels/microblocks in creative inventory (true or false): +setting("bool", "stairsplus_in_creative_inventory", false) diff --git a/mods/moreblocks/crafting.lua b/mods/moreblocks/crafting.lua new file mode 100644 index 0000000..2047727 --- /dev/null +++ b/mods/moreblocks/crafting.lua @@ -0,0 +1,446 @@ +-- Crafting + +minetest.register_craft({ + output = "default:stick", + recipe = {{"default:dry_shrub"},} +}) + +minetest.register_craft({ + output = "default:stick", + recipe = {{"default:sapling"},} +}) + +minetest.register_craft({ + output = "default:stick", + recipe = {{"default:junglesapling"},} +}) + +minetest.register_craft({ + output = "default:wood", + recipe = { + {"default:stick", "default:stick"}, + {"default:stick", "default:stick"}, + } +}) + +minetest.register_craft({ + output = "default:junglewood", + recipe = { + {"moreblocks:jungle_stick", "moreblocks:jungle_stick"}, + {"moreblocks:jungle_stick", "moreblocks:jungle_stick"}, + } +}) + +minetest.register_craft({ + output = "default:dirt_with_grass", + type = "shapeless", + recipe = {"default:junglegrass", "default:dirt"}, +}) + +minetest.register_craft({ + output = "default:dirt_with_grass", + type = "shapeless", + recipe = {"default:mese", "default:dirt"}, +}) + +minetest.register_craft({ + output = "default:mossycobble", + type = "shapeless", + recipe = {"default:junglegrass", "default:cobble"}, +}) + +minetest.register_craft({ + output = "default:mossycobble", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "default:cobble"}, +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile 9", + recipe = { + {"default:wood", "default:wood", "default:wood"}, + {"default:wood", "default:wood", "default:wood"}, + {"default:wood", "default:wood", "default:wood"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_flipped", + recipe = {{"moreblocks:wood_tile"},} +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_center 9", + recipe = { + {"default:wood", "default:wood", "default:wood"}, + {"default:wood", "moreblocks:wood_tile", "default:wood"}, + {"default:wood", "default:wood", "default:wood"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_full 4", + recipe = { + {"moreblocks:wood_tile", "moreblocks:wood_tile"}, + {"moreblocks:wood_tile", "moreblocks:wood_tile"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_up", + recipe = { + {"default:stick"}, + {"moreblocks:wood_tile_center"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_down", + recipe = { + {"moreblocks:wood_tile_center"}, + {"default:stick"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_left", + recipe = { + {"default:stick", "moreblocks:wood_tile_center"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_right", + recipe = { + {"moreblocks:wood_tile_center", "default:stick"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:junglestick 4", + recipe = {{"default:junglewood"},} +}) + +minetest.register_craft({ + output = "moreblocks:fence_jungle_wood 2", + recipe = { + {"moreblocks:jungle_stick", "moreblocks:jungle_stick", "moreblocks:jungle_stick"}, + {"moreblocks:jungle_stick", "moreblocks:jungle_stick", "moreblocks:jungle_stick"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:circle_stone_bricks 8", + recipe = { + {"default:stone", "default:stone", "default:stone"}, + {"default:stone", "", "default:stone"}, + {"default:stone", "default:stone", "default:stone"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:all_faces_tree 8", + recipe = { + {"default:tree", "default:tree", "default:tree"}, + {"default:tree", "", "default:tree"}, + {"default:tree", "default:tree", "default:tree"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:all_faces_jungle_tree 8", + recipe = { + {"default:jungletree", "default:jungletree", "default:jungletree"}, + {"default:jungletree", "", "default:jungletree"}, + {"default:jungletree", "default:jungletree", "default:jungletree"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:sweeper 4", + recipe = { + {"default:junglegrass"}, + {"default:stick"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:stone_tile 4", + recipe = { + {"default:cobble", "default:cobble"}, + {"default:cobble", "default:cobble"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:split_stone_tile", + recipe = { + {"moreblocks:stone_tile"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:split_stone_tile_alt", + recipe = { + {"moreblocks:split_stone_tile"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:grey_bricks 2", + type = "shapeless", + recipe = {"default:stone", "default:brick"}, +}) + +minetest.register_craft({ + output = "moreblocks:grey_bricks 2", + type = "shapeless", + recipe = {"default:stonebrick", "default:brick"}, +}) + +minetest.register_craft({ + output = "moreblocks:empty_bookshelf", + type = "shapeless", + recipe = {"moreblocks:sweeper", "default:bookshelf"}, +}) + +minetest.register_craft({ + output = "moreblocks:coal_stone_bricks 4", + recipe = { + {"moreblocks:coal_stone", "moreblocks:coal_stone"}, + {"moreblocks:coal_stone", "moreblocks:coal_stone"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:iron_stone_bricks 4", + recipe = { + {"moreblocks:iron_stone", "moreblocks:iron_stone"}, + {"moreblocks:iron_stone", "moreblocks:iron_stone"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:plankstone 4", + recipe = { + {"default:stone", "default:wood"}, + {"default:wood", "default:stone"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:plankstone 4", + recipe = { + {"default:wood", "default:stone"}, + {"default:stone", "default:wood"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:coal_checker 4", + recipe = { + {"default:stone", "default:coal_lump"}, + {"default:coal_lump", "default:stone"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:coal_checker 4", + recipe = { + {"default:coal_lump", "default:stone"}, + {"default:stone", "default:coal_lump"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:iron_checker 4", + recipe = { + {"default:steel_ingot", "default:stone"}, + {"default:stone", "default:steel_ingot"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:iron_checker 4", + recipe = { + {"default:stone", "default:steel_ingot"}, + {"default:steel_ingot", "default:stone"}, + } +}) + +minetest.register_craft({ + output = "default:chest_locked", + type = "shapeless", + recipe = {"default:steel_ingot", "default:chest"}, +}) +minetest.register_craft({ + output = "default:chest_locked", + type = "shapeless", + recipe = {"default:copper_ingot", "default:chest"}, +}) + +minetest.register_craft({ + output = "default:chest_locked", + type = "shapeless", + recipe = {"default:bronze_ingot", "default:chest"}, +}) + +minetest.register_craft({ + output = "default:chest_locked", + type = "shapeless", + recipe = {"default:gold_ingot", "default:chest"}, +}) + +minetest.register_craft({ + output = "moreblocks:iron_glass", + type = "shapeless", + recipe = {"default:steel_ingot", "default:glass"}, +}) + +minetest.register_craft({ + output = "default:glass", + type = "shapeless", + recipe = {"default:coal_lump", "moreblocks:iron_glass"}, +}) + + +minetest.register_craft({ + output = "moreblocks:coal_glass", + type = "shapeless", + recipe = {"default:coal_lump", "default:glass"}, +}) + +minetest.register_craft({ + output = "default:glass", + type = "shapeless", + recipe = {"default:steel_ingot", "moreblocks:coal_glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:clean_glass", + type = "shapeless", + recipe = {"moreblocks:sweeper", "default:glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:glow_glass", + type = "shapeless", + recipe = {"default:torch", "default:glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:trap_glow_glass", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "default:glass", "default:torch"}, +}) + +minetest.register_craft({ + output = "moreblocks:trap_glow_glass", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "moreblocks:glow_glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:super_glow_glass", + type = "shapeless", + recipe = {"default:torch", "default:torch", "default:glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:super_glow_glass", + type = "shapeless", + recipe = {"default:torch", "moreblocks:glow_glass"}, +}) + + +minetest.register_craft({ + output = "moreblocks:trap_super_glow_glass", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "default:glass", "default:torch", "default:torch"}, +}) + +minetest.register_craft({ + output = "moreblocks:trap_super_glow_glass", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "moreblocks:super_glow_glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:coal_stone", + type = "shapeless", + recipe = {"default:coal_lump", "default:stone"}, +}) + +minetest.register_craft({ + output = "default:stone", + type = "shapeless", + recipe = {"default:steel_ingot", "moreblocks:coal_stone"}, +}) + +minetest.register_craft({ + output = "moreblocks:iron_stone", + type = "shapeless", + recipe = {"default:steel_ingot", "default:stone"}, +}) + +minetest.register_craft({ + output = "default:stone", + type = "shapeless", + recipe = {"default:coal_lump", "moreblocks:iron_stone"}, +}) + +minetest.register_craft({ + output = "moreblocks:trap_stone", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "default:stone"}, +}) + +minetest.register_craft({ + output = "moreblocks:trap_glass", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "default:glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:cactus_brick", + type = "shapeless", + recipe = {"default:cactus", "default:brick"}, +}) + +minetest.register_craft({ + output = "moreblocks:cactus_checker 4", + recipe = { + {"default:cactus", "default:stone"}, + {"default:stone", "default:cactus"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:cactuschecker 4", + recipe = { + {"default:stone", "default:cactus"}, + {"default:cactus", "default:stone"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:rope 3", + recipe = { + {"default:junglegrass"}, + {"default:junglegrass"}, + {"default:junglegrass"}, + } +}) + +minetest.register_craft({ + type = "cooking", output = "moreblocks:tar", recipe = "default:gravel", +}) + +minetest.register_craft({ + output = "moreblocks:circular_saw", + recipe = { + { "", "default:steel_ingot", "" }, + { "group:wood", "group:wood", "group:wood"}, + { "group:wood", "", "group:wood"}, + } +}) diff --git a/mods/moreblocks/depends.txt b/mods/moreblocks/depends.txt new file mode 100644 index 0000000..198fe8a --- /dev/null +++ b/mods/moreblocks/depends.txt @@ -0,0 +1,2 @@ +default +intllib? diff --git a/mods/moreblocks/init.lua b/mods/moreblocks/init.lua new file mode 100644 index 0000000..8180251 --- /dev/null +++ b/mods/moreblocks/init.lua @@ -0,0 +1,31 @@ +--[[ +-- More Blocks (moreblocks) by Calinou +-- Licensed under the zlib/ license for code and CC BY-SA 3.0 for textures, see LICENSE.txt for info. +--]] + +moreblocks = {} + +-- Load translation library if intllib is installed + +local S -- Load translation library if intllib is installed: +if intllib then + S = intllib.Getter(minetest.get_current_modname()) +else + S = function(s) return s end +end +moreblocks.gettext = S + +local modpath = minetest.get_modpath("moreblocks") + +dofile(modpath .. "/config.lua") +dofile(modpath .. "/circular_saw.lua") +dofile(modpath .. "/stairsplus/init.lua") +dofile(modpath .. "/nodes.lua") +dofile(modpath .. "/redefinitions.lua") +dofile(modpath .. "/crafting.lua") +dofile(modpath .. "/aliases.lua") + +if minetest.setting_getbool("log_mods") then + print(S("[moreblocks] loaded.")) +end + diff --git a/mods/moreblocks/locale/de.txt b/mods/moreblocks/locale/de.txt new file mode 100644 index 0000000..542f977 --- /dev/null +++ b/mods/moreblocks/locale/de.txt @@ -0,0 +1,67 @@ +# Translation by Xanthin + +###init.lua### +[moreblocks] loaded. = [moreblocks] geladen. + +###nodes.lua### +Jungle Wood Fence = Tropenholzzaun +Empty Bookshelf = Leeres Buecherregal +Clean Glass = Klares Glas +Plankstone = Brettstein +Wooden Tile = Holzfliese +Full Wooden Tile = Vollholzfliese +Centered Wooden Tile = Holzfliese mittig +Up Wooden Tile = Holzfliese oben +Down Wooden Tile = Holzfliese unten +Left Wooden Tile = Holzfliese links +Right Wooden Tile = Holzfliese rechts +Circle Stone Bricks = Kreissteinziegel +Stone Tile = Steinfliese +Split Stone Tile = Geteilte Steinfliese +Glow Glass = Leuchtglas +Super Glow Glass = Superleuchtglas +Coal Glass = Kohleglas +Iron Glass = Eisenglas +Coal Checker = Karierte Kohle +Iron Checker = Kariertes Eisen +Trap Stone = Steinfalle +Trap Glass = Glasfalle +Trap Glow Glass = Leuchtglasfalle +Trap Super Glow Glass = Superleuchtglasfalle +Coal Stone = Kohlestein +Iron Stone = Eisenstein +Coal Stone Bricks = Kohlesteinziegel +Iron Stone Bricks = Eisensteinziegel +Cactus Checker = Karierter Kaktus +Cactus Brick = Kaktusziegel +Sweeper = Besen +Jungle Stick = Tropenholzstock +Rope = Seil +All-faces Tree = Baumscheibenstamm + +###circular_saw.lua### +Circular Saw = Kreissaege +Circular saw, empty (owned by %s) = Kreissaege, leer (gehoert %s) +Circular saw, working with %s (owned by %s) = Kreissaege, arbeitet mit %s (gehoert %s) +Circular saw, empty = Kreissaege, leer +Circular saw is empty (owned by %s) = Kreissaege ist leer (gehoert %s) + +Input\nmaterial = Ausgangs-\nmaterial +Left-over = Rest +Max = Anzahl +Set = Ok +Recycle\noutput = Wiederver-\nwerten + +###./stairsplus/*### +%s Stairs = %streppe +%s Slab = %sstufe +%s Panel = %spaneel +%s Microblock = %smikroblock + +%s Pane = %sscheibe +%s Fence = %szaun + +###ownership.lua### +someone = jemand +Sorry, %s owns that spot. = Tut mir leid, %s gehoert diese Stelle. + diff --git a/mods/moreblocks/locale/es.txt b/mods/moreblocks/locale/es.txt new file mode 100644 index 0000000..d11ba49 --- /dev/null +++ b/mods/moreblocks/locale/es.txt @@ -0,0 +1,52 @@ +# Translation by kaeza + +[moreblocks] loaded. = [moreblocks] cargado. + +Jungle Wooden Planks = Tablones de madera de jungla +Empty Bookshelf = Estante para libros vacío +Clean Glass = Cristal Limpio +Plankstone = Tablones de piedra +Wooden Tile = Parquet +Full Wooden Tile = Parquet Completo +Centered Wooden Tile = Parquet Centrado +Up Wooden Tile = Parquet Superior +Down Wooden Tile = Parquet Inferior +Left Wooden Tile = Parquet Izquierdo +Right Wooden Tile = Parquet Derecho +Circle Stone Bricks = Bloques de Piedra Circulares +Stone Tile = Baldosa de Piedra +Split Stone Tile = Baldosas de Piedra Partida +Glow Glass = Cristal Brillante +Super Glow Glass = Cristal Súper Brillante +Coal Glass = Cristal con Carbón +Iron Glass = Cristal con Hierro +Coal Checker = Cuadros de Carbón +Iron Checker = Cuadros de Hierro +Trap Stone = Piedra Trampa +Trap Glass = Cristal Trampa +Coal Stone = Carbón y Piedra +Iron Stone = Hierro y Piedra +Cactus Checker = Cuadros de Cactus +Cactus Brick = Ladrillos de Cactus +Sweeper = Limpiador +Jungle Stick = Varita de Madera de Jungla +Horizontal Tree = Tronco de árbol horizontal +Horizontal Jungle Tree = Tronco de árbol de la jungla horizontal +Rope = Soga +All-faces Tree = Tronco de Árbol + +%s Stairs = Escalera de %s +%s Slab = Losa de %s +%s Panel = Panel de %s +%s Microblock = Microbloque de %s + +Wooden = Madera +Papyrus = Papiro +Dry Shrub = Arbusto Desértico +Sapling = Brote de Árbol +Wooden Planks = Tablones de Madera +Ladder = Escalera de Mano +Glass = Cristal + +%s Pane = Panel de %s +%s Fence = Valla de %s diff --git a/mods/moreblocks/locale/fr.txt b/mods/moreblocks/locale/fr.txt new file mode 100644 index 0000000..6bd7f98 --- /dev/null +++ b/mods/moreblocks/locale/fr.txt @@ -0,0 +1,72 @@ +# Translation by Calinou + +###init.lua### +[moreblocks] loaded. = [moreblocks] a t charg. + +Jungle Wooden Planks = Planches de bois de jungle +Empty Bookshelf = tagre vide +Clean Glass = Verre propre +Plankstone = Pierre-bois +Wooden Tile = Dalle en bois +Full Wooden Tile = Dalle en bois complte +Centered Wooden Tile = Dalle en bois centre +Up Wooden Tile = Dalle en bois vers le haut +Down Wooden Tile = Dalle en bois vers le bas +Left Wooden Tile = Dalle en bois vers la gauche +Right Wooden Tile = Dalle en bois vers la droite +Circle Stone Bricks = Briques en pierre circulaires +Stone Tile = Dalle en pierre +Split Stone Tile = Dalle en pierre dcoupe +Glow Glass = Verre brillant +Super Glow Glass = Verre trs brillant +Coal Glass = Verre de charbon +Iron Glass = Verre de fer +Coal Checker = Damier en charbon +Iron Checker = Damier en fer +Trap Stone = Pierre traversable +Trap Glass = Verre traversable +Trap Glow Glass = Verre brillant traversable +Trap Super Glow Glass = Verre trs brillant traversable +Coal Stone = Pierre de charbon +Iron Stone = Pierre de fer +Coal Stone Bricks = Briques en pierre de charbon +Iron Stone Bricks = Briques en pierre de fer +Cactus Checker = Damier en cactus +Cactus Brick = Briques de cactus +Sweeper = Balai +Jungle Stick = Bton en bois de jungle +Horizontal Tree = Tronc d'arbre horizontal +Horizontal Jungle Tree = Tronc d'arbre de jungle horizontal +Rope = Corde +All-faces Tree = Tronc d'arbre + +###redefinition.lua### +Wooden = bois +Papyrus = Papyrus +Dry Shrub = Buisson mort +Sapling = Pousse d'arbre +Wooden Planks = Planches de bois +Ladder = chelle +Glass = Verre + +###circular_saw.lua### +Circular Saw = Scie circulaire +Circular saw, empty (owned by %s) = Scie circulaire, vide (proprit de %s) +Circular saw, working with %s (owned by %s) = Scie circulaire, manipule %s (proprit de %s) +Circular saw, empty = Scie circulaire, vide +Circular saw is empty (owned by %s) = Scie circulaire est vide (proprit de %s) + +Input material = Entre du matriel +Rest/microblocks = Reste/microbloc +Max: = Max: +Set = Fixer +Recycle output = Recyclage + +###./stairsplus/*### +%s Stairs = Escaliers en %s +%s Slab = Demi-dalle en %s +%s Panel = Barre en %s +%s Microblock = Microbloc en %s + +%s Pane = Panneau en %s +%s Fence = Barrire en %s \ No newline at end of file diff --git a/mods/moreblocks/locale/template.txt b/mods/moreblocks/locale/template.txt new file mode 100644 index 0000000..2b88227 --- /dev/null +++ b/mods/moreblocks/locale/template.txt @@ -0,0 +1,64 @@ +###init.lua### +[moreblocks] loaded. = + +###nodes.lua### +Jungle Wood Fence = +Empty Bookshelf = +Clean Glass = +Plankstone = +Wooden Tile = +Full Wooden Tile = +Centered Wooden Tile = +Up Wooden Tile = +Down Wooden Tile = +Left Wooden Tile = +Right Wooden Tile = +Circle Stone Bricks = +Stone Tile = +Split Stone Tile = +Glow Glass = +Super Glow Glass = +Coal Glass = +Iron Glass = +Coal Checker = +Iron Checker = +Trap Stone = +Trap Glass = +Trap Glow Glass = +Trap Super Glow Glass = +Coal Stone = +Iron Stone = +Coal Stone Bricks = +Iron Stone Bricks = +Cactus Checker = +Cactus Brick = +Sweeper = +Jungle Stick = +Rope = +All-faces Tree = + +###circular_saw.lua### +Circular Saw = +Circular saw, empty (owned by %s) = +Circular saw, working with %s (owned by %s) = +Circular saw, empty = +Circular saw is empty (owned by %s) = + +Input\nmaterial = +Left-over = +Max = +Set = +Recycle\noutput = + +###ownership.lua### +someone = +Sorry, %s owns that spot. = + +###./stairsplus/*### +%s Stairs = +%s Slab = +%s Panel = +%s Microblock = + +%s Pane = +%s Fence = diff --git a/mods/moreblocks/nodes.lua b/mods/moreblocks/nodes.lua new file mode 100644 index 0000000..5efda8f --- /dev/null +++ b/mods/moreblocks/nodes.lua @@ -0,0 +1,344 @@ +local S = moreblocks.gettext + +local sound_wood = default.node_sound_wood_defaults() +local sound_stone = default.node_sound_stone_defaults() +local sound_glass = default.node_sound_glass_defaults() +local sound_leaves = default.node_sound_leaves_defaults() + +local function tile_tiles(name) + local tex = "moreblocks_" ..name.. ".png" + return {tex, tex, tex, tex, tex.. "^[transformR90", tex.. "^[transformR90"} +end + +local nodes = { + ["wood_tile"] = { + description = S("Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^moreblocks_wood_tile.png", + "default_wood.png^moreblocks_wood_tile.png", + "default_wood.png^moreblocks_wood_tile.png", + "default_wood.png^moreblocks_wood_tile.png", + "default_wood.png^moreblocks_wood_tile.png^[transformR90", + "default_wood.png^moreblocks_wood_tile.png^[transformR90"}, + sounds = sound_wood, + }, + ["wood_tile_flipped"] = { + description = S("Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^moreblocks_wood_tile.png^[transformR90", + "default_wood.png^moreblocks_wood_tile.png^[transformR90", + "default_wood.png^moreblocks_wood_tile.png^[transformR90", + "default_wood.png^moreblocks_wood_tile.png^[transformR90", + "default_wood.png^moreblocks_wood_tile.png^[transformR180", + "default_wood.png^moreblocks_wood_tile.png^[transformR180"}, + sounds = sound_wood, + no_stairs = true, + }, + ["wood_tile_center"] = { + description = S("Centered Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^moreblocks_wood_tile_center.png"}, + sounds = sound_wood, + }, + ["wood_tile_full"] = { + description = S("Full Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = tile_tiles("wood_tile_full"), + sounds = sound_wood, + }, + ["wood_tile_up"] = { + description = S("Upwards Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^moreblocks_wood_tile_up.png"}, + sounds = sound_wood, + no_stairs = true, + }, + ["wood_tile_down"] = { + description = S("Downwards Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^[transformR180^moreblocks_wood_tile_up.png^[transformR180"}, + sounds = sound_wood, + no_stairs = true, + }, + ["wood_tile_left"] = { + description = S("Leftwards Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^[transformR270^moreblocks_wood_tile_up.png^[transformR270"}, + sounds = sound_wood, + no_stairs = true, + }, + ["wood_tile_right"] = { + description = S("Rightwards Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^[transformR90^moreblocks_wood_tile_up.png^[transformR90"}, + sounds = sound_wood, + no_stairs = true, + }, + ["circle_stone_bricks"] = { + description = S("Circle Stone Bricks"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["grey_bricks"] = { + description = S("Stone Bricks"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["coal_stone_bricks"] = { + description = S("Coal Stone Bricks"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["iron_stone_bricks"] = { + description = S("Iron Stone Bricks"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["stone_tile"] = { + description = S("Stone Tile"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["split_stone_tile"] = { + description = S("Split Stone Tile"), + tiles = {"moreblocks_split_stone_tile_top.png", + "moreblocks_split_stone_tile.png"}, + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["split_stone_tile_alt"] = { + description = S("Checkered Stone Tile"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["tar"] = { + description = S("Tar"), + groups = {cracky = 2}, + sounds = sound_stone, + }, + ["plankstone"] = { + description = S("Plankstone"), + groups = {cracky = 3}, + tiles = tile_tiles("plankstone"), + sounds = sound_stone, + }, + ["iron_glass"] = { + description = S("Iron Glass"), + drawtype = "glasslike_framed", + paramtype = "light", + sunlight_propagates = true, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + }, + ["coal_glass"] = { + description = S("Coal Glass"), + drawtype = "glasslike_framed", + paramtype = "light", + sunlight_propagates = true, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + }, + ["clean_glass"] = { + description = S("Clean Glass"), + drawtype = "glasslike_framed", + paramtype = "light", + sunlight_propagates = true, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + }, + ["cactus_brick"] = { + description = S("Cactus Brick"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["cactus_checker"] = { + description = S("Cactus Checker"), + groups = {cracky = 3}, + tiles = {"default_stone.png^moreblocks_cactus_checker.png", + "default_stone.png^moreblocks_cactus_checker.png", + "default_stone.png^moreblocks_cactus_checker.png", + "default_stone.png^moreblocks_cactus_checker.png", + "default_stone.png^moreblocks_cactus_checker.png^[transformR90", + "default_stone.png^moreblocks_cactus_checker.png^[transformR90"}, + sounds = sound_stone, + }, + ["empty_bookshelf"] = { + description = S("Empty Bookshelf"), + tiles = {"default_wood.png", "default_wood.png", + "moreblocks_empty_bookshelf.png"}, + groups = {snappy = 2, choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = sound_wood, + no_stairs = true, + }, + ["coal_stone"] = { + description = S("Coal Stone"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["iron_stone"] = { + description = S("Iron Stone"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["coal_checker"] = { + description = S("Coal Checker"), + tiles = {"default_stone.png^moreblocks_coal_checker.png", + "default_stone.png^moreblocks_coal_checker.png", + "default_stone.png^moreblocks_coal_checker.png", + "default_stone.png^moreblocks_coal_checker.png", + "default_stone.png^moreblocks_coal_checker.png^[transformR90", + "default_stone.png^moreblocks_coal_checker.png^[transformR90"}, + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["iron_checker"] = { + description = S("Iron Checker"), + tiles = {"default_stone.png^moreblocks_iron_checker.png", + "default_stone.png^moreblocks_iron_checker.png", + "default_stone.png^moreblocks_iron_checker.png", + "default_stone.png^moreblocks_iron_checker.png", + "default_stone.png^moreblocks_iron_checker.png^[transformR90", + "default_stone.png^moreblocks_iron_checker.png^[transformR90"}, + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["trap_stone"] = { + description = S("Trap Stone"), + walkable = false, + groups = {cracky = 3}, + sounds = sound_stone, + no_stairs = true, + }, + ["trap_glass"] = { + description = S("Trap Glass"), + drawtype = "glasslike_framed", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + no_stairs = true, + }, + ["fence_jungle_wood"] = { + description = S("Jungle Wood Fence"), + drawtype = "fencelike", + tiles = {"default_junglewood.png"}, + inventory_image = "default_fence_overlay.png^default_junglewood.png^default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_junglewood.png^default_fence_overlay.png^[makealpha:255,126,126", + paramtype = "light", + selection_box = { + type = "fixed", + fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7}, + }, + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = sound_wood, + no_stairs = true, + }, + ["all_faces_tree"] = { + description = S("All-faces Tree"), + tiles = {"default_tree_top.png"}, + groups = {tree = 1,snappy = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = sound_wood, + furnace_burntime = 30, + }, + ["all_faces_jungle_tree"] = { + description = S("All-faces Jungle Tree"), + tiles = {"default_jungletree_top.png"}, + groups = {tree = 1,snappy = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = sound_wood, + furnace_burntime = 30, + }, + ["glow_glass"] = { + description = S("Glow Glass"), + drawtype = "glasslike_framed", + paramtype = "light", + sunlight_propagates = true, + light_source = 11, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + }, + ["trap_glow_glass"] = { + description = S("Trap Glow Glass"), + drawtype = "glasslike_framed", + paramtype = "light", + sunlight_propagates = true, + light_source = 11, + walkable = false, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + no_stairs = true, + }, + ["super_glow_glass"] = { + description = S("Super Glow Glass"), + drawtype = "glasslike_framed", + paramtype = "light", + sunlight_propagates = true, + light_source = 15, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + }, + ["trap_super_glow_glass"] = { + description = S("Trap Super Glow Glass"), + drawtype = "glasslike_framed", + paramtype = "light", + sunlight_propagates = true, + light_source = 15, + walkable = false, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + no_stairs = true, + }, + ["rope"] = { + description = S("Rope"), + drawtype = "signlike", + inventory_image = "moreblocks_rope.png", + wield_image = "moreblocks_rope.png", + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "wallmounted", + walkable = false, + climbable = true, + selection_box = {type = "wallmounted",}, + groups = {snappy = 3, flammable = 2}, + sounds = sound_leaves, + no_stairs = true, + }, +} + +for name, def in pairs(nodes) do + def.tiles = def.tiles or {"moreblocks_" ..name.. ".png"} + minetest.register_node("moreblocks:" ..name, def) + minetest.register_alias(name, "moreblocks:" ..name) + if not def.no_stairs then + local groups = {} + for k, v in pairs(def.groups) do groups[k] = v end + stairsplus:register_all("moreblocks", name, "moreblocks:" ..name, { + description = def.description, + groups = groups, + tiles = def.tiles, + sunlight_propagates = def.sunlight_propagates, + light_source = def.light_source, + sounds = def.sounds, + }) + end +end + + +-- Items + +minetest.register_craftitem("moreblocks:sweeper", { + description = S("Sweeper"), + inventory_image = "moreblocks_sweeper.png", +}) + +minetest.register_craftitem("moreblocks:jungle_stick", { + description = S("Jungle Stick"), + inventory_image = "moreblocks_junglestick.png", + groups = {stick= 1}, +}) + +minetest.register_craftitem("moreblocks:nothing", { + inventory_image = "invisible.png", + on_use = function() end, +}) + diff --git a/mods/moreblocks/ownership.lua b/mods/moreblocks/ownership.lua new file mode 100644 index 0000000..9cd4cb3 --- /dev/null +++ b/mods/moreblocks/ownership.lua @@ -0,0 +1,35 @@ + +local S = moreblocks.gettext + +function moreblocks.node_is_owned(pos, placer) + local ownername = false + if type(IsPlayerNodeOwner) == "function" then -- node_ownership mod + if HasOwner(pos, placer) then -- returns true if the node is owned + if not IsPlayerNodeOwner(pos, placer:get_player_name()) then + if type(getLastOwner) == "function" then -- ...is an old version + ownername = getLastOwner(pos) + elseif type(GetNodeOwnerName) == "function" then -- ...is a recent version + ownername = GetNodeOwnerName(pos) + else + ownername = S("someone") + end + end + end + + elseif type(isprotect)=="function" then -- glomie's protection mod + if not isprotect(5, pos, placer) then + ownername = S("someone") + end + elseif type(protector)=="table" and type(protector.can_dig)=="function" then -- Zeg9's protection mod + if not protector.can_dig(5, pos, placer) then + ownername = S("someone") + end + end + + if ownername ~= false then + minetest.chat_send_player( placer:get_player_name(), S("Sorry, %s owns that spot."):format(ownername) ) + return true + else + return false + end +end diff --git a/mods/moreblocks/redefinitions.lua b/mods/moreblocks/redefinitions.lua new file mode 100644 index 0000000..d97f7d1 --- /dev/null +++ b/mods/moreblocks/redefinitions.lua @@ -0,0 +1,101 @@ +-- Redefinitions of some default crafting recipes: + +minetest.register_craft({ + output = "default:sign_wall 4", + recipe = { + {"default:wood", "default:wood", "default:wood"}, + {"default:wood", "default:wood", "default:wood"}, + {"", "default:stick", ""}, + } +}) + +minetest.register_craft({ + output = "default:ladder 4", + recipe = { + {"default:stick", "", "default:stick"}, + {"default:stick", "default:stick", "default:stick"}, + {"default:stick", "", "default:stick"}, + } +}) + +minetest.register_craft({ + output = "default:paper 4", + recipe = { + {"default:papyrus", "default:papyrus", "default:papyrus"}, + } +}) + +minetest.register_craft({ + output = "default:rail 16", + recipe = { + {"default:steel_ingot", "", "default:steel_ingot"}, + {"default:steel_ingot", "default:stick", "default:steel_ingot"}, + {"default:steel_ingot", "", "default:steel_ingot"}, + } +}) + +minetest.register_craft({ + type = "toolrepair", + additional_wear = -0.15, -- Tool repair buff (15% bonus instead of 2%). +}) + +-- Redefinitions of some default nodes: + +-- Make glass and obsidian glass framed, like the More Blocks glasses: +minetest.override_item("default:glass", { + drawtype = "glasslike_framed", +}) + +minetest.override_item("default:obsidian_glass", { + drawtype = "glasslike_framed", +}) + +-- Let there be light. This makes some nodes let light pass through: +minetest.override_item("default:ladder", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:sapling", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:dry_shrub", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:papyrus", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:fence_wood", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:junglegrass", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:junglesapling", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:grass_1", { + inventory_image = "default_grass_3.png", -- Use a bigger inventory image. + wield_image = "default_grass_3.png", + paramtype = "light", + sunlight_propagates = true, +}) + +for i = 2, 5 do + minetest.override_item("default:grass_" ..i, { + paramtype = "light", + sunlight_propagates = true, + }) +end diff --git a/mods/moreblocks/stairsplus/API.md b/mods/moreblocks/stairsplus/API.md new file mode 100644 index 0000000..a98ec81 --- /dev/null +++ b/mods/moreblocks/stairsplus/API.md @@ -0,0 +1,25 @@ +API documentation for Stairs+ +================================ +- - - - - - - - - - - - - - - - + +* `stairsplus:register_all(modname, subname, recipeitem, fields)` + Registers a stair, slab, panel, microblock, and any other types of + nodes to be added in the future. + This also registers the node with the circular saw. + Example: + ```lua + stairsplus:register_all("moreblocks", "wood", "defaut:wood", { + description = "Wooden", + tiles = {"default_wood.png"}, + groups = {oddly_breakabe_by_hand=1}, + sounds = default.node_sound_wood_defaults(), + }) + ``` +The following register only a particular type of microblock. +You will probably never want to use them directly: + +* `stairsplus:register_stair(modname, subname, recipeitem, fields)` +* `stairsplus:register_slab(modname, subname, recipeitem, fields)` +* `stairsplus:register_panel(modname, subname, recipeitem, fields)` +* `stairsplus:register_micro(modname, subname, recipeitem, fields)` + diff --git a/mods/moreblocks/stairsplus/aliases.lua b/mods/moreblocks/stairsplus/aliases.lua new file mode 100644 index 0000000..c92df48 --- /dev/null +++ b/mods/moreblocks/stairsplus/aliases.lua @@ -0,0 +1,62 @@ + +local function register_stairsplus_alias(modname, origname, newname) + minetest.register_alias(modname.. ":slab_" ..origname, "moreblocks:slab_" ..newname) + minetest.register_alias(modname.. ":slab_" ..origname.. "_inverted", "moreblocks:slab_" ..newname.. "_inverted") + minetest.register_alias(modname.. ":slab_" ..origname.. "_wall", "moreblocks:slab_" ..newname.. "_wall") + minetest.register_alias(modname.. ":slab_" ..origname.. "_quarter", "moreblocks:slab_" ..newname.. "_quarter") + minetest.register_alias(modname.. ":slab_" ..origname.. "_quarter_inverted", "moreblocks:slab_" ..newname.. "_quarter_inverted") + minetest.register_alias(modname.. ":slab_" ..origname.. "_quarter_wall", "moreblocks:slab_" ..newname.. "_quarter_wall") + minetest.register_alias(modname.. ":slab_" ..origname.. "_three_quarter", "moreblocks:slab_" ..newname.. "_three_quarter") + minetest.register_alias(modname.. ":slab_" ..origname.. "_three_quarter_inverted", "moreblocks:slab_" ..newname.. "_three_quarter_inverted") + minetest.register_alias(modname.. ":slab_" ..origname.. "_three_quarter_wall", "moreblocks:slab_" ..newname.. "_three_quarter_wall") + minetest.register_alias(modname.. ":stair_" ..origname, "moreblocks:stair_" ..newname) + minetest.register_alias(modname.. ":stair_" ..origname.. "_inverted", "moreblocks:stair_" ..newname.. "_inverted") + minetest.register_alias(modname.. ":stair_" ..origname.. "_wall", "moreblocks:stair_" ..newname.. "_wall") + minetest.register_alias(modname.. ":stair_" ..origname.. "_wall_half", "moreblocks:stair_" ..newname.. "_wall_half") + minetest.register_alias(modname.. ":stair_" ..origname.. "_wall_half_inverted", "moreblocks:stair_" ..newname.. "_wall_half_inverted") + minetest.register_alias(modname.. ":stair_" ..origname.. "_half", "moreblocks:stair_" ..newname.. "_half") + minetest.register_alias(modname.. ":stair_" ..origname.. "_half_inverted", "moreblocks:stair_" ..newname.. "_half_inverted") + minetest.register_alias(modname.. ":stair_" ..origname.. "_right_half", "moreblocks:stair_" ..newname.. "_right_half") + minetest.register_alias(modname.. ":stair_" ..origname.. "_right_half_inverted", "moreblocks:stair_" ..newname.. "_right_half_inverted") + minetest.register_alias(modname.. ":stair_" ..origname.. "_wall_half", "moreblocks:stair_" ..newname.. "_wall_half") + minetest.register_alias(modname.. ":stair_" ..origname.. "_wall_half_inverted", "moreblocks:stair_" ..newname.. "_wall_half_inverted") + minetest.register_alias(modname.. ":stair_" ..origname.. "_inner", "moreblocks:stair_" ..newname.. "_inner") + minetest.register_alias(modname.. ":stair_" ..origname.. "_inner_inverted", "moreblocks:stair_" ..newname.. "_inner_inverted") + minetest.register_alias(modname.. ":stair_" ..origname.. "_outer", "moreblocks:stair_" ..newname.. "_outer") + minetest.register_alias(modname.. ":stair_" ..origname.. "_outer_inverted", "moreblocks:stair_" ..newname.. "_outer_inverted") + minetest.register_alias(modname.. ":panel_" ..origname.. "_bottom", "moreblocks:panel_" ..newname.. "_bottom") + minetest.register_alias(modname.. ":panel_" ..origname.. "_top", "moreblocks:panel_" ..newname.. "_top") + minetest.register_alias(modname.. ":panel_" ..origname.. "_vertical", "moreblocks:panel_" ..newname.. "_vertical") + minetest.register_alias(modname.. ":micro_" ..origname.. "_bottom", "moreblocks:micro_" ..newname.. "_bottom") + minetest.register_alias(modname.. ":micro_" ..origname.. "_top", "moreblocks:micro_" ..newname.. "_top") +end + +register_stairsplus_alias("stairsplus", "stone", "stone") +register_stairsplus_alias("stairsplus", "wood", "wood") +register_stairsplus_alias("stairsplus", "cobble", "cobble") +register_stairsplus_alias("stairsplus", "brick", "brick") +register_stairsplus_alias("stairsplus", "sandstone", "sandstone") +register_stairsplus_alias("stairsplus", "glass", "glass") +register_stairsplus_alias("stairsplus", "tree", "tree") +register_stairsplus_alias("stairsplus", "jungletree", "jungletree") +register_stairsplus_alias("stairsplus", "desert_stone", "desert_stone") +register_stairsplus_alias("stairsplus", "steelblock", "steelblock") +register_stairsplus_alias("stairsplus", "mossycobble", "mossycobble") + +register_stairsplus_alias("moreblocks", "coalstone", "coal_stone") +register_stairsplus_alias("moreblocks", "junglewood", "jungle_wood") +register_stairsplus_alias("moreblocks", "circlestonebrick", "circle_stone_bricks") +register_stairsplus_alias("moreblocks", "ironstone", "iron_stone") +register_stairsplus_alias("moreblocks", "coalglass", "coal_glass") +register_stairsplus_alias("moreblocks", "ironglass", "iron_glass") +register_stairsplus_alias("moreblocks", "glowglass", "glow_glass") +register_stairsplus_alias("moreblocks", "superglowglass", "super_glow_glass") +register_stairsplus_alias("moreblocks", "coalchecker", "coal_checker") +register_stairsplus_alias("moreblocks", "ironchecker", "iron_checker") +register_stairsplus_alias("moreblocks", "cactuschecker", "cactus_checker") +register_stairsplus_alias("moreblocks", "ironstonebrick", "iron_stone_bricks") +register_stairsplus_alias("moreblocks", "stonesquare", "stone_tile") +register_stairsplus_alias("moreblocks", "splitstonesquare", "split_stone_tile") +register_stairsplus_alias("moreblocks", "woodtile", "wood_tile") +register_stairsplus_alias("moreblocks", "woodtile_centered", "wood_tile_centered") +register_stairsplus_alias("moreblocks", "woodtile_full", "wood_tile_full") diff --git a/mods/moreblocks/stairsplus/conversion.lua b/mods/moreblocks/stairsplus/conversion.lua new file mode 100644 index 0000000..fda30c7 --- /dev/null +++ b/mods/moreblocks/stairsplus/conversion.lua @@ -0,0 +1,132 @@ +-- Function to convert all stairs/slabs/etc nodes from +-- inverted, wall, etc to regular + 6d facedir + +local dirs1 = {21, 20, 23, 22, 21} +local dirs2 = {15, 8, 17, 6, 15} +local dirs3 = {14, 11, 16, 5, 14} + +function stairsplus:register_6dfacedir_conversion(modname, material) + --print("Register stairsplus 6d facedir conversion") + --print('ABM for '..modname..' "'..material..'"') + + local objects_list1 = { + modname.. ":slab_" ..material.. "_inverted", + modname.. ":slab_" ..material.. "_quarter_inverted", + modname.. ":slab_" ..material.. "_three_quarter_inverted", + modname.. ":stair_" ..material.. "_inverted", + modname.. ":stair_" ..material.. "_wall", + modname.. ":stair_" ..material.. "_wall_half", + modname.. ":stair_" ..material.. "_wall_half_inverted", + modname.. ":stair_" ..material.. "_half_inverted", + modname.. ":stair_" ..material.. "_right_half_inverted", + modname.. ":panel_" ..material.. "_vertical", + modname.. ":panel_" ..material.. "_top", + } + + local objects_list2 = { + modname.. ":slab_" ..material.. "_wall", + modname.. ":slab_" ..material.. "_quarter_wall", + modname.. ":slab_" ..material.. "_three_quarter_wall", + modname.. ":stair_" ..material.. "_inner_inverted", + modname.. ":stair_" ..material.. "_outer_inverted", + modname.. ":micro_" ..material.. "_top" + } + + for _, object in pairs(objects_list1) do + local flip_upside_down = false + local flip_to_wall = false + + local dest_object = object + + if string.find(dest_object, "_inverted") then + flip_upside_down = true + dest_object = string.gsub(dest_object, "_inverted", "") + end + + if string.find(object, "_top") then + flip_upside_down = true + dest_object = string.gsub(dest_object, "_top", "") + end + + if string.find(dest_object, "_wall") then + flip_to_wall = true + dest_object = string.gsub(dest_object, "_wall", "") + end + + if string.find(dest_object, "_vertical") then + flip_to_wall = true + dest_object = string.gsub(dest_object, "_vertical", "") + end + + if string.find(dest_object, "_half") and not string.find(dest_object, "_right_half") then + dest_object = string.gsub(dest_object, "_half", "_right_half") + elseif string.find(dest_object, "_right_half") then + dest_object = string.gsub(dest_object, "_right_half", "_half") + end + + --print(" +---> convert " ..object) + --print(" | to " ..dest_object) + + minetest.register_abm({ + nodenames = {object}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local fdir = node.param2 or 0 + + if flip_upside_down and not flip_to_wall then + nfdir = dirs1[fdir + 2] + elseif flip_to_wall and not flip_upside_down then + nfdir = dirs2[fdir + 1] + elseif flip_to_wall and flip_upside_down then + nfdir = dirs3[fdir + 2] + end + minetest.set_node(pos, {name = dest_object, param2 = nfdir}) + end + }) + end + + for _, object in pairs(objects_list2) do + local flip_upside_down = false + local flip_to_wall = false + + local dest_object = object + + if string.find(dest_object, "_inverted") then + flip_upside_down = true + dest_object = string.gsub(dest_object, "_inverted", "") + end + + if string.find(dest_object, "_top") then + flip_upside_down = true + dest_object = string.gsub(dest_object, "_top", "") + end + + if string.find(dest_object, "_wall") then + flip_to_wall = true + dest_object = string.gsub(dest_object, "_wall", "") + end + + --print(" +---> convert " ..object) + --print(" | to " ..dest_object) + + minetest.register_abm({ + nodenames = {object}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local fdir = node.param2 + local nfdir = 20 + + if flip_upside_down and not flip_to_wall then + nfdir = dirs1[fdir + 1] + elseif flip_to_wall and not flip_upside_down then + nfdir = dirs2[fdir + 2] + + end + minetest.set_node(pos, {name = dest_object, param2 = nfdir}) + end + }) + end +end + diff --git a/mods/moreblocks/stairsplus/init.lua b/mods/moreblocks/stairsplus/init.lua new file mode 100644 index 0000000..cceee2a --- /dev/null +++ b/mods/moreblocks/stairsplus/init.lua @@ -0,0 +1,43 @@ +-- Nodes will be called :{stair,slab,panel,micro}_ + +local modpath = minetest.get_modpath("moreblocks").. "/stairsplus" + +stairsplus = {} +stairsplus.expect_infinite_stacks = false + +if not minetest.get_modpath("unified_inventory") +and minetest.setting_getbool("creative_mode") then + stairsplus.expect_infinite_stacks = true +end + +function stairsplus:register_all(modname, subname, recipeitem, fields) + fields = fields or {} + fields.groups = fields.groups or {} + if not moreblocks.config.show_stairsplus_creative_inv then + fields.groups.not_in_creative_inventory = 1 + end + self:register_stair(modname, subname, recipeitem, fields) + self:register_slab (modname, subname, recipeitem, fields) + self:register_panel(modname, subname, recipeitem, fields) + self:register_micro(modname, subname, recipeitem, fields) + -- self:register_6dfacedir_conversion(modname, subname) -- Not needed as of Q3 2013, uncomment to fix old maps. + circular_saw.known_nodes[recipeitem] = {modname, subname} +end + +function register_stair_slab_panel_micro(modname, subname, recipeitem, groups, images, description, drop, light) + stairsplus:register_all(modname, subname, recipeitem, { + groups = groups, + tiles = images, + description = description, + drop = drop, + light_source = light + }) +end + +-- dofile(modpath.. "/aliases.lua") -- Not needed as of Q2 2013, uncomment to fix old maps. +-- dofile(modpath.. "/conversion.lua") -- Not needed as of Q2 2013, uncomment to fix old maps. +dofile(modpath.. "/stairs.lua") +dofile(modpath.. "/slabs.lua") +dofile(modpath.. "/panels.lua") +dofile(modpath.. "/microblocks.lua") +dofile(modpath.. "/registrations.lua") diff --git a/mods/moreblocks/stairsplus/microblocks.lua b/mods/moreblocks/stairsplus/microblocks.lua new file mode 100644 index 0000000..aac69ee --- /dev/null +++ b/mods/moreblocks/stairsplus/microblocks.lua @@ -0,0 +1,122 @@ +local S -- Load translation library if intllib is installed: +if intllib then + S = intllib.Getter(minetest.get_current_modname()) +else + S = function(s) return s end +end + +-- Node will be called :micro_ + +function register_micro(modname, subname, recipeitem, groups, images, description, drop, light) + return stairsplus:register_micro(modname, subname, recipeitem, { + groups = groups, + tiles = images, + description = description, + drop = drop, + light_source = light, + sounds = default.node_sound_stone_defaults(), + }) +end + +function stairsplus:register_micro(modname, subname, recipeitem, fields) + local defs = { + [""] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, 0, 0.5}, + }, + }, + ["_1"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, -0.4375, 0.5}, + }, + }, + ["_2"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, -0.375, 0.5}, + }, + }, + ["_4"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, -0.25, 0.5}, + }, + }, + ["_12"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, 0.25, 0.5}, + }, + }, + ["_14"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, 0.375, 0.5}, + }, + }, + ["_15"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, 0.4375, 0.5}, + }, + } + } + + local desc = S("%s Microblock"):format(fields.description) + for alternate, def in pairs(defs) do + def.drawtype = "nodebox" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.on_place = minetest.rotate_node + for k, v in pairs(fields) do + def[k] = v + end + def.description = desc + if fields.drop then + def.drop = modname.. ":micro_" ..fields.drop..alternate + end + minetest.register_node(":" ..modname.. ":micro_" ..subname..alternate, def) + end + + minetest.register_alias(modname.. ":micro_" ..subname.. "_bottom", modname.. ":micro_" ..subname) + + -- Some saw-less recipes: + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":micro_" .. subname .. " 7", + recipe = {modname .. ":stair_" .. subname .. "_inner"}, + }) + + minetest.register_craft({ + output = modname .. ":micro_" .. subname .. " 6", + type = "shapeless", + recipe = {modname .. ":stair_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":micro_" .. subname .. " 5", + recipe = {modname .. ":stair_" .. subname .. "_outer"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":micro_" .. subname .. " 4", + recipe = {modname .. ":slab_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":micro_" .. subname .. " 2", + recipe = {modname .. ":panel_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) +end diff --git a/mods/moreblocks/stairsplus/panels.lua b/mods/moreblocks/stairsplus/panels.lua new file mode 100644 index 0000000..f93f1cf --- /dev/null +++ b/mods/moreblocks/stairsplus/panels.lua @@ -0,0 +1,113 @@ +local S -- Load translation library if intllib is installed: +if intllib then + S = intllib.Getter(minetest.get_current_modname()) +else + S = function(s) return s end +end + +-- Node will be called :panel_ + +function register_panel(modname, subname, recipeitem, groups, images, description, drop, light) + return stairsplus:register_panel(modname, subname, recipeitem, { + groups = groups, + tiles = images, + description = description, + drop = drop, + light_source = light, + sounds = default.node_sound_stone_defaults(), + }) +end + +function stairsplus:register_panel(modname, subname, recipeitem, fields) + local defs = { + [""] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0, 0.5}, + }, + }, + ["_1"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, -0.4375, 0.5}, + }, + }, + ["_2"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, -0.375, 0.5}, + }, + }, + ["_4"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, -0.25, 0.5}, + }, + }, + ["_12"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.25, 0.5}, + }, + }, + ["_14"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.375, 0.5}, + }, + }, + ["_15"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.4375, 0.5}, + }, + } + } + + local desc = S("%s Panel"):format(fields.description) + for alternate, def in pairs(defs) do + def.drawtype = "nodebox" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.on_place = minetest.rotate_node + for k, v in pairs(fields) do + def[k] = v + end + def.description = desc + if fields.drop then + def.drop = modname.. ":panel_" ..fields.drop..alternate + end + minetest.register_node(":" ..modname.. ":panel_" ..subname..alternate, def) + end + minetest.register_alias(modname.. ":panel_" ..subname.. "_bottom", modname.. ":panel_" ..subname) + + -- Some saw-less recipes: + + minetest.register_craft({ + output = modname .. ":panel_" .. subname .. " 12", + recipe = { + {recipeitem, ""}, + {recipeitem, recipeitem}, + }, + }) + + minetest.register_craft({ + output = modname .. ":panel_" .. subname .. " 12", + recipe = { + {"", recipeitem}, + {recipeitem, recipeitem}, + }, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":panel_" .. subname, + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":panel_" .. subname, modname .. ":panel_" .. subname, modname .. ":panel_" .. subname, modname .. ":panel_" .. subname}, + }) +end diff --git a/mods/moreblocks/stairsplus/registrations.lua b/mods/moreblocks/stairsplus/registrations.lua new file mode 100644 index 0000000..cc22d33 --- /dev/null +++ b/mods/moreblocks/stairsplus/registrations.lua @@ -0,0 +1,49 @@ +local default_nodes = { -- Default stairs/slabs/panels/microblocks: + "stone", + "cobble", + "mossycobble", + "brick", + "sandstone", + "steelblock", + "goldblock", + "copperblock", + "bronzeblock", + "diamondblock", + "desert_stone", +-- "desert_cobble", + "glass", + "tree", + "wood", + "jungletree", + "junglewood", + "obsidian", + "obsidian_glass", + "stonebrick", + "desert_stonebrick", + "sandstonebrick", +} + +for _, name in pairs(default_nodes) do + local nodename = "default:" .. name + local ndef = minetest.registered_nodes[nodename] + local groups = {} + for k, v in pairs(ndef.groups) + -- Ignore wood and stone groups to not make them usable in crafting: + do if k ~= "wood" and k ~= "stone" then + groups[k] = v + end + end + local drop + if type(ndef.drop) == "string" then + drop = ndef.drop:sub(9) + end + stairsplus:register_all("moreblocks", name, nodename, { + description = ndef.description, + drop = drop, + groups = groups, + sounds = ndef.sounds, + tiles = ndef.tiles, + sunlight_propagates = true, + }) +end + diff --git a/mods/moreblocks/stairsplus/slabs.lua b/mods/moreblocks/stairsplus/slabs.lua new file mode 100644 index 0000000..bbae96b --- /dev/null +++ b/mods/moreblocks/stairsplus/slabs.lua @@ -0,0 +1,120 @@ +local S -- Load translation library if intllib is installed: +if intllib then + S = intllib.Getter(minetest.get_current_modname()) +else + S = function(s) return s end +end + +-- Node will be called :slab_ + +function register_slab(modname, subname, recipeitem, groups, images, description, drop, light) + return stairsplus:register_slab(modname, subname, recipeitem, { + groups = groups, + tiles = images, + description = description, + drop = drop, + light_source = light, + sounds = default.node_sound_stone_defaults(), + }) +end + +function stairsplus:register_slab(modname, subname, recipeitem, fields) + local defs = { + [""] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + }, + ["_quarter"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, + }, + }, + ["_three_quarter"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.25, 0.5}, + }, + }, + ["_1"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -0.4375, 0.5}, + }, + }, + ["_2"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -0.375, 0.5}, + }, + }, + ["_14"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.375, 0.5}, + }, + }, + ["_15"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.4375, 0.5}, + }, + }, + } + local desc = S("%s Slab"):format(fields.description) + for alternate, def in pairs(defs) do + def.drawtype = "nodebox" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.on_place = minetest.rotate_node + for k, v in pairs(fields) do + def[k] = v + end + def.description = desc + if fields.drop then + def.drop = modname.. ":slab_" ..fields.drop..alternate + end + minetest.register_node(":" ..modname.. ":slab_" ..subname..alternate, def) + end + minetest.register_alias("stairs:slab_" ..subname, modname.. ":slab_" ..subname) + + -- Some saw-less recipes: + + minetest.register_craft({ + output = modname .. ":slab_" .. subname .. " 6", + recipe = {{recipeitem, recipeitem, recipeitem}}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname, + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) + + minetest.register_craft({ + output = modname .. ":slab_" .. subname, + recipe = {{modname .. ":panel_" .. subname, modname .. ":panel_" .. subname}}, + }) + + minetest.register_craft({ + output = modname .. ":slab_" .. subname, + recipe = { + {modname .. ":panel_" .. subname}, + {modname .. ":panel_" .. subname}, + }, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slab_" .. subname, modname .. ":slab_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname .. " 3", + recipe = {modname .. ":stair_" .. subname, modname .. ":stair_" .. subname}, + }) +end diff --git a/mods/moreblocks/stairsplus/stairs.lua b/mods/moreblocks/stairsplus/stairs.lua new file mode 100644 index 0000000..b921d08 --- /dev/null +++ b/mods/moreblocks/stairsplus/stairs.lua @@ -0,0 +1,225 @@ +local S -- Load translation library if intllib is installed: +if intllib then + S = intllib.Getter(minetest.get_current_modname()) +else + S = function(s) return s end +end + +-- Node will be called :stair_ + +function register_stair(modname, subname, recipeitem, groups, images, description, drop, light) + return stairsplus:register_stair(modname, subname, recipeitem, { + groups = groups, + tiles = images, + description = description, + drop = drop, + light_source = light, + sounds = default.node_sound_stone_defaults(), + }) +end + +function stairsplus:register_stair(modname, subname, recipeitem, fields) + local defs = { + [""] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.5, 0.5}, + }, + }, + }, + ["_half"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0, 0, 0.5}, + {-0.5, 0, 0, 0, 0.5, 0.5}, + }, + }, + }, + ["_right_half" ]= { + node_box = { + type = "fixed", + fixed = { + {0, -0.5, -0.5, 0.5, 0, 0.5}, + {0, 0, 0, 0.5, 0.5, 0.5}, + }, + }, + }, + ["_inner"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.5, 0.5}, + {-0.5, 0, -0.5, 0, 0.5, 0}, + }, + }, + }, + ["_outer"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0, 0.5, 0.5}, + }, + }, + }, + ["_alt"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0}, + {-0.5, 0, 0, 0.5, 0.5, 0.5}, + }, + }, + }, + ["_alt_1"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.0625, -0.5, 0.5, 0, 0}, + {-0.5, 0.4375, 0, 0.5, 0.5, 0.5}, + }, + }, + }, + ["_alt_2"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.125, -0.5, 0.5, 0, 0}, + {-0.5, 0.375, 0, 0.5, 0.5, 0.5}, + }, + }, + }, + ["_alt_4"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.25, -0.5, 0.5, 0, 0}, + {-0.5, 0.25, 0, 0.5, 0.5, 0.5}, + }, + }, + }, + } + + local desc = S("%s Stairs"):format(fields.description) + for alternate, def in pairs(defs) do + def.drawtype = "nodebox" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.on_place = minetest.rotate_node + for k, v in pairs(fields) do + def[k] = v + end + def.description = desc + if fields.drop then + def.drop = modname.. ":stair_" ..fields.drop..alternate + end + minetest.register_node(":" ..modname.. ":stair_" ..subname..alternate, def) + end + minetest.register_alias(":stairs:stair_" ..subname, modname.. ":stair_" ..subname) + + -- Some saw-less recipes: + + minetest.register_craft({ + output = modname .. ":stair_" .. subname .. " 8", + recipe = { + {recipeitem, "", ""}, + {recipeitem, recipeitem, ""}, + {recipeitem, recipeitem, recipeitem}, + }, + }) + + minetest.register_craft({ + output = modname .. ":stair_" .. subname .. " 8", + recipe = { + {"", "", recipeitem}, + {"", recipeitem, recipeitem}, + {recipeitem, recipeitem, recipeitem}, + }, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname, + recipe = {modname .. ":panel_" .. subname, modname .. ":slab_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname, + recipe = {modname .. ":panel_" .. subname, modname .. ":panel_" .. subname, modname .. ":panel_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname .. "_outer", + recipe = {modname .. ":micro_" .. subname, modname .. ":slab_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname .. "_half", + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname .. "_half", + recipe = {modname .. ":panel_" .. subname, modname .. ":micro_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname .. "_right_half", + recipe = {modname .. ":stair_" .. subname .. "_half"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname .. "_half", + recipe = {modname .. ":stair_" .. subname .. "_right_half"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname, + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname .. "_inner", + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname .. "_outer", + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname, + recipe = {modname .. ":panel_" .. subname, modname .. ":panel_" .. subname, modname .. ":panel_" .. subname}, + }) + + minetest.register_craft({ -- See mirrored variation of the recipe below. + output = modname .. ":stair_" .. subname .. "_alt", + recipe = { + {modname .. ":panel_" .. subname, ""}, + {"" , modname .. ":panel_" .. subname}, + }, + }) + + minetest.register_craft({ -- Mirrored variation of the recipe above. + output = modname .. ":stair_" .. subname .. "_alt", + recipe = { + {"" , modname .. ":panel_" .. subname}, + {modname .. ":panel_" .. subname, ""}, + }, + }) +end diff --git a/mods/moreblocks/textures/default_brick.png b/mods/moreblocks/textures/default_brick.png new file mode 100644 index 0000000..9c76033 Binary files /dev/null and b/mods/moreblocks/textures/default_brick.png differ diff --git a/mods/moreblocks/textures/default_fence_overlay.png b/mods/moreblocks/textures/default_fence_overlay.png new file mode 100644 index 0000000..780e736 Binary files /dev/null and b/mods/moreblocks/textures/default_fence_overlay.png differ diff --git a/mods/moreblocks/textures/invisible.png b/mods/moreblocks/textures/invisible.png new file mode 100644 index 0000000..4b5b302 Binary files /dev/null and b/mods/moreblocks/textures/invisible.png differ diff --git a/mods/moreblocks/textures/moreblocks_cactus_brick.png b/mods/moreblocks/textures/moreblocks_cactus_brick.png new file mode 100644 index 0000000..0e8c2c9 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_cactus_brick.png differ diff --git a/mods/moreblocks/textures/moreblocks_cactus_checker.png b/mods/moreblocks/textures/moreblocks_cactus_checker.png new file mode 100644 index 0000000..99c2677 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_cactus_checker.png differ diff --git a/mods/moreblocks/textures/moreblocks_circle_stone_bricks.png b/mods/moreblocks/textures/moreblocks_circle_stone_bricks.png new file mode 100644 index 0000000..4ca0134 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_circle_stone_bricks.png differ diff --git a/mods/moreblocks/textures/moreblocks_circular_saw_bottom.png b/mods/moreblocks/textures/moreblocks_circular_saw_bottom.png new file mode 100644 index 0000000..1522829 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_circular_saw_bottom.png differ diff --git a/mods/moreblocks/textures/moreblocks_circular_saw_side.png b/mods/moreblocks/textures/moreblocks_circular_saw_side.png new file mode 100644 index 0000000..ce9e16f Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_circular_saw_side.png differ diff --git a/mods/moreblocks/textures/moreblocks_circular_saw_top.png b/mods/moreblocks/textures/moreblocks_circular_saw_top.png new file mode 100644 index 0000000..96f3350 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_circular_saw_top.png differ diff --git a/mods/moreblocks/textures/moreblocks_clean_glass.png b/mods/moreblocks/textures/moreblocks_clean_glass.png new file mode 100644 index 0000000..140ee2b Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_clean_glass.png differ diff --git a/mods/moreblocks/textures/moreblocks_coal_checker.png b/mods/moreblocks/textures/moreblocks_coal_checker.png new file mode 100644 index 0000000..3df90c3 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_coal_checker.png differ diff --git a/mods/moreblocks/textures/moreblocks_coal_glass.png b/mods/moreblocks/textures/moreblocks_coal_glass.png new file mode 100644 index 0000000..5cb7227 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_coal_glass.png differ diff --git a/mods/moreblocks/textures/moreblocks_coal_glass_stairsplus.png b/mods/moreblocks/textures/moreblocks_coal_glass_stairsplus.png new file mode 100644 index 0000000..8086a28 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_coal_glass_stairsplus.png differ diff --git a/mods/moreblocks/textures/moreblocks_coal_stone.png b/mods/moreblocks/textures/moreblocks_coal_stone.png new file mode 100644 index 0000000..1e514ed Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_coal_stone.png differ diff --git a/mods/moreblocks/textures/moreblocks_coal_stone_bricks.png b/mods/moreblocks/textures/moreblocks_coal_stone_bricks.png new file mode 100644 index 0000000..366e445 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_coal_stone_bricks.png differ diff --git a/mods/moreblocks/textures/moreblocks_empty_bookshelf.png b/mods/moreblocks/textures/moreblocks_empty_bookshelf.png new file mode 100644 index 0000000..b49fd2e Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_empty_bookshelf.png differ diff --git a/mods/moreblocks/textures/moreblocks_fence_jungle_wood.png b/mods/moreblocks/textures/moreblocks_fence_jungle_wood.png new file mode 100644 index 0000000..b59db10 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_fence_jungle_wood.png differ diff --git a/mods/moreblocks/textures/moreblocks_fence_wood.png b/mods/moreblocks/textures/moreblocks_fence_wood.png new file mode 100644 index 0000000..e3510c5 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_fence_wood.png differ diff --git a/mods/moreblocks/textures/moreblocks_glass.png b/mods/moreblocks/textures/moreblocks_glass.png new file mode 100644 index 0000000..912b029 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_glass.png differ diff --git a/mods/moreblocks/textures/moreblocks_glass_stairsplus.png b/mods/moreblocks/textures/moreblocks_glass_stairsplus.png new file mode 100644 index 0000000..b879ec3 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_glass_stairsplus.png differ diff --git a/mods/moreblocks/textures/moreblocks_glow_glass.png b/mods/moreblocks/textures/moreblocks_glow_glass.png new file mode 100644 index 0000000..843bebf Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_glow_glass.png differ diff --git a/mods/moreblocks/textures/moreblocks_glow_glass_stairsplus.png b/mods/moreblocks/textures/moreblocks_glow_glass_stairsplus.png new file mode 100644 index 0000000..cdb8044 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_glow_glass_stairsplus.png differ diff --git a/mods/moreblocks/textures/moreblocks_grey_bricks.png b/mods/moreblocks/textures/moreblocks_grey_bricks.png new file mode 100644 index 0000000..9839ca2 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_grey_bricks.png differ diff --git a/mods/moreblocks/textures/moreblocks_iron_checker.png b/mods/moreblocks/textures/moreblocks_iron_checker.png new file mode 100644 index 0000000..d27f4df Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_iron_checker.png differ diff --git a/mods/moreblocks/textures/moreblocks_iron_glass.png b/mods/moreblocks/textures/moreblocks_iron_glass.png new file mode 100644 index 0000000..51be0d6 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_iron_glass.png differ diff --git a/mods/moreblocks/textures/moreblocks_iron_glass_stairsplus.png b/mods/moreblocks/textures/moreblocks_iron_glass_stairsplus.png new file mode 100644 index 0000000..52e3bf3 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_iron_glass_stairsplus.png differ diff --git a/mods/moreblocks/textures/moreblocks_iron_stone.png b/mods/moreblocks/textures/moreblocks_iron_stone.png new file mode 100644 index 0000000..20c42f3 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_iron_stone.png differ diff --git a/mods/moreblocks/textures/moreblocks_iron_stone_bricks.png b/mods/moreblocks/textures/moreblocks_iron_stone_bricks.png new file mode 100644 index 0000000..1f817f8 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_iron_stone_bricks.png differ diff --git a/mods/moreblocks/textures/moreblocks_junglestick.png b/mods/moreblocks/textures/moreblocks_junglestick.png new file mode 100644 index 0000000..7c6c462 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_junglestick.png differ diff --git a/mods/moreblocks/textures/moreblocks_obsidian_glass_stairsplus.png b/mods/moreblocks/textures/moreblocks_obsidian_glass_stairsplus.png new file mode 100644 index 0000000..3eb22d0 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_obsidian_glass_stairsplus.png differ diff --git a/mods/moreblocks/textures/moreblocks_plankstone.png b/mods/moreblocks/textures/moreblocks_plankstone.png new file mode 100644 index 0000000..b1a65c5 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_plankstone.png differ diff --git a/mods/moreblocks/textures/moreblocks_plankstone_2.png b/mods/moreblocks/textures/moreblocks_plankstone_2.png new file mode 100644 index 0000000..953c2f5 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_plankstone_2.png differ diff --git a/mods/moreblocks/textures/moreblocks_rope.png b/mods/moreblocks/textures/moreblocks_rope.png new file mode 100644 index 0000000..19787fe Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_rope.png differ diff --git a/mods/moreblocks/textures/moreblocks_split_stone_tile.png b/mods/moreblocks/textures/moreblocks_split_stone_tile.png new file mode 100644 index 0000000..d7d69af Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_split_stone_tile.png differ diff --git a/mods/moreblocks/textures/moreblocks_split_stone_tile_alt.png b/mods/moreblocks/textures/moreblocks_split_stone_tile_alt.png new file mode 100644 index 0000000..9d11b4f Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_split_stone_tile_alt.png differ diff --git a/mods/moreblocks/textures/moreblocks_split_stone_tile_top.png b/mods/moreblocks/textures/moreblocks_split_stone_tile_top.png new file mode 100644 index 0000000..3c8eb6d Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_split_stone_tile_top.png differ diff --git a/mods/moreblocks/textures/moreblocks_stone_tile.png b/mods/moreblocks/textures/moreblocks_stone_tile.png new file mode 100644 index 0000000..c2083ea Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_stone_tile.png differ diff --git a/mods/moreblocks/textures/moreblocks_super_glow_glass.png b/mods/moreblocks/textures/moreblocks_super_glow_glass.png new file mode 100644 index 0000000..a9d4c5f Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_super_glow_glass.png differ diff --git a/mods/moreblocks/textures/moreblocks_super_glow_glass_stairsplus.png b/mods/moreblocks/textures/moreblocks_super_glow_glass_stairsplus.png new file mode 100644 index 0000000..9118c78 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_super_glow_glass_stairsplus.png differ diff --git a/mods/moreblocks/textures/moreblocks_sweeper.png b/mods/moreblocks/textures/moreblocks_sweeper.png new file mode 100644 index 0000000..34f1cde Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_sweeper.png differ diff --git a/mods/moreblocks/textures/moreblocks_tar.png b/mods/moreblocks/textures/moreblocks_tar.png new file mode 100644 index 0000000..e1eb427 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_tar.png differ diff --git a/mods/moreblocks/textures/moreblocks_trap_glass.png b/mods/moreblocks/textures/moreblocks_trap_glass.png new file mode 100644 index 0000000..25c3387 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_trap_glass.png differ diff --git a/mods/moreblocks/textures/moreblocks_trap_glow_glass.png b/mods/moreblocks/textures/moreblocks_trap_glow_glass.png new file mode 100644 index 0000000..1096dd7 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_trap_glow_glass.png differ diff --git a/mods/moreblocks/textures/moreblocks_trap_stone.png b/mods/moreblocks/textures/moreblocks_trap_stone.png new file mode 100644 index 0000000..764aa81 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_trap_stone.png differ diff --git a/mods/moreblocks/textures/moreblocks_trap_super_glow_glass.png b/mods/moreblocks/textures/moreblocks_trap_super_glow_glass.png new file mode 100644 index 0000000..fef974b Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_trap_super_glow_glass.png differ diff --git a/mods/moreblocks/textures/moreblocks_tree_stairsplus.png b/mods/moreblocks/textures/moreblocks_tree_stairsplus.png new file mode 100644 index 0000000..60100c9 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_tree_stairsplus.png differ diff --git a/mods/moreblocks/textures/moreblocks_wood_tile.png b/mods/moreblocks/textures/moreblocks_wood_tile.png new file mode 100644 index 0000000..d0faa3d Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_wood_tile.png differ diff --git a/mods/moreblocks/textures/moreblocks_wood_tile_center.png b/mods/moreblocks/textures/moreblocks_wood_tile_center.png new file mode 100644 index 0000000..02b0f84 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_wood_tile_center.png differ diff --git a/mods/moreblocks/textures/moreblocks_wood_tile_full.png b/mods/moreblocks/textures/moreblocks_wood_tile_full.png new file mode 100644 index 0000000..7ec7f05 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_wood_tile_full.png differ diff --git a/mods/moreblocks/textures/moreblocks_wood_tile_up.png b/mods/moreblocks/textures/moreblocks_wood_tile_up.png new file mode 100644 index 0000000..3f6a2f2 Binary files /dev/null and b/mods/moreblocks/textures/moreblocks_wood_tile_up.png differ diff --git a/mods/name_restrictions b/mods/name_restrictions new file mode 160000 index 0000000..98af163 --- /dev/null +++ b/mods/name_restrictions @@ -0,0 +1 @@ +Subproject commit 98af16381817b7dee198ccb66a648eedde32707f diff --git a/mods/pipeworks/LICENSE b/mods/pipeworks/LICENSE new file mode 100644 index 0000000..eb930e9 --- /dev/null +++ b/mods/pipeworks/LICENSE @@ -0,0 +1,17 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + +---------- + +This license is commonly known as "WTFPL". diff --git a/mods/pipeworks/README b/mods/pipeworks/README new file mode 100644 index 0000000..b9c68f9 --- /dev/null +++ b/mods/pipeworks/README @@ -0,0 +1,22 @@ +This mod uses nodeboxes to supply a complete set of 3D pipes and tubes, +along devices that work with them. + +See http://vanessae.github.io/pipeworks/ for detailed information about usage of this mod. + +Unlike the previous version of this mod, these pipes are rounded, and when +placed, they'll automatically join together as needed. Pipes can go vertically +or horizontally, and there are enough nodes defined to allow for all possible +connections. Valves and pumps can only be placed horizontally, and will +automatically rotate and join with neighboring pipes as objects are added, as +well as joining with each other under certain circumstances. + +Pipes come in two variants: one type bears one or more dark windows on each +pipe, suggesting they're empty, while the other type bears green-tinted +windows, as if full (the two colors should also be easy to select if you want +to change them in a paint program). These windows only appear on straight +lengths and on certain junctions. + +This mod is a work in progress. + +Please note that owing to the nature of this mod, I have opted to use 64px +textures. Anything less just looks terrible. diff --git a/mods/pipeworks/autocrafter.lua b/mods/pipeworks/autocrafter.lua new file mode 100644 index 0000000..b2e50c1 --- /dev/null +++ b/mods/pipeworks/autocrafter.lua @@ -0,0 +1,131 @@ +local autocrafterCache = {} -- caches some recipe data to avoid to call the slow function minetest.get_craft_result() every second + +local function make_inventory_cache(invlist) + local l = {} + for _, stack in ipairs(invlist) do + l[stack:get_name()] = (l[stack:get_name()] or 0) + stack:get_count() + end + return l +end + +local function autocraft(inventory, pos) + local recipe = inventory:get_list("recipe") + local recipe_last + local result + local new + + if autocrafterCache[minetest.hash_node_position(pos)] == nil then + recipe_last = {} + for i = 1, 9 do + recipe_last[i] = recipe[i] + recipe[i] = ItemStack({name = recipe[i]:get_name(), count = 1}) + end + result, new = minetest.get_craft_result({method = "normal", width = 3, items = recipe}) + autocrafterCache[minetest.hash_node_position(pos)] = {["recipe"] = recipe, ["result"] = result, ["new"] = new} + else + local autocrafterCacheEntry = autocrafterCache[minetest.hash_node_position(pos)] + recipe_last = autocrafterCacheEntry["recipe"] + result = autocrafterCacheEntry["result"] + new = autocrafterCacheEntry["new"] + local recipeUnchanged = true + for i = 1, 9 do + if recipe[i]:get_name() ~= recipe_last[i]:get_name() then + recipeUnchanged = false + break + end + if recipe[i]:get_count() ~= recipe_last[i]:get_count() then + recipeUnchanged = false + break + end + end + if recipeUnchanged then + else + for i = 1, 9 do + recipe_last[i] = recipe[i] + recipe[i] = ItemStack({name = recipe[i]:get_name(), count = 1}) + end + result, new = minetest.get_craft_result({method = "normal", width = 3, items = recipe}) + autocrafterCache[minetest.hash_node_position(pos)] = {["recipe"] = recipe, ["result"] = result, ["new"] = new} + end + end + + if result.item:is_empty() then return end + result = result.item + if not inventory:room_for_item("dst", result) then return end + local to_use = {} + for _, item in ipairs(recipe) do + if item~= nil and not item:is_empty() then + if to_use[item:get_name()] == nil then + to_use[item:get_name()] = 1 + else + to_use[item:get_name()] = to_use[item:get_name()]+1 + end + end + end + local invcache = make_inventory_cache(inventory:get_list("src")) + for itemname, number in pairs(to_use) do + if (not invcache[itemname]) or invcache[itemname] < number then return end + end + for itemname, number in pairs(to_use) do + for i = 1, number do -- We have to do that since remove_item does not work if count > stack_max + inventory:remove_item("src", ItemStack(itemname)) + end + end + inventory:add_item("dst", result) + for i = 1, 9 do + inventory:add_item("dst", new.items[i]) + end +end + +minetest.register_node("pipeworks:autocrafter", { + description = "Autocrafter", + drawtype = "normal", + tiles = {"pipeworks_autocrafter.png"}, + groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1}, + tube = {insert_object = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:add_item("src", stack) + end, + can_insert = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:room_for_item("src", stack) + end, + input_inventory = "dst", + connect_sides = {left = 1, right = 1, front = 1, back = 1, top = 1, bottom = 1}}, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", + "size[8,11]".. + "list[current_name;recipe;0,0;3,3;]".. + "list[current_name;src;0,3.5;8,3;]".. + "list[current_name;dst;4,0;4,3;]".. + "list[current_player;main;0,7;8,4;]") + meta:set_string("infotext", "Autocrafter") + local inv = meta:get_inventory() + inv:set_size("src", 3*8) + inv:set_size("recipe", 3*3) + inv:set_size("dst", 4*3) + end, + can_dig = function(pos, player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return (inv:is_empty("src") and inv:is_empty("recipe") and inv:is_empty("dst")) + end, + after_place_node = function(pos) + pipeworks.scan_for_tube_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_tube_objects(pos) + autocrafterCache[minetest.hash_node_position(pos)] = nil + end +}) + +minetest.register_abm({nodenames = {"pipeworks:autocrafter"}, interval = 1, chance = 1, + action = function(pos, node) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + autocraft(inv, pos) + end +}) diff --git a/mods/pipeworks/autoplace_pipes.lua b/mods/pipeworks/autoplace_pipes.lua new file mode 100644 index 0000000..69bd90e --- /dev/null +++ b/mods/pipeworks/autoplace_pipes.lua @@ -0,0 +1,200 @@ +-- autorouting for pipes +local tube_table = {[0] = 1, 2, 2, 4, 2, 4, 4, 5, 2, 3, 4, 6, 4, 6, 5, 7, 2, 4, 3, 6, 4, 5, 6, 7, 4, 6, 6, 8, 5, 7, 7, 9, 2, 4, 4, 5, 3, 6, 6, 7, 4, 6, 5, 7, 6, 8, 7, 9, 4, 5, 6, 7, 6, 7, 8, 9, 5, 7, 7, 9, 7, 9, 9, 10} +local tube_table_facedirs = {[0] = 0, 0, 5, 0, 3, 4, 3, 0, 2, 0, 2, 0, 6, 4, 3, 0, 7, 12, 5, 12, 7, 4, 5, 5, 18, 20, 16, 0, 7, 4, 7, 0, 1, 8, 1, 1, 1, 13, 1, 1, 10, 8, 2, 2, 17, 4, 3, 6, 9, 9, 9, 9, 21, 13, 1, 1, 10, 10, 11, 2, 19, 4, 3, 0} +local function autoroute_pipes(pos) + local nctr = minetest.get_node(pos) + local state = "_empty" + if (string.find(nctr.name, "pipeworks:pipe_") == nil) then return end + if (string.find(nctr.name, "_loaded") ~= nil) then state = "_loaded" end + local nsurround = pipeworks.scan_pipe_surroundings(pos) + + if nsurround == 0 then nsurround = 9 end + minetest.add_node(pos, {name = "pipeworks:pipe_"..tube_table[nsurround]..state, + param2 = tube_table_facedirs[nsurround]}) +end + +function pipeworks.scan_for_pipe_objects(pos) + autoroute_pipes({ x=pos.x-1, y=pos.y , z=pos.z }) + autoroute_pipes({ x=pos.x+1, y=pos.y , z=pos.z }) + autoroute_pipes({ x=pos.x , y=pos.y-1, z=pos.z }) + autoroute_pipes({ x=pos.x , y=pos.y+1, z=pos.z }) + autoroute_pipes({ x=pos.x , y=pos.y , z=pos.z-1 }) + autoroute_pipes({ x=pos.x , y=pos.y , z=pos.z+1 }) + autoroute_pipes(pos) +end + +-- auto-rotation code for various devices the tubes attach to + +function pipeworks.scan_pipe_surroundings(pos) + local pxm=0 + local pxp=0 + local pym=0 + local pyp=0 + local pzm=0 + local pzp=0 + + local nxm = minetest.get_node({ x=pos.x-1, y=pos.y , z=pos.z }) + local nxp = minetest.get_node({ x=pos.x+1, y=pos.y , z=pos.z }) + local nym = minetest.get_node({ x=pos.x , y=pos.y-1, z=pos.z }) + local nyp = minetest.get_node({ x=pos.x , y=pos.y+1, z=pos.z }) + local nzm = minetest.get_node({ x=pos.x , y=pos.y , z=pos.z-1 }) + local nzp = minetest.get_node({ x=pos.x , y=pos.y , z=pos.z+1 }) + + if (string.find(nxm.name, "pipeworks:pipe_") ~= nil) then pxm=1 end + if (string.find(nxp.name, "pipeworks:pipe_") ~= nil) then pxp=1 end + if (string.find(nym.name, "pipeworks:pipe_") ~= nil) then pym=1 end + if (string.find(nyp.name, "pipeworks:pipe_") ~= nil) then pyp=1 end + if (string.find(nzm.name, "pipeworks:pipe_") ~= nil) then pzm=1 end + if (string.find(nzp.name, "pipeworks:pipe_") ~= nil) then pzp=1 end + +-- Special handling for valves... + + if (string.find(nxm.name, "pipeworks:valve") ~= nil) + and (nxm.param2 == 0 or nxm.param2 == 2) then + pxm=1 + end + + if (string.find(nxp.name, "pipeworks:valve") ~= nil) + and (nxp.param2 == 0 or nxp.param2 == 2) then + pxp=1 + end + + if (string.find(nzm.name, "pipeworks:valve") ~= nil) + and (nzm.param2 == 1 or nzm.param2 == 3) then + pzm=1 + end + + if (string.find(nzp.name, "pipeworks:valve") ~= nil) + and (nzp.param2 == 1 or nzp.param2 == 3) then + pzp=1 + end + +-- ...flow sensors... + + if (string.find(nxm.name, "pipeworks:flow_sensor") ~= nil) + and (nxm.param2 == 0 or nxm.param2 == 2) then + pxm=1 + end + + if (string.find(nxp.name, "pipeworks:flow_sensor") ~= nil) + and (nxp.param2 == 0 or nxp.param2 == 2) then + pxp=1 + end + + if (string.find(nzm.name, "pipeworks:flow_sensor") ~= nil) + and (nzm.param2 == 1 or nzm.param2 == 3) then + pzm=1 + end + + if (string.find(nzp.name, "pipeworks:flow_sensor") ~= nil) + and (nzp.param2 == 1 or nzp.param2 == 3) then + pzp=1 + end + +-- ...spigots... + + if (string.find(nxm.name, "pipeworks:spigot") ~= nil) + and nxm.param2 == 1 then + pxm=1 + end + + if (string.find(nxp.name, "pipeworks:spigot") ~= nil) + and nxp.param2 == 3 then + pxp=1 + end + + if (string.find(nzm.name, "pipeworks:spigot") ~= nil) + and nzm.param2 == 0 then + pzm=1 + end + + if (string.find(nzp.name, "pipeworks:spigot") ~= nil) + and nzp.param2 == 2 then + pzp=1 + end + +-- ...sealed pipe entry/exit... + + if (string.find(nxm.name, "pipeworks:entry_panel") ~= nil) + and (nxm.param2 == 1 or nxm.param2 == 3) then + pxm=1 + end + + if (string.find(nxp.name, "pipeworks:entry_panel") ~= nil) + and (nxp.param2 == 1 or nxp.param2 == 3) then + pxp=1 + end + + if (string.find(nzm.name, "pipeworks:entry_panel") ~= nil) + and (nzm.param2 == 0 or nzm.param2 == 2) then + pzm=1 + end + + if (string.find(nzp.name, "pipeworks:entry_panel") ~= nil) + and (nzp.param2 == 0 or nzp.param2 == 2) then + pzp=1 + end + + if (string.find(nym.name, "pipeworks:entry_panel") ~= nil) + and nym.param2 == 13 then + pym=1 + end + + if (string.find(nyp.name, "pipeworks:entry_panel") ~= nil) + and nyp.param2 == 13 then + pyp=1 + end + + +-- ...pumps, grates... + + if (string.find(nym.name, "pipeworks:grating") ~= nil) or + (string.find(nym.name, "pipeworks:pump") ~= nil) then + pym=1 + end + +-- ...fountainheads... + + if (string.find(nyp.name, "pipeworks:fountainhead") ~= nil) then + pyp=1 + end + +-- ... and storage tanks. + + if (string.find(nym.name, "pipeworks:storage_tank_") ~= nil) then + pym=1 + end + + if (string.find(nyp.name, "pipeworks:storage_tank_") ~= nil) then + pyp=1 + end + +-- ...extra devices specified via the function's parameters +-- ...except that this part is not implemented yet +-- +-- xxx = nxm, nxp, nym, nyp, nzm, or nzp depending on the direction to check +-- yyy = pxm, pxp, pym, pyp, pzm, or pzp accordingly. +-- +-- if string.find(xxx.name, "modname:nodename") ~= nil then +-- yyy = 1 +-- end +-- +-- for example: +-- +-- if string.find(nym.name, "aero:outlet") ~= nil then +-- pym = 1 +-- end +-- + + return pxm+8*pxp+2*pym+16*pyp+4*pzm+32*pzp +end + +function pipeworks.look_for_stackable_tanks(pos) + local tym = minetest.get_node({ x=pos.x , y=pos.y-1, z=pos.z }) + + if string.find(tym.name, "pipeworks:storage_tank_") ~= nil or + string.find(tym.name, "pipeworks:expansion_tank_") ~= nil then + minetest.add_node(pos, { name = "pipeworks:expansion_tank_0", param2 = tym.param2}) + end +end + diff --git a/mods/pipeworks/autoplace_tubes.lua b/mods/pipeworks/autoplace_tubes.lua new file mode 100755 index 0000000..42cf98b --- /dev/null +++ b/mods/pipeworks/autoplace_tubes.lua @@ -0,0 +1,130 @@ +-- autorouting for pneumatic tubes + +local function is_tube(nodename) + return table.contains(pipeworks.tubenodes, nodename) +end + +--a function for determining which side of the node we are on +local function nodeside(node, tubedir) + if node.param2 < 0 or node.param2 > 23 then + node.param2 = 0 + end + + local backdir = minetest.facedir_to_dir(node.param2) + local back = vector.dot(backdir, tubedir) + if back == 1 then + return "back" + elseif back == -1 then + return "front" + end + + local topdir = minetest.facedir_to_top_dir(node.param2) + local top = vector.dot(topdir, tubedir) + if top == 1 then + return "top" + elseif top == -1 then + return "bottom" + end + + local rightdir = minetest.facedir_to_right_dir(node.param2) + local right = vector.dot(rightdir, tubedir) + if right == 1 then + return "right" + else + return "left" + end +end + +local vts = {0, 3, 1, 4, 2, 5} +local tube_table = {[0] = 1, 2, 2, 4, 2, 4, 4, 5, 2, 3, 4, 6, 4, 6, 5, 7, 2, 4, 3, 6, 4, 5, 6, 7, 4, 6, 6, 8, 5, 7, 7, 9, 2, 4, 4, 5, 3, 6, 6, 7, 4, 6, 5, 7, 6, 8, 7, 9, 4, 5, 6, 7, 6, 7, 8, 9, 5, 7, 7, 9, 7, 9, 9, 10} +local tube_table_facedirs = {[0] = 0, 0, 5, 0, 3, 4, 3, 0, 2, 0, 2, 0, 6, 4, 3, 0, 7, 12, 5, 12, 7, 4, 5, 5, 18, 20, 16, 0, 7, 4, 7, 0, 1, 8, 1, 1, 1, 13, 1, 1, 10, 8, 2, 2, 17, 4, 3, 6, 9, 9, 9, 9, 21, 13, 1, 1, 10, 10, 11, 2, 19, 4, 3, 0} +local function tube_autoroute(pos) + local active = {0, 0, 0, 0, 0, 0} + local nctr = minetest.get_node(pos) + if not is_tube(nctr.name) then return end + + local adjustments = { + {x = -1, y = 0, z = 0}, + {x = 1, y = 0, z = 0}, + {x = 0, y = -1, z = 0}, + {x = 0, y = 1, z = 0}, + {x = 0, y = 0, z = -1}, + {x = 0, y = 0, z = 1} + } + -- xm = 1, xp = 2, ym = 3, yp = 4, zm = 5, zp = 6 + + local positions = {} + local nodes = {} + for i, adj in ipairs(adjustments) do + positions[i] = vector.add(pos, adj) + nodes[i] = minetest.get_node(positions[i]) + end + + for i, node in ipairs(nodes) do + local idef = minetest.registered_nodes[node.name] + -- handle the tubes themselves + if is_tube(node.name) then + active[i] = 1 + -- handle new style connectors + elseif idef and idef.tube and idef.tube.connect_sides then + local dir = adjustments[i] + if idef.tube.connect_sides[nodeside(node, vector.multiply(dir, -1))] then + active[i] = 1 + end + end + end + + -- all sides checked, now figure which tube to use. + + local nodedef = minetest.registered_nodes[nctr.name] + local basename = nodedef.basename + if nodedef.style == "old" then + local nsurround = "" + for i, n in ipairs(active) do + nsurround = nsurround..n + end + nctr.name = basename.."_"..nsurround + elseif nodedef.style == "6d" then + local s = 0 + for i, n in ipairs(active) do + if n == 1 then + s = s + 2^vts[i] + end + end + nctr.name = basename.."_"..tube_table[s] + nctr.param2 = tube_table_facedirs[s] + end + minetest.swap_node(pos, nctr) +end + +function pipeworks.scan_for_tube_objects(pos) + for side = 0, 6 do + tube_autoroute(vector.add(pos, directions.side_to_dir(side))) + end +end + +minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) + if minetest.registered_items[newnode.name] + and minetest.registered_items[newnode.name].tube + and minetest.registered_items[newnode.name].tube.connect_sides then + pipeworks.scan_for_tube_objects(pos) + end +end) + +minetest.register_on_dignode(function(pos, oldnode, digger) + if minetest.registered_items[oldnode.name] + and minetest.registered_items[oldnode.name].tube + and minetest.registered_items[oldnode.name].tube.connect_sides then + pipeworks.scan_for_tube_objects(pos) + end +end) + +if minetest.get_modpath("mesecons_mvps") then + mesecon:register_on_mvps_move(function(moved_nodes) + for _, n in ipairs(moved_nodes) do + pipeworks.scan_for_tube_objects(n.pos) + pipeworks.scan_for_tube_objects(n.oldpos) + end + end) +end + diff --git a/mods/pipeworks/changelog.txt b/mods/pipeworks/changelog.txt new file mode 100644 index 0000000..251df29 --- /dev/null +++ b/mods/pipeworks/changelog.txt @@ -0,0 +1,93 @@ +Changelog +--------- + +2013-01-13: Tubes can transport items now! Namely, I added Novatux/Nore's item +transport mod as a default part of this mod, to make tubes do something useful! +Thanks to Nore and RealBadAngel for the code contributions! + +2013-01-05: made storage tanks connect from top/bottom, made storage tank and +pipe textures use the ^ combine operator so they can show the actual liquid +going through the pipes/tanks. + +2013-01-04 (a bit later): Made pipes able to carry water! It was just a minor +logic error resulting from moving the water flowing code into it's own file +when I originally imported it. Many thanks to Mauvebic for writing it! + +2013-01-04: First stage of integrating Mauvebic's water flowing code. This is +experimental and doesn't move water yet - but at least it doesn't break +anything :-) + +2013-01-01: Various minor tweaks to textures, facedir settings, some other +stuff. Changed crafting recipes to account for revamped pumps, valves, etc. +Now requires the moreores mod and most recent git (for mese crystal fragments) +to craft a pump. Added a "sealed" entry/exit panel (really just a horizontal +pipe with a metal panel overlayed into the middle). Also, tweaked pipes to +always drop the empty ones. Revamped pumps so that now they should sit in/on +liquid and be connected only from the top, relegated grates to decorational- +only, added outlet spigot. Got rid of a few obsolete textures. Got rid of +that whole _x and _z naming thing - now all directional devices (pumps, valves, +spigots, tanks) use facedir. Valves, spigots no longer auto-rotate to find +nearby pipes. + +2012-09-17: Added test object for pneumatic tube autorouting code, made tubes +connect to it and any object that bears groups={tubedevice=1} (connects to any +side) + +2012-09-05: All recipes doubled except for junglegrass -> plastic sheet (since +that is derived from home decor) + +2012-09-02: Fixed plastic sheeting recipe. Added crafting recipes for various +objects, with options: If homedecor is installed, use the plastic sheeting +therein. If not, we define it manually. If the Technic mod is installed, +don't define any recipes at all. Also removed the extra "loaded!" messages and +tweaked the default pipe alias to point to something that is actually visible +:-) + +2012-09-01: flattened wielded pipe segment. + +2012-08-24: Added square-ish pneumatic tubes with their own autoplace code +(does not connect to steel pipes or pipe-oriented devices), then revised their +textures shortly after. Fixed a recursion bug that sometimes caused a stack +overflow. Old pipes were overriding the pipeworks:pipe defintion that belongs +with the new pipes. + +2012-08-22: Added outlet grate, made it participate in autoplace algorithm. +Extended storage tank to show fill level in 10% steps (0% to 100%). Added +"expansion tank" that appears if the user stacks tanks upwards. (Downwards is +not checked). + +2012-08-21: Made storage tank participate in autoplace algorithm. Tuned API a +little to allow for more flexible placement. Re-organized code a bit to allow +for some upcoming rules changes. Made storage tanks' upper/lower fittins and +intake grate participate in autoplace algorithm. + +2012-08-20: Added temporary nodes for storage tank and intake grating, but +without autoplace. + +2012-08-19: Pumps and valves now fully participate in the +auto-rotate/auto-place algorithm. + +2012-08-18: Total rewrite again. All pipes are now nice and round-looking, and +they auto-connect! Also added temporary nodes for pump and valve (each with an +on/off setting - punch to change). No crafting recipes yet and the pipes still +don't do anything useful yet. Soon. + +2012-08-06: Moved this changelog off the forum post and into a separate file. + +2012-08-05 (multiple updates): Rewrote pipeworks to use loops and tables to +create the nodes. Requires far less code now. Added -X, +X, -Y, +Y, -Z, +Z +capped stubs and a short centered horizontal segment. Changed node definitions +so that the aforementioned "short centered" segment is given on dig/drop. +Renamed it to just "pipeworks:pipe" (and pipe_loaded). Added empty/loaded +indicator images to the capped ends, removed some redundant comments. Made the +empty/loaded indication at the capped end more prominent. + +2012-07-21: Added screenshot showing pipes as they look now that nodebox +texture rotation is fixed. + +2012-07-18: Changed the mod name and all internals to 'pipeworks' instead of +'pipes'... after a couple of mistakes :-) + +2012-07-12: moved project to github. + +2012-06-23: Initial release, followed by reworking the textures a bit. diff --git a/mods/pipeworks/common.lua b/mods/pipeworks/common.lua new file mode 100755 index 0000000..b50b733 --- /dev/null +++ b/mods/pipeworks/common.lua @@ -0,0 +1,146 @@ +---------------------- +-- Vector functions -- +---------------------- + +function vector.cross(a, b) + return { + x = a.y * b.z - a.z * b.y, + y = a.z * b.x - a.x * b.z, + z = a.x * b.y - a.y * b.x + } +end + +function vector.dot(a, b) + return a.x * b.x + a.y * b.y + a.z * b.z +end + +----------------------- +-- Facedir functions -- +----------------------- + +function minetest.facedir_to_top_dir(facedir) + return ({[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}}) + [math.floor(facedir / 4)] +end + +function minetest.facedir_to_right_dir(facedir) + return vector.cross( + minetest.facedir_to_top_dir(facedir), + minetest.facedir_to_dir(facedir) + ) +end + +directions = {} +function directions.side_to_dir(side) + return ({[0] = vector.new(), + vector.new( 0, 1, 0), + vector.new( 0, -1, 0), + vector.new( 1, 0, 0), + vector.new(-1, 0, 0), + vector.new( 0, 0, 1), + vector.new( 0, 0, -1) + })[side] +end + +function directions.dir_to_side(dir) + local c = vector.dot(dir, vector.new(1, 2, 3)) + 4 + return ({6, 2, 4, 0, 3, 1, 5})[c] +end + +---------------------- +-- String functions -- +---------------------- + +--[[function string.split(str, sep) + local fields = {} + local index = 1 + local expr = "([^"..sep.."])+" + string.gsub(str, expr, function(substring) + fields[index] = substring + index = index + 1 + end) + return fields +end]] + +function string.startswith(str, substr) + return str:sub(1, substr:len()) == substr +end + +--------------------- +-- Table functions -- +--------------------- + +function table.contains(tbl, element) + for _, elt in pairs(tbl) do + if elt == element then + return true + end + end + return false +end + +function table.extend(tbl, tbl2) + local index = #tbl + 1 + for _, elt in ipairs(tbl2) do + tbl[index] = elt + index = index + 1 + end +end + +function table.recursive_replace(tbl, pattern, replace_with) + if type(tbl) == "table" then + local tbl2 = {} + for key, value in pairs(tbl) do + tbl2[key] = table.recursive_replace(value, pattern, replace_with) + end + return tbl2 + elseif type(tbl) == "string" then + return tbl:gsub(pattern, replace_with) + else + return tbl + end +end + +------------------------ +-- Formspec functions -- +------------------------ + +fs_helpers = {} +function fs_helpers.on_receive_fields(pos, fields) + local meta = minetest.get_meta(pos) + for field, value in pairs(fields) do + if field:startswith("fs_helpers_cycling:") then + local l = field:split(":") + local new_value = tonumber(l[2]) + local meta_name = l[3] + meta:set_int(meta_name, new_value) + end + end +end + +function fs_helpers.cycling_button(meta, base, meta_name, values) + local current_value = meta:get_int(meta_name) + local new_value = (current_value + 1) % (#values) + local text = values[current_value + 1] + local field = "fs_helpers_cycling:"..new_value..":"..meta_name + return base..";"..field..";"..minetest.formspec_escape(text).."]" +end + +--------- +-- Env -- +--------- + +function minetest.load_position(pos) + if pos.x < -30912 or pos.y < -30912 or pos.z < -30912 or + pos.x > 30927 or pos.y > 30927 or pos.z > 30927 then return end + if minetest.get_node_or_nil(pos) then + return + end + local vm = minetest.get_voxel_manip() + vm:read_from_map(pos, pos) +end diff --git a/mods/pipeworks/compat.lua b/mods/pipeworks/compat.lua new file mode 100644 index 0000000..a1c1d45 --- /dev/null +++ b/mods/pipeworks/compat.lua @@ -0,0 +1,130 @@ +-- this bit of code modifies the default chests and furnaces to be compatible +-- with pipeworks. + +minetest.override_item("default:furnace", { + tiles = { + "default_furnace_top.png^pipeworks_tube_connection_stony.png", + "default_furnace_bottom.png^pipeworks_tube_connection_stony.png", + "default_furnace_side.png^pipeworks_tube_connection_stony.png", + "default_furnace_side.png^pipeworks_tube_connection_stony.png", + "default_furnace_side.png^pipeworks_tube_connection_stony.png", + "default_furnace_front.png" + }, + groups = {cracky = 2, tubedevice = 1, tubedevice_receiver = 1}, + tube = { + insert_object = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if direction.y == 1 then + return inv:add_item("fuel",stack) + else + return inv:add_item("src",stack) + end + end, + can_insert = function(pos,node,stack,direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if direction.y == 1 then + return inv:room_for_item("fuel", stack) + else + return inv:room_for_item("src", stack) + end + end, + input_inventory = "dst", + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} + }, +}) + +minetest.override_item("default:furnace_active", { + tiles = { + "default_furnace_top.png^pipeworks_tube_connection_stony.png", + "default_furnace_bottom.png^pipeworks_tube_connection_stony.png", + "default_furnace_side.png^pipeworks_tube_connection_stony.png", + "default_furnace_side.png^pipeworks_tube_connection_stony.png", + "default_furnace_side.png^pipeworks_tube_connection_stony.png", + { + image = "default_furnace_front_active.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.5 + }, + } + }, + groups = {cracky = 2, tubedevice = 1, tubedevice_receiver = 1, not_in_creative_inventory = 1}, + tube = { + insert_object = function(pos,node,stack,direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if direction.y == 1 then + return inv:add_item("fuel", stack) + else + return inv:add_item("src", stack) + end + end, + can_insert = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if direction.y == 1 then + return inv:room_for_item("fuel", stack) + else + return inv:room_for_item("src", stack) + end + end, + input_inventory = "dst", + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} + }, +}) + +minetest.override_item("default:chest", { + tiles = { + "default_chest_top.png^pipeworks_tube_connection_wooden.png", + "default_chest_top.png^pipeworks_tube_connection_wooden.png", + "default_chest_side.png^pipeworks_tube_connection_wooden.png", + "default_chest_side.png^pipeworks_tube_connection_wooden.png", + "default_chest_side.png^pipeworks_tube_connection_wooden.png", + "default_chest_front.png" + }, + groups = {choppy = 2, oddly_breakable_by_hand = 2, tubedevice = 1, tubedevice_receiver = 1}, + tube = { + insert_object = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:add_item("main", stack) + end, + can_insert = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:room_for_item("main", stack) + end, + input_inventory = "main", + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} + }, +}) + +minetest.override_item("default:chest_locked", { + tiles = { + "default_chest_top.png^pipeworks_tube_connection_wooden.png", + "default_chest_top.png^pipeworks_tube_connection_wooden.png", + "default_chest_side.png^pipeworks_tube_connection_wooden.png", + "default_chest_side.png^pipeworks_tube_connection_wooden.png", + "default_chest_side.png^pipeworks_tube_connection_wooden.png", + "default_chest_lock.png" + }, + groups = {choppy = 2, oddly_breakable_by_hand = 2, tubedevice = 1, tubedevice_receiver = 1}, + tube = { + insert_object = function(pos, node, stack, direction) + local meta = minetest.env:get_meta(pos) + local inv = meta:get_inventory() + return inv:add_item("main", stack) + end, + can_insert = function(pos, node, stack, direction) + local meta = minetest.env:get_meta(pos) + local inv = meta:get_inventory() + return inv:room_for_item("main", stack) + end, + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} + }, +}) diff --git a/mods/pipeworks/crafts.lua b/mods/pipeworks/crafts.lua new file mode 100644 index 0000000..12913d7 --- /dev/null +++ b/mods/pipeworks/crafts.lua @@ -0,0 +1,321 @@ +-- Crafting recipes for pipes + +minetest.register_craft( { + output = "pipeworks:pipe_1_empty 12", + recipe = { + { "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" }, + { "", "", "" }, + { "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:spigot 3", + recipe = { + { "pipeworks:pipe_1_empty", "" }, + { "", "pipeworks:pipe_1_empty" }, + }, +}) + +minetest.register_craft( { + output = "pipeworks:entry_panel_empty 2", + recipe = { + { "", "default:steel_ingot", "" }, + { "", "pipeworks:pipe_1_empty", "" }, + { "", "default:steel_ingot", "" }, + }, +}) + +-- Various ancillary pipe devices + +minetest.register_craft( { + output = "pipeworks:pump_off 2", + recipe = { + { "default:stone", "default:steel_ingot", "default:stone" }, + { "moreores:copper_ingot", "default:mese_crystal_fragment", "moreores:copper_ingot" }, + { "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:valve_off_empty 2", + recipe = { + { "", "group:stick", "" }, + { "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" }, + { "", "default:steel_ingot", "" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:storage_tank_0 2", + recipe = { + { "", "default:steel_ingot", "default:steel_ingot" }, + { "default:steel_ingot", "default:glass", "default:steel_ingot" }, + { "default:steel_ingot", "default:steel_ingot", "" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:grating 2", + recipe = { + { "default:steel_ingot", "", "default:steel_ingot" }, + { "", "pipeworks:pipe_1_empty", "" }, + { "default:steel_ingot", "", "default:steel_ingot" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:flow_sensor_empty 2", + recipe = { + { "pipeworks:pipe_1_empty", "mesecons:mesecon", "pipeworks:pipe_1_empty" }, + }, +}) + +minetest.register_craft( { + output = "pipeworks:fountainhead 2", + recipe = { + { "pipeworks:pipe_1_empty" }, + { "pipeworks:pipe_1_empty" } + }, +}) + + +-- Crafting recipes for pneumatic tubes + +-- If homedecor is not installed, we need to register its crafting chain for +-- plastic sheeting so that pipeworks remains compatible with it. + +if minetest.get_modpath("homedecor") == nil then + + minetest.register_craftitem(":homedecor:oil_extract", { + description = "Oil extract", + inventory_image = "homedecor_oil_extract.png", + }) + + minetest.register_craftitem(":homedecor:paraffin", { + description = "Unprocessed paraffin", + inventory_image = "homedecor_paraffin.png", + }) + + minetest.register_alias("homedecor:plastic_base", "homedecor:paraffin") + + minetest.register_craftitem(":homedecor:plastic_sheeting", { + description = "Plastic sheet", + inventory_image = "homedecor_plastic_sheeting.png", + }) + + minetest.register_craft({ + type = "shapeless", + output = "homedecor:oil_extract 4", + recipe = { + "group:leaves", + "group:leaves", + "group:leaves", + "group:leaves", + "group:leaves", + "group:leaves" + } + }) + + minetest.register_craft({ + type = "cooking", + output = "homedecor:paraffin", + recipe = "homedecor:oil_extract", + }) + + minetest.register_craft({ + type = "cooking", + output = "homedecor:plastic_sheeting", + recipe = "homedecor:paraffin", + }) + + minetest.register_craft({ + type = "fuel", + recipe = "homedecor:oil_extract", + burntime = 30, + }) + + minetest.register_craft({ + type = "fuel", + recipe = "homedecor:paraffin", + burntime = 30, + }) + + minetest.register_craft({ + type = "fuel", + recipe = "homedecor:plastic_sheeting", + burntime = 30, + }) +end + +minetest.register_craft( { + output = "pipeworks:one_way_tube 2", + recipe = { + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }, + { "group:stick", "default:mese_crystal", "homedecor:plastic_sheeting" }, + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" } + }, +}) + + +minetest.register_craft( { + output = "pipeworks:tube_1 6", + recipe = { + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }, + { "", "", "" }, + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:mese_tube_1 2", + recipe = { + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }, + { "", "default:mese_crystal", "" }, + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" } + }, +}) + +minetest.register_craft( { + type = "shapeless", + output = "pipeworks:mese_tube_000000", + recipe = { + "pipeworks:tube_1", + "default:mese_crystal_fragment", + "default:mese_crystal_fragment", + "default:mese_crystal_fragment", + "default:mese_crystal_fragment" + }, +}) + +minetest.register_craft( { + output = "pipeworks:conductor_tube_off_1 6", + recipe = { + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }, + { "mesecons:mesecon", "mesecons:mesecon", "mesecons:mesecon" }, + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:detector_tube_off_1 2", + recipe = { + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }, + { "mesecons:mesecon", "mesecons_materials:silicon", "mesecons:mesecon" }, + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:accelerator_tube_1 2", + recipe = { + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }, + { "default:mese_crystal_fragment", "default:steel_ingot", "default:mese_crystal_fragment" }, + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:teleport_tube_1 2", + recipe = { + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }, + { "default:desert_stone", "default:mese_block", "default:desert_stone" }, + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:sand_tube_1 2", + recipe = { + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }, + { "default:sand", "default:sand", "default:sand" }, + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:sand_tube_1 2", + recipe = { + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }, + { "default:desert_sand", "default:desert_sand", "default:desert_sand" }, + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:sand_tube_1", + recipe = { + { "default:desert_sand", "pipeworks:tube_1", "default:desert_sand" }, + }, +}) + +minetest.register_craft( { + output = "pipeworks:mese_sand_tube_1 2", + recipe = { + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }, + { "default:sand", "default:mese_crystal", "default:sand" }, + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:mese_sand_tube_1 2", + recipe = { + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }, + { "default:desert_sand", "default:mese_crystal", "default:desert_sand" }, + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:crossing_tube_1 5", + recipe = { + { "", "pipeworks:tube_1", "" }, + { "pipeworks:tube_1", "pipeworks:tube_1", "pipeworks:tube_1" }, + { "", "pipeworks:tube_1", "" } + }, +}) + + +minetest.register_craft( { + type = "shapeless", + output = "pipeworks:mese_sand_tube_1", + recipe = { + "pipeworks:sand_tube_1", + "default:mese_crystal_fragment", + "default:mese_crystal_fragment", + "default:mese_crystal_fragment", + "default:mese_crystal_fragment" + }, +}) + +-- Various ancillary tube devices + +minetest.register_craft( { + output = "pipeworks:filter 2", + recipe = { + { "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" }, + { "group:stick", "default:mese_crystal", "homedecor:plastic_sheeting" }, + { "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:mese_filter 2", + recipe = { + { "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" }, + { "group:stick", "default:mese", "homedecor:plastic_sheeting" }, + { "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" } + }, +}) + +minetest.register_craft( { + output = "pipeworks:autocrafter 2", + recipe = { + { "default:steel_ingot", "default:mese_crystal", "default:steel_ingot" }, + { "homedecor:plastic_sheeting", "default:steel_ingot", "homedecor:plastic_sheeting" }, + { "default:steel_ingot", "default:mese_crystal", "default:steel_ingot" } + }, +}) + + diff --git a/mods/pipeworks/default_settings.txt b/mods/pipeworks/default_settings.txt new file mode 100644 index 0000000..4aa4150 --- /dev/null +++ b/mods/pipeworks/default_settings.txt @@ -0,0 +1,19 @@ +-- Various settings + +pipeworks.enable_pipes = true +pipeworks.enable_autocrafter = true +pipeworks.enable_deployer = true +pipeworks.enable_dispenser = true +pipeworks.enable_node_breaker = true +pipeworks.enable_teleport_tube = true +pipeworks.enable_pipe_devices = true +pipeworks.enable_redefines = true +pipeworks.enable_mese_tube = true +pipeworks.enable_detector_tube = true +pipeworks.enable_conductor_tube = true +pipeworks.enable_accelerator_tube = true +pipeworks.enable_crossing_tube = true +pipeworks.enable_sand_tube = true +pipeworks.enable_mese_sand_tube = true +pipeworks.enable_one_way_tube = true +pipeworks.enable_cyclic_mode = true diff --git a/mods/pipeworks/depends.txt b/mods/pipeworks/depends.txt new file mode 100644 index 0000000..02a542c --- /dev/null +++ b/mods/pipeworks/depends.txt @@ -0,0 +1,3 @@ +default +mesecons? +mesecons_mvps? diff --git a/mods/pipeworks/devices.lua b/mods/pipeworks/devices.lua new file mode 100644 index 0000000..b7571d3 --- /dev/null +++ b/mods/pipeworks/devices.lua @@ -0,0 +1,702 @@ +-- List of devices that should participate in the autoplace algorithm + +local pipereceptor_on = nil +local pipereceptor_off = nil + +if mesecon then + pipereceptor_on = { + receptor = { + state = mesecon.state.on, + rules = pipeworks.mesecons_rules + } + } + + pipereceptor_off = { + receptor = { + state = mesecon.state.off, + rules = pipeworks.mesecons_rules + } + } +end + +local pipes_devicelist = { + "pump", + "valve", + "storage_tank_0", + "storage_tank_1", + "storage_tank_2", + "storage_tank_3", + "storage_tank_4", + "storage_tank_5", + "storage_tank_6", + "storage_tank_7", + "storage_tank_8", + "storage_tank_9", + "storage_tank_10" +} + +-- Now define the nodes. + +local states = { "on", "off" } +local dgroups = "" +local pumpboxes = {} + +for s in ipairs(states) do + + if states[s] == "off" then + dgroups = {snappy=3, pipe=1} + else + dgroups = {snappy=3, pipe=1, not_in_creative_inventory=1} + end + + pumpboxes = {} + + pipeworks.add_node_box(pumpboxes, pipeworks.pipe_pumpbody) + pipeworks.add_node_box(pumpboxes, pipeworks.pipe_topstub) + + minetest.register_node("pipeworks:pump_"..states[s], { + description = "Pump/Intake Module", + drawtype = "nodebox", + tiles = { + "pipeworks_pump_top.png", + "pipeworks_pump_bottom.png", + "pipeworks_pump_sides.png", + "pipeworks_pump_sides.png", + "pipeworks_pump_sides.png", + "pipeworks_pump_"..states[s]..".png" + }, + paramtype = "light", + paramtype2 = "facedir", + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 } + }, + node_box = { + type = "fixed", + fixed = pumpboxes + }, + groups = dgroups, + sounds = default.node_sound_wood_defaults(), + walkable = true, + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + drop = "pipeworks:pump_off", + mesecons = {effector = { + action_on = function (pos, node) + minetest.add_node(pos,{name="pipeworks:pump_on", param2 = node.param2}) + end, + action_off = function (pos, node) + minetest.add_node(pos,{name="pipeworks:pump_off", param2 = node.param2}) + end + }}, + on_punch = function(pos, node, puncher) + local fdir = minetest.get_node(pos).param2 + minetest.add_node(pos, { name = "pipeworks:pump_"..states[3-s], param2 = fdir }) + end + }) + + local valveboxes = {} + pipeworks.add_node_box(valveboxes, pipeworks.pipe_leftstub) + pipeworks.add_node_box(valveboxes, pipeworks.pipe_valvebody) + if states[s] == "off" then + pipeworks.add_node_box(valveboxes, pipeworks.pipe_valvehandle_off) + else + pipeworks.add_node_box(valveboxes, pipeworks.pipe_valvehandle_on) + end + pipeworks.add_node_box(valveboxes, pipeworks.pipe_rightstub) + local tilex = "pipeworks_valvebody_ends.png" + local tilez = "pipeworks_valvebody_sides.png" + + minetest.register_node("pipeworks:valve_"..states[s].."_empty", { + description = "Valve", + drawtype = "nodebox", + tiles = { + "pipeworks_valvebody_top_"..states[s]..".png", + "pipeworks_valvebody_bottom.png", + tilex, + tilex, + tilez, + tilez, + }, + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + selection_box = { + type = "fixed", + fixed = { -8/16, -4/16, -5/16, 8/16, 5/16, 5/16 } + }, + node_box = { + type = "fixed", + fixed = valveboxes + }, + groups = dgroups, + sounds = default.node_sound_wood_defaults(), + walkable = true, + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + drop = "pipeworks:valve_off_empty", + mesecons = {effector = { + action_on = function (pos, node) + minetest.add_node(pos,{name="pipeworks:valve_on_empty", param2 = node.param2}) + end, + action_off = function (pos, node) + minetest.add_node(pos,{name="pipeworks:valve_off_empty", param2 = node.param2}) + end + }}, + on_punch = function(pos, node, puncher) + local fdir = minetest.get_node(pos).param2 + minetest.add_node(pos, { name = "pipeworks:valve_"..states[3-s].."_empty", param2 = fdir }) + end + }) +end + +local valveboxes = {} +pipeworks.add_node_box(valveboxes, pipeworks.pipe_leftstub) +pipeworks.add_node_box(valveboxes, pipeworks.pipe_valvebody) +pipeworks.add_node_box(valveboxes, pipeworks.pipe_rightstub) +pipeworks.add_node_box(valveboxes, pipeworks.pipe_valvehandle_on) + +minetest.register_node("pipeworks:valve_on_loaded", { + description = "Valve", + drawtype = "nodebox", + tiles = { + "pipeworks_valvebody_top_on.png", + "pipeworks_valvebody_bottom.png", + "pipeworks_valvebody_ends.png", + "pipeworks_valvebody_ends.png", + "pipeworks_valvebody_sides.png", + "pipeworks_valvebody_sides.png", + }, + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + selection_box = { + type = "fixed", + fixed = { -8/16, -4/16, -5/16, 8/16, 5/16, 5/16 } + }, + node_box = { + type = "fixed", + fixed = valveboxes + }, + groups = {snappy=3, pipe=1, not_in_creative_inventory=1}, + sounds = default.node_sound_wood_defaults(), + walkable = true, + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + drop = "pipeworks:valve_off_empty", + mesecons = {effector = { + action_on = function (pos, node) + minetest.add_node(pos,{name="pipeworks:valve_on_empty", param2 = node.param2}) + end, + action_off = function (pos, node) + minetest.add_node(pos,{name="pipeworks:valve_off_empty", param2 = node.param2}) + end + }}, + on_punch = function(pos, node, puncher) + local fdir = minetest.get_node(pos).param2 + minetest.add_node(pos, { name = "pipeworks:valve_off_empty", param2 = fdir }) + end +}) + +-- grating + +minetest.register_node("pipeworks:grating", { + description = "Decorative grating", + tiles = { + "pipeworks_grating_top.png", + "pipeworks_grating_sides.png", + "pipeworks_grating_sides.png", + "pipeworks_grating_sides.png", + "pipeworks_grating_sides.png", + "pipeworks_grating_sides.png" + }, + sunlight_propagates = true, + paramtype = "light", + groups = {snappy=3, pipe=1}, + sounds = default.node_sound_wood_defaults(), + walkable = true, + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, +}) + +-- outlet spigot + + local spigotboxes = {} + pipeworks.add_node_box(spigotboxes, pipeworks.pipe_backstub) + pipeworks.add_node_box(spigotboxes, pipeworks.spigot_bottomstub) + pipeworks.add_node_box(spigotboxes, pipeworks.pipe_bendsphere) + + local spigotboxes_pouring = {} + pipeworks.add_node_box(spigotboxes_pouring, pipeworks.spigot_stream) + pipeworks.add_node_box(spigotboxes_pouring, pipeworks.pipe_backstub) + pipeworks.add_node_box(spigotboxes_pouring, pipeworks.spigot_bottomstub) + pipeworks.add_node_box(spigotboxes_pouring, pipeworks.pipe_bendsphere) + +minetest.register_node("pipeworks:spigot", { + description = "Spigot outlet", + drawtype = "nodebox", + tiles = { + "pipeworks_spigot_sides.png", + "pipeworks_pipe_end_empty.png", + "pipeworks_spigot_sides.png", + "pipeworks_spigot_sides.png", + "pipeworks_pipe_end_empty.png", + "pipeworks_spigot_sides.png" + }, + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy=3, pipe=1}, + sounds = default.node_sound_wood_defaults(), + walkable = true, + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + node_box = { + type = "fixed", + fixed = spigotboxes, + }, + selection_box = { + type = "fixed", + fixed = { -2/16, -6/16, -2/16, 2/16, 2/16, 8/16 } + } +}) + +minetest.register_node("pipeworks:spigot_pouring", { + description = "Spigot outlet", + drawtype = "nodebox", + tiles = { + "pipeworks_spigot_sides.png", + "default_water.png^pipeworks_spigot_bottom2.png", + { name = "default_water_flowing_animated.png^pipeworks_spigot_sides2.png", + animation = { + type = "vertical_frames", + aspect_w=16, + aspect_h=16, + length=0.8 + } + }, + { name = "default_water_flowing_animated.png^pipeworks_spigot_sides2.png", + animation = { + type = "vertical_frames", + aspect_w=16, + aspect_h=16, + length=0.8 + } + }, + { name = "default_water_flowing_animated.png^pipeworks_spigot_sides2.png", + animation = { + type = "vertical_frames", + aspect_w=16, + aspect_h=16, + length=0.8 + } + }, + { name = "default_water_flowing_animated.png^pipeworks_spigot_sides2.png", + animation = { + type = "vertical_frames", + aspect_w=16, + aspect_h=16, + length=0.8 + } + }, + }, + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy=3, pipe=1, not_in_creative_inventory=1}, + sounds = default.node_sound_wood_defaults(), + walkable = true, + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + node_box = { + type = "fixed", + fixed = spigotboxes_pouring, + }, + selection_box = { + type = "fixed", + fixed = { -2/16, -6/16, -2/16, 2/16, 2/16, 8/16 } + }, + drop = "pipeworks:spigot", +}) + +-- sealed pipe entry/exit (horizontal pipe passing through a metal +-- wall, for use in places where walls should look like they're airtight) + +local airtightboxes = {} +pipeworks.add_node_box(airtightboxes, pipeworks.pipe_frontstub) +pipeworks.add_node_box(airtightboxes, pipeworks.pipe_backstub) +pipeworks.add_node_box(airtightboxes, pipeworks.entry_panel) + +minetest.register_node("pipeworks:entry_panel_empty", { + description = "Airtight Pipe entry/exit", + drawtype = "nodebox", + tiles = { + "pipeworks_plain.png", + "pipeworks_plain.png", + "pipeworks_plain.png", + "pipeworks_plain.png", + "pipeworks_pipe_end_empty.png", + "pipeworks_pipe_end_empty.png" + }, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy=3, pipe=1}, + sounds = default.node_sound_wood_defaults(), + walkable = true, + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + node_box = { + type = "fixed", + fixed = airtightboxes, + }, + selection_box = { + type = "fixed", + fixed = { + { -2/16, -2/16, -8/16, 2/16, 2/16, 8/16 }, + { -8/16, -8/16, -1/16, 8/16, 8/16, 1/16 } + } + }, + on_place = function(itemstack, placer, pointed_thing) + if not pipeworks.node_is_owned(pointed_thing.under, placer) + and not pipeworks.node_is_owned(pointed_thing.above, placer) then + local node = minetest.get_node(pointed_thing.under) + + if not minetest.registered_nodes[node.name] + or not minetest.registered_nodes[node.name].on_rightclick then + local pitch = placer:get_look_pitch() + local above = pointed_thing.above + local under = pointed_thing.under + local fdir = minetest.dir_to_facedir(placer:get_look_dir()) + local undernode = minetest.get_node(under) + local abovenode = minetest.get_node(above) + local uname = undernode.name + local aname = abovenode.name + local isabove = (above.x == under.x) and (above.z == under.z) and (pitch > 0) + local pos1 = above + + if above.x == under.x + and above.z == under.z + and ( string.find(uname, "pipeworks:pipe_") + or string.find(uname, "pipeworks:storage_") + or string.find(uname, "pipeworks:expansion_") + or ( string.find(uname, "pipeworks:grating") and not isabove ) + or ( string.find(uname, "pipeworks:pump_") and not isabove ) + or ( string.find(uname, "pipeworks:entry_panel") + and undernode.param2 == 13 ) + ) + then + fdir = 13 + end + + if minetest.registered_nodes[uname]["buildable_to"] then + pos1 = under + end + + if not minetest.registered_nodes[minetest.get_node(pos1).name]["buildable_to"] then return end + + minetest.add_node(pos1, {name = "pipeworks:entry_panel_empty", param2 = fdir }) + pipeworks.scan_for_pipe_objects(pos1) + + if not pipeworks.expect_infinite_stacks then + itemstack:take_item() + end + + else + minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) + end + end + return itemstack + end +}) + +minetest.register_node("pipeworks:entry_panel_loaded", { + description = "Airtight Pipe entry/exit", + drawtype = "nodebox", + tiles = { + "pipeworks_plain.png", + "pipeworks_plain.png", + "pipeworks_plain.png", + "pipeworks_plain.png", + "pipeworks_pipe_end_empty.png", + "pipeworks_pipe_end_empty.png" + }, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy=3, pipe=1, not_in_creative_inventory=1}, + sounds = default.node_sound_wood_defaults(), + walkable = true, + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + node_box = { + type = "fixed", + fixed = airtightboxes, + }, + selection_box = { + type = "fixed", + fixed = { + { -2/16, -2/16, -8/16, 2/16, 2/16, 8/16 }, + { -8/16, -8/16, -1/16, 8/16, 8/16, 1/16 } + } + }, + drop = "pipeworks:entry_panel_empty" +}) + +local sensorboxes = {} +pipeworks.add_node_box(sensorboxes, pipeworks.pipe_leftstub) +pipeworks.add_node_box(sensorboxes, pipeworks.pipe_sensorbody) +pipeworks.add_node_box(sensorboxes, pipeworks.pipe_rightstub) + +minetest.register_node("pipeworks:flow_sensor_empty", { + description = "Flow Sensor", + drawtype = "nodebox", + tiles = { + "pipeworks_plain.png", + "pipeworks_plain.png", + "pipeworks_plain.png", + "pipeworks_plain.png", + "pipeworks_windowed_empty.png", + "pipeworks_windowed_empty.png" + }, + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy=3, pipe=1}, + sounds = default.node_sound_wood_defaults(), + walkable = true, + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + on_construct = function(pos) + if mesecon then + mesecon:receptor_off(pos, rules) + end + end, + node_box = { + type = "fixed", + fixed = sensorboxes, + }, + selection_box = { + type = "fixed", + fixed = { + { -8/16, -2/16, -2/16, 8/16, 2/16, 2/16 }, + } + }, + mesecons = pipereceptor_off +}) + +minetest.register_node("pipeworks:flow_sensor_loaded", { + description = "Flow sensor (on)", + drawtype = "nodebox", + tiles = { + "pipeworks_plain.png", + "pipeworks_plain.png", + "pipeworks_plain.png", + "pipeworks_plain.png", + "pipeworks_sensor_sides_on.png", + "pipeworks_sensor_sides_on.png" + }, + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy=3, pipe=1, not_in_creative_inventory=1}, + sounds = default.node_sound_wood_defaults(), + walkable = true, + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + on_construct = function(pos) + if mesecon then + mesecon:receptor_on(pos, rules) + end + end, + node_box = { + type = "fixed", + fixed = sensorboxes, + }, + selection_box = { + type = "fixed", + fixed = { + { -8/16, -2/16, -2/16, 8/16, 2/16, 2/16 }, + } + }, + drop = "pipeworks:flow_sensor_empty", + mesecons = pipereceptor_on +}) + +-- tanks + +for fill = 0, 10 do + local filldesc="empty" + local sgroups = {snappy=3, pipe=1, tankfill=fill+1} + local image = nil + + if fill ~= 0 then + filldesc=fill.."0% full" + sgroups = {snappy=3, pipe=1, tankfill=fill+1, not_in_creative_inventory=1} + image = "pipeworks_storage_tank_fittings.png" + end + + minetest.register_node("pipeworks:expansion_tank_"..fill, { + description = "Expansion Tank ("..filldesc..")... You hacker, you.", + tiles = { + "pipeworks_storage_tank_fittings.png", + "pipeworks_storage_tank_fittings.png", + "pipeworks_storage_tank_back.png", + "pipeworks_storage_tank_back.png", + "pipeworks_storage_tank_back.png", + pipeworks.liquid_texture.."^pipeworks_storage_tank_front_"..fill..".png" + }, + inventory_image = image, + paramtype = "light", + paramtype2 = "facedir", + groups = {snappy=3, pipe=1, tankfill=fill+1, not_in_creative_inventory=1}, + sounds = default.node_sound_wood_defaults(), + walkable = true, + drop = "pipeworks:storage_tank_0", + after_place_node = function(pos) + pipeworks.look_for_stackable_tanks(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + }) + + minetest.register_node("pipeworks:storage_tank_"..fill, { + description = "Fluid Storage Tank ("..filldesc..")", + tiles = { + "pipeworks_storage_tank_fittings.png", + "pipeworks_storage_tank_fittings.png", + "pipeworks_storage_tank_back.png", + "pipeworks_storage_tank_back.png", + "pipeworks_storage_tank_back.png", + pipeworks.liquid_texture.."^pipeworks_storage_tank_front_"..fill..".png" + }, + inventory_image = image, + paramtype = "light", + paramtype2 = "facedir", + groups = sgroups, + sounds = default.node_sound_wood_defaults(), + walkable = true, + drop = "pipeworks:storage_tank_0", + after_place_node = function(pos) + pipeworks.look_for_stackable_tanks(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + }) +end + +-- fountainhead + +minetest.register_node("pipeworks:fountainhead", { + description = "Fountainhead", + drawtype = "nodebox", + tiles = { + "pipeworks_fountainhead_top.png", + "pipeworks_pipe_end.png", + "pipeworks_plain.png", + }, + sunlight_propagates = true, + paramtype = "light", + groups = {snappy=3, pipe=1}, + sounds = default.node_sound_wood_defaults(), + walkable = true, + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + on_construct = function(pos) + if mesecon then + mesecon:receptor_on(pos, rules) + end + end, + node_box = { + type = "fixed", + fixed = pipeworks.fountainhead_model , + }, + selection_box = { + type = "fixed", + fixed = { -2/16, -8/16, -2/16, 2/16, 8/16, 2/16 } + }, +}) + +minetest.register_node("pipeworks:fountainhead_pouring", { + description = "Fountainhead", + drawtype = "nodebox", + tiles = { + "pipeworks_fountainhead_top.png", + "pipeworks_pipe_end.png", + "pipeworks_plain.png", + }, + sunlight_propagates = true, + paramtype = "light", + groups = {snappy=3, pipe=1, not_in_creative_inventory=1}, + sounds = default.node_sound_wood_defaults(), + walkable = true, + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + on_construct = function(pos) + if mesecon then + mesecon:receptor_on(pos, rules) + end + end, + node_box = { + type = "fixed", + fixed = pipeworks.fountainhead_model, + }, + selection_box = { + type = "fixed", + fixed = { -2/16, -8/16, -2/16, 2/16, 8/16, 2/16 }, + }, + drop = "pipeworks:fountainhead" +}) + +minetest.register_alias("pipeworks:valve_off_loaded", "pipeworks:valve_off_empty") + diff --git a/mods/pipeworks/flowing_logic.lua b/mods/pipeworks/flowing_logic.lua new file mode 100644 index 0000000..e0a6236 --- /dev/null +++ b/mods/pipeworks/flowing_logic.lua @@ -0,0 +1,121 @@ +-- This file provides the actual flow and pathfinding logic that makes water +-- move through the pipes. +-- +-- Contributed by mauvebic, 2013-01-03, rewritten a bit by Vanessa Ezekowitz +-- + +local finitewater = minetest.setting_getbool("liquid_finite") + +pipeworks.check_for_liquids = function(pos) + local coords = { + {x=pos.x,y=pos.y-1,z=pos.z}, + {x=pos.x,y=pos.y+1,z=pos.z}, + {x=pos.x-1,y=pos.y,z=pos.z}, + {x=pos.x+1,y=pos.y,z=pos.z}, + {x=pos.x,y=pos.y,z=pos.z-1}, + {x=pos.x,y=pos.y,z=pos.z+1}, } + for i =1,6 do + local name = minetest.get_node(coords[i]).name + if name and string.find(name,"water") then + if finitewater then minetest.remove_node(coords[i]) end + return true + end + end + return false +end + +pipeworks.check_for_inflows = function(pos,node) + local coords = { + {x=pos.x,y=pos.y-1,z=pos.z}, + {x=pos.x,y=pos.y+1,z=pos.z}, + {x=pos.x-1,y=pos.y,z=pos.z}, + {x=pos.x+1,y=pos.y,z=pos.z}, + {x=pos.x,y=pos.y,z=pos.z-1}, + {x=pos.x,y=pos.y,z=pos.z+1}, } + local newnode = false + local source = false + for i =1,6 do + if newnode then break end + local name = minetest.get_node(coords[i]).name + if name and (name == "pipeworks:pump_on" and pipeworks.check_for_liquids(coords[i])) or string.find(name,"_loaded") then + if string.find(name,"_loaded") then + source = minetest.get_meta(coords[i]):get_string("source") + if source == minetest.pos_to_string(pos) then break end + end + newnode = string.gsub(node.name,"empty","loaded") + source = {x=coords[i].x,y=coords[i].y,z=coords[i].z} + end + end + if newnode then + minetest.add_node(pos,{name=newnode, param2 = node.param2}) + minetest.get_meta(pos):set_string("source",minetest.pos_to_string(source)) + end +end + +pipeworks.check_sources = function(pos,node) + local sourcepos = minetest.string_to_pos(minetest.get_meta(pos):get_string("source")) + if not sourcepos then return end + local source = minetest.get_node(sourcepos).name + local newnode = false + if source and not ((source == "pipeworks:pump_on" and pipeworks.check_for_liquids(sourcepos)) or string.find(source,"_loaded") or source == "ignore" ) then + newnode = string.gsub(node.name,"loaded","empty") + end + + if newnode then + minetest.add_node(pos,{name=newnode, param2 = node.param2}) + minetest.get_meta(pos):set_string("source","") + end +end + +pipeworks.spigot_check = function(pos, node) + local belowname = minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}).name + if belowname and (belowname == "air" or belowname == "default:water_flowing" or belowname == "default:water_source") then + local spigotname = minetest.get_node(pos).name + local fdir=node.param2 + local check = { + {x=pos.x,y=pos.y,z=pos.z+1}, + {x=pos.x+1,y=pos.y,z=pos.z}, + {x=pos.x,y=pos.y,z=pos.z-1}, + {x=pos.x-1,y=pos.y,z=pos.z} + } + local near_node = minetest.get_node(check[fdir+1]) + if near_node and string.find(near_node.name, "_loaded") then + if spigotname and spigotname == "pipeworks:spigot" then + minetest.add_node(pos,{name = "pipeworks:spigot_pouring", param2 = fdir}) + if finitewater or belowname ~= "default:water_source" then + minetest.add_node({x=pos.x,y=pos.y-1,z=pos.z},{name = "default:water_source"}) + end + end + else + if spigotname == "pipeworks:spigot_pouring" then + minetest.add_node({x=pos.x,y=pos.y,z=pos.z},{name = "pipeworks:spigot", param2 = fdir}) + if belowname == "default:water_source" and not finitewater then + minetest.remove_node({x=pos.x,y=pos.y-1,z=pos.z}) + end + end + end + end +end + +pipeworks.fountainhead_check = function(pos, node) + local abovename = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}).name + if abovename and (abovename == "air" or abovename == "default:water_flowing" or abovename == "default:water_source") then + local fountainhead_name = minetest.get_node(pos).name + local near_node = minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}) + if near_node and string.find(near_node.name, "_loaded") then + if fountainhead_name and fountainhead_name == "pipeworks:fountainhead" then + minetest.add_node(pos,{name = "pipeworks:fountainhead_pouring"}) + if finitewater or abovename ~= "default:water_source" then + minetest.add_node({x=pos.x,y=pos.y+1,z=pos.z},{name = "default:water_source"}) + end + end + else + if fountainhead_name == "pipeworks:fountainhead_pouring" then + minetest.add_node({x=pos.x,y=pos.y,z=pos.z},{name = "pipeworks:fountainhead"}) + if abovename == "default:water_source" and not finitewater then + minetest.remove_node({x=pos.x,y=pos.y+1,z=pos.z}) + end + end + end + end +end diff --git a/mods/pipeworks/init.lua b/mods/pipeworks/init.lua new file mode 100755 index 0000000..b6c91d6 --- /dev/null +++ b/mods/pipeworks/init.lua @@ -0,0 +1,130 @@ +-- Pipeworks mod by Vanessa Ezekowitz - 2013-07-13 +-- +-- This mod supplies various steel pipes and plastic pneumatic tubes +-- and devices that they can connect to. +-- +-- License: WTFPL +-- + +pipeworks = {} + +local DEBUG = false + +pipeworks.worldpath = minetest.get_worldpath() +pipeworks.modpath = minetest.get_modpath("pipeworks") + +dofile(pipeworks.modpath.."/default_settings.txt") + +-- Read the external config file if it exists. +if io.open(pipeworks.worldpath.."/pipeworks_settings.txt","r") then + dofile(pipeworks.worldpath.."/pipeworks_settings.txt") + io.close() +end + +-- Random variables + +pipeworks.expect_infinite_stacks = true +if minetest.get_modpath("unified_inventory") or not minetest.setting_getbool("creative_mode") then + pipeworks.expect_infinite_stacks = false +end + +pipeworks.meseadjlist={{x=0,y=0,z=1},{x=0,y=0,z=-1},{x=0,y=1,z=0},{x=0,y=-1,z=0},{x=1,y=0,z=0},{x=-1,y=0,z=0}} + +pipeworks.rules_all = {{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=1},{x=0, y=1, z=-1},{x=1, y=1, z=0},{x=-1, y=1, z=0}, + {x=0, y=-1, z=1},{x=0, y=-1, z=-1},{x=1, y=-1, z=0},{x=-1, y=-1, z=0}, + {x=0, y=1, z=0}, {x=0, y=-1, z=0}} + +pipeworks.mesecons_rules={{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},{x=0,y=-1,z=0}} + +pipeworks.liquid_texture = "default_water.png" + +-- Helper functions + +function pipeworks.fix_image_names(table, replacement) + local outtable={} + for i in ipairs(table) do + outtable[i]=string.gsub(table[i], "_XXXXX", replacement) + end + + return outtable +end + +function pipeworks.add_node_box(t, b) + for i in ipairs(b) + do table.insert(t, b[i]) + end +end + +function pipeworks.node_is_owned(pos, placer) + local ownername = false + if type(IsPlayerNodeOwner) == "function" then -- node_ownership mod + if HasOwner(pos, placer) then -- returns true if the node is owned + if not IsPlayerNodeOwner(pos, placer:get_player_name()) then + if type(getLastOwner) == "function" then -- ...is an old version + ownername = getLastOwner(pos) + elseif type(GetNodeOwnerName) == "function" then -- ...is a recent version + ownername = GetNodeOwnerName(pos) + else + ownername = S("someone") + end + end + end + + elseif type(isprotect)=="function" then -- glomie's protection mod + if not isprotect(5, pos, placer) then + ownername = S("someone") + end + elseif type(protector)=="table" and type(protector.can_dig)=="function" then -- Zeg9's protection mod + if not protector.can_dig(5, pos, placer) then + ownername = S("someone") + end + end + + if ownername ~= false then + minetest.chat_send_player( placer:get_player_name(), S("Sorry, %s owns that spot."):format(ownername) ) + return true + else + return false + end +end + +function pipeworks.replace_name(tbl,tr,name) + local ntbl={} + for key,i in pairs(tbl) do + if type(i)=="string" then + ntbl[key]=string.gsub(i,tr,name) + elseif type(i)=="table" then + ntbl[key]=pipeworks.replace_name(i,tr,name) + else + ntbl[key]=i + end + end + return ntbl +end + +------------------------------------------- +-- Load the various other parts of the mod + +dofile(pipeworks.modpath.."/common.lua") +dofile(pipeworks.modpath.."/models.lua") +dofile(pipeworks.modpath.."/autoplace_pipes.lua") +dofile(pipeworks.modpath.."/autoplace_tubes.lua") +dofile(pipeworks.modpath.."/luaentity.lua") +dofile(pipeworks.modpath.."/item_transport.lua") +dofile(pipeworks.modpath.."/flowing_logic.lua") +dofile(pipeworks.modpath.."/crafts.lua") +dofile(pipeworks.modpath.."/tubes.lua") +dofile(pipeworks.modpath.."/trashcan.lua") +dofile(pipeworks.modpath.."/wielder.lua") + +if pipeworks.enable_pipes then dofile(pipeworks.modpath.."/pipes.lua") end +if pipeworks.enable_teleport_tube then dofile(pipeworks.modpath.."/teleport_tube.lua") end +if pipeworks.enable_pipe_devices then dofile(pipeworks.modpath.."/devices.lua") end +if pipeworks.enable_redefines then dofile(pipeworks.modpath.."/compat.lua") end +if pipeworks.enable_autocrafter then dofile(pipeworks.modpath.."/autocrafter.lua") end + +minetest.register_alias("pipeworks:pipe", "pipeworks:pipe_110000_empty") + +print("Pipeworks loaded!") + diff --git a/mods/pipeworks/item_transport.lua b/mods/pipeworks/item_transport.lua new file mode 100755 index 0000000..c378d6e --- /dev/null +++ b/mods/pipeworks/item_transport.lua @@ -0,0 +1,482 @@ +local fakePlayer = { + get_player_name = function() return ":pipeworks" end, + -- any other player functions called by allow_metadata_inventory_take anywhere... + -- perhaps a custom metaclass that errors specially when fakePlayer. is not found? +} + +function pipeworks.tube_item(pos, item) + error("obsolete pipeworks.tube_item() called; change caller to use pipeworks.tube_inject_item() instead") +end + +function pipeworks.tube_inject_item(pos, start_pos, velocity, item) + -- Take item in any format + local stack = ItemStack(item) + local obj = luaentity.add_entity(pos, "pipeworks:tubed_item") + obj:set_item(stack:to_string()) + obj.start_pos = vector.new(start_pos) + obj:setvelocity(velocity) + --obj:set_color("red") -- todo: this is test-only code + return obj +end + +-- adding two tube functions +-- can_remove(pos,node,stack,dir) returns the maximum number of items of that stack that can be removed +-- remove_items(pos,node,stack,dir,count) removes count items and returns them +-- both optional w/ sensible defaults and fallback to normal allow_* function +-- XXX: possibly change insert_object to insert_item + +local function set_filter_infotext(data, meta) + local infotext = data.wise_desc.." Filter-Injector" + if meta:get_int("slotseq_mode") == 2 then + infotext = infotext .. " (slot #"..meta:get_int("slotseq_index").." next)" + end + meta:set_string("infotext", infotext) +end + +local function set_filter_formspec(data, meta) + local itemname = data.wise_desc.." Filter-Injector" + local formspec = "size[8,8.5]".. + "item_image[0,0;1,1;pipeworks:"..data.name.."]".. + "label[1,0;"..minetest.formspec_escape(itemname).."]".. + "label[0,1;Prefer item types:]".. + "list[current_name;main;0,1.5;8,2;]".. + fs_helpers.cycling_button(meta, "button[0,3.5;4,1", "slotseq_mode", + {"Sequence slots by Priority", + "Sequence slots Randomly", + "Sequence slots by Rotation"}).. + "list[current_player;main;0,4.5;8,4;]" + meta:set_string("formspec", formspec) +end + +-- todo SOON: this function has *way too many* parameters +local function grabAndFire(data,slotseq_mode,filtmeta,frominv,frominvname,frompos,fromnode,filtername,fromtube,fromdef,dir,all) + local sposes = {} + for spos,stack in ipairs(frominv:get_list(frominvname)) do + local matches + if filtername == "" then + matches = stack:get_name() ~= "" + else + matches = stack:get_name() == filtername + end + if matches then table.insert(sposes, spos) end + end + if #sposes == 0 then return false end + if slotseq_mode == 1 then + for i = #sposes, 2, -1 do + local j = math.random(i) + local t = sposes[j] + sposes[j] = sposes[i] + sposes[i] = t + end + elseif slotseq_mode == 2 then + local headpos = filtmeta:get_int("slotseq_index") + table.sort(sposes, function (a, b) + if a >= headpos then + if b < headpos then return true end + else + if b >= headpos then return false end + end + return a < b + end) + end + for _, spos in ipairs(sposes) do + local stack = frominv:get_stack(frominvname, spos) + local doRemove = stack:get_count() + if fromtube.can_remove then + doRemove = fromtube.can_remove(frompos, fromnode, stack, dir) + elseif fromdef.allow_metadata_inventory_take then + doRemove = fromdef.allow_metadata_inventory_take(frompos, frominvname,spos, stack, fakePlayer) + end + -- stupid lack of continue statements grumble + if doRemove > 0 then + if slotseq_mode == 2 then + local nextpos = spos + 1 + if nextpos > frominv:get_size(frominvname) then + nextpos = 1 + end + filtmeta:set_int("slotseq_index", nextpos) + set_filter_infotext(data, filtmeta) + end + local item + local count + if all then + count = math.min(stack:get_count(), doRemove) + else + count = 1 + end + if fromtube.remove_items then + -- it could be the entire stack... + item = fromtube.remove_items(frompos, fromnode, stack, dir, count) + else + item = stack:take_item(count) + frominv:set_stack(frominvname, spos, stack) + if fromdef.on_metadata_inventory_take then + fromdef.on_metadata_inventory_take(frompos, frominvname, spos, item, fakePlayer) + end + end + local pos = vector.add(frompos, vector.multiply(dir, 1.4)) + local start_pos = vector.add(frompos, dir) + local item1 = pipeworks.tube_inject_item(pos, start_pos, dir, item) + return true-- only fire one item, please + end + end + return false +end + +local function punch_filter(data, filtpos, filtnode) + local filtmeta = minetest.get_meta(filtpos) + local filtinv = filtmeta:get_inventory() + local dir = minetest.facedir_to_right_dir(filtnode.param2) + local frompos = vector.subtract(filtpos, dir) + local fromnode = minetest.get_node(frompos) + if not fromnode then return end + local fromdef = minetest.registered_nodes[fromnode.name] + if not fromdef then return end + local fromtube = fromdef.tube + if not (fromtube and fromtube.input_inventory) then return end + local filters = {} + for _, filterstack in ipairs(filtinv:get_list("main")) do + local filtername = filterstack:get_name() + if filtername ~= "" then table.insert(filters, filtername) end + end + if #filters == 0 then table.insert(filters, "") end + local slotseq_mode = filtmeta:get_int("slotseq_mode") + local frommeta = minetest.get_meta(frompos) + local frominv = frommeta:get_inventory() + if fromtube.before_filter then fromtube.before_filter(frompos) end + for _, frominvname in ipairs(type(fromtube.input_inventory) == "table" and fromtube.input_inventory or {fromtube.input_inventory}) do + local done = false + for _, filtername in ipairs(filters) do + if grabAndFire(data, slotseq_mode, filtmeta, frominv, frominvname, frompos, fromnode, filtername, fromtube, fromdef, dir, data.stackwise) then + done = true + break + end + end + if done then break end + end + if fromtube.after_filter then fromtube.after_filter(frompos) end +end + +for _, data in ipairs({ + { + name = "filter", + wise_desc = "Itemwise", + stackwise = false, + }, + { + name = "mese_filter", + wise_desc = "Stackwise", + stackwise = true, + }, +}) do + minetest.register_node("pipeworks:"..data.name, { + description = data.wise_desc.." Filter-Injector", + tiles = { + "pipeworks_"..data.name.."_top.png", + "pipeworks_"..data.name.."_top.png", + "pipeworks_"..data.name.."_output.png", + "pipeworks_"..data.name.."_input.png", + "pipeworks_"..data.name.."_side.png", + "pipeworks_"..data.name.."_top.png", + }, + paramtype2 = "facedir", + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, mesecon = 2}, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + set_filter_formspec(data, meta) + set_filter_infotext(data, meta) + local inv = meta:get_inventory() + inv:set_size("main", 8*2) + end, + on_receive_fields = function(pos, formname, fields, sender) + fs_helpers.on_receive_fields(pos, fields) + local meta = minetest.get_meta(pos) + meta:set_int("slotseq_index", 1) + set_filter_formspec(data, meta) + set_filter_infotext(data, meta) + end, + can_dig = function(pos, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:is_empty("main") + end, + mesecons = { + effector = { + action_on = function(pos, node) + punch_filter(data, pos, node) + end, + }, + }, + tube = {connect_sides = {right = 1}}, + on_punch = function (pos, node, puncher) + punch_filter(data, pos, node) + end, + }) +end + +local adjlist={{x=0,y=0,z=1},{x=0,y=0,z=-1},{x=0,y=1,z=0},{x=0,y=-1,z=0},{x=1,y=0,z=0},{x=-1,y=0,z=0}} + +function pipeworks.notvel(tbl, vel) + local tbl2={} + for _,val in ipairs(tbl) do + if val.x ~= -vel.x or val.y ~= -vel.y or val.z ~= -vel.z then table.insert(tbl2, val) end + end + return tbl2 +end + +local function go_next(pos, velocity, stack) + local next_positions = {} + local max_priority = 0 + local cnode = minetest.get_node(pos) + local cmeta = minetest.get_meta(pos) + local can_go + local speed = math.abs(velocity.x + velocity.y + velocity.z) + if speed == 0 then + speed = 1 + end + local vel = {x = velocity.x/speed, y = velocity.y/speed, z = velocity.z/speed,speed=speed} + if speed >= 4.1 then + speed = 4 + elseif speed >= 1.1 then + speed = speed - 0.1 + else + speed = 1 + end + vel.speed = speed + if minetest.registered_nodes[cnode.name] and minetest.registered_nodes[cnode.name].tube and minetest.registered_nodes[cnode.name].tube.can_go then + can_go = minetest.registered_nodes[cnode.name].tube.can_go(pos, cnode, vel, stack) + else + can_go = pipeworks.notvel(adjlist, vel) + end + for _, vect in ipairs(can_go) do + local npos = vector.add(pos, vect) + local node = minetest.get_node(npos) + local reg_node = minetest.registered_nodes[node.name] + if reg_node then + local tube_def = reg_node.tube + local tubedevice = minetest.get_item_group(node.name, "tubedevice") + local tube_priority = (tube_def and tube_def.priority) or 100 + if tubedevice > 0 and tube_priority >= max_priority then + if not tube_def or not tube_def.can_insert or + tube_def.can_insert(npos, node, stack, vect) then + if tube_priority > max_priority then + max_priority = tube_priority + next_positions = {} + end + next_positions[#next_positions + 1] = {pos = npos, vect = vect} + end + end + end + end + + if not next_positions[1] then + return false, nil + end + + local n = (cmeta:get_int("tubedir") % (#next_positions)) + 1 + if pipeworks.enable_cyclic_mode then + cmeta:set_int("tubedir", n) + end + local new_velocity = vector.multiply(next_positions[n].vect, vel.speed) + return true, new_velocity +end + +minetest.register_entity("pipeworks:tubed_item", { + initial_properties = { + hp_max = 1, + physical = false, + collisionbox = {0.1, 0.1, 0.1, 0.1, 0.1, 0.1}, + visual = "wielditem", + visual_size = {x = 0.15, y = 0.15}, + textures = {""}, + spritediv = {x = 1, y = 1}, + initial_sprite_basepos = {x = 0, y = 0}, + is_visible = false, + }, + + physical_state = false, + + from_data = function(self, itemstring) + local stack = ItemStack(itemstring) + local itemtable = stack:to_table() + local itemname = nil + if itemtable then + itemname = stack:to_table().name + end + local item_texture = nil + local item_type = "" + if minetest.registered_items[itemname] then + item_texture = minetest.registered_items[itemname].inventory_image + item_type = minetest.registered_items[itemname].type + end + self.object:set_properties({ + is_visible = true, + textures = {stack:get_name()} + }) + local def = stack:get_definition() + self.object:setyaw((def and def.type == "node") and 0 or math.pi * 0.25) + end, + + get_staticdata = luaentity.get_staticdata, + on_activate = function(self, staticdata) -- Legacy code, should be replaced later by luaentity.on_activate + if staticdata == "" or staticdata == nil then + return + end + if staticdata == "toremove" then + self.object:remove() + return + end + local item = minetest.deserialize(staticdata) + pipeworks.tube_inject_item(self.object:getpos(), item.start_pos, item.velocity, item.itemstring) + self.object:remove() + end, +}) + +minetest.register_entity("pipeworks:color_entity", { + initial_properties = { + hp_max = 1, + physical = false, + collisionbox = {0.1, 0.1, 0.1, 0.1, 0.1, 0.1}, + visual = "cube", + visual_size = {x = 3.5, y = 3.5, z = 3.5}, -- todo: find correct size + textures = {""}, + is_visible = false, + }, + + physical_state = false, + + from_data = function(self, color) + local t = "pipeworks_color_"..color..".png" + local prop = { + is_visible = true, + visual = "cube", + textures = {t, t, t, t, t, t} -- todo: textures + } + self.object:set_properties(prop) + end, + + get_staticdata = luaentity.get_staticdata, + on_activate = luaentity.on_activate, +}) + +luaentity.register_entity("pipeworks:tubed_item", { + itemstring = '', + item_entity = nil, + color_entity = nil, + color = nil, + start_pos = nil, + + set_item = function(self, item) + local itemstring = ItemStack(item):to_string() -- Accept any input format + if self.itemstring == itemstring then + return + end + if self.item_entity then + self:remove_attached_entity(self.item_entity) + end + self.itemstring = itemstring + self.item_entity = self:add_attached_entity("pipeworks:tubed_item", itemstring) + end, + + set_color = function(self, color) + if self.color == color then + return + end + self.color = color + if self.color_entity then + self:remove_attached_entity(self.color_entity) + end + if color then + self.color_entity = self:add_attached_entity("pipeworks:color_entity", color) + else + self.color_entity = nil + end + end, + + on_step = function(self, dtime) + if self.start_pos == nil then + local pos = self:getpos() + self.start_pos = vector.round(pos) + self:setpos(pos) + end + + local pos = self:getpos() + local stack = ItemStack(self.itemstring) + local drop_pos + + local velocity = self:getvelocity() + + local moved = false + local speed = math.abs(velocity.x + velocity.y + velocity.z) + if speed == 0 then + speed = 1 + moved = true + end + local vel = {x = velocity.x / speed, y = velocity.y / speed, z = velocity.z / speed, speed = speed} + + if vector.distance(pos, self.start_pos) >= 1 then + self.start_pos = vector.add(self.start_pos, vel) + moved = true + end + + minetest.load_position(self.start_pos) + local node = minetest.get_node(self.start_pos) + if moved and minetest.get_item_group(node.name, "tubedevice_receiver") == 1 then + local leftover + if minetest.registered_nodes[node.name].tube and minetest.registered_nodes[node.name].tube.insert_object then + leftover = minetest.registered_nodes[node.name].tube.insert_object(self.start_pos, node, stack, vel) + else + leftover = stack + end + if leftover:is_empty() then + self:remove() + return + end + velocity = vector.multiply(velocity, -1) + self:setvelocity(velocity) + self:set_item(leftover:to_string()) + return + end + + if moved then + local found_next, new_velocity = go_next(self.start_pos, velocity, stack) -- todo: color + if not found_next then + drop_pos = minetest.find_node_near(vector.add(self.start_pos, velocity), 1, "air") + if drop_pos then + minetest.item_drop(stack, "", drop_pos) + self:remove() + return + end + end + + if new_velocity and not vector.equals(velocity, new_velocity) then + self:setpos(self.start_pos) + self:setvelocity(new_velocity) + end + end + end +}) + +if minetest.get_modpath("mesecons_mvps") then + mesecon:register_mvps_unmov("pipeworks:tubed_item") + mesecon:register_mvps_unmov("pipeworks:color_entity") + mesecon:register_on_mvps_move(function(moved_nodes) + local moved = {} + for _, n in ipairs(moved_nodes) do + moved[minetest.hash_node_position(n.oldpos)] = vector.subtract(n.pos, n.oldpos) + end + for id, entity in pairs(luaentity.entities) do + if entity.name == "pipeworks:tubed_item" then + local pos = entity:getpos() + local rpos = vector.round(pos) + local dir = moved[minetest.hash_node_position(rpos)] + if dir then + entity:setpos(vector.add(pos, dir)) + entity.start_pos = vector.add(entity.start_pos, dir) + end + end + end + end) +end diff --git a/mods/pipeworks/legacy.lua b/mods/pipeworks/legacy.lua new file mode 100644 index 0000000..84ae31d --- /dev/null +++ b/mods/pipeworks/legacy.lua @@ -0,0 +1,60 @@ + +if not minetest.get_modpath("auto_tree_tap") and + minetest.get_modpath("technic") then + + minetest.register_abm({ + nodenames = { "auto_tree_tap:off", "auto_tree_tap:on" }, + chance = 1, + interval = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local fdir = node.param2 + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("pick", 1) + inv:set_size("ghost_pick", 1) + inv:set_size("main", 100) + minetest.set_node(pos, {name = "pipeworks:nodebreaker_off", param2 = fdir}) + minetest.registered_nodes["pipeworks:nodebreaker_off"].on_punch(pos, node) + inv:set_stack("pick", 1, ItemStack("technic:treetap")) + end + }) + + minetest.register_node(":auto_tree_tap:off", { + description = "Auto-Tap", + tiles = {"pipeworks_nodebreaker_top_off.png","pipeworks_nodebreaker_bottom_off.png","pipeworks_nodebreaker_side2_off.png","pipeworks_nodebreaker_side1_off.png", + "pipeworks_nodebreaker_back.png","pipeworks_nodebreaker_front_off.png"}, + is_ground_content = true, + paramtype2 = "facedir", + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon = 2,tubedevice=1, not_in_creative_inventory=1 }, + mesecons= {effector={rules=pipeworks.rules_all,action_on=node_breaker_on, action_off=node_breaker_off}}, + sounds = default.node_sound_stone_defaults(), + tube = {connect_sides={back=1}}, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("pick", 1) + inv:set_stack("pick", 1, ItemStack("default:pick_mese")) + end, + after_place_node = function (pos, placer) + pipeworks.scan_for_tube_objects(pos, placer) + local placer_pos = placer:getpos() + + --correct for the player's height + if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end + + --correct for 6d facedir + if placer_pos then + local dir = { + x = pos.x - placer_pos.x, + y = pos.y - placer_pos.y, + z = pos.z - placer_pos.z + } + local node = minetest.get_node(pos) + node.param2 = minetest.dir_to_facedir(dir, true) + minetest.set_node(pos, node) + minetest.log("action", "real (6d) facedir: " .. node.param2) + end + end, + after_dig_node = pipeworks.scan_for_tube_objects, + }) +end diff --git a/mods/pipeworks/luaentity.lua b/mods/pipeworks/luaentity.lua new file mode 100755 index 0000000..241da14 --- /dev/null +++ b/mods/pipeworks/luaentity.lua @@ -0,0 +1,334 @@ +local max_entity_id = 1000000000000 -- If you need more, there's a problem with your code + +luaentity = {} + +luaentity.registered_entities = {} + +local filename = minetest.get_worldpath().."/luaentities" +local function read_file() + local f = io.open(filename, "r") + if f == nil then return {} end + local t = f:read("*all") + f:close() + if t == "" or t == nil then return {} end + return minetest.deserialize(t) +end + +local function write_file(tbl) + local f = io.open(filename, "w") + f:write(minetest.serialize(tbl)) + f:close() +end + +local function read_entities() + local t = read_file() + for _, entity in pairs(t) do + setmetatable(entity, luaentity.registered_entities[entity.name]) + end + return t +end + +local function write_entities() + for _, entity in pairs(luaentity.entities) do + setmetatable(entity, nil) + for _, attached in pairs(entity._attached_entities) do + if attached.entity then + attached.entity:remove() + attached.entity = nil + end + end + entity._attached_entities_master = nil + end + write_file(luaentity.entities) +end + +minetest.register_on_shutdown(write_entities) +luaentity.entities_index = 0 + +local function get_blockpos(pos) + return {x = math.floor(pos.x / 16), + y = math.floor(pos.y / 16), + z = math.floor(pos.z / 16)} +end + +local active_blocks = {} -- These only contain active blocks near players (i.e., not forceloaded ones) +local handle_active_blocks_step = 2 +local handle_active_blocks_timer = 0 +minetest.register_globalstep(function(dtime) + handle_active_blocks_timer = handle_active_blocks_timer + dtime + if handle_active_blocks_timer >= handle_active_blocks_step then + handle_active_blocks_timer = handle_active_blocks_timer - handle_active_blocks_step + local active_block_range = tonumber(minetest.setting_get("active_block_range")) or 2 + local new_active_blocks = {} + for _, player in ipairs(minetest.get_connected_players()) do + local blockpos = get_blockpos(player:getpos()) + local minp = vector.subtract(blockpos, active_block_range) + local maxp = vector.add(blockpos, active_block_range) + + for x = minp.x, maxp.x do + for y = minp.y, maxp.y do + for z = minp.z, maxp.z do + local pos = {x = x, y = y, z = z} + new_active_blocks[minetest.hash_node_position(pos)] = pos + end + end + end + end + active_blocks = new_active_blocks + -- todo: callbacks on block load/unload + end +end) + +local function is_active(pos) + return active_blocks[minetest.hash_node_position(get_blockpos(pos))] ~= nil +end + +local entitydef_default = { + _attach = function(self, attached, attach_to) + local attached_def = self._attached_entities[attached] + local attach_to_def = self._attached_entities[attach_to] + attached_def.entity:set_attach( + attach_to_def.entity, "", + vector.subtract(attached_def.offset, attach_to_def.offset), -- todo: Does not work because is object space + vector.new(0, 0, 0) + ) + end, + _set_master = function(self, index) + self._attached_entities_master = index + if not index then + return + end + local def = self._attached_entities[index] + if not def.entity then + return + end + def.entity:setpos(vector.add(self._pos, def.offset)) + def.entity:setvelocity(self._velocity) + def.entity:setacceleration(self._acceleration) + end, + _attach_all = function(self) + local master = self._attached_entities_master + if not master then + return + end + for id, entity in pairs(self._attached_entities) do + if id ~= master and entity.entity then + self:_attach(id, master) + end + end + end, + _detach_all = function(self) + local master = self._attached_entities_master + for id, entity in pairs(self._attached_entities) do + if id ~= master and entity.entity then + entity.entity:set_detach() + end + end + end, + _add_attached = function(self, index) + local entity = self._attached_entities[index] + if entity.entity then + return + end + local entity_pos = vector.add(self._pos, entity.offset) + if not is_active(entity_pos) then + return + end + local ent = minetest.add_entity(entity_pos, entity.name):get_luaentity() + ent:from_data(entity.data) + ent.parent_id = self._id + ent.attached_id = index + entity.entity = ent.object + local master = self._attached_entities_master + if master then + self:_attach(index, master) + else + self:_set_master(index) + end + end, + _remove_attached = function(self, index) + local master = self._attached_entities_master + local entity = self._attached_entities[index] + local ent = entity.entity + entity.entity = nil + if index == master then + self:_detach_all() + local newmaster + for id, attached in pairs(self._attached_entities) do + if id ~= master and attached.entity then + newmaster = id + break + end + end + self:_set_master(newmaster) + self:_attach_all() + elseif master and ent then + ent:set_detach() + end + if ent then + ent:remove() + end + end, + _add_loaded = function(self) + for id, _ in pairs(self._attached_entities) do + self:_add_attached(id) + end + end, + getid = function(self) + return self._id + end, + getpos = function(self) + return vector.new(self._pos) + end, + setpos = function(self, pos) + self._pos = vector.new(pos) + --for _, entity in pairs(self._attached_entities) do + -- if entity.entity then + -- entity.entity:setpos(vector.add(self._pos, entity.offset)) + -- end + --end + local master = self._attached_entities_master + if master then + local master_def = self._attached_entities[master] + master_def.entity:setpos(vector.add(self._pos, master_def.offset)) + end + end, + getvelocity = function(self) + return vector.new(self._velocity) + end, + setvelocity = function(self, velocity) + self._velocity = vector.new(velocity) + local master = self._attached_entities_master + if master then + self._attached_entities[master].entity:setvelocity(self._velocity) + end + end, + getacceleration = function(self) + return vector.new(self._acceleration) + end, + setacceleration = function(self, acceleration) + self._acceleration = vector.new(acceleration) + local master = self._attached_entities_master + if master then + self._attached_entities[master].entity:setacceleration(self._acceleration) + end + end, + remove = function(self) + self:_detach_all() + for _, entity in pairs(self._attached_entities) do + if entity.entity then + entity.entity:remove() + end + end + luaentity.entities[self._id] = nil + end, + add_attached_entity = function(self, name, data, offset) + local index = #self._attached_entities + 1 + self._attached_entities[index] = { + name = name, + data = data, + offset = vector.new(offset), + } + self:_add_attached(index) + return index + end, + remove_attached_entity = function(self, index) + self:_remove_attached(index) + self._attached_entities[index] = nil + end, +} + +function luaentity.register_entity(name, prototype) + -- name = check_modname_prefix(name) + prototype.name = name + setmetatable(prototype, {__index = entitydef_default}) + prototype.__index = prototype -- Make it possible to use it as metatable + luaentity.registered_entities[name] = prototype +end + +-- function luaentity.get_entity_definition(entity) +-- return luaentity.registered_entities[entity.name] +-- end + +function luaentity.add_entity(pos, name) + local index = luaentity.entities_index + while luaentity.entities[index] do + index = index + 1 + if index >= max_entity_id then + index = 0 + end + end + luaentity.entities_index = index + + local entity = { + name = name, + _id = index, + _pos = vector.new(pos), + _velocity = {x = 0, y = 0, z = 0}, + _acceleration = {x = 0, y = 0, z = 0}, + _attached_entities = {}, + } + + local prototype = luaentity.registered_entities[name] + setmetatable(entity, prototype) -- Default to prototype for other methods + luaentity.entities[index] = entity + + if entity.on_activate then + entity:on_activate() + end + return entity +end + +-- todo: check if remove in get_staticdata works +function luaentity.get_staticdata(self) + local parent = luaentity.entities[self.parent_id] + if parent and parent._remove_attached then + parent:_remove_attached(self.attached_id) + end + return "toremove" +end + +function luaentity.on_activate(self, staticdata) + if staticdata == "toremove" then + self.object:remove() + end +end + +function luaentity.get_objects_inside_radius(pos, radius) + local objects = {} + local index = 1 + for id, entity in pairs(luaentity.entities) do + if vector.distance(pos, entity:getpos()) <= radius then + objects[index] = entity + index = index + 1 + end + end +end + +minetest.register_globalstep(function(dtime) + if not luaentity.entities then + luaentity.entities = read_entities() + end + for id, entity in pairs(luaentity.entities) do + local master = entity._attached_entities_master + if master then + local master_def = entity._attached_entities[master] + local master_entity = master_def.entity + entity._pos = vector.subtract(master_entity:getpos(), master_def.offset) + entity._velocity = master_entity:getvelocity() + entity._acceleration = master_entity:getacceleration() + else + entity._pos = vector.add(vector.add( + entity._pos, + vector.multiply(entity._velocity, dtime)), + vector.multiply(entity._acceleration, 0.5 * dtime * dtime)) + entity._velocity = vector.add( + entity._velocity, + vector.multiply(entity._acceleration, dtime)) + end + entity:_add_loaded() + if entity.on_step then + entity:on_step(dtime) + end + end +end) diff --git a/mods/pipeworks/models.lua b/mods/pipeworks/models.lua new file mode 100644 index 0000000..6a841d3 --- /dev/null +++ b/mods/pipeworks/models.lua @@ -0,0 +1,202 @@ +--------------------- +-- The various models + +-- Pipe models + +pipeworks.pipe_leftstub = { + { -32/64, -2/64, -6/64, 1/64, 2/64, 6/64 }, -- pipe segment against -X face + { -32/64, -4/64, -5/64, 1/64, 4/64, 5/64 }, + { -32/64, -5/64, -4/64, 1/64, 5/64, 4/64 }, + { -32/64, -6/64, -2/64, 1/64, 6/64, 2/64 }, + + { -32/64, -3/64, -8/64, -30/64, 3/64, 8/64 }, -- (the flange for it) + { -32/64, -5/64, -7/64, -30/64, 5/64, 7/64 }, + { -32/64, -6/64, -6/64, -30/64, 6/64, 6/64 }, + { -32/64, -7/64, -5/64, -30/64, 7/64, 5/64 }, + { -32/64, -8/64, -3/64, -30/64, 8/64, 3/64 } +} + +pipeworks.pipe_rightstub = { + { -1/64, -2/64, -6/64, 32/64, 2/64, 6/64 }, -- pipe segment against +X face + { -1/64, -4/64, -5/64, 32/64, 4/64, 5/64 }, + { -1/64, -5/64, -4/64, 32/64, 5/64, 4/64 }, + { -1/64, -6/64, -2/64, 32/64, 6/64, 2/64 }, + + { 30/64, -3/64, -8/64, 32/64, 3/64, 8/64 }, -- (the flange for it) + { 30/64, -5/64, -7/64, 32/64, 5/64, 7/64 }, + { 30/64, -6/64, -6/64, 32/64, 6/64, 6/64 }, + { 30/64, -7/64, -5/64, 32/64, 7/64, 5/64 }, + { 30/64, -8/64, -3/64, 32/64, 8/64, 3/64 } +} + +pipeworks.pipe_bottomstub = { + { -2/64, -32/64, -6/64, 2/64, 1/64, 6/64 }, -- pipe segment against -Y face + { -4/64, -32/64, -5/64, 4/64, 1/64, 5/64 }, + { -5/64, -32/64, -4/64, 5/64, 1/64, 4/64 }, + { -6/64, -32/64, -2/64, 6/64, 1/64, 2/64 }, + + { -3/64, -32/64, -8/64, 3/64, -30/64, 8/64 }, -- (the flange for it) + { -5/64, -32/64, -7/64, 5/64, -30/64, 7/64 }, + { -6/64, -32/64, -6/64, 6/64, -30/64, 6/64 }, + { -7/64, -32/64, -5/64, 7/64, -30/64, 5/64 }, + { -8/64, -32/64, -3/64, 8/64, -30/64, 3/64 } +} + +pipeworks.pipe_topstub = { + { -2/64, -1/64, -6/64, 2/64, 32/64, 6/64 }, -- pipe segment against +Y face + { -4/64, -1/64, -5/64, 4/64, 32/64, 5/64 }, + { -5/64, -1/64, -4/64, 5/64, 32/64, 4/64 }, + { -6/64, -1/64, -2/64, 6/64, 32/64, 2/64 }, + + { -3/64, 30/64, -8/64, 3/64, 32/64, 8/64 }, -- (the flange for it) + { -5/64, 30/64, -7/64, 5/64, 32/64, 7/64 }, + { -6/64, 30/64, -6/64, 6/64, 32/64, 6/64 }, + { -7/64, 30/64, -5/64, 7/64, 32/64, 5/64 }, + { -8/64, 30/64, -3/64, 8/64, 32/64, 3/64 } +} + +pipeworks.pipe_frontstub = { + { -6/64, -2/64, -32/64, 6/64, 2/64, 1/64 }, -- pipe segment against -Z face + { -5/64, -4/64, -32/64, 5/64, 4/64, 1/64 }, + { -4/64, -5/64, -32/64, 4/64, 5/64, 1/64 }, + { -2/64, -6/64, -32/64, 2/64, 6/64, 1/64 }, + + { -8/64, -3/64, -32/64, 8/64, 3/64, -30/64 }, -- (the flange for it) + { -7/64, -5/64, -32/64, 7/64, 5/64, -30/64 }, + { -6/64, -6/64, -32/64, 6/64, 6/64, -30/64 }, + { -5/64, -7/64, -32/64, 5/64, 7/64, -30/64 }, + { -3/64, -8/64, -32/64, 3/64, 8/64, -30/64 } +} + +pipeworks.pipe_backstub = { + { -6/64, -2/64, -1/64, 6/64, 2/64, 32/64 }, -- pipe segment against -Z face + { -5/64, -4/64, -1/64, 5/64, 4/64, 32/64 }, + { -4/64, -5/64, -1/64, 4/64, 5/64, 32/64 }, + { -2/64, -6/64, -1/64, 2/64, 6/64, 32/64 }, + + { -8/64, -3/64, 30/64, 8/64, 3/64, 32/64 }, -- (the flange for it) + { -7/64, -5/64, 30/64, 7/64, 5/64, 32/64 }, + { -6/64, -6/64, 30/64, 6/64, 6/64, 32/64 }, + { -5/64, -7/64, 30/64, 5/64, 7/64, 32/64 }, + { -3/64, -8/64, 30/64, 3/64, 8/64, 32/64 } +} + +pipeworks.pipe_boxes = {pipeworks.pipe_leftstub, pipeworks.pipe_rightstub, pipeworks.pipe_bottomstub, pipeworks.pipe_topstub, pipeworks.pipe_frontstub, pipeworks.pipe_backstub} + +pipeworks.pipe_selectboxes = { + { -32/64, -8/64, -8/64, 8/64, 8/64, 8/64 }, + { -8/64 , -8/64, -8/64, 32/64, 8/64, 8/64 }, + { -8/64 , -32/64, -8/64, 8/64, 8/64, 8/64 }, + { -8/64 , -8/64, -8/64, 8/64, 32/64, 8/64 }, + { -8/64 , -8/64, -32/64, 8/64, 8/64, 8/64 }, + { -8/64 , -8/64, -8/64, 8/64, 8/64, 32/64 } +} + +pipeworks.pipe_bendsphere = { + { -4/64, -4/64, -4/64, 4/64, 4/64, 4/64 }, + { -5/64, -3/64, -3/64, 5/64, 3/64, 3/64 }, + { -3/64, -5/64, -3/64, 3/64, 5/64, 3/64 }, + { -3/64, -3/64, -5/64, 3/64, 3/64, 5/64 } +} + +-- Tube models + +pipeworks.tube_leftstub = { + { -32/64, -9/64, -9/64, 9/64, 9/64, 9/64 }, -- tube segment against -X face +} + +pipeworks.tube_rightstub = { + { -9/64, -9/64, -9/64, 32/64, 9/64, 9/64 }, -- tube segment against +X face +} + +pipeworks.tube_bottomstub = { + { -9/64, -32/64, -9/64, 9/64, 9/64, 9/64 }, -- tube segment against -Y face +} + +pipeworks.tube_topstub = { + { -9/64, -9/64, -9/64, 9/64, 32/64, 9/64 }, -- tube segment against +Y face +} + +pipeworks.tube_frontstub = { + { -9/64, -9/64, -32/64, 9/64, 9/64, 9/64 }, -- tube segment against -Z face +} + +pipeworks.tube_backstub = { + { -9/64, -9/64, -9/64, 9/64, 9/64, 32/64 }, -- tube segment against -Z face +} + +pipeworks.tube_boxes = {pipeworks.tube_leftstub, pipeworks.tube_rightstub, pipeworks.tube_bottomstub, pipeworks.tube_topstub, pipeworks.tube_frontstub, pipeworks.tube_backstub} + +pipeworks.tube_selectboxes = { + { -32/64, -10/64, -10/64, 10/64, 10/64, 10/64 }, + { -10/64 , -10/64, -10/64, 32/64, 10/64, 10/64 }, + { -10/64 , -32/64, -10/64, 10/64, 10/64, 10/64 }, + { -10/64 , -10/64, -10/64, 10/64, 32/64, 10/64 }, + { -10/64 , -10/64, -32/64, 10/64, 10/64, 10/64 }, + { -10/64 , -10/64, -10/64, 10/64, 10/64, 32/64 } +} + +-- Device models + +pipeworks.pipe_pumpbody = { + { -7/16, -6/16, -7/16, 7/16, 5/16, 7/16 }, + { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 } +} + +pipeworks.pipe_valvebody = { + { -4/16, -4/16, -4/16, 4/16, 4/16, 4/16 } +} + +pipeworks.pipe_valvehandle_on = { + { -5/16, 4/16, -1/16, 0, 5/16, 1/16 } +} + +pipeworks.pipe_valvehandle_off = { + { -1/16, 4/16, -5/16, 1/16, 5/16, 0 } +} + +pipeworks.pipe_sensorbody = { + { -3/16, -2/16, -2/16, 3/16, 2/16, 2/16 } +} + +pipeworks.spigot_bottomstub = { + { -2/64, -16/64, -6/64, 2/64, 1/64, 6/64 }, -- pipe segment against -Y face + { -4/64, -16/64, -5/64, 4/64, 1/64, 5/64 }, + { -5/64, -16/64, -4/64, 5/64, 1/64, 4/64 }, + { -6/64, -16/64, -2/64, 6/64, 1/64, 2/64 }, + + { -3/64, -16/64, -8/64, 3/64, -14/64, 8/64 }, -- (the flange for it) + { -5/64, -16/64, -7/64, 5/64, -14/64, 7/64 }, + { -6/64, -16/64, -6/64, 6/64, -14/64, 6/64 }, + { -7/64, -16/64, -5/64, 7/64, -14/64, 5/64 }, + { -8/64, -16/64, -3/64, 8/64, -14/64, 3/64 } +} + +pipeworks.spigot_stream = { + { -3/64, (-41/64)-0.01, -5/64, 3/64, -16/64, 5/64 }, + { -4/64, (-41/64)-0.01, -4/64, 4/64, -16/64, 4/64 }, + { -5/64, (-41/64)-0.01, -3/64, 5/64, -16/64, 3/64 } +} + +pipeworks.entry_panel = { + { -8/16, -8/16, -1/16, 8/16, 8/16, 1/16 } +} + +pipeworks.fountainhead_model = { + { -2/64, -32/64, -6/64, 2/64, 21/64, 6/64 }, -- main segment + { -4/64, -32/64, -5/64, 4/64, 21/64, 5/64 }, + { -5/64, -32/64, -4/64, 5/64, 21/64, 4/64 }, + { -6/64, -32/64, -2/64, 6/64, 21/64, 2/64 }, + + { -3/64, -32/64, -8/64, 3/64, -30/64, 8/64 }, -- bottom flange + { -5/64, -32/64, -7/64, 5/64, -30/64, 7/64 }, + { -6/64, -32/64, -6/64, 6/64, -30/64, 6/64 }, + { -7/64, -32/64, -5/64, 7/64, -30/64, 5/64 }, + { -8/64, -32/64, -3/64, 8/64, -30/64, 3/64 }, + + { -3/64, 20/64, -8/64, 3/64, 32/64, 8/64 }, -- top flange/outlet + { -5/64, 20/64, -7/64, 5/64, 32/64, 7/64 }, + { -6/64, 20/64, -6/64, 6/64, 32/64, 6/64 }, + { -7/64, 20/64, -5/64, 7/64, 32/64, 5/64 }, + { -8/64, 20/64, -3/64, 8/64, 32/64, 3/64 } +} diff --git a/mods/pipeworks/pipes.lua b/mods/pipeworks/pipes.lua new file mode 100644 index 0000000..ad79a3e --- /dev/null +++ b/mods/pipeworks/pipes.lua @@ -0,0 +1,226 @@ +-- This file supplies the steel pipes + +local REGISTER_COMPATIBILITY = true + +local pipes_empty_nodenames = {} +local pipes_full_nodenames = {} + +local vti = {4, 3, 2, 1, 6, 5} +local cconnects = {{}, {1}, {1, 2}, {1, 3}, {1, 3, 5}, {1, 2, 3}, {1, 2, 3, 5}, {1, 2, 3, 4}, {1, 2, 3, 4, 5}, {1, 2, 3, 4, 5, 6}} +for index, connects in ipairs(cconnects) do + local outboxes = {} + local outsel = {} + local outimgs = {} + + for i = 1, 6 do + outimgs[vti[i]] = "pipeworks_plain.png" + end + + local jx = 0 + local jy = 0 + local jz = 0 + for _, v in ipairs(connects) do + if v == 1 or v == 2 then + jx = jx + 1 + elseif v == 3 or v == 4 then + jy = jy + 1 + else + jz = jz + 1 + end + pipeworks.add_node_box(outboxes, pipeworks.pipe_boxes[v]) + table.insert(outsel, pipeworks.pipe_selectboxes[v]) + outimgs[vti[v]] = "pipeworks_pipe_end.png" + end + + if #connects == 1 then + local v = connects[1] + v = v-1 + 2*(v%2) -- Opposite side + outimgs[vti[v]] = "^pipeworks_plain.png" + end + + if #connects >= 2 then + pipeworks.add_node_box(outboxes, pipeworks.pipe_bendsphere) + end + + if jx == 2 and jy ~= 2 and jz ~= 2 then + outimgs[5] = pipeworks.liquid_texture.."^pipeworks_windowed_XXXXX.png" + outimgs[6] = outimgs[5] + end + + local pgroups = {snappy = 3, pipe = 1, not_in_creative_inventory = 1} + local pipedesc = "Pipe segement".." "..dump(connects).."... You hacker, you." + local image = nil + + if #connects == 0 then + pgroups = {snappy = 3, tube = 1} + pipedesc = "Pipe segment" + image = "pipeworks_pipe_inv.png" + end + + --table.insert(pipeworks.tubenodes, name.."_"..tname) + + minetest.register_node("pipeworks:pipe_"..index.."_empty", { + description = pipedesc, + drawtype = "nodebox", + tiles = pipeworks.fix_image_names(outimgs, "_empty"), + sunlight_propagates = true, + inventory_image = image, + wield_image = image, + paramtype = "light", + paramtype2 = "facedir", + selection_box = { + type = "fixed", + fixed = outsel + }, + node_box = { + type = "fixed", + fixed = outboxes + }, + groups = pgroups, + sounds = default.node_sound_wood_defaults(), + walkable = true, + drop = "pipeworks:pipe_1_empty", + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end + }) + + local pgroups = {snappy = 3, pipe = 1, not_in_creative_inventory = 1} + + minetest.register_node("pipeworks:pipe_"..index.."_loaded", { + description = pipedesc, + drawtype = "nodebox", + tiles = pipeworks.fix_image_names(outimgs, "_loaded"), + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + selection_box = { + type = "fixed", + fixed = outsel + }, + node_box = { + type = "fixed", + fixed = outboxes + }, + groups = pgroups, + sounds = default.node_sound_wood_defaults(), + walkable = true, + drop = "pipeworks:pipe_1_empty", + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end + }) + + table.insert(pipes_empty_nodenames, "pipeworks:pipe_"..index.."_empty") + table.insert(pipes_full_nodenames, "pipeworks:pipe_"..index.."_loaded") +end + + + +if REGISTER_COMPATIBILITY then + local cempty = "pipeworks:pipe_compatibility_empty" + local cloaded = "pipeworks:pipe_compatibility_loaded" + minetest.register_node(cempty, { + drawtype = "airlike", + sunlight_propagates = true, + paramtype = "light", + inventory_image = "pipeworks_pipe_inv.png", + wield_image = "pipeworks_pipe_inv.png", + description = "Pipe Segment (legacy)", + groups = {not_in_creative_inventory = 1, pipe_to_update = 1}, + drop = "pipeworks:pipe_1_empty", + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + }) + minetest.register_node(cloaded, { + drawtype = "airlike", + sunlight_propagates = true, + paramtype = "light", + inventory_image = "pipeworks_pipe_inv.png", + groups = {not_in_creative_inventory = 1, pipe_to_update = 1}, + drop = "pipeworks:pipe_1_empty", + after_place_node = function(pos) + pipeworks.scan_for_pipe_objects(pos) + end, + }) + for xm = 0, 1 do + for xp = 0, 1 do + for ym = 0, 1 do + for yp = 0, 1 do + for zm = 0, 1 do + for zp = 0, 1 do + local pname = xm..xp..ym..yp..zm..zp + minetest.register_alias("pipeworks:pipe_"..pname.."_empty", cempty) + minetest.register_alias("pipeworks:pipe_"..pname.."_loaded", cloaded) + end + end + end + end + end + end + minetest.register_abm({ + nodenames = {"group:pipe_to_update"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local minp = {x = pos.x-1, y = pos.y-1, z = pos.z-1} + local maxp = {x = pos.x+1, y = pos.y+1, z = pos.z+1} + if table.getn(minetest.find_nodes_in_area(minp, maxp, "ignore")) == 0 then + pipeworks.scan_for_pipe_objects(pos) + end + end + }) +end + +table.insert(pipes_empty_nodenames,"pipeworks:valve_on_empty") +table.insert(pipes_empty_nodenames,"pipeworks:valve_off_empty") +table.insert(pipes_empty_nodenames,"pipeworks:entry_panel_empty") +table.insert(pipes_empty_nodenames,"pipeworks:flow_sensor_empty") + +table.insert(pipes_full_nodenames,"pipeworks:valve_on_loaded") +table.insert(pipes_full_nodenames,"pipeworks:entry_panel_loaded") +table.insert(pipes_full_nodenames,"pipeworks:flow_sensor_loaded") + +minetest.register_abm({ + nodenames = pipes_empty_nodenames, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + pipeworks.check_for_inflows(pos,node) + end +}) + +minetest.register_abm({ + nodenames = pipes_full_nodenames, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + pipeworks.check_sources(pos,node) + end +}) + +minetest.register_abm({ + nodenames = {"pipeworks:spigot","pipeworks:spigot_pouring"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + pipeworks.spigot_check(pos,node) + end +}) + +minetest.register_abm({ + nodenames = {"pipeworks:fountainhead","pipeworks:fountainhead_pouring"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + pipeworks.fountainhead_check(pos,node) + end +}) + diff --git a/mods/pipeworks/teleport_tube.lua b/mods/pipeworks/teleport_tube.lua new file mode 100644 index 0000000..16985e2 --- /dev/null +++ b/mods/pipeworks/teleport_tube.lua @@ -0,0 +1,181 @@ + +local filename=minetest.get_worldpath() .. "/teleport_tubes" + +local function read_file() + local f = io.open(filename, "r") + if f == nil then return {} end + local t = f:read("*all") + f:close() + if t == "" or t == nil then return {} end + return minetest.deserialize(t) +end + +local function write_file(tbl) + local f = io.open(filename, "w") + f:write(minetest.serialize(tbl)) + f:close() +end + +local function update_pos_in_file(pos) + local tbl=read_file() + for _, val in ipairs(tbl) do + if val.x == pos.x and val.y == pos.y and val.z == pos.z then + local meta = minetest.get_meta(val) + val.channel = meta:get_string("channel") + val.cr = meta:get_int("can_receive") + end + end + write_file(tbl) +end + +local function add_tube_in_file(pos,channel, cr) + local tbl=read_file() + for _,val in ipairs(tbl) do + if val.x==pos.x and val.y==pos.y and val.z==pos.z then + return + end + end + table.insert(tbl,{x=pos.x,y=pos.y,z=pos.z,channel=channel,cr=cr}) + write_file(tbl) +end + +local function remove_tube_in_file(pos) + local tbl = read_file() + local newtbl = {} + for _, val in ipairs(tbl) do + if val.x ~= pos.x or val.y ~= pos.y or val.z ~= pos.z then + table.insert(newtbl, val) + end + end + write_file(newtbl) +end + +local function read_node_with_vm(pos) + local vm = VoxelManip() + local MinEdge, MaxEdge = vm:read_from_map(pos, pos) + local data = vm:get_data() + local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge}) + return minetest.get_name_from_content_id(data[area:index(pos.x, pos.y, pos.z)]) +end + +local function get_tubes_in_file(pos,channel) + local tbl = read_file() + local newtbl = {} + local changed = false + for _, val in ipairs(tbl) do + local meta = minetest.get_meta(val) + local name = read_node_with_vm(val) + local is_loaded = (minetest.get_node_or_nil(val) ~= nil) + local is_teleport_tube = minetest.registered_nodes[name] and minetest.registered_nodes[name].is_teleport_tube + if is_teleport_tube then + if is_loaded and (val.channel ~= meta:get_string("channel") or val.cr ~= meta:get_int("can_receive")) then + val.channel = meta:get_string("channel") + val.cr = meta:get_int("can_receive") + changed = true + end + if val.cr == 1 and val.channel == channel and (val.x ~= pos.x or val.y ~= pos.y or val.z ~= pos.z) then + table.insert(newtbl, val) + end + else + val.to_remove = true + changed = true + end + end + if changed then + local updated = {} + for _, val in ipairs(tbl) do + if not val.to_remove then + table.insert(updated, val) + end + end + write_file(updated) + end + return newtbl +end + +local teleport_noctr_textures={"pipeworks_teleport_tube_noctr.png","pipeworks_teleport_tube_noctr.png","pipeworks_teleport_tube_noctr.png", + "pipeworks_teleport_tube_noctr.png","pipeworks_teleport_tube_noctr.png","pipeworks_teleport_tube_noctr.png"} +local teleport_plain_textures={"pipeworks_teleport_tube_plain.png","pipeworks_teleport_tube_plain.png","pipeworks_teleport_tube_plain.png", + "pipeworks_teleport_tube_plain.png","pipeworks_teleport_tube_plain.png","pipeworks_teleport_tube_plain.png"} +local teleport_end_textures={"pipeworks_teleport_tube_end.png","pipeworks_teleport_tube_end.png","pipeworks_teleport_tube_end.png", + "pipeworks_teleport_tube_end.png","pipeworks_teleport_tube_end.png","pipeworks_teleport_tube_end.png"} +local teleport_short_texture="pipeworks_teleport_tube_short.png" +local teleport_inv_texture="pipeworks_teleport_tube_inv.png" + +local function set_teleport_tube_formspec(meta) + local cr = meta:get_int("can_receive") ~= 0 + meta:set_string("formspec","size[10.5,1;]".. + "field[0,0.5;7,1;channel;Channel:;${channel}]".. + "button[8,0;2.5,1;"..(cr and "cr0" or "cr1")..";".. + (cr and "Send and Receive" or "Send only").."]") +end + +pipeworks.register_tube("pipeworks:teleport_tube","Teleporting Pneumatic Tube Segment",teleport_plain_textures, + teleport_noctr_textures,teleport_end_textures,teleport_short_texture,teleport_inv_texture, { + is_teleport_tube = true, + tube = { + can_go = function(pos,node,velocity,stack) + velocity.x = 0 + velocity.y = 0 + velocity.z = 0 + local meta = minetest.get_meta(pos) + local channel = meta:get_string("channel") + local target = get_tubes_in_file(pos,channel) + if target[1] == nil then return {} end + local d = math.random(1,#target) + pos.x = target[d].x + pos.y = target[d].y + pos.z = target[d].z + return pipeworks.meseadjlist + end + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("channel","") + meta:set_int("can_receive",1) + add_tube_in_file(pos,"") + set_teleport_tube_formspec(meta) + end, + on_receive_fields = function(pos,formname,fields,sender) + local meta = minetest.get_meta(pos) + + --check for private channels + if fields.channel ~= nil then + local name, mode = fields.channel:match("^([^:;]+)([:;])") + if name and mode and name ~= sender:get_player_name() then + + --channels starting with '[name]:' can only be used by the named player + if mode == ":" then + minetest.chat_send_player(sender:get_player_name(), "Sorry, channel '"..fields.channel.."' is reserved for exclusive use by "..name) + return + + --channels starting with '[name];' can be used by other players, but cannot be received from + elseif mode == ";" and (fields.cr1 or (meta:get_int("can_receive") ~= 0 and not fields.cr0)) then + minetest.chat_send_player(sender:get_player_name(), "Sorry, receiving from channel '"..fields.channel.."' is reserved for "..name) + return + end + end + end + + if fields.channel==nil then fields.channel=meta:get_string("channel") end + meta:set_string("channel",fields.channel) + remove_tube_in_file(pos) + if fields.cr0 then meta:set_int("can_receive", 0) end + if fields.cr1 then meta:set_int("can_receive", 1) end + local cr = meta:get_int("can_receive") + add_tube_in_file(pos, fields.channel, meta:get_int("can_receive")) + set_teleport_tube_formspec(meta) + end, + on_destruct = function(pos) + remove_tube_in_file(pos) + end}) + +if minetest.get_modpath("mesecons_mvps") ~= nil then + mesecon:register_on_mvps_move(function(moved_nodes) + for _, n in ipairs(moved_nodes) do + if string.find(n.node.name, "pipeworks:teleport_tube") ~= nil then + update_pos_in_file(n.pos) + end + end + end) +end diff --git a/mods/pipeworks/textures/homedecor_oil_extract.png b/mods/pipeworks/textures/homedecor_oil_extract.png new file mode 100644 index 0000000..ef0f896 Binary files /dev/null and b/mods/pipeworks/textures/homedecor_oil_extract.png differ diff --git a/mods/pipeworks/textures/homedecor_paraffin.png b/mods/pipeworks/textures/homedecor_paraffin.png new file mode 100644 index 0000000..5f98300 Binary files /dev/null and b/mods/pipeworks/textures/homedecor_paraffin.png differ diff --git a/mods/pipeworks/textures/homedecor_plastic_sheeting.png b/mods/pipeworks/textures/homedecor_plastic_sheeting.png new file mode 100644 index 0000000..fea8773 Binary files /dev/null and b/mods/pipeworks/textures/homedecor_plastic_sheeting.png differ diff --git a/mods/pipeworks/textures/pipeworks_accelerator_tube_end.png b/mods/pipeworks/textures/pipeworks_accelerator_tube_end.png new file mode 100644 index 0000000..a3dd09a Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_accelerator_tube_end.png differ diff --git a/mods/pipeworks/textures/pipeworks_accelerator_tube_inv.png b/mods/pipeworks/textures/pipeworks_accelerator_tube_inv.png new file mode 100644 index 0000000..6cc2937 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_accelerator_tube_inv.png differ diff --git a/mods/pipeworks/textures/pipeworks_accelerator_tube_noctr.png b/mods/pipeworks/textures/pipeworks_accelerator_tube_noctr.png new file mode 100644 index 0000000..61a46a3 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_accelerator_tube_noctr.png differ diff --git a/mods/pipeworks/textures/pipeworks_accelerator_tube_plain.png b/mods/pipeworks/textures/pipeworks_accelerator_tube_plain.png new file mode 100644 index 0000000..0baa541 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_accelerator_tube_plain.png differ diff --git a/mods/pipeworks/textures/pipeworks_accelerator_tube_short.png b/mods/pipeworks/textures/pipeworks_accelerator_tube_short.png new file mode 100644 index 0000000..4f389d9 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_accelerator_tube_short.png differ diff --git a/mods/pipeworks/textures/pipeworks_autocrafter.png b/mods/pipeworks/textures/pipeworks_autocrafter.png new file mode 100644 index 0000000..6c7c84d Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_autocrafter.png differ diff --git a/mods/pipeworks/textures/pipeworks_black.png b/mods/pipeworks/textures/pipeworks_black.png new file mode 100644 index 0000000..ada83a4 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_black.png differ diff --git a/mods/pipeworks/textures/pipeworks_blue.png b/mods/pipeworks/textures/pipeworks_blue.png new file mode 100644 index 0000000..c063ae1 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_blue.png differ diff --git a/mods/pipeworks/textures/pipeworks_conductor_tube_end.png b/mods/pipeworks/textures/pipeworks_conductor_tube_end.png new file mode 100644 index 0000000..a0d6915 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_conductor_tube_end.png differ diff --git a/mods/pipeworks/textures/pipeworks_conductor_tube_inv.png b/mods/pipeworks/textures/pipeworks_conductor_tube_inv.png new file mode 100644 index 0000000..5db1153 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_conductor_tube_inv.png differ diff --git a/mods/pipeworks/textures/pipeworks_conductor_tube_noctr.png b/mods/pipeworks/textures/pipeworks_conductor_tube_noctr.png new file mode 100644 index 0000000..cc03245 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_conductor_tube_noctr.png differ diff --git a/mods/pipeworks/textures/pipeworks_conductor_tube_on_end.png b/mods/pipeworks/textures/pipeworks_conductor_tube_on_end.png new file mode 100644 index 0000000..a70d988 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_conductor_tube_on_end.png differ diff --git a/mods/pipeworks/textures/pipeworks_conductor_tube_on_noctr.png b/mods/pipeworks/textures/pipeworks_conductor_tube_on_noctr.png new file mode 100644 index 0000000..30edb60 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_conductor_tube_on_noctr.png differ diff --git a/mods/pipeworks/textures/pipeworks_conductor_tube_on_plain.png b/mods/pipeworks/textures/pipeworks_conductor_tube_on_plain.png new file mode 100644 index 0000000..1aaa15b Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_conductor_tube_on_plain.png differ diff --git a/mods/pipeworks/textures/pipeworks_conductor_tube_plain.png b/mods/pipeworks/textures/pipeworks_conductor_tube_plain.png new file mode 100644 index 0000000..b432dc4 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_conductor_tube_plain.png differ diff --git a/mods/pipeworks/textures/pipeworks_conductor_tube_short.png b/mods/pipeworks/textures/pipeworks_conductor_tube_short.png new file mode 100644 index 0000000..0c4b1d2 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_conductor_tube_short.png differ diff --git a/mods/pipeworks/textures/pipeworks_crossing_tube_end.png b/mods/pipeworks/textures/pipeworks_crossing_tube_end.png new file mode 100644 index 0000000..f708b05 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_crossing_tube_end.png differ diff --git a/mods/pipeworks/textures/pipeworks_crossing_tube_inv.png b/mods/pipeworks/textures/pipeworks_crossing_tube_inv.png new file mode 100644 index 0000000..8f24d1a Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_crossing_tube_inv.png differ diff --git a/mods/pipeworks/textures/pipeworks_crossing_tube_noctr.png b/mods/pipeworks/textures/pipeworks_crossing_tube_noctr.png new file mode 100644 index 0000000..f4a75c9 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_crossing_tube_noctr.png differ diff --git a/mods/pipeworks/textures/pipeworks_crossing_tube_plain.png b/mods/pipeworks/textures/pipeworks_crossing_tube_plain.png new file mode 100644 index 0000000..68d1fc8 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_crossing_tube_plain.png differ diff --git a/mods/pipeworks/textures/pipeworks_crossing_tube_short.png b/mods/pipeworks/textures/pipeworks_crossing_tube_short.png new file mode 100644 index 0000000..1c5e39f Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_crossing_tube_short.png differ diff --git a/mods/pipeworks/textures/pipeworks_deployer_back.png b/mods/pipeworks/textures/pipeworks_deployer_back.png new file mode 100644 index 0000000..2bac175 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_deployer_back.png differ diff --git a/mods/pipeworks/textures/pipeworks_deployer_bottom.png b/mods/pipeworks/textures/pipeworks_deployer_bottom.png new file mode 100644 index 0000000..763a7bd Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_deployer_bottom.png differ diff --git a/mods/pipeworks/textures/pipeworks_deployer_front_off.png b/mods/pipeworks/textures/pipeworks_deployer_front_off.png new file mode 100644 index 0000000..323cdaa Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_deployer_front_off.png differ diff --git a/mods/pipeworks/textures/pipeworks_deployer_front_on.png b/mods/pipeworks/textures/pipeworks_deployer_front_on.png new file mode 100644 index 0000000..38caed6 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_deployer_front_on.png differ diff --git a/mods/pipeworks/textures/pipeworks_deployer_side.png b/mods/pipeworks/textures/pipeworks_deployer_side.png new file mode 100644 index 0000000..f3ede41 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_deployer_side.png differ diff --git a/mods/pipeworks/textures/pipeworks_deployer_side1.png b/mods/pipeworks/textures/pipeworks_deployer_side1.png new file mode 100644 index 0000000..f3ede41 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_deployer_side1.png differ diff --git a/mods/pipeworks/textures/pipeworks_deployer_side2.png b/mods/pipeworks/textures/pipeworks_deployer_side2.png new file mode 100644 index 0000000..0b31eec Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_deployer_side2.png differ diff --git a/mods/pipeworks/textures/pipeworks_deployer_top.png b/mods/pipeworks/textures/pipeworks_deployer_top.png new file mode 100644 index 0000000..1a78cc9 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_deployer_top.png differ diff --git a/mods/pipeworks/textures/pipeworks_detector_tube_end.png b/mods/pipeworks/textures/pipeworks_detector_tube_end.png new file mode 100644 index 0000000..ef0d5fe Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_detector_tube_end.png differ diff --git a/mods/pipeworks/textures/pipeworks_detector_tube_inv.png b/mods/pipeworks/textures/pipeworks_detector_tube_inv.png new file mode 100644 index 0000000..b6cadb9 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_detector_tube_inv.png differ diff --git a/mods/pipeworks/textures/pipeworks_detector_tube_noctr.png b/mods/pipeworks/textures/pipeworks_detector_tube_noctr.png new file mode 100644 index 0000000..c415d77 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_detector_tube_noctr.png differ diff --git a/mods/pipeworks/textures/pipeworks_detector_tube_plain.png b/mods/pipeworks/textures/pipeworks_detector_tube_plain.png new file mode 100644 index 0000000..d99cddc Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_detector_tube_plain.png differ diff --git a/mods/pipeworks/textures/pipeworks_detector_tube_short.png b/mods/pipeworks/textures/pipeworks_detector_tube_short.png new file mode 100644 index 0000000..ad5e034 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_detector_tube_short.png differ diff --git a/mods/pipeworks/textures/pipeworks_dispenser_back.png b/mods/pipeworks/textures/pipeworks_dispenser_back.png new file mode 100644 index 0000000..f4fade2 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_dispenser_back.png differ diff --git a/mods/pipeworks/textures/pipeworks_dispenser_bottom.png b/mods/pipeworks/textures/pipeworks_dispenser_bottom.png new file mode 100644 index 0000000..35416de Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_dispenser_bottom.png differ diff --git a/mods/pipeworks/textures/pipeworks_dispenser_front_off.png b/mods/pipeworks/textures/pipeworks_dispenser_front_off.png new file mode 100644 index 0000000..4fc0017 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_dispenser_front_off.png differ diff --git a/mods/pipeworks/textures/pipeworks_dispenser_front_on.png b/mods/pipeworks/textures/pipeworks_dispenser_front_on.png new file mode 100644 index 0000000..36f7f0b Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_dispenser_front_on.png differ diff --git a/mods/pipeworks/textures/pipeworks_dispenser_side1.png b/mods/pipeworks/textures/pipeworks_dispenser_side1.png new file mode 100644 index 0000000..56e8973 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_dispenser_side1.png differ diff --git a/mods/pipeworks/textures/pipeworks_dispenser_side2.png b/mods/pipeworks/textures/pipeworks_dispenser_side2.png new file mode 100644 index 0000000..8f306b2 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_dispenser_side2.png differ diff --git a/mods/pipeworks/textures/pipeworks_dispenser_top.png b/mods/pipeworks/textures/pipeworks_dispenser_top.png new file mode 100644 index 0000000..8d6f9d0 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_dispenser_top.png differ diff --git a/mods/pipeworks/textures/pipeworks_filter_input.png b/mods/pipeworks/textures/pipeworks_filter_input.png new file mode 100644 index 0000000..e57a5ec Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_filter_input.png differ diff --git a/mods/pipeworks/textures/pipeworks_filter_output.png b/mods/pipeworks/textures/pipeworks_filter_output.png new file mode 100644 index 0000000..e0ae622 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_filter_output.png differ diff --git a/mods/pipeworks/textures/pipeworks_filter_side.png b/mods/pipeworks/textures/pipeworks_filter_side.png new file mode 100644 index 0000000..6645948 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_filter_side.png differ diff --git a/mods/pipeworks/textures/pipeworks_filter_top.png b/mods/pipeworks/textures/pipeworks_filter_top.png new file mode 100644 index 0000000..c1c130c Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_filter_top.png differ diff --git a/mods/pipeworks/textures/pipeworks_fountainhead_top.png b/mods/pipeworks/textures/pipeworks_fountainhead_top.png new file mode 100644 index 0000000..503d051 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_fountainhead_top.png differ diff --git a/mods/pipeworks/textures/pipeworks_grating_sides.png b/mods/pipeworks/textures/pipeworks_grating_sides.png new file mode 100644 index 0000000..615965b Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_grating_sides.png differ diff --git a/mods/pipeworks/textures/pipeworks_grating_top.png b/mods/pipeworks/textures/pipeworks_grating_top.png new file mode 100644 index 0000000..7219861 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_grating_top.png differ diff --git a/mods/pipeworks/textures/pipeworks_green.png b/mods/pipeworks/textures/pipeworks_green.png new file mode 100644 index 0000000..2e4939d Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_green.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_filter_input.png b/mods/pipeworks/textures/pipeworks_mese_filter_input.png new file mode 100644 index 0000000..d0353a7 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_filter_input.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_filter_output.png b/mods/pipeworks/textures/pipeworks_mese_filter_output.png new file mode 100644 index 0000000..35db0fe Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_filter_output.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_filter_side.png b/mods/pipeworks/textures/pipeworks_mese_filter_side.png new file mode 100644 index 0000000..f2793b1 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_filter_side.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_filter_top.png b/mods/pipeworks/textures/pipeworks_mese_filter_top.png new file mode 100644 index 0000000..7b8e2b1 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_filter_top.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_sand_tube_end.png b/mods/pipeworks/textures/pipeworks_mese_sand_tube_end.png new file mode 100644 index 0000000..b044d73 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_sand_tube_end.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_sand_tube_inv.png b/mods/pipeworks/textures/pipeworks_mese_sand_tube_inv.png new file mode 100644 index 0000000..8829422 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_sand_tube_inv.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_sand_tube_noctr.png b/mods/pipeworks/textures/pipeworks_mese_sand_tube_noctr.png new file mode 100644 index 0000000..9e41bc8 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_sand_tube_noctr.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_sand_tube_plain.png b/mods/pipeworks/textures/pipeworks_mese_sand_tube_plain.png new file mode 100644 index 0000000..ff0a107 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_sand_tube_plain.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_sand_tube_short.png b/mods/pipeworks/textures/pipeworks_mese_sand_tube_short.png new file mode 100644 index 0000000..2defd5d Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_sand_tube_short.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_end.png b/mods/pipeworks/textures/pipeworks_mese_tube_end.png new file mode 100644 index 0000000..e4b677d Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_end.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_inv.png b/mods/pipeworks/textures/pipeworks_mese_tube_inv.png new file mode 100644 index 0000000..123d9f7 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_inv.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_noctr_1.png b/mods/pipeworks/textures/pipeworks_mese_tube_noctr_1.png new file mode 100644 index 0000000..da29b06 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_noctr_1.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_noctr_2.png b/mods/pipeworks/textures/pipeworks_mese_tube_noctr_2.png new file mode 100644 index 0000000..1f37163 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_noctr_2.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_noctr_3.png b/mods/pipeworks/textures/pipeworks_mese_tube_noctr_3.png new file mode 100644 index 0000000..1371ce7 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_noctr_3.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_noctr_4.png b/mods/pipeworks/textures/pipeworks_mese_tube_noctr_4.png new file mode 100644 index 0000000..bca7439 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_noctr_4.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_noctr_5.png b/mods/pipeworks/textures/pipeworks_mese_tube_noctr_5.png new file mode 100644 index 0000000..2cc44d4 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_noctr_5.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_noctr_6.png b/mods/pipeworks/textures/pipeworks_mese_tube_noctr_6.png new file mode 100644 index 0000000..d93213d Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_noctr_6.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_plain_1.png b/mods/pipeworks/textures/pipeworks_mese_tube_plain_1.png new file mode 100644 index 0000000..517f5a4 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_plain_1.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_plain_2.png b/mods/pipeworks/textures/pipeworks_mese_tube_plain_2.png new file mode 100644 index 0000000..6323492 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_plain_2.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_plain_3.png b/mods/pipeworks/textures/pipeworks_mese_tube_plain_3.png new file mode 100644 index 0000000..c7af0cf Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_plain_3.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_plain_4.png b/mods/pipeworks/textures/pipeworks_mese_tube_plain_4.png new file mode 100644 index 0000000..bc19da2 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_plain_4.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_plain_5.png b/mods/pipeworks/textures/pipeworks_mese_tube_plain_5.png new file mode 100644 index 0000000..f781787 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_plain_5.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_plain_6.png b/mods/pipeworks/textures/pipeworks_mese_tube_plain_6.png new file mode 100644 index 0000000..efd85a5 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_plain_6.png differ diff --git a/mods/pipeworks/textures/pipeworks_mese_tube_short.png b/mods/pipeworks/textures/pipeworks_mese_tube_short.png new file mode 100644 index 0000000..fae64c4 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_mese_tube_short.png differ diff --git a/mods/pipeworks/textures/pipeworks_nodebreaker_back.png b/mods/pipeworks/textures/pipeworks_nodebreaker_back.png new file mode 100644 index 0000000..6337d40 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_nodebreaker_back.png differ diff --git a/mods/pipeworks/textures/pipeworks_nodebreaker_bottom_off.png b/mods/pipeworks/textures/pipeworks_nodebreaker_bottom_off.png new file mode 100644 index 0000000..133be48 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_nodebreaker_bottom_off.png differ diff --git a/mods/pipeworks/textures/pipeworks_nodebreaker_bottom_on.png b/mods/pipeworks/textures/pipeworks_nodebreaker_bottom_on.png new file mode 100644 index 0000000..b21c261 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_nodebreaker_bottom_on.png differ diff --git a/mods/pipeworks/textures/pipeworks_nodebreaker_front_off.png b/mods/pipeworks/textures/pipeworks_nodebreaker_front_off.png new file mode 100644 index 0000000..cab8bf9 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_nodebreaker_front_off.png differ diff --git a/mods/pipeworks/textures/pipeworks_nodebreaker_front_on.png b/mods/pipeworks/textures/pipeworks_nodebreaker_front_on.png new file mode 100644 index 0000000..82ebd3a Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_nodebreaker_front_on.png differ diff --git a/mods/pipeworks/textures/pipeworks_nodebreaker_side1_off.png b/mods/pipeworks/textures/pipeworks_nodebreaker_side1_off.png new file mode 100644 index 0000000..ec0a00f Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_nodebreaker_side1_off.png differ diff --git a/mods/pipeworks/textures/pipeworks_nodebreaker_side1_on.png b/mods/pipeworks/textures/pipeworks_nodebreaker_side1_on.png new file mode 100644 index 0000000..9dace63 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_nodebreaker_side1_on.png differ diff --git a/mods/pipeworks/textures/pipeworks_nodebreaker_side2_off.png b/mods/pipeworks/textures/pipeworks_nodebreaker_side2_off.png new file mode 100644 index 0000000..8320646 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_nodebreaker_side2_off.png differ diff --git a/mods/pipeworks/textures/pipeworks_nodebreaker_side2_on.png b/mods/pipeworks/textures/pipeworks_nodebreaker_side2_on.png new file mode 100644 index 0000000..467a1fc Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_nodebreaker_side2_on.png differ diff --git a/mods/pipeworks/textures/pipeworks_nodebreaker_top_off.png b/mods/pipeworks/textures/pipeworks_nodebreaker_top_off.png new file mode 100644 index 0000000..8e5a1cd Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_nodebreaker_top_off.png differ diff --git a/mods/pipeworks/textures/pipeworks_nodebreaker_top_on.png b/mods/pipeworks/textures/pipeworks_nodebreaker_top_on.png new file mode 100644 index 0000000..8fca471 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_nodebreaker_top_on.png differ diff --git a/mods/pipeworks/textures/pipeworks_one_way_tube_input.png b/mods/pipeworks/textures/pipeworks_one_way_tube_input.png new file mode 100644 index 0000000..3968c0d Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_one_way_tube_input.png differ diff --git a/mods/pipeworks/textures/pipeworks_one_way_tube_output.png b/mods/pipeworks/textures/pipeworks_one_way_tube_output.png new file mode 100644 index 0000000..7dc5910 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_one_way_tube_output.png differ diff --git a/mods/pipeworks/textures/pipeworks_one_way_tube_side.png b/mods/pipeworks/textures/pipeworks_one_way_tube_side.png new file mode 100644 index 0000000..044e4f4 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_one_way_tube_side.png differ diff --git a/mods/pipeworks/textures/pipeworks_one_way_tube_top.png b/mods/pipeworks/textures/pipeworks_one_way_tube_top.png new file mode 100644 index 0000000..bb54e45 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_one_way_tube_top.png differ diff --git a/mods/pipeworks/textures/pipeworks_pipe_end.png b/mods/pipeworks/textures/pipeworks_pipe_end.png new file mode 100644 index 0000000..3b64478 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_pipe_end.png differ diff --git a/mods/pipeworks/textures/pipeworks_pipe_end_empty.png b/mods/pipeworks/textures/pipeworks_pipe_end_empty.png new file mode 100644 index 0000000..0e647be Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_pipe_end_empty.png differ diff --git a/mods/pipeworks/textures/pipeworks_pipe_end_loaded.png b/mods/pipeworks/textures/pipeworks_pipe_end_loaded.png new file mode 100644 index 0000000..0a5bece Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_pipe_end_loaded.png differ diff --git a/mods/pipeworks/textures/pipeworks_pipe_inv.png b/mods/pipeworks/textures/pipeworks_pipe_inv.png new file mode 100644 index 0000000..567b771 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_pipe_inv.png differ diff --git a/mods/pipeworks/textures/pipeworks_plain.png b/mods/pipeworks/textures/pipeworks_plain.png new file mode 100644 index 0000000..48af08f Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_plain.png differ diff --git a/mods/pipeworks/textures/pipeworks_plastic_sheeting.png b/mods/pipeworks/textures/pipeworks_plastic_sheeting.png new file mode 100644 index 0000000..1386b19 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_plastic_sheeting.png differ diff --git a/mods/pipeworks/textures/pipeworks_pump_bottom.png b/mods/pipeworks/textures/pipeworks_pump_bottom.png new file mode 100644 index 0000000..615965b Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_pump_bottom.png differ diff --git a/mods/pipeworks/textures/pipeworks_pump_off.png b/mods/pipeworks/textures/pipeworks_pump_off.png new file mode 100644 index 0000000..0b640c9 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_pump_off.png differ diff --git a/mods/pipeworks/textures/pipeworks_pump_on.png b/mods/pipeworks/textures/pipeworks_pump_on.png new file mode 100644 index 0000000..5cdca6b Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_pump_on.png differ diff --git a/mods/pipeworks/textures/pipeworks_pump_sides.png b/mods/pipeworks/textures/pipeworks_pump_sides.png new file mode 100644 index 0000000..11b6c64 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_pump_sides.png differ diff --git a/mods/pipeworks/textures/pipeworks_pump_top.png b/mods/pipeworks/textures/pipeworks_pump_top.png new file mode 100644 index 0000000..0271e8f Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_pump_top.png differ diff --git a/mods/pipeworks/textures/pipeworks_red.png b/mods/pipeworks/textures/pipeworks_red.png new file mode 100644 index 0000000..05ccc05 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_red.png differ diff --git a/mods/pipeworks/textures/pipeworks_sand_tube_end.png b/mods/pipeworks/textures/pipeworks_sand_tube_end.png new file mode 100644 index 0000000..3c4db02 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_sand_tube_end.png differ diff --git a/mods/pipeworks/textures/pipeworks_sand_tube_inv.png b/mods/pipeworks/textures/pipeworks_sand_tube_inv.png new file mode 100644 index 0000000..e1c46b9 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_sand_tube_inv.png differ diff --git a/mods/pipeworks/textures/pipeworks_sand_tube_noctr.png b/mods/pipeworks/textures/pipeworks_sand_tube_noctr.png new file mode 100644 index 0000000..cbb3a09 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_sand_tube_noctr.png differ diff --git a/mods/pipeworks/textures/pipeworks_sand_tube_plain.png b/mods/pipeworks/textures/pipeworks_sand_tube_plain.png new file mode 100644 index 0000000..71deecc Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_sand_tube_plain.png differ diff --git a/mods/pipeworks/textures/pipeworks_sand_tube_short.png b/mods/pipeworks/textures/pipeworks_sand_tube_short.png new file mode 100644 index 0000000..9cfc124 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_sand_tube_short.png differ diff --git a/mods/pipeworks/textures/pipeworks_sensor_sides_on.png b/mods/pipeworks/textures/pipeworks_sensor_sides_on.png new file mode 100644 index 0000000..3551191 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_sensor_sides_on.png differ diff --git a/mods/pipeworks/textures/pipeworks_spigot_bottom2.png b/mods/pipeworks/textures/pipeworks_spigot_bottom2.png new file mode 100644 index 0000000..86b9696 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_spigot_bottom2.png differ diff --git a/mods/pipeworks/textures/pipeworks_spigot_sides.png b/mods/pipeworks/textures/pipeworks_spigot_sides.png new file mode 100644 index 0000000..f9898e6 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_spigot_sides.png differ diff --git a/mods/pipeworks/textures/pipeworks_spigot_sides2.png b/mods/pipeworks/textures/pipeworks_spigot_sides2.png new file mode 100644 index 0000000..e385700 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_spigot_sides2.png differ diff --git a/mods/pipeworks/textures/pipeworks_storage_tank_back.png b/mods/pipeworks/textures/pipeworks_storage_tank_back.png new file mode 100644 index 0000000..cf7f245 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_storage_tank_back.png differ diff --git a/mods/pipeworks/textures/pipeworks_storage_tank_fittings.png b/mods/pipeworks/textures/pipeworks_storage_tank_fittings.png new file mode 100644 index 0000000..d694fad Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_storage_tank_fittings.png differ diff --git a/mods/pipeworks/textures/pipeworks_storage_tank_front_0.png b/mods/pipeworks/textures/pipeworks_storage_tank_front_0.png new file mode 100644 index 0000000..c91466f Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_storage_tank_front_0.png differ diff --git a/mods/pipeworks/textures/pipeworks_storage_tank_front_1.png b/mods/pipeworks/textures/pipeworks_storage_tank_front_1.png new file mode 100644 index 0000000..6656834 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_storage_tank_front_1.png differ diff --git a/mods/pipeworks/textures/pipeworks_storage_tank_front_10.png b/mods/pipeworks/textures/pipeworks_storage_tank_front_10.png new file mode 100644 index 0000000..6456afe Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_storage_tank_front_10.png differ diff --git a/mods/pipeworks/textures/pipeworks_storage_tank_front_2.png b/mods/pipeworks/textures/pipeworks_storage_tank_front_2.png new file mode 100644 index 0000000..89a4412 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_storage_tank_front_2.png differ diff --git a/mods/pipeworks/textures/pipeworks_storage_tank_front_3.png b/mods/pipeworks/textures/pipeworks_storage_tank_front_3.png new file mode 100644 index 0000000..d237dd5 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_storage_tank_front_3.png differ diff --git a/mods/pipeworks/textures/pipeworks_storage_tank_front_4.png b/mods/pipeworks/textures/pipeworks_storage_tank_front_4.png new file mode 100644 index 0000000..25e43d3 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_storage_tank_front_4.png differ diff --git a/mods/pipeworks/textures/pipeworks_storage_tank_front_5.png b/mods/pipeworks/textures/pipeworks_storage_tank_front_5.png new file mode 100644 index 0000000..f51d113 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_storage_tank_front_5.png differ diff --git a/mods/pipeworks/textures/pipeworks_storage_tank_front_6.png b/mods/pipeworks/textures/pipeworks_storage_tank_front_6.png new file mode 100644 index 0000000..c21115e Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_storage_tank_front_6.png differ diff --git a/mods/pipeworks/textures/pipeworks_storage_tank_front_7.png b/mods/pipeworks/textures/pipeworks_storage_tank_front_7.png new file mode 100644 index 0000000..aa7c665 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_storage_tank_front_7.png differ diff --git a/mods/pipeworks/textures/pipeworks_storage_tank_front_8.png b/mods/pipeworks/textures/pipeworks_storage_tank_front_8.png new file mode 100644 index 0000000..5598e59 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_storage_tank_front_8.png differ diff --git a/mods/pipeworks/textures/pipeworks_storage_tank_front_9.png b/mods/pipeworks/textures/pipeworks_storage_tank_front_9.png new file mode 100644 index 0000000..b0f750d Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_storage_tank_front_9.png differ diff --git a/mods/pipeworks/textures/pipeworks_teleport_tube_end.png b/mods/pipeworks/textures/pipeworks_teleport_tube_end.png new file mode 100644 index 0000000..d3df799 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_teleport_tube_end.png differ diff --git a/mods/pipeworks/textures/pipeworks_teleport_tube_inv.png b/mods/pipeworks/textures/pipeworks_teleport_tube_inv.png new file mode 100644 index 0000000..653afbb Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_teleport_tube_inv.png differ diff --git a/mods/pipeworks/textures/pipeworks_teleport_tube_noctr.png b/mods/pipeworks/textures/pipeworks_teleport_tube_noctr.png new file mode 100644 index 0000000..3d10b41 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_teleport_tube_noctr.png differ diff --git a/mods/pipeworks/textures/pipeworks_teleport_tube_plain.png b/mods/pipeworks/textures/pipeworks_teleport_tube_plain.png new file mode 100644 index 0000000..23a793d Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_teleport_tube_plain.png differ diff --git a/mods/pipeworks/textures/pipeworks_teleport_tube_short.png b/mods/pipeworks/textures/pipeworks_teleport_tube_short.png new file mode 100644 index 0000000..e0a15b9 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_teleport_tube_short.png differ diff --git a/mods/pipeworks/textures/pipeworks_testobject.png b/mods/pipeworks/textures/pipeworks_testobject.png new file mode 100644 index 0000000..2c67561 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_testobject.png differ diff --git a/mods/pipeworks/textures/pipeworks_trashcan_bottom.png b/mods/pipeworks/textures/pipeworks_trashcan_bottom.png new file mode 100644 index 0000000..a50c789 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_trashcan_bottom.png differ diff --git a/mods/pipeworks/textures/pipeworks_trashcan_side.png b/mods/pipeworks/textures/pipeworks_trashcan_side.png new file mode 100644 index 0000000..7b081bf Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_trashcan_side.png differ diff --git a/mods/pipeworks/textures/pipeworks_tube_connection_metallic.png b/mods/pipeworks/textures/pipeworks_tube_connection_metallic.png new file mode 100644 index 0000000..86a74c6 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_tube_connection_metallic.png differ diff --git a/mods/pipeworks/textures/pipeworks_tube_connection_stony.png b/mods/pipeworks/textures/pipeworks_tube_connection_stony.png new file mode 100644 index 0000000..1e72d81 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_tube_connection_stony.png differ diff --git a/mods/pipeworks/textures/pipeworks_tube_connection_wooden.png b/mods/pipeworks/textures/pipeworks_tube_connection_wooden.png new file mode 100644 index 0000000..c20cd7d Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_tube_connection_wooden.png differ diff --git a/mods/pipeworks/textures/pipeworks_tube_end.png b/mods/pipeworks/textures/pipeworks_tube_end.png new file mode 100644 index 0000000..ef0d5fe Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_tube_end.png differ diff --git a/mods/pipeworks/textures/pipeworks_tube_inv.png b/mods/pipeworks/textures/pipeworks_tube_inv.png new file mode 100644 index 0000000..d24d61c Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_tube_inv.png differ diff --git a/mods/pipeworks/textures/pipeworks_tube_noctr.png b/mods/pipeworks/textures/pipeworks_tube_noctr.png new file mode 100644 index 0000000..c415d77 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_tube_noctr.png differ diff --git a/mods/pipeworks/textures/pipeworks_tube_plain.png b/mods/pipeworks/textures/pipeworks_tube_plain.png new file mode 100644 index 0000000..a5022d8 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_tube_plain.png differ diff --git a/mods/pipeworks/textures/pipeworks_tube_short.png b/mods/pipeworks/textures/pipeworks_tube_short.png new file mode 100644 index 0000000..ad5e034 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_tube_short.png differ diff --git a/mods/pipeworks/textures/pipeworks_tube_transparent.png b/mods/pipeworks/textures/pipeworks_tube_transparent.png new file mode 100644 index 0000000..10e8907 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_tube_transparent.png differ diff --git a/mods/pipeworks/textures/pipeworks_valvebody_bottom.png b/mods/pipeworks/textures/pipeworks_valvebody_bottom.png new file mode 100644 index 0000000..43d30d5 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_valvebody_bottom.png differ diff --git a/mods/pipeworks/textures/pipeworks_valvebody_ends.png b/mods/pipeworks/textures/pipeworks_valvebody_ends.png new file mode 100644 index 0000000..69a615f Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_valvebody_ends.png differ diff --git a/mods/pipeworks/textures/pipeworks_valvebody_sides.png b/mods/pipeworks/textures/pipeworks_valvebody_sides.png new file mode 100644 index 0000000..47e80ea Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_valvebody_sides.png differ diff --git a/mods/pipeworks/textures/pipeworks_valvebody_top_off.png b/mods/pipeworks/textures/pipeworks_valvebody_top_off.png new file mode 100644 index 0000000..0587e79 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_valvebody_top_off.png differ diff --git a/mods/pipeworks/textures/pipeworks_valvebody_top_on.png b/mods/pipeworks/textures/pipeworks_valvebody_top_on.png new file mode 100644 index 0000000..320c7e4 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_valvebody_top_on.png differ diff --git a/mods/pipeworks/textures/pipeworks_white.png b/mods/pipeworks/textures/pipeworks_white.png new file mode 100644 index 0000000..64386eb Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_white.png differ diff --git a/mods/pipeworks/textures/pipeworks_windowed_empty.png b/mods/pipeworks/textures/pipeworks_windowed_empty.png new file mode 100644 index 0000000..3b64478 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_windowed_empty.png differ diff --git a/mods/pipeworks/textures/pipeworks_windowed_loaded.png b/mods/pipeworks/textures/pipeworks_windowed_loaded.png new file mode 100644 index 0000000..0a5bece Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_windowed_loaded.png differ diff --git a/mods/pipeworks/textures/pipeworks_yellow.png b/mods/pipeworks/textures/pipeworks_yellow.png new file mode 100644 index 0000000..44ea445 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_yellow.png differ diff --git a/mods/pipeworks/trashcan.lua b/mods/pipeworks/trashcan.lua new file mode 100644 index 0000000..fdec79f --- /dev/null +++ b/mods/pipeworks/trashcan.lua @@ -0,0 +1,49 @@ +minetest.register_node("pipeworks:trashcan", { + description = "Trash Can", + drawtype = "normal", + tiles = { + "pipeworks_trashcan_bottom.png", + "pipeworks_trashcan_bottom.png", + "pipeworks_trashcan_side.png", + "pipeworks_trashcan_side.png", + "pipeworks_trashcan_side.png", + "pipeworks_trashcan_side.png", + }, + groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1}, + tube = { + insert_object = function(pos, node, stack, direction) + return ItemStack("") + end, + connect_sides = {left = 1, right = 1, front = 1, back = 1, top = 1, bottom = 1}, + priority = 1, -- Lower than anything else + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", + "size[8,7]".. + "item_image[0,0;1,1;pipeworks:trashcan]".. + "label[1,0;Trash Can]".. + "list[current_name;trash;3.5,1;1,1;]".. + "list[current_player;main;0,3;8,4;]") + meta:set_string("infotext", "Trash Can") + meta:get_inventory():set_size("trash", 1) + end, + after_place_node = function(pos) + pipeworks.scan_for_tube_objects(pos) + end, + after_dig_node = function(pos) + pipeworks.scan_for_tube_objects(pos) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.get_meta(pos):get_inventory():set_stack(listname, index, ItemStack("")) + end, +}) + +minetest.register_craft({ + output = "pipeworks:trashcan", + recipe = { + { "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }, + { "default:steel_ingot", "", "default:steel_ingot" }, + { "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" }, + }, +}) diff --git a/mods/pipeworks/tubes.lua b/mods/pipeworks/tubes.lua new file mode 100755 index 0000000..2822a10 --- /dev/null +++ b/mods/pipeworks/tubes.lua @@ -0,0 +1,594 @@ +-- This file supplies the various kinds of pneumatic tubes + +pipeworks.tubenodes = {} + +minetest.register_alias("pipeworks:tube", "pipeworks:tube_000000") + +-- now, a function to define the tubes + +local REGISTER_COMPATIBILITY = true + +local vti = {4, 3, 2, 1, 6, 5} + +local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, ends, short, inv, special, connects, style) + local outboxes = {} + local outsel = {} + local outimgs = {} + + for i = 1, 6 do + outimgs[vti[i]] = plain[i] + end + + for _, v in ipairs(connects) do + table.extend(outboxes, pipeworks.tube_boxes[v]) + table.insert(outsel, pipeworks.tube_selectboxes[v]) + outimgs[vti[v]] = noctrs[v] + end + + if #connects == 1 then + local v = connects[1] + v = v-1 + 2*(v%2) -- Opposite side + outimgs[vti[v]] = ends[v] + end + + local tgroups = {snappy = 3, tube = 1, tubedevice = 1, not_in_creative_inventory = 1} + local tubedesc = desc.." "..dump(connects).."... You hacker, you." + local iimg = plain[1] + local wscale = {x = 1, y = 1, z = 1} + + if #connects == 0 then + tgroups = {snappy = 3, tube = 1, tubedevice = 1} + tubedesc = desc + iimg=inv + outimgs = { + short, short, + ends[3],ends[4], + short, short + } + outboxes = { -24/64, -9/64, -9/64, 24/64, 9/64, 9/64 } + outsel = { -24/64, -10/64, -10/64, 24/64, 10/64, 10/64 } + wscale = {x = 1, y = 1, z = 0.01} + end + + local rname = name.."_"..tname + table.insert(pipeworks.tubenodes, rname) + + local nodedef = { + description = tubedesc, + drawtype = "nodebox", + tiles = outimgs, + sunlight_propagates = true, + inventory_image = iimg, + wield_image = iimg, + wield_scale = wscale, + paramtype = "light", + selection_box = { + type = "fixed", + fixed = outsel + }, + node_box = { + type = "fixed", + fixed = outboxes + }, + groups = tgroups, + sounds = default.node_sound_wood_defaults(), + walkable = true, + stack_max = 99, + basename = name, + style = style, + drop = name.."_"..dropname, + tubelike = 1, + tube = { + connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1}, + priority = 50 + }, + --[[after_place_node = function(pos) + pipeworks.scan_for_tube_objects(pos) + if minetest.registered_nodes[rname].after_place_node_ then + minetest.registered_nodes[rname].after_place_node_(pos) + end + end, + after_dig_node = function(pos) + pipeworks.scan_for_tube_objects(pos) + if minetest.registered_nodes[rname].after_dig_node_ then + minetest.registered_nodes[rname].after_dig_node_(pos) + end + end]] + } + if style == "6d" then + nodedef.paramtype2 = "facedir" + end + + if special == nil then special = {} end + + for key, value in pairs(special) do + --if key == "after_dig_node" or key == "after_place_node" then + -- nodedef[key.."_"] = value + if key == "groups" then + for group, val in pairs(value) do + nodedef.groups[group] = val + end + elseif key == "tube" then + for key, val in pairs(value) do + nodedef.tube[key] = val + end + else + nodedef[key] = table.recursive_replace(value, "#id", tname) + end + end + + minetest.register_node(rname, nodedef) +end + +pipeworks.register_tube = function(name, desc, plain, noctrs, ends, short, inv, special, old_registration) + if old_registration then + for xm = 0, 1 do + for xp = 0, 1 do + for ym = 0, 1 do + for yp = 0, 1 do + for zm = 0, 1 do + for zp = 0, 1 do + local connects = {} + if xm == 1 then + connects[#connects+1] = 1 + end + if xp == 1 then + connects[#connects+1] = 2 + end + if ym == 1 then + connects[#connects+1] = 3 + end + if yp == 1 then + connects[#connects+1] = 4 + end + if zm == 1 then + connects[#connects+1] = 5 + end + if zp == 1 then + connects[#connects+1] = 6 + end + local tname = xm..xp..ym..yp..zm..zp + register_one_tube(name, tname, "000000", desc, plain, noctrs, ends, short, inv, special, connects, "old") + end + end + end + end + end + end + else + -- 6d tubes: uses only 10 nodes instead of 64, but the textures must be rotated + local cconnects = {{}, {1}, {1, 2}, {1, 3}, {1, 3, 5}, {1, 2, 3}, {1, 2, 3, 5}, {1, 2, 3, 4}, {1, 2, 3, 4, 5}, {1, 2, 3, 4, 5, 6}} + for index, connects in ipairs(cconnects) do + register_one_tube(name, tostring(index), "1", desc, plain, noctrs, ends, short, inv, special, connects, "6d") + end + if REGISTER_COMPATIBILITY then + local cname = name.."_compatibility" + minetest.register_node(cname, { + drawtype = "airlike", + style = "6d", + basename = name, + inventory_image = inv, + wield_image = inv, + paramtype = "light", + sunlight_propagates = true, + description = "Pneumatic tube segment (legacy)", + --[[after_place_node = function(pos) + pipeworks.scan_for_tube_objects(pos) + if minetest.registered_nodes[name.."_1"].after_place_node_ then + minetest.registered_nodes[name.."_1"].after_place_node_(pos) + end + end,]] + groups = {not_in_creative_inventory = 1, tube_to_update = 1, tube = 1}, + tube = {connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1}}, + drop = name.."_1", + }) + table.insert(pipeworks.tubenodes, cname) + for xm = 0, 1 do + for xp = 0, 1 do + for ym = 0, 1 do + for yp = 0, 1 do + for zm = 0, 1 do + for zp = 0, 1 do + local tname = xm..xp..ym..yp..zm..zp + minetest.register_alias(name.."_"..tname, cname) + end + end + end + end + end + end + end + end +end + +if REGISTER_COMPATIBILITY then + minetest.register_abm({ + nodenames = {"group:tube_to_update"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local minp = vector.subtract(pos, 1) + local maxp = vector.add(pos, 1) + if table.getn(minetest.find_nodes_in_area(minp, maxp, "ignore")) == 0 then + pipeworks.scan_for_tube_objects(pos) + end + end + }) +end + +-- now let's actually call that function to get the real work done! + +local noctr_textures = {"pipeworks_tube_noctr.png", "pipeworks_tube_noctr.png", "pipeworks_tube_noctr.png", + "pipeworks_tube_noctr.png", "pipeworks_tube_noctr.png", "pipeworks_tube_noctr.png"} +local plain_textures = {"pipeworks_tube_plain.png", "pipeworks_tube_plain.png", "pipeworks_tube_plain.png", + "pipeworks_tube_plain.png", "pipeworks_tube_plain.png", "pipeworks_tube_plain.png"} +local end_textures = {"pipeworks_tube_end.png", "pipeworks_tube_end.png", "pipeworks_tube_end.png", + "pipeworks_tube_end.png", "pipeworks_tube_end.png", "pipeworks_tube_end.png"} +local short_texture = "pipeworks_tube_short.png" +local inv_texture = "pipeworks_tube_inv.png" + +pipeworks.register_tube("pipeworks:tube", "Pneumatic tube segment", plain_textures, noctr_textures, end_textures, short_texture, inv_texture) + +if pipeworks.enable_mese_tube then + local mese_noctr_textures = {"pipeworks_mese_tube_noctr_1.png", "pipeworks_mese_tube_noctr_2.png", "pipeworks_mese_tube_noctr_3.png", + "pipeworks_mese_tube_noctr_4.png", "pipeworks_mese_tube_noctr_5.png", "pipeworks_mese_tube_noctr_6.png"} + local mese_plain_textures = {"pipeworks_mese_tube_plain_1.png", "pipeworks_mese_tube_plain_2.png", "pipeworks_mese_tube_plain_3.png", + "pipeworks_mese_tube_plain_4.png", "pipeworks_mese_tube_plain_5.png", "pipeworks_mese_tube_plain_6.png"} + local mese_end_textures = {"pipeworks_mese_tube_end.png", "pipeworks_mese_tube_end.png", "pipeworks_mese_tube_end.png", + "pipeworks_mese_tube_end.png", "pipeworks_mese_tube_end.png", "pipeworks_mese_tube_end.png"} + local mese_short_texture = "pipeworks_mese_tube_short.png" + local mese_inv_texture = "pipeworks_mese_tube_inv.png" + local function update_formspec(pos) + local meta = minetest.get_meta(pos) + local old_formspec = meta:get_string("formspec") + if string.find(old_formspec, "button1") then -- Old version + local inv = meta:get_inventory() + for i = 1, 6 do + for _, stack in ipairs(inv:get_list("line"..i)) do + minetest.item_drop(stack, "", pos) + end + end + end + meta:set_string("formspec", + "size[8,11]".. + "list[current_name;line1;1,0;6,1;]".. + "list[current_name;line2;1,1;6,1;]".. + "list[current_name;line3;1,2;6,1;]".. + "list[current_name;line4;1,3;6,1;]".. + "list[current_name;line5;1,4;6,1;]".. + "list[current_name;line6;1,5;6,1;]".. + "image[0,0;1,1;pipeworks_white.png]".. + "image[0,1;1,1;pipeworks_black.png]".. + "image[0,2;1,1;pipeworks_green.png]".. + "image[0,3;1,1;pipeworks_yellow.png]".. + "image[0,4;1,1;pipeworks_blue.png]".. + "image[0,5;1,1;pipeworks_red.png]".. + fs_helpers.cycling_button(meta, "button[7,0;1,1", "l1s", {"Off", "On"}).. + fs_helpers.cycling_button(meta, "button[7,1;1,1", "l2s", {"Off", "On"}).. + fs_helpers.cycling_button(meta, "button[7,2;1,1", "l3s", {"Off", "On"}).. + fs_helpers.cycling_button(meta, "button[7,3;1,1", "l4s", {"Off", "On"}).. + fs_helpers.cycling_button(meta, "button[7,4;1,1", "l5s", {"Off", "On"}).. + fs_helpers.cycling_button(meta, "button[7,5;1,1", "l6s", {"Off", "On"}).. + "list[current_player;main;0,7;8,4;]") + end + pipeworks.register_tube("pipeworks:mese_tube", "Sorting Pneumatic Tube Segment", mese_plain_textures, mese_noctr_textures, + mese_end_textures, mese_short_texture, mese_inv_texture, + {tube = {can_go = function(pos, node, velocity, stack) + local tbl = {} + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local found = false + local name = stack:get_name() + for i, vect in ipairs(pipeworks.meseadjlist) do + if meta:get_int("l"..tostring(i).."s") == 1 then + for _, st in ipairs(inv:get_list("line"..tostring(i))) do + if st:get_name() == name then + found = true + table.insert(tbl, vect) + break + end + end + end + end + if found == false then + for i, vect in ipairs(pipeworks.meseadjlist) do + if meta:get_int("l"..tostring(i).."s") == 1 then + if inv:is_empty("line"..tostring(i)) then + table.insert(tbl, vect) + end + end + end + end + return tbl + end}, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + for i = 1, 6 do + meta:set_int("l"..tostring(i).."s", 1) + inv:set_size("line"..tostring(i), 6*1) + end + update_formspec(pos) + meta:set_string("infotext", "Mese pneumatic tube") + end, + on_punch = update_formspec, + on_receive_fields = function(pos, formname, fields, sender) + fs_helpers.on_receive_fields(pos, fields) + update_formspec(pos) + end, + can_dig = function(pos, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return (inv:is_empty("line1") and inv:is_empty("line2") and inv:is_empty("line3") and + inv:is_empty("line4") and inv:is_empty("line5") and inv:is_empty("line6")) + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + update_formspec(pos) -- For old tubes + local inv = minetest.get_meta(pos):get_inventory() + local stack_copy = ItemStack(stack) + stack_copy:set_count(1) + inv:set_stack(listname, index, stack_copy) + return 0 + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + update_formspec(pos) -- For old tubes + local inv = minetest.get_meta(pos):get_inventory() + inv:set_stack(listname, index, ItemStack("")) + return 0 + end, + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + update_formspec(pos) -- For old tubes + local inv = minetest.get_meta(pos):get_inventory() + inv:set_stack(from_list, from_index, ItemStack("")) + return 0 + end, + }, true) -- Must use old tubes, since the textures are rotated with 6d ones +end + +if pipeworks.enable_detector_tube then + local detector_plain_textures = {"pipeworks_detector_tube_plain.png", "pipeworks_detector_tube_plain.png", "pipeworks_detector_tube_plain.png", + "pipeworks_detector_tube_plain.png", "pipeworks_detector_tube_plain.png", "pipeworks_detector_tube_plain.png"} + local detector_inv_texture = "pipeworks_detector_tube_inv.png" + local detector_tube_step = 2 * tonumber(minetest.setting_get("dedicated_server_step")) + pipeworks.register_tube("pipeworks:detector_tube_on", "Detecting Pneumatic Tube Segment on (you hacker you)", detector_plain_textures, noctr_textures, + end_textures, short_texture, detector_inv_texture, + {tube = {can_go = function(pos, node, velocity, stack) + local meta = minetest.get_meta(pos) + local name = minetest.get_node(pos).name + local nitems = meta:get_int("nitems")+1 + meta:set_int("nitems", nitems) + local saved_pos = vector.new(pos) + minetest.after(detector_tube_step, minetest.registered_nodes[name].item_exit, saved_pos) + return pipeworks.notvel(pipeworks.meseadjlist,velocity) + end}, + groups = {mesecon = 2, not_in_creative_inventory = 1}, + drop = "pipeworks:detector_tube_off_1", + mesecons = {receptor = {state = "on", + rules = pipeworks.mesecons_rules}}, + item_exit = function(pos) + local meta = minetest.get_meta(pos) + local nitems = meta:get_int("nitems")-1 + local node = minetest.get_node(pos) + local name = node.name + local fdir = node.param2 + if nitems == 0 then + minetest.set_node(pos, {name = string.gsub(name, "on", "off"), param2 = fdir}) + mesecon:receptor_off(pos, pipeworks.mesecons_rules) + else + meta:set_int("nitems", nitems) + end + end, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_int("nitems", 1) + local name = minetest.get_node(pos).name + local saved_pos = vector.new(pos) + minetest.after(detector_tube_step, minetest.registered_nodes[name].item_exit, saved_pos) + + end + }) + pipeworks.register_tube("pipeworks:detector_tube_off", "Detecting Pneumatic Tube Segment", detector_plain_textures, noctr_textures, + end_textures, short_texture, detector_inv_texture, + {tube = {can_go = function(pos, node, velocity, stack) + local node = minetest.get_node(pos) + local name = node.name + local fdir = node.param2 + minetest.set_node(pos,{name = string.gsub(name, "off", "on"), param2 = fdir}) + mesecon:receptor_on(pos, pipeworks.mesecons_rules) + return pipeworks.notvel(pipeworks.meseadjlist, velocity) + end}, + groups = {mesecon = 2}, + mesecons = {receptor = {state = "off", + rules = pipeworks.mesecons_rules}} + }) +end + +if pipeworks.enable_conductor_tube then + local conductor_plain_textures = {"pipeworks_conductor_tube_plain.png", "pipeworks_conductor_tube_plain.png", "pipeworks_conductor_tube_plain.png", + "pipeworks_conductor_tube_plain.png", "pipeworks_conductor_tube_plain.png", "pipeworks_conductor_tube_plain.png"} + local conductor_noctr_textures = {"pipeworks_conductor_tube_noctr.png", "pipeworks_conductor_tube_noctr.png", "pipeworks_conductor_tube_noctr.png", + "pipeworks_conductor_tube_noctr.png", "pipeworks_conductor_tube_noctr.png", "pipeworks_conductor_tube_noctr.png"} + local conductor_end_textures = {"pipeworks_conductor_tube_end.png", "pipeworks_conductor_tube_end.png", "pipeworks_conductor_tube_end.png", + "pipeworks_conductor_tube_end.png", "pipeworks_conductor_tube_end.png", "pipeworks_conductor_tube_end.png"} + local conductor_short_texture = "pipeworks_conductor_tube_short.png" + local conductor_inv_texture = "pipeworks_conductor_tube_inv.png" + + local conductor_on_plain_textures = {"pipeworks_conductor_tube_on_plain.png", "pipeworks_conductor_tube_on_plain.png", "pipeworks_conductor_tube_on_plain.png", + "pipeworks_conductor_tube_on_plain.png", "pipeworks_conductor_tube_on_plain.png", "pipeworks_conductor_tube_on_plain.png"} + local conductor_on_noctr_textures = {"pipeworks_conductor_tube_on_noctr.png", "pipeworks_conductor_tube_on_noctr.png", "pipeworks_conductor_tube_on_noctr.png", + "pipeworks_conductor_tube_on_noctr.png", "pipeworks_conductor_tube_on_noctr.png", "pipeworks_conductor_tube_on_noctr.png"} + local conductor_on_end_textures = {"pipeworks_conductor_tube_on_end.png", "pipeworks_conductor_tube_on_end.png", "pipeworks_conductor_tube_on_end.png", + "pipeworks_conductor_tube_on_end.png", "pipeworks_conductor_tube_on_end.png", "pipeworks_conductor_tube_on_end.png"} + + pipeworks.register_tube("pipeworks:conductor_tube_off", "Conducting Pneumatic Tube Segment", conductor_plain_textures, conductor_noctr_textures, + conductor_end_textures, conductor_short_texture, conductor_inv_texture, + {groups = {mesecon = 2}, + mesecons = {conductor = {state = "off", + rules = pipeworks.mesecons_rules, + onstate = "pipeworks:conductor_tube_on_#id"}} + }) + + pipeworks.register_tube("pipeworks:conductor_tube_on", "Conducting Pneumatic Tube Segment on (you hacker you)", conductor_on_plain_textures, conductor_on_noctr_textures, + conductor_on_end_textures, conductor_short_texture, conductor_inv_texture, + {groups = {mesecon = 2, not_in_creative_inventory = 1}, + drop = "pipeworks:conductor_tube_off_1", + mesecons = {conductor = {state = "on", + rules = pipeworks.mesecons_rules, + offstate = "pipeworks:conductor_tube_off_#id"}} + }) +end + +if pipeworks.enable_accelerator_tube then + local accelerator_noctr_textures = {"pipeworks_accelerator_tube_noctr.png", "pipeworks_accelerator_tube_noctr.png", "pipeworks_accelerator_tube_noctr.png", + "pipeworks_accelerator_tube_noctr.png", "pipeworks_accelerator_tube_noctr.png", "pipeworks_accelerator_tube_noctr.png"} + local accelerator_plain_textures = {"pipeworks_accelerator_tube_plain.png" ,"pipeworks_accelerator_tube_plain.png", "pipeworks_accelerator_tube_plain.png", + "pipeworks_accelerator_tube_plain.png", "pipeworks_accelerator_tube_plain.png", "pipeworks_accelerator_tube_plain.png"} + local accelerator_end_textures = {"pipeworks_accelerator_tube_end.png", "pipeworks_accelerator_tube_end.png", "pipeworks_accelerator_tube_end.png", + "pipeworks_accelerator_tube_end.png", "pipeworks_accelerator_tube_end.png", "pipeworks_accelerator_tube_end.png"} + local accelerator_short_texture = "pipeworks_accelerator_tube_short.png" + local accelerator_inv_texture = "pipeworks_accelerator_tube_inv.png" + + pipeworks.register_tube("pipeworks:accelerator_tube", "Accelerating Pneumatic Tube Segment", accelerator_plain_textures, + accelerator_noctr_textures, accelerator_end_textures, accelerator_short_texture, accelerator_inv_texture, + {tube = {can_go = function(pos, node, velocity, stack) + velocity.speed = velocity.speed+1 + return pipeworks.notvel(pipeworks.meseadjlist, velocity) + end} + }) +end + +if pipeworks.enable_crossing_tube then + local crossing_noctr_textures = {"pipeworks_crossing_tube_noctr.png", "pipeworks_crossing_tube_noctr.png", "pipeworks_crossing_tube_noctr.png", + "pipeworks_crossing_tube_noctr.png", "pipeworks_crossing_tube_noctr.png", "pipeworks_crossing_tube_noctr.png"} + local crossing_plain_textures = {"pipeworks_crossing_tube_plain.png" ,"pipeworks_crossing_tube_plain.png", "pipeworks_crossing_tube_plain.png", + "pipeworks_crossing_tube_plain.png", "pipeworks_crossing_tube_plain.png", "pipeworks_crossing_tube_plain.png"} + local crossing_end_textures = {"pipeworks_crossing_tube_end.png", "pipeworks_crossing_tube_end.png", "pipeworks_crossing_tube_end.png", + "pipeworks_crossing_tube_end.png", "pipeworks_crossing_tube_end.png", "pipeworks_crossing_tube_end.png"} + local crossing_short_texture = "pipeworks_crossing_tube_short.png" + local crossing_inv_texture = "pipeworks_crossing_tube_inv.png" + + pipeworks.register_tube("pipeworks:crossing_tube", "Crossing Pneumatic Tube Segment", crossing_plain_textures, + crossing_noctr_textures, crossing_end_textures, crossing_short_texture, crossing_inv_texture, + {tube = {can_go = function(pos, node, velocity, stack) + return {velocity} + end} + }) +end + +if pipeworks.enable_sand_tube then + local sand_noctr_textures = {"pipeworks_sand_tube_noctr.png", "pipeworks_sand_tube_noctr.png", "pipeworks_sand_tube_noctr.png", + "pipeworks_sand_tube_noctr.png", "pipeworks_sand_tube_noctr.png", "pipeworks_sand_tube_noctr.png"} + local sand_plain_textures = {"pipeworks_sand_tube_plain.png", "pipeworks_sand_tube_plain.png", "pipeworks_sand_tube_plain.png", + "pipeworks_sand_tube_plain.png", "pipeworks_sand_tube_plain.png", "pipeworks_sand_tube_plain.png"} + local sand_end_textures = {"pipeworks_sand_tube_end.png", "pipeworks_sand_tube_end.png", "pipeworks_sand_tube_end.png", + "pipeworks_sand_tube_end.png", "pipeworks_sand_tube_end.png", "pipeworks_sand_tube_end.png"} + local sand_short_texture = "pipeworks_sand_tube_short.png" + local sand_inv_texture = "pipeworks_sand_tube_inv.png" + + pipeworks.register_tube("pipeworks:sand_tube", "Vacuuming Pneumatic Tube Segment", sand_plain_textures, sand_noctr_textures, sand_end_textures, + sand_short_texture, sand_inv_texture, + {groups = {sand_tube = 1}}) + + minetest.register_abm({nodenames = {"group:sand_tube"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + for _, object in ipairs(minetest.get_objects_inside_radius(pos, 2)) do + if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then + if object:get_luaentity().itemstring ~= "" then + pipeworks.tube_inject_item(pos, pos, vector.new(0, 0, 0), object:get_luaentity().itemstring) + end + object:get_luaentity().itemstring = "" + object:remove() + end + end + end + }) +end + +if pipeworks.enable_mese_sand_tube then + local mese_sand_noctr_textures = {"pipeworks_mese_sand_tube_noctr.png", "pipeworks_mese_sand_tube_noctr.png", "pipeworks_mese_sand_tube_noctr.png", + "pipeworks_mese_sand_tube_noctr.png", "pipeworks_mese_sand_tube_noctr.png", "pipeworks_mese_sand_tube_noctr.png"} + local mese_sand_plain_textures = {"pipeworks_mese_sand_tube_plain.png", "pipeworks_mese_sand_tube_plain.png", "pipeworks_mese_sand_tube_plain.png", + "pipeworks_mese_sand_tube_plain.png", "pipeworks_mese_sand_tube_plain.png", "pipeworks_mese_sand_tube_plain.png"} + local mese_sand_end_textures = {"pipeworks_mese_sand_tube_end.png", "pipeworks_mese_sand_tube_end.png", "pipeworks_mese_sand_tube_end.png", + "pipeworks_mese_sand_tube_end.png", "pipeworks_mese_sand_tube_end.png", "pipeworks_mese_sand_tube_end.png"} + local mese_sand_short_texture = "pipeworks_mese_sand_tube_short.png" + local mese_sand_inv_texture = "pipeworks_mese_sand_tube_inv.png" + + pipeworks.register_tube("pipeworks:mese_sand_tube", "Adjustable Vacuuming Pneumatic Tube Segment", mese_sand_plain_textures, mese_sand_noctr_textures, + mese_sand_end_textures, mese_sand_short_texture,mese_sand_inv_texture, + {groups = {mese_sand_tube = 1}, + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_int("dist", 0) + meta:set_string("formspec", + "size[2,1]".. + "field[.5,.5;1.5,1;dist;distance;${dist}]") + meta:set_string("infotext", "Adjustable Vacuuming Pneumatic Tube Segment") + end, + on_receive_fields = function(pos,formname,fields,sender) + local meta = minetest.env:get_meta(pos) + local dist + _, dist = pcall(tonumber, fields.dist) + if dist and 0 <= dist and dist <= 8 then meta:set_int("dist", dist) end + end, + }) + + local function get_objects_with_square_radius(pos, rad) + rad = rad + .5; + local objs = {} + for _,object in ipairs(minetest.env:get_objects_inside_radius(pos, math.sqrt(3)*rad)) do + if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then + local opos = object:getpos() + if pos.x - rad <= opos.x and opos.x <= pos.x + rad and pos.y - rad <= opos.y and opos.y <= pos.y + rad and pos.z - rad <= opos.z and opos.z <= pos.z + rad then + objs[#objs + 1] = object + end + end + end + return objs + end + + minetest.register_abm({nodenames = {"group:mese_sand_tube"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + for _,object in ipairs(get_objects_with_square_radius(pos, minetest.env:get_meta(pos):get_int("dist"))) do + if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then + if object:get_luaentity().itemstring ~= "" then + pipeworks.tube_inject_item(pos, pos, vector.new(0, 0, 0), object:get_luaentity().itemstring) + end + object:get_luaentity().itemstring = "" + object:remove() + end + end + end + }) +end + +if pipeworks.enable_one_way_tube then + minetest.register_node("pipeworks:one_way_tube", { + description = "One way tube", + tiles = {"pipeworks_one_way_tube_top.png", "pipeworks_one_way_tube_top.png", "pipeworks_one_way_tube_output.png", + "pipeworks_one_way_tube_input.png", "pipeworks_one_way_tube_side.png", "pipeworks_one_way_tube_top.png"}, + paramtype2 = "facedir", + drawtype = "nodebox", + paramtype = "light", + node_box = {type = "fixed", + fixed = {{-1/2, -9/64, -9/64, 1/2, 9/64, 9/64}}}, + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, tubedevice = 1}, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + tube = { + connect_sides = {left = 1, right = 1}, + can_go = function(pos, node, velocity, stack) + return {velocity} + end, + can_insert = function(pos, node, stack, direction) + local dir = minetest.facedir_to_right_dir(node.param2) + return vector.equals(dir, direction) + end, + priority = 75 -- Higher than normal tubes, but lower than receivers + }, + }) +end diff --git a/mods/pipeworks/wielder.lua b/mods/pipeworks/wielder.lua new file mode 100644 index 0000000..3ce73f6 --- /dev/null +++ b/mods/pipeworks/wielder.lua @@ -0,0 +1,423 @@ +local assumed_eye_pos = vector.new(0, 1.5, 0) + +local function vector_copy(v) + return { x = v.x, y = v.y, z = v.z } +end + +local function delay(x) + return (function() return x end) +end + +local function set_wielder_formspec(data, meta) + meta:set_string("formspec", + "invsize[8,"..(6+data.wield_inv_height)..";]".. + "item_image[0,0;1,1;"..data.name_base.."_off]".. + "label[1,0;"..minetest.formspec_escape(data.description).."]".. + "list[current_name;"..minetest.formspec_escape(data.wield_inv_name)..";"..((8-data.wield_inv_width)*0.5)..",1;"..data.wield_inv_width..","..data.wield_inv_height..";]".. + "list[current_player;main;0,"..(2+data.wield_inv_height)..";8,4;]") + meta:set_string("infotext", data.description) +end + +local function wielder_on(data, wielder_pos, wielder_node) + data.fixup_node(wielder_pos, wielder_node) + if wielder_node.name ~= data.name_base.."_off" then return end + wielder_node.name = data.name_base.."_on" + minetest.swap_node(wielder_pos, wielder_node) + nodeupdate(wielder_pos) + local wielder_meta = minetest.get_meta(wielder_pos) + local inv = wielder_meta:get_inventory() + local wield_inv_name = data.wield_inv_name + local wieldindex, wieldstack + for i, stack in ipairs(inv:get_list(wield_inv_name)) do + if not stack:is_empty() then + wieldindex = i + wieldstack = stack + break + end + end + if not wieldindex then + if not data.ghost_inv_name then return end + wield_inv_name = data.ghost_inv_name + inv:set_stack(wield_inv_name, 1, ItemStack(data.ghost_tool)) + wieldindex = 1 + wieldstack = inv:get_stack(wield_inv_name, 1) + end + local dir = minetest.facedir_to_dir(wielder_node.param2) + local under_pos = vector.subtract(wielder_pos, dir) + local above_pos = vector.subtract(under_pos, dir) + local pitch + local yaw + if dir.z < 0 then + yaw = 0 + pitch = 0 + elseif dir.z > 0 then + yaw = math.pi + pitch = 0 + elseif dir.x < 0 then + yaw = 3*math.pi/2 + pitch = 0 + elseif dir.x > 0 then + yaw = math.pi/2 + pitch = 0 + elseif dir.y > 0 then + yaw = 0 + pitch = -math.pi/2 + else + yaw = 0 + pitch = math.pi/2 + end + local virtplayer = { + get_inventory_formspec = delay(wielder_meta:get_string("formspec")), + get_look_dir = delay(vector.multiply(dir, -1)), + get_look_pitch = delay(pitch), + get_look_yaw = delay(yaw), + get_player_control = delay({ jump=false, right=false, left=false, LMB=false, RMB=false, sneak=data.sneak, aux1=false, down=false, up=false }), + get_player_control_bits = delay(data.sneak and 64 or 0), + get_player_name = delay(data.masquerade_as_owner and wielder_meta:get_string("owner") or ":pipeworks:"..minetest.pos_to_string(wielder_pos)), + is_player = delay(true), + is_fake_player = true, + set_inventory_formspec = delay(), + getpos = delay(vector.subtract(wielder_pos, assumed_eye_pos)), + get_hp = delay(20), + get_inventory = delay(inv), + get_wielded_item = delay(wieldstack), + get_wield_index = delay(wieldindex), + get_wield_list = delay(wield_inv_name), + moveto = delay(), + punch = delay(), + remove = delay(), + right_click = delay(), + setpos = delay(), + set_hp = delay(), + set_properties = delay(), + set_wielded_item = function(self, item) inv:set_stack(wield_inv_name, wieldindex, item) end, + set_animation = delay(), + set_attach = delay(), + set_detach = delay(), + set_bone_position = delay(), + } + local pointed_thing = { type="node", under=under_pos, above=above_pos } + data.act(virtplayer, pointed_thing) + if data.eject_drops then + for i, stack in ipairs(inv:get_list("main")) do + if not stack:is_empty() then + pipeworks.tube_inject_item(wielder_pos, wielder_pos, dir, stack) + inv:set_stack("main", i, ItemStack("")) + end + end + end +end + +local function wielder_off(data, pos, node) + if node.name == data.name_base.."_on" then + node.name = data.name_base.."_off" + minetest.swap_node(pos, node) + nodeupdate(pos) + end +end + +local function register_wielder(data) + data.fixup_node = data.fixup_node or function (pos, node) end + data.fixup_oldmetadata = data.fixup_oldmetadata or function (m) return m end + for _, state in ipairs({ "off", "on" }) do + local groups = { snappy=2, choppy=2, oddly_breakable_by_hand=2, mesecon=2, tubedevice=1, tubedevice_receiver=1 } + if state == "on" then groups.not_in_creative_inventory = 1 end + local tile_images = {} + for _, face in ipairs({ "top", "bottom", "side2", "side1", "back", "front" }) do + table.insert(tile_images, data.texture_base.."_"..face..(data.texture_stateful[face] and "_"..state or "")..".png") + end + minetest.register_node(data.name_base.."_"..state, { + description = data.description, + tile_images = tile_images, + mesecons = { + effector = { + rules = pipeworks.rules_all, + action_on = function (pos, node) + wielder_on(data, pos, node) + end, + action_off = function (pos, node) + wielder_off(data, pos, node) + end, + }, + }, + tube = { + can_insert = function(pos, node, stack, tubedir) + if not data.tube_permit_anteroposterior_insert then + local nodedir = minetest.facedir_to_dir(node.param2) + if vector.equals(tubedir, nodedir) or vector.equals(tubedir, vector.multiply(nodedir, -1)) then + return false + end + end + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:room_for_item(data.wield_inv_name, stack) + end, + insert_object = function(pos, node, stack, tubedir) + if not data.tube_permit_anteroposterior_insert then + local nodedir = minetest.facedir_to_dir(node.param2) + if vector.equals(tubedir, nodedir) or vector.equals(tubedir, vector.multiply(nodedir, -1)) then + return stack + end + end + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:add_item(data.wield_inv_name, stack) + end, + input_inventory = data.wield_inv_name, + connect_sides = data.tube_connect_sides, + can_remove = function(pos, node, stack, tubedir) + return stack:get_count() + end, + }, + is_ground_content = true, + paramtype2 = "facedir", + tubelike = 1, + groups = groups, + sounds = default.node_sound_stone_defaults(), + drop = data.name_base.."_off", + on_construct = function(pos) + local meta = minetest.get_meta(pos) + set_wielder_formspec(data, meta) + local inv = meta:get_inventory() + inv:set_size(data.wield_inv_name, data.wield_inv_width*data.wield_inv_height) + if data.ghost_inv_name then + inv:set_size(data.ghost_inv_name, 1) + end + if data.eject_drops then + inv:set_size("main", 100) + end + end, + after_place_node = function (pos, placer) + pipeworks.scan_for_tube_objects(pos) + local placer_pos = placer:getpos() + if placer_pos and placer:is_player() then placer_pos = vector.add(placer_pos, assumed_eye_pos) end + if placer_pos then + local dir = vector.subtract(pos, placer_pos) + local node = minetest.get_node(pos) + node.param2 = minetest.dir_to_facedir(dir, true) + minetest.set_node(pos, node) + minetest.log("action", "real (6d) facedir: " .. node.param2) + end + minetest.get_meta(pos):set_string("owner", placer:get_player_name()) + end, + can_dig = (data.can_dig_nonempty_wield_inv and delay(true) or function(pos, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:is_empty(data.wield_inv_name) + end), + after_dig_node = function(pos, oldnode, oldmetadata, digger) + -- The legacy-node fixup is done here in a + -- different form from the standard fixup, + -- rather than relying on a standard fixup + -- in an on_dig callback, because some + -- non-standard diggers (such as technic's + -- mining drill) don't respect on_dig. + oldmetadata = data.fixup_oldmetadata(oldmetadata) + for _, stack in ipairs(oldmetadata.inventory[data.wield_inv_name] or {}) do + if not stack:is_empty() then + minetest.add_item(pos, stack) + end + end + pipeworks.scan_for_tube_objects(pos) + end, + on_punch = data.fixup_node, + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + if player:get_player_name() ~= meta:get_string("owner") and meta:get_string("owner") ~= "" then + return 0 + end + return count + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if player:get_player_name() ~= meta:get_string("owner") and meta:get_string("owner") ~= "" then + return 0 + end + return stack:get_count() + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if player:get_player_name() ~= meta:get_string("owner") and meta:get_string("owner") ~= "" then + return 0 + end + return stack:get_count() + end, + }) + end +end + +if pipeworks.enable_node_breaker then + local data + data = { + name_base = "pipeworks:nodebreaker", + description = "Node Breaker", + texture_base = "pipeworks_nodebreaker", + texture_stateful = { top = true, bottom = true, side2 = true, side1 = true, front = true }, + tube_connect_sides = { top=1, bottom=1, left=1, right=1, back=1 }, + tube_permit_anteroposterior_insert = false, + wield_inv_name = "pick", + wield_inv_width = 1, + wield_inv_height = 1, + can_dig_nonempty_wield_inv = true, + ghost_inv_name = "ghost_pick", + ghost_tool = "default:pick_mese", + fixup_node = function (pos, node) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + -- Node breakers predating the visible pick slot + -- may have been partially updated. This code + -- fully updates them. Some have been observed + -- to have no pick slot at all; first add one. + if inv:get_size("pick") ~= 1 then + inv:set_size("pick", 1) + end + -- Originally, they had a ghost pick in a "pick" + -- inventory, no other inventory, and no form. + -- The partial update of early with-form node + -- breaker code gives them "ghost_pick" and "main" + -- inventories, but leaves the old ghost pick in + -- the "pick" inventory, and doesn't add a form. + -- First perform that partial update. + if inv:get_size("ghost_pick") ~= 1 then + inv:set_size("ghost_pick", 1) + inv:set_size("main", 100) + end + -- If the node breaker predates the visible pick + -- slot, which we can detect by it not having a + -- form, then the pick slot needs to be cleared + -- of the old ghost pick. + if (meta:get_string("formspec") or "") == "" then + inv:set_stack("pick", 1, ItemStack("")) + end + -- Finally, unconditionally set the formspec + -- and infotext. This not only makes the + -- pick slot visible for node breakers where + -- it wasn't before; it also updates the form + -- for node breakers that had an older version + -- of the form, and sets infotext where it was + -- missing for early with-form node breakers. + set_wielder_formspec(data, meta) + end, + fixup_oldmetadata = function (oldmetadata) + -- Node breakers predating the visible pick slot, + -- with node form, kept their ghost pick in an + -- inventory named "pick", the same name as the + -- later visible pick slot. The pick must be + -- removed to avoid spilling it. + if not oldmetadata.fields.formspec then + return { inventory = { pick = {} }, fields = oldmetadata.fields } + else + return oldmetadata + end + end, + masquerade_as_owner = true, + sneak = false, + act = function(virtplayer, pointed_thing) + local wieldstack = virtplayer:get_wielded_item() + local oldwieldstack = ItemStack(wieldstack) + local on_use = (minetest.registered_items[wieldstack:get_name()] or {}).on_use + if on_use then + virtplayer:set_wielded_item(on_use(wieldstack, virtplayer, pointed_thing) or wieldstack) + else + local under_node = minetest.get_node(pointed_thing.under) + local on_dig = (minetest.registered_nodes[under_node.name] or {on_dig=minetest.node_dig}).on_dig + on_dig(pointed_thing.under, under_node, virtplayer) + end + wieldstack = virtplayer:get_wielded_item() + local wieldname = wieldstack:get_name() + if wieldname == oldwieldstack:get_name() then + -- don't mechanically wear out tool + if wieldstack:get_count() == oldwieldstack:get_count() and + wieldstack:get_metadata() == oldwieldstack:get_metadata() and + ((minetest.registered_items[wieldstack:get_name()] or {}).wear_represents or "mechanical_wear") == "mechanical_wear" then + virtplayer:set_wielded_item(oldwieldstack) + end + elseif wieldname ~= "" then + -- tool got replaced by something else: + -- treat it as a drop + virtplayer:get_inventory():add_item("main", wieldstack) + virtplayer:set_wielded_item(ItemStack("")) + end + end, + eject_drops = true, + } + register_wielder(data) + minetest.register_craft({ + output = "pipeworks:nodebreaker_off", + recipe = { + { "group:wood", "default:pick_mese", "group:wood" }, + { "default:stone", "mesecons:piston", "default:stone" }, + { "default:stone", "mesecons:mesecon", "default:stone" }, + } + }) + -- aliases for when someone had technic installed, but then uninstalled it but not pipeworks + minetest.register_alias("technic:nodebreaker_off", "pipeworks:nodebreaker_off") + minetest.register_alias("technic:nodebreaker_on", "pipeworks:nodebreaker_on") + minetest.register_alias("technic:node_breaker_off", "pipeworks:nodebreaker_off") + minetest.register_alias("technic:node_breaker_on", "pipeworks:nodebreaker_on") + -- turn legacy auto-tree-taps into node breakers + dofile(pipeworks.modpath.."/legacy.lua") +end + +if pipeworks.enable_deployer then + register_wielder({ + name_base = "pipeworks:deployer", + description = "Deployer", + texture_base = "pipeworks_deployer", + texture_stateful = { front = true }, + tube_connect_sides = { back=1 }, + tube_permit_anteroposterior_insert = true, + wield_inv_name = "main", + wield_inv_width = 3, + wield_inv_height = 3, + can_dig_nonempty_wield_inv = false, + masquerade_as_owner = true, + sneak = false, + act = function(virtplayer, pointed_thing) + local wieldstack = virtplayer:get_wielded_item() + virtplayer:set_wielded_item((minetest.registered_items[wieldstack:get_name()] or {on_place=minetest.item_place}).on_place(wieldstack, virtplayer, pointed_thing) or wieldstack) + end, + eject_drops = false, + }) + minetest.register_craft({ + output = "pipeworks:deployer_off", + recipe = { + { "group:wood", "default:chest", "group:wood" }, + { "default:stone", "mesecons:piston", "default:stone" }, + { "default:stone", "mesecons:mesecon", "default:stone" }, + } + }) + -- aliases for when someone had technic installed, but then uninstalled it but not pipeworks + minetest.register_alias("technic:deployer_off", "pipeworks:deployer_off") + minetest.register_alias("technic:deployer_on", "pipeworks:deployer_on") +end + +if pipeworks.enable_dispenser then + register_wielder({ + name_base = "pipeworks:dispenser", + description = "Dispenser", + texture_base = "pipeworks_dispenser", + texture_stateful = { front = true }, + tube_connect_sides = { back=1 }, + tube_permit_anteroposterior_insert = true, + wield_inv_name = "main", + wield_inv_width = 3, + wield_inv_height = 3, + can_dig_nonempty_wield_inv = false, + masquerade_as_owner = false, + sneak = true, + act = function(virtplayer, pointed_thing) + local wieldstack = virtplayer:get_wielded_item() + virtplayer:set_wielded_item((minetest.registered_items[wieldstack:get_name()] or {on_drop=minetest.item_drop}).on_drop(wieldstack, virtplayer, virtplayer:getpos()) or wieldstack) + end, + eject_drops = false, + }) + minetest.register_craft({ + output = "pipeworks:dispenser_off", + recipe = { + { "default:desert_sand", "default:chest", "default:desert_sand" }, + { "default:stone", "mesecons:piston", "default:stone" }, + { "default:stone", "mesecons:mesecon", "default:stone" }, + } + }) +end diff --git a/mods/unified_inventory/api.lua b/mods/unified_inventory/api.lua new file mode 100644 index 0000000..f090712 --- /dev/null +++ b/mods/unified_inventory/api.lua @@ -0,0 +1,105 @@ + +-- Create detached creative inventory after loading all mods +minetest.after(0.01, function() + unified_inventory.items_list = {} + for name, def in pairs(minetest.registered_items) do + if (not def.groups.not_in_creative_inventory or + def.groups.not_in_creative_inventory == 0) and + def.description and def.description ~= "" then + table.insert(unified_inventory.items_list, name) + local recipes = minetest.get_all_craft_recipes(name) + if unified_inventory.crafts_table[name] == nil then + unified_inventory.crafts_table[name] = {} + end + if recipes then + for i=1,#recipes,1 do + table.insert(unified_inventory.crafts_table[name],recipes[i]) + end + end + end + end + table.sort(unified_inventory.items_list) + unified_inventory.items_list_size = #unified_inventory.items_list + print("Unified Inventory. inventory size: "..#unified_inventory.items_list) +end) + + +-- load_home +local function load_home() + local input = io.open(unified_inventory.home_filename, "r") + if input then + while true do + local x = input:read("*n") + if x == nil then + break + end + local y = input:read("*n") + local z = input:read("*n") + local name = input:read("*l") + unified_inventory.home_pos[name:sub(2)] = {x = x, y = y, z = z} + end + io.close(input) + else + unified_inventory.home_pos = {} + end +end +load_home() + +function unified_inventory.set_home(player, pos) + local player_name = player:get_player_name() + unified_inventory.home_pos[player_name] = pos + -- save the home data from the table to the file + local output = io.open(unified_inventory.home_filename, "w") + for k, v in pairs(unified_inventory.home_pos) do + if v ~= nil then + output:write(math.floor(v.x).." " + ..math.floor(v.y).." " + ..math.floor(v.z).." " + ..k.."\n") + end + end + io.close(output) +end + +function unified_inventory.go_home(player) + local pos = unified_inventory.home_pos[player:get_player_name()] + if pos ~= nil then + player:setpos(pos) + end +end + +-- register_craft +function unified_inventory.register_craft(options) + if options.output == nil then + return + end + local itemstack = ItemStack(options.output) + if itemstack:is_empty() then + return + end + if unified_inventory.crafts_table[itemstack:get_name()] == nil then + unified_inventory.crafts_table[itemstack:get_name()] = {} + end + table.insert(unified_inventory.crafts_table[itemstack:get_name()],options) +end + +function unified_inventory.register_page(name, def) + unified_inventory.pages[name] = def +end + +function unified_inventory.register_button(name, def) + if not def.action then + def.action = function(player) + unified_inventory.set_inventory_formspec(player, name) + end + end + def.name = name + table.insert(unified_inventory.buttons, def) +end + +function unified_inventory.is_creative(playername) + if minetest.check_player_privs(playername, {creative=true}) or + minetest.setting_getbool("creative_mode") then + return true + end +end diff --git a/mods/unified_inventory/bags.lua b/mods/unified_inventory/bags.lua new file mode 100644 index 0000000..497a9f8 --- /dev/null +++ b/mods/unified_inventory/bags.lua @@ -0,0 +1,146 @@ +-- Bags for Minetest + +-- Copyright (c) 2012 cornernote, Brett O'Donnell +-- License: GPLv3 + +unified_inventory.register_page("bags", { + get_formspec = function(player) + local player_name = player:get_player_name() + local formspec = "background[0.06,0.99;7.92,7.52;ui_bags_main_form.png]" + formspec = formspec.."label[0,0;Bags]" + formspec = formspec.."button[0,2;2,0.5;bag1;Bag 1]" + formspec = formspec.."button[2,2;2,0.5;bag2;Bag 2]" + formspec = formspec.."button[4,2;2,0.5;bag3;Bag 3]" + formspec = formspec.."button[6,2;2,0.5;bag4;Bag 4]" + formspec = formspec.."listcolors[#00000000;#00000000]" + formspec = formspec.."list[detached:"..player_name.."_bags;bag1;0.5,1;1,1;]" + formspec = formspec.."list[detached:"..player_name.."_bags;bag2;2.5,1;1,1;]" + formspec = formspec.."list[detached:"..player_name.."_bags;bag3;4.5,1;1,1;]" + formspec = formspec.."list[detached:"..player_name.."_bags;bag4;6.5,1;1,1;]" + return {formspec=formspec} + end, +}) + +unified_inventory.register_button("bags", { + type = "image", + image = "ui_bags_icon.png", +}) + +for i = 1, 4 do + unified_inventory.register_page("bag"..i, { + get_formspec = function(player) + local stack = player:get_inventory():get_stack("bag"..i, 1) + local image = stack:get_definition().inventory_image + local formspec = "image[7,0;1,1;"..image.."]" + formspec = formspec.."listcolors[#00000000;#00000000]" + formspec = formspec.."list[current_player;bag"..i.."contents;0,1;8,3;]" + local slots = stack:get_definition().groups.bagslots + if slots == 8 then + formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_sm_form.png]" + elseif slots == 16 then + formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_med_form.png]" + elseif slots == 24 then + formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_lg_form.png]" + end + return {formspec=formspec} + end, + }) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + for i = 1, 4 do + if fields["bag"..i] then + local stack = player:get_inventory():get_stack("bag"..i, 1) + if not stack:get_definition().groups.bagslots then + return + end + unified_inventory.set_inventory_formspec(player, "bag"..i) + return + end + end +end) + +minetest.register_on_joinplayer(function(player) + local player_inv = player:get_inventory() + local bags_inv = minetest.create_detached_inventory(player:get_player_name().."_bags",{ + on_put = function(inv, listname, index, stack, player) + player:get_inventory():set_stack(listname, index, stack) + player:get_inventory():set_size(listname.."contents", + stack:get_definition().groups.bagslots) + end, + on_take = function(inv, listname, index, stack, player) + player:get_inventory():set_stack(listname, index, nil) + end, + allow_put = function(inv, listname, index, stack, player) + if stack:get_definition().groups.bagslots then + return 1 + else + return 0 + end + end, + allow_take = function(inv, listname, index, stack, player) + if player:get_inventory():is_empty(listname.."contents") then + return stack:get_count() + else + return 0 + end + end, + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + }) + for i=1,4 do + local bag = "bag"..i + player_inv:set_size(bag, 1) + bags_inv:set_size(bag, 1) + bags_inv:set_stack(bag, 1, player_inv:get_stack(bag, 1)) + end +end) + +-- register bag tools +minetest.register_tool("unified_inventory:bag_small", { + description = "Small Bag", + inventory_image = "bags_small.png", + groups = {bagslots=8}, +}) + +minetest.register_tool("unified_inventory:bag_medium", { + description = "Medium Bag", + inventory_image = "bags_medium.png", + groups = {bagslots=16}, +}) + +minetest.register_tool("unified_inventory:bag_large", { + description = "Large Bag", + inventory_image = "bags_large.png", + groups = {bagslots=24}, +}) + +-- register bag crafts +minetest.register_craft({ + output = "unified_inventory:bag_small", + recipe = { + {"", "default:stick", ""}, + {"group:wood", "group:wood", "group:wood"}, + {"group:wood", "group:wood", "group:wood"}, + }, +}) + +minetest.register_craft({ + output = "unified_inventory:bag_medium", + recipe = { + {"", "", ""}, + {"default:stick", "unified_inventory:bag_small", "default:stick"}, + {"default:stick", "unified_inventory:bag_small", "default:stick"}, + }, +}) + +minetest.register_craft({ + output = "unified_inventory:bag_large", + recipe = { + {"", "", ""}, + {"default:stick", "unified_inventory:bag_medium", "default:stick"}, + {"default:stick", "unified_inventory:bag_medium", "default:stick"}, + }, +}) + diff --git a/mods/unified_inventory/callbacks.lua b/mods/unified_inventory/callbacks.lua new file mode 100644 index 0000000..4f9913c --- /dev/null +++ b/mods/unified_inventory/callbacks.lua @@ -0,0 +1,176 @@ + +minetest.register_on_joinplayer(function(player) + local player_name = player:get_player_name() + unified_inventory.players[player_name] = {} + unified_inventory.current_index[player_name] = 1 + unified_inventory.filtered_items_list[player_name] = + unified_inventory.items_list + unified_inventory.activefilter[player_name] = "" + unified_inventory.apply_filter(player, "") + unified_inventory.alternate[player_name] = 1 + unified_inventory.current_item[player_name] = nil + unified_inventory.set_inventory_formspec(player, + unified_inventory.default) + + -- Crafting guide inventories + local inv = minetest.create_detached_inventory(player_name.."craftrecipe", { + allow_put = function(inv, listname, index, stack, player) + return 0 + end, + allow_take = function(inv, listname, index, stack, player) + return 0 + end, + allow_move = function(inv, from_list, from_index, to_list, + to_index, count, player) + return 0 + end, + }) + inv:set_size("output", 1) + + -- Refill slot + local refill = minetest.create_detached_inventory(player_name.."refill", { + allow_put = function(inv, listname, index, stack, player) + local player_name = player:get_player_name() + if unified_inventory.is_creative(player_name) then + return stack:get_count() + else + return 0 + end + end, + on_put = function(inv, listname, index, stack, player) + local player_name = player:get_player_name() + stack:set_count(stack:get_stack_max()) + inv:set_stack(listname, index, stack) + minetest.sound_play("electricity", + {to_player=player_name, gain = 1.0}) + end, + }) + refill:set_size("main", 1) +end) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local player_name = player:get_player_name() + + for i, def in pairs(unified_inventory.buttons) do + if fields[def.name] then + def.action(player) + minetest.sound_play("click", + {to_player=player_name, gain = 0.1}) + return + end + end + + -- Inventory page controls + local start = math.floor( + unified_inventory.current_index[player_name] / 80 + 1) + local start_i = start + local pagemax = math.floor( + (#unified_inventory.filtered_items_list[player_name] - 1) + / (80) + 1) + + if fields.start_list then + minetest.sound_play("paperflip1", + {to_player=player_name, gain = 1.0}) + start_i = 1 + end + if fields.rewind1 then + minetest.sound_play("paperflip1", + {to_player=player_name, gain = 1.0}) + start_i = start_i - 1 + end + if fields.forward1 then + minetest.sound_play("paperflip1", + {to_player=player_name, gain = 1.0}) + start_i = start_i + 1 + end + if fields.rewind3 then + minetest.sound_play("paperflip1", + {to_player=player_name, gain = 1.0}) + start_i = start_i - 3 + end + if fields.forward3 then + minetest.sound_play("paperflip1", + {to_player=player_name, gain = 1.0}) + start_i = start_i + 3 + end + if fields.end_list then + minetest.sound_play("paperflip1", + {to_player=player_name, gain = 1.0}) + start_i = pagemax + end + if start_i < 1 then + start_i = 1 + end + if start_i > pagemax then + start_i = pagemax + end + if not (start_i == start) then + unified_inventory.current_index[player_name] = (start_i - 1) * 80 + 1 + unified_inventory.set_inventory_formspec(player, + unified_inventory.current_page[player_name]) + end + + local clicked_item = nil + for name, value in pairs(fields) do + if string.sub(name, 1, 12) == "item_button_" then + clicked_item = string.sub(name, 13) + break + end + end + if clicked_item then + minetest.sound_play("click", + {to_player=player_name, gain = 0.1}) + local page = unified_inventory.current_page[player_name] + if not unified_inventory.is_creative(player_name) then + page = "craftguide" + end + if page == "craftguide" then + unified_inventory.current_item[player_name] = clicked_item + unified_inventory.alternate[player_name] = 1 + unified_inventory.set_inventory_formspec(player, + "craftguide") + else + if unified_inventory.is_creative(player_name) then + local inv = player:get_inventory() + local stack = ItemStack(clicked_item) + stack:set_count(99) + if inv:room_for_item("main", stack) then + inv:add_item("main", stack) + end + end + end + end + + if fields.searchbutton then + unified_inventory.apply_filter(player, fields.searchbox) + unified_inventory.set_inventory_formspec(player, + unified_inventory.current_page[player_name]) + minetest.sound_play("paperflip2", + {to_player=player_name, gain = 1.0}) + end + + -- alternate button + if fields.alternate then + minetest.sound_play("click", + {to_player=player_name, gain = 0.1}) + local item_name = unified_inventory.current_item[player_name] + if item_name then + local alternates = 0 + local alternate = unified_inventory.alternate[player_name] + local crafts = unified_inventory.crafts_table[item_name] + if crafts ~= nil then + alternates = #crafts + end + if alternates > 1 then + alternate = alternate + 1 + if alternate > alternates then + alternate = 1 + end + unified_inventory.alternate[player_name] = alternate + unified_inventory.set_inventory_formspec(player, + unified_inventory.current_page[player_name]) + end + end + end +end) + diff --git a/mods/unified_inventory/depends.txt b/mods/unified_inventory/depends.txt new file mode 100644 index 0000000..8d390c8 --- /dev/null +++ b/mods/unified_inventory/depends.txt @@ -0,0 +1 @@ +creative? diff --git a/mods/unified_inventory/init.lua b/mods/unified_inventory/init.lua new file mode 100644 index 0000000..3f26fef --- /dev/null +++ b/mods/unified_inventory/init.lua @@ -0,0 +1,42 @@ +-- Unified Inventory for Minetest 0.4.8+ + +local modpath = minetest.get_modpath(minetest.get_current_modname()) +local worldpath = minetest.get_worldpath() + +-- Data tables definitions +unified_inventory = {} +unified_inventory.activefilter = {} +unified_inventory.alternate = {} +unified_inventory.current_page = {} +unified_inventory.current_index = {} +unified_inventory.current_item = {} +unified_inventory.crafts_table = {} +unified_inventory.crafts_table_count = 0 +unified_inventory.players = {} +unified_inventory.items_list_size = 0 +unified_inventory.items_list = {} +unified_inventory.filtered_items_list_size = {} +unified_inventory.filtered_items_list = {} +unified_inventory.pages = {} +unified_inventory.buttons = {} + +-- Homepos stuff +unified_inventory.home_pos = {} +unified_inventory.home_filename = + worldpath.."/unified_inventory_home.home" + +-- Default inventory page +unified_inventory.default = "craft" + +-- Disable default creative inventory +if creative_inventory then + function creative_inventory.set_creative_formspec(player, start_i, pagenum) + return + end +end + +dofile(modpath.."/api.lua") +dofile(modpath.."/internal.lua") +dofile(modpath.."/callbacks.lua") +dofile(modpath.."/register.lua") +dofile(modpath.."/bags.lua") diff --git a/mods/unified_inventory/internal.lua b/mods/unified_inventory/internal.lua new file mode 100644 index 0000000..3ea410e --- /dev/null +++ b/mods/unified_inventory/internal.lua @@ -0,0 +1,136 @@ + +function unified_inventory.get_formspec(player, page) + if not player then + return "" + end + local player_name = player:get_player_name() + unified_inventory.current_page[player_name] = page + local pagedef = unified_inventory.pages[page] + + local formspec = "size[14,10]" + local fsdata = nil + + -- Background + formspec = formspec .. "background[-0.19,-0.25;14.4,10.75;ui_form_bg.png]" + -- Current page + if unified_inventory.pages[page] then + fsdata = pagedef.get_formspec(player) + formspec = formspec .. fsdata.formspec + else + return "" -- Invalid page name + end + + -- Main buttons + for i, def in pairs(unified_inventory.buttons) do + if def.type == "image" then + formspec = formspec.."image_button[" + ..(0.65 * (i - 1))..",9;0.8,0.8;" + ..minetest.formspec_escape(def.image)..";" + ..minetest.formspec_escape(def.name)..";]" + end + end + + if fsdata.draw_inventory ~= false then + -- Player inventory + formspec = formspec.."listcolors[#00000000;#00000000]" + formspec = formspec .. "list[current_player;main;0,4.5;8,4;]" + end + + if fsdata.draw_item_list == false then + return formspec + end + + -- Controls to flip items pages + local start_x = 9.2 + formspec = formspec .. "image_button["..(start_x + 0.6 * 0)..",9;.8,.8;ui_skip_backward_icon.png;start_list;]" + formspec = formspec .. "image_button["..(start_x + 0.6 * 1)..",9;.8,.8;ui_doubleleft_icon.png;rewind3;]" + formspec = formspec .. "image_button["..(start_x + 0.6 * 2)..",9;.8,.8;ui_left_icon.png;rewind1;]" + formspec = formspec .. "image_button["..(start_x + 0.6 * 3)..",9;.8,.8;ui_right_icon.png;forward1;]" + formspec = formspec .. "image_button["..(start_x + 0.6 * 4)..",9;.8,.8;ui_doubleright_icon.png;forward3;]" + formspec = formspec .. "image_button["..(start_x + 0.6 * 5)..",9;.8,.8;ui_skip_forward_icon.png;end_list;]" + + -- Search box + formspec = formspec .. "field[9.5,8.325;3,1;searchbox;;]" + formspec = formspec .. "image_button[12.2,8.1;.8,.8;ui_search_icon.png;searchbutton;]" + + -- Items list + local list_index = unified_inventory.current_index[player_name] + local page = math.floor(list_index / (80) + 1) + local pagemax = math.floor( + (#unified_inventory.filtered_items_list[player_name] - 1) + / (80) + 1) + local item = {} + for y = 0, 9 do + for x = 0, 7 do + name = unified_inventory.filtered_items_list[player_name][list_index] + if minetest.registered_items[name] then + formspec = formspec.."item_image_button[" + ..(8.2 + x * 0.7).."," + ..(1 + y * 0.7)..";.81,.81;" + ..name..";item_button_" + ..name..";]" + list_index = list_index + 1 + end + end + end + formspec = formspec.."label[8.2,0;Page:]" + formspec = formspec.."label[9,0;"..page.." of "..pagemax.."]" + formspec = formspec.."label[8.2,0.4;Filter:]" + formspec = formspec.."label[9,0.4;"..unified_inventory.activefilter[player_name].."]" + return formspec +end + +function unified_inventory.set_inventory_formspec(player, page) + if player then + local formspec = unified_inventory.get_formspec(player, page) + player:set_inventory_formspec(formspec) + end +end + +--apply filter to the inventory list (create filtered copy of full one) +function unified_inventory.apply_filter(player, filter) + local player_name = player:get_player_name() + local size = 0 + local lfilter = string.lower(filter) + if lfilter ~= "" then + for c in lfilter:gmatch(".") do + if c == '[' or c == ']' or c == '{' or c == '}' or + c == '(' or c == ')' or c == '%' then + lfilter = "" + break + end + end + end + unified_inventory.filtered_items_list[player_name]={} + for name, def in pairs(minetest.registered_items) do + if (not def.groups.not_in_creative_inventory or + def.groups.not_in_creative_inventory == 0) + and def.description and def.description ~= "" then + local lname = string.lower(name) + local ldesc = string.lower(def.description) + if string.find(lname, lfilter) or string.find(ldesc, lfilter) then + table.insert(unified_inventory.filtered_items_list[player_name], name) + size = size + 1 + end + end + + end + table.sort(unified_inventory.filtered_items_list[player_name]) + unified_inventory.filtered_items_list_size[player_name] = size + unified_inventory.current_index[player_name] = 1 + unified_inventory.activefilter[player_name] = filter + unified_inventory.set_inventory_formspec(player, + unified_inventory.current_page[player_name]) +end + +function unified_inventory.items_in_group(groups) + local items = {} + for name, item in pairs(minetest.registered_items) do + for _, group in pairs(groups:split(',')) do + if item.groups[group] then + table.insert(items, name) + end + end + end + return items +end diff --git a/mods/unified_inventory/readme.md b/mods/unified_inventory/readme.md new file mode 100644 index 0000000..bcb3698 --- /dev/null +++ b/mods/unified_inventory/readme.md @@ -0,0 +1,6 @@ +unified_inventory +================= + +Replacement for Minetest creative inventory. + +Unified Inventory replaces the survival and creative inventory; it also functions as a crafting guide. diff --git a/mods/unified_inventory/register.lua b/mods/unified_inventory/register.lua new file mode 100644 index 0000000..abe9d01 --- /dev/null +++ b/mods/unified_inventory/register.lua @@ -0,0 +1,304 @@ + +minetest.register_privilege("creative", { + description = "Can use the creative inventory", + give_to_singleplayer = false, +}) + +local trash = minetest.create_detached_inventory("trash", { + --allow_put = function(inv, listname, index, stack, player) + -- if unified_inventory.is_creative(player:get_player_name()) then + -- return stack:get_count() + -- else + -- return 0 + -- end + --end, + on_put = function(inv, listname, index, stack, player) + inv:set_stack(listname, index, nil) + local player_name = player:get_player_name() + minetest.sound_play("trash", {to_player=player_name, gain = 1.0}) + end, +}) +trash:set_size("main", 1) + +unified_inventory.register_button("craft", { + type = "image", + image = "ui_craft_icon.png", +}) + +unified_inventory.register_button("craftguide", { + type = "image", + image = "ui_craftguide_icon.png", +}) + +unified_inventory.register_button("home_gui_set", { + type = "image", + image = "ui_sethome_icon.png", + action = function(player) + local player_name = player:get_player_name() + unified_inventory.set_home(player, player:getpos()) + local home = unified_inventory.home_pos[player_name] + if home ~= nil then + minetest.sound_play("dingdong", + {to_player=player_name, gain = 1.0}) + minetest.chat_send_player(player_name, + "Home position set to: " + ..minetest.pos_to_string(home)) + end + end, +}) + +unified_inventory.register_button("home_gui_go", { + type = "image", + image = "ui_gohome_icon.png", + action = function(player) + minetest.sound_play("teleport", + {to_player=player:get_player_name(), gain = 1.0}) + unified_inventory.go_home(player) + end, +}) + +unified_inventory.register_button("misc_set_day", { + type = "image", + image = "ui_sun_icon.png", + action = function(player) + local player_name = player:get_player_name() + if minetest.check_player_privs(player_name, {settime=true}) then + minetest.sound_play("birds", + {to_player=player_name, gain = 1.0}) + minetest.set_timeofday((6000 % 24000) / 24000) + minetest.chat_send_player(player_name, + "Time of day set to 6am") + else + minetest.chat_send_player(player_name, + "You don't have the" + .." settime priviledge!") + end + end, +}) + +unified_inventory.register_button("misc_set_night", { + type = "image", + image = "ui_moon_icon.png", + action = function(player) + local player_name = player:get_player_name() + if minetest.check_player_privs(player_name, {settime=true}) then + minetest.sound_play("owl", + {to_player=player_name, gain = 1.0}) + minetest.set_timeofday((21000 % 24000) / 24000) + minetest.chat_send_player(player_name, + "Time of day set to 9pm") + else + minetest.chat_send_player(player_name, + "You don't have the" + .." settime priviledge!") + end + end, +}) + +unified_inventory.register_button("clear_inv", { + type = "image", + image = "ui_trash_icon.png", + action = function(player) + local player_name = player:get_player_name() + if not unified_inventory.is_creative(player_name) then + minetest.chat_send_player(player_name, + "This button has been disabled outside" + .." of creative mode to prevent" + .." accidental inventory trashing." + .." Use the trash slot instead.") + return + end + player:get_inventory():set_list("main", {}) + minetest.chat_send_player(player_name, 'Inventory Cleared!') + minetest.sound_play("trash_all", + {to_player=player_name, gain = 1.0}) + end, +}) + +unified_inventory.register_page("craft", { + get_formspec = function(player, formspec) + local player_name = player:get_player_name() + local formspec = "background[0,1;8,3;ui_crafting_form.png]" + formspec = formspec.."background[0,4.5;8,4;ui_main_inventory.png]" + formspec = formspec.."label[0,0;Crafting]" + formspec = formspec.."listcolors[#00000000;#00000000]" + formspec = formspec.."list[current_player;craftpreview;6,1;1,1;]" + formspec = formspec.."list[current_player;craft;2,1;3,3;]" + formspec = formspec.."label[7,2.5;Trash:]" + formspec = formspec.."list[detached:trash;main;7,3;1,1;]" + if unified_inventory.is_creative(player_name) then + formspec = formspec.."label[0,2.5;Refill:]" + formspec = formspec.."list[detached:"..player_name.."refill;main;0,3;1,1;]" + end + return {formspec=formspec} + end, +}) + +unified_inventory.register_page("craftguide", { + get_formspec = function(player) + local player_name = player:get_player_name() + local formspec = "background[0,1;8,3;ui_craftguide_form.png]" + formspec = formspec.."background[0,4.5;8,4;ui_main_inventory.png]" + formspec = formspec.."label[0,0;Crafting Guide]" + formspec = formspec.."listcolors[#00000000;#00000000]" + formspec = formspec.."list[detached:"..player_name.."craftrecipe;output;6,1;1,1;]" + formspec = formspec.."label[6,3.35;Method:]" + local item_name = unified_inventory.current_item[player_name] + local craft = nil + if item_name then + formspec = formspec.."textarea[0.3,0.6;10,1;;Result: "..item_name..";]" + local alternates = 0 + local alternate = unified_inventory.alternate[player_name] + local crafts = unified_inventory.crafts_table[item_name] + if crafts ~= nil and #crafts > 0 then + alternates = #crafts + craft = crafts[alternate] + local method = craft.type + local allow_auto_craft = ((method == "normal") or (method == "shapeless")) + if craft.type == "normal" then + method = "crafting" + elseif craft.type == "shapeless" then + method = "shapeless crafting" + elseif craft.type == "alloy" then + method = "alloy cooking" + end + formspec = formspec.."label[6,3.75;"..method.."]" + if allow_auto_craft then + formspec = formspec.."label[6,1.95;Copy to craft grid:]" + formspec = formspec.."button[6,2.5;0.6,0.5;craftguide_craft_1;1]" + formspec = formspec.."button[6.6,2.5;0.6,0.5;craftguide_craft_10;10]" + formspec = formspec.."button[7.2,2.5;0.6,0.5;craftguide_craft_max;All]" + end + end + if alternates > 1 then + formspec = formspec.."label[0,2.6;Recipe " + ..tostring(alternate).." of " + ..tostring(alternates).."]" + formspec = formspec.."button[0,3.15;2,1;alternate;Alternate]" + end + end + + local craftinv = minetest.get_inventory({ + type = "detached", + name = player_name.."craftrecipe" + }) + + -- fake buttons just to make 3x3 grid + for y = 1, 3 do + for x = 1, 3 do + formspec = formspec.."image_button[" + ..(1.0 + x)..","..(0.0 + y)..";1.1,1.1;ui_blank_image.png;;]" + end + end + + if not craft then + craftinv:set_stack("output", 1, nil) + return {formspec=formspec} + end + + craftinv:set_stack("output", 1, craft.output) + + local width = craft.width + if width == 0 then + -- Shapeless recipe + width = 3 + end + + local i = 1 + for y = 1, 3 do + for x = 1, width do + local item = craft.items[i] + if item then + if string.sub(item, 1, 6) == "group:" then + local group = string.sub(item, 7) + formspec = formspec.."image_button[" + ..(1.0 + x)..","..(0.0 + y)..";1.1,1.1;" + .."ui_group.png;;" + ..minetest.formspec_escape(group).."]" + else + formspec = formspec.."item_image_button[" + ..(1.0 + x)..","..(0.0 + y)..";1.1,1.1;" + ..minetest.formspec_escape(item)..";" + .."item_button_" + ..minetest.formspec_escape(item)..";]" + end + end + i = i + 1 + end + end + return {formspec=formspec} + end, +}) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local amount + for k, v in pairs(fields) do + amount = k:match("craftguide_craft_(.*)") + if amount then break end + end + if not amount then return end + local player_name = player:get_player_name() + local recipe_inv = minetest.get_inventory({ + type="detached", + name=player_name.."craftrecipe", + }) + + local output = unified_inventory.current_item[player_name] + if (not output) or (output == "") then return end + + local player_inv = player:get_inventory() + + local crafts = unified_inventory.crafts_table[output] + if (not crafts) or (#crafts == 0) then return end + + local alternate = unified_inventory.alternate[player_name] + + local craft = crafts[alternate] + if craft.width > 3 then return end + + local needed = craft.items + + local craft_list = player_inv:get_list("craft") + + local width = craft.width + if width == 0 then + -- Shapeless recipe + width = 3 + end + + if amount == "max" then + amount = 99 -- Arbitrary; need better way to do this. + else + amount = tonumber(amount) + end + + for iter = 1, amount do + local index = 1 + for y = 1, 3 do + for x = 1, width do + local needed_item = needed[index] + if needed_item then + local craft_index = ((y - 1) * 3) + x + local craft_item = craft_list[craft_index] + if (not craft_item) or (craft_item:is_empty()) or (craft_item:get_name() == needed_item) then + itemname = craft_item and craft_item:get_name() or needed_item + local needed_stack = ItemStack(needed_item) + if player_inv:contains_item("main", needed_stack) then + local count = (craft_item and craft_item:get_count() or 0) + 1 + if count <= needed_stack:get_definition().stack_max then + local stack = ItemStack({name=needed_item, count=count}) + craft_list[craft_index] = stack + player_inv:remove_item("main", needed_stack) + end + end + end + end + index = index + 1 + end + end + end + + player_inv:set_list("craft", craft_list) + + unified_inventory.set_inventory_formspec(player, "craft") +end) diff --git a/mods/unified_inventory/sounds/birds.ogg b/mods/unified_inventory/sounds/birds.ogg new file mode 100644 index 0000000..4a93395 Binary files /dev/null and b/mods/unified_inventory/sounds/birds.ogg differ diff --git a/mods/unified_inventory/sounds/click.ogg b/mods/unified_inventory/sounds/click.ogg new file mode 100644 index 0000000..3db63a0 Binary files /dev/null and b/mods/unified_inventory/sounds/click.ogg differ diff --git a/mods/unified_inventory/sounds/dingdong.ogg b/mods/unified_inventory/sounds/dingdong.ogg new file mode 100644 index 0000000..2c9d7ef Binary files /dev/null and b/mods/unified_inventory/sounds/dingdong.ogg differ diff --git a/mods/unified_inventory/sounds/electricity.ogg b/mods/unified_inventory/sounds/electricity.ogg new file mode 100644 index 0000000..4cd7c84 Binary files /dev/null and b/mods/unified_inventory/sounds/electricity.ogg differ diff --git a/mods/unified_inventory/sounds/owl.ogg b/mods/unified_inventory/sounds/owl.ogg new file mode 100644 index 0000000..f30d0b3 Binary files /dev/null and b/mods/unified_inventory/sounds/owl.ogg differ diff --git a/mods/unified_inventory/sounds/paperflip1.ogg b/mods/unified_inventory/sounds/paperflip1.ogg new file mode 100644 index 0000000..eaed13f Binary files /dev/null and b/mods/unified_inventory/sounds/paperflip1.ogg differ diff --git a/mods/unified_inventory/sounds/paperflip2.ogg b/mods/unified_inventory/sounds/paperflip2.ogg new file mode 100644 index 0000000..321bc48 Binary files /dev/null and b/mods/unified_inventory/sounds/paperflip2.ogg differ diff --git a/mods/unified_inventory/sounds/teleport.ogg b/mods/unified_inventory/sounds/teleport.ogg new file mode 100644 index 0000000..ca32f74 Binary files /dev/null and b/mods/unified_inventory/sounds/teleport.ogg differ diff --git a/mods/unified_inventory/sounds/trash.ogg b/mods/unified_inventory/sounds/trash.ogg new file mode 100644 index 0000000..51e4f24 Binary files /dev/null and b/mods/unified_inventory/sounds/trash.ogg differ diff --git a/mods/unified_inventory/sounds/trash_all.ogg b/mods/unified_inventory/sounds/trash_all.ogg new file mode 100644 index 0000000..85c3f66 Binary files /dev/null and b/mods/unified_inventory/sounds/trash_all.ogg differ diff --git a/mods/unified_inventory/textures/bags_large.png b/mods/unified_inventory/textures/bags_large.png new file mode 100644 index 0000000..c26f075 Binary files /dev/null and b/mods/unified_inventory/textures/bags_large.png differ diff --git a/mods/unified_inventory/textures/bags_medium.png b/mods/unified_inventory/textures/bags_medium.png new file mode 100644 index 0000000..7bc8030 Binary files /dev/null and b/mods/unified_inventory/textures/bags_medium.png differ diff --git a/mods/unified_inventory/textures/bags_small.png b/mods/unified_inventory/textures/bags_small.png new file mode 100644 index 0000000..e9656a5 Binary files /dev/null and b/mods/unified_inventory/textures/bags_small.png differ diff --git a/mods/unified_inventory/textures/ui_bags_icon.png b/mods/unified_inventory/textures/ui_bags_icon.png new file mode 100644 index 0000000..d75ff8b Binary files /dev/null and b/mods/unified_inventory/textures/ui_bags_icon.png differ diff --git a/mods/unified_inventory/textures/ui_bags_lg_form.png b/mods/unified_inventory/textures/ui_bags_lg_form.png new file mode 100644 index 0000000..15f511d Binary files /dev/null and b/mods/unified_inventory/textures/ui_bags_lg_form.png differ diff --git a/mods/unified_inventory/textures/ui_bags_main_form.png b/mods/unified_inventory/textures/ui_bags_main_form.png new file mode 100644 index 0000000..26e6938 Binary files /dev/null and b/mods/unified_inventory/textures/ui_bags_main_form.png differ diff --git a/mods/unified_inventory/textures/ui_bags_med_form.png b/mods/unified_inventory/textures/ui_bags_med_form.png new file mode 100644 index 0000000..f786806 Binary files /dev/null and b/mods/unified_inventory/textures/ui_bags_med_form.png differ diff --git a/mods/unified_inventory/textures/ui_bags_sm_form.png b/mods/unified_inventory/textures/ui_bags_sm_form.png new file mode 100644 index 0000000..c77ff7c Binary files /dev/null and b/mods/unified_inventory/textures/ui_bags_sm_form.png differ diff --git a/mods/unified_inventory/textures/ui_blank_image.png b/mods/unified_inventory/textures/ui_blank_image.png new file mode 100644 index 0000000..f9bcda2 Binary files /dev/null and b/mods/unified_inventory/textures/ui_blank_image.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton0.png b/mods/unified_inventory/textures/ui_colorbutton0.png new file mode 100644 index 0000000..35b7db2 Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton0.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton1.png b/mods/unified_inventory/textures/ui_colorbutton1.png new file mode 100644 index 0000000..cbf095d Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton1.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton10.png b/mods/unified_inventory/textures/ui_colorbutton10.png new file mode 100644 index 0000000..8dfc5f0 Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton10.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton11.png b/mods/unified_inventory/textures/ui_colorbutton11.png new file mode 100644 index 0000000..3b279e0 Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton11.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton12.png b/mods/unified_inventory/textures/ui_colorbutton12.png new file mode 100644 index 0000000..a387b5f Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton12.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton13.png b/mods/unified_inventory/textures/ui_colorbutton13.png new file mode 100644 index 0000000..b1e7790 Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton13.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton14.png b/mods/unified_inventory/textures/ui_colorbutton14.png new file mode 100644 index 0000000..c4ad486 Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton14.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton15.png b/mods/unified_inventory/textures/ui_colorbutton15.png new file mode 100644 index 0000000..b7060d6 Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton15.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton2.png b/mods/unified_inventory/textures/ui_colorbutton2.png new file mode 100644 index 0000000..caf1fc6 Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton2.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton3.png b/mods/unified_inventory/textures/ui_colorbutton3.png new file mode 100644 index 0000000..6ac79a3 Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton3.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton4.png b/mods/unified_inventory/textures/ui_colorbutton4.png new file mode 100644 index 0000000..dc43592 Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton4.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton5.png b/mods/unified_inventory/textures/ui_colorbutton5.png new file mode 100644 index 0000000..98b8c67 Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton5.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton6.png b/mods/unified_inventory/textures/ui_colorbutton6.png new file mode 100644 index 0000000..66478bc Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton6.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton7.png b/mods/unified_inventory/textures/ui_colorbutton7.png new file mode 100644 index 0000000..85f6b93 Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton7.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton8.png b/mods/unified_inventory/textures/ui_colorbutton8.png new file mode 100644 index 0000000..868c35d Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton8.png differ diff --git a/mods/unified_inventory/textures/ui_colorbutton9.png b/mods/unified_inventory/textures/ui_colorbutton9.png new file mode 100644 index 0000000..50eac0b Binary files /dev/null and b/mods/unified_inventory/textures/ui_colorbutton9.png differ diff --git a/mods/unified_inventory/textures/ui_copper_chest_inventory.png b/mods/unified_inventory/textures/ui_copper_chest_inventory.png new file mode 100644 index 0000000..debc9fc Binary files /dev/null and b/mods/unified_inventory/textures/ui_copper_chest_inventory.png differ diff --git a/mods/unified_inventory/textures/ui_craft_icon.png b/mods/unified_inventory/textures/ui_craft_icon.png new file mode 100644 index 0000000..727b645 Binary files /dev/null and b/mods/unified_inventory/textures/ui_craft_icon.png differ diff --git a/mods/unified_inventory/textures/ui_craftguide_form.png b/mods/unified_inventory/textures/ui_craftguide_form.png new file mode 100644 index 0000000..e103c04 Binary files /dev/null and b/mods/unified_inventory/textures/ui_craftguide_form.png differ diff --git a/mods/unified_inventory/textures/ui_craftguide_icon.png b/mods/unified_inventory/textures/ui_craftguide_icon.png new file mode 100644 index 0000000..079aacb Binary files /dev/null and b/mods/unified_inventory/textures/ui_craftguide_icon.png differ diff --git a/mods/unified_inventory/textures/ui_crafting_form.png b/mods/unified_inventory/textures/ui_crafting_form.png new file mode 100644 index 0000000..74389ed Binary files /dev/null and b/mods/unified_inventory/textures/ui_crafting_form.png differ diff --git a/mods/unified_inventory/textures/ui_doubleleft_icon.png b/mods/unified_inventory/textures/ui_doubleleft_icon.png new file mode 100644 index 0000000..b9dcfc4 Binary files /dev/null and b/mods/unified_inventory/textures/ui_doubleleft_icon.png differ diff --git a/mods/unified_inventory/textures/ui_doubleright_icon.png b/mods/unified_inventory/textures/ui_doubleright_icon.png new file mode 100644 index 0000000..f56d404 Binary files /dev/null and b/mods/unified_inventory/textures/ui_doubleright_icon.png differ diff --git a/mods/unified_inventory/textures/ui_form_bg.png b/mods/unified_inventory/textures/ui_form_bg.png new file mode 100644 index 0000000..37683f0 Binary files /dev/null and b/mods/unified_inventory/textures/ui_form_bg.png differ diff --git a/mods/unified_inventory/textures/ui_furnace_inventory.png b/mods/unified_inventory/textures/ui_furnace_inventory.png new file mode 100644 index 0000000..ce84efb Binary files /dev/null and b/mods/unified_inventory/textures/ui_furnace_inventory.png differ diff --git a/mods/unified_inventory/textures/ui_gohome_icon.png b/mods/unified_inventory/textures/ui_gohome_icon.png new file mode 100644 index 0000000..57b448c Binary files /dev/null and b/mods/unified_inventory/textures/ui_gohome_icon.png differ diff --git a/mods/unified_inventory/textures/ui_gold_chest_inventory.png b/mods/unified_inventory/textures/ui_gold_chest_inventory.png new file mode 100644 index 0000000..b19524b Binary files /dev/null and b/mods/unified_inventory/textures/ui_gold_chest_inventory.png differ diff --git a/mods/unified_inventory/textures/ui_group.png b/mods/unified_inventory/textures/ui_group.png new file mode 100644 index 0000000..8de5a77 Binary files /dev/null and b/mods/unified_inventory/textures/ui_group.png differ diff --git a/mods/unified_inventory/textures/ui_home_icon.png b/mods/unified_inventory/textures/ui_home_icon.png new file mode 100644 index 0000000..6e1efca Binary files /dev/null and b/mods/unified_inventory/textures/ui_home_icon.png differ diff --git a/mods/unified_inventory/textures/ui_hv_battery_box.png b/mods/unified_inventory/textures/ui_hv_battery_box.png new file mode 100644 index 0000000..61c55de Binary files /dev/null and b/mods/unified_inventory/textures/ui_hv_battery_box.png differ diff --git a/mods/unified_inventory/textures/ui_iron_chest_inventory.png b/mods/unified_inventory/textures/ui_iron_chest_inventory.png new file mode 100644 index 0000000..1785f88 Binary files /dev/null and b/mods/unified_inventory/textures/ui_iron_chest_inventory.png differ diff --git a/mods/unified_inventory/textures/ui_left_icon.png b/mods/unified_inventory/textures/ui_left_icon.png new file mode 100644 index 0000000..2534c77 Binary files /dev/null and b/mods/unified_inventory/textures/ui_left_icon.png differ diff --git a/mods/unified_inventory/textures/ui_lv_alloy_furnace.png b/mods/unified_inventory/textures/ui_lv_alloy_furnace.png new file mode 100644 index 0000000..3b98650 Binary files /dev/null and b/mods/unified_inventory/textures/ui_lv_alloy_furnace.png differ diff --git a/mods/unified_inventory/textures/ui_lv_battery_box.png b/mods/unified_inventory/textures/ui_lv_battery_box.png new file mode 100644 index 0000000..61c55de Binary files /dev/null and b/mods/unified_inventory/textures/ui_lv_battery_box.png differ diff --git a/mods/unified_inventory/textures/ui_lv_electric_furnace.png b/mods/unified_inventory/textures/ui_lv_electric_furnace.png new file mode 100644 index 0000000..a91b241 Binary files /dev/null and b/mods/unified_inventory/textures/ui_lv_electric_furnace.png differ diff --git a/mods/unified_inventory/textures/ui_lv_grinder.png b/mods/unified_inventory/textures/ui_lv_grinder.png new file mode 100644 index 0000000..7af5155 Binary files /dev/null and b/mods/unified_inventory/textures/ui_lv_grinder.png differ diff --git a/mods/unified_inventory/textures/ui_main_inventory.png b/mods/unified_inventory/textures/ui_main_inventory.png new file mode 100644 index 0000000..b65dabb Binary files /dev/null and b/mods/unified_inventory/textures/ui_main_inventory.png differ diff --git a/mods/unified_inventory/textures/ui_misc_form.png b/mods/unified_inventory/textures/ui_misc_form.png new file mode 100644 index 0000000..d34d326 Binary files /dev/null and b/mods/unified_inventory/textures/ui_misc_form.png differ diff --git a/mods/unified_inventory/textures/ui_mithril_chest_inventory.png b/mods/unified_inventory/textures/ui_mithril_chest_inventory.png new file mode 100644 index 0000000..9054775 Binary files /dev/null and b/mods/unified_inventory/textures/ui_mithril_chest_inventory.png differ diff --git a/mods/unified_inventory/textures/ui_moon_icon.png b/mods/unified_inventory/textures/ui_moon_icon.png new file mode 100644 index 0000000..f43fff8 Binary files /dev/null and b/mods/unified_inventory/textures/ui_moon_icon.png differ diff --git a/mods/unified_inventory/textures/ui_mv_battery_box.png b/mods/unified_inventory/textures/ui_mv_battery_box.png new file mode 100644 index 0000000..61c55de Binary files /dev/null and b/mods/unified_inventory/textures/ui_mv_battery_box.png differ diff --git a/mods/unified_inventory/textures/ui_right_icon.png b/mods/unified_inventory/textures/ui_right_icon.png new file mode 100644 index 0000000..5c2e7c5 Binary files /dev/null and b/mods/unified_inventory/textures/ui_right_icon.png differ diff --git a/mods/unified_inventory/textures/ui_search_icon.png b/mods/unified_inventory/textures/ui_search_icon.png new file mode 100644 index 0000000..b7284d1 Binary files /dev/null and b/mods/unified_inventory/textures/ui_search_icon.png differ diff --git a/mods/unified_inventory/textures/ui_sethome_icon.png b/mods/unified_inventory/textures/ui_sethome_icon.png new file mode 100644 index 0000000..7dbf1dc Binary files /dev/null and b/mods/unified_inventory/textures/ui_sethome_icon.png differ diff --git a/mods/unified_inventory/textures/ui_silver_chest_inventory.png b/mods/unified_inventory/textures/ui_silver_chest_inventory.png new file mode 100644 index 0000000..a61c4b9 Binary files /dev/null and b/mods/unified_inventory/textures/ui_silver_chest_inventory.png differ diff --git a/mods/unified_inventory/textures/ui_skip_backward_icon.png b/mods/unified_inventory/textures/ui_skip_backward_icon.png new file mode 100644 index 0000000..695d410 Binary files /dev/null and b/mods/unified_inventory/textures/ui_skip_backward_icon.png differ diff --git a/mods/unified_inventory/textures/ui_skip_forward_icon.png b/mods/unified_inventory/textures/ui_skip_forward_icon.png new file mode 100644 index 0000000..bd6948e Binary files /dev/null and b/mods/unified_inventory/textures/ui_skip_forward_icon.png differ diff --git a/mods/unified_inventory/textures/ui_sun_icon.png b/mods/unified_inventory/textures/ui_sun_icon.png new file mode 100644 index 0000000..89bb77c Binary files /dev/null and b/mods/unified_inventory/textures/ui_sun_icon.png differ diff --git a/mods/unified_inventory/textures/ui_trash_icon.png b/mods/unified_inventory/textures/ui_trash_icon.png new file mode 100644 index 0000000..180c827 Binary files /dev/null and b/mods/unified_inventory/textures/ui_trash_icon.png differ diff --git a/mods/unified_inventory/textures/ui_wooden_chest_inventory.png b/mods/unified_inventory/textures/ui_wooden_chest_inventory.png new file mode 100644 index 0000000..145d9d2 Binary files /dev/null and b/mods/unified_inventory/textures/ui_wooden_chest_inventory.png differ