From c0a7b5e9f21d873645a108df72d2697bc4aa4a65 Mon Sep 17 00:00:00 2001 From: OgelGames Date: Thu, 12 Nov 2020 18:26:31 +1100 Subject: [PATCH 1/4] rewrite chests with more functionality --- technic_chests/chests.lua | 152 +++++ technic_chests/common.lua | 88 --- technic_chests/copper_chest.lua | 46 -- technic_chests/depends.txt | 9 - technic_chests/digilines.lua | 93 +++ technic_chests/formspec.lua | 252 ++++++++ technic_chests/gold_chest.lua | 57 -- technic_chests/init.lua | 135 ++-- technic_chests/inventory.lua | 142 +++++ technic_chests/iron_chest.lua | 53 -- technic_chests/mithril_chest.lua | 71 --- technic_chests/mod.conf | 2 +- technic_chests/register.lua | 588 ++++++------------ technic_chests/silver_chest.lua | 48 -- .../textures/technic_protector_overlay.png | Bin 0 -> 138 bytes 15 files changed, 897 insertions(+), 839 deletions(-) create mode 100644 technic_chests/chests.lua delete mode 100644 technic_chests/common.lua delete mode 100644 technic_chests/copper_chest.lua delete mode 100644 technic_chests/depends.txt create mode 100644 technic_chests/digilines.lua create mode 100644 technic_chests/formspec.lua delete mode 100644 technic_chests/gold_chest.lua create mode 100644 technic_chests/inventory.lua delete mode 100644 technic_chests/iron_chest.lua delete mode 100644 technic_chests/mithril_chest.lua delete mode 100644 technic_chests/silver_chest.lua create mode 100644 technic_chests/textures/technic_protector_overlay.png diff --git a/technic_chests/chests.lua b/technic_chests/chests.lua new file mode 100644 index 0000000..51363e6 --- /dev/null +++ b/technic_chests/chests.lua @@ -0,0 +1,152 @@ + +local function register_chests(name, data) + for _,t in pairs({"", "_locked", "_protected"}) do + local data_copy = {} + for k, v in pairs(data) do + data_copy[k] = v + end + data_copy.locked = t == "_locked" + data_copy.protected = t == "_protected" + technic.chests.register_chest(name, data_copy) + end +end + +local function register_crafts(name, material, base_open, base_locked, base_protected) + name = name:lower() + if minetest.registered_items[material] then + if minetest.registered_items[base_open] then + minetest.register_craft({ + output = "technic:"..name.."_chest", + recipe = { + {material, material, material}, + {material, base_open, material}, + {material, material, material}, + } + }) + end + if minetest.registered_items[base_locked] then + minetest.register_craft({ + output = "technic:"..name.."_locked_chest", + recipe = { + {material, material, material}, + {material, base_locked, material}, + {material, material, material}, + } + }) + end + if minetest.registered_items[base_protected] then + minetest.register_craft({ + output = "technic:"..name.."_protected_chest", + recipe = { + {material, material, material}, + {material, base_protected, material}, + {material, material, material}, + } + }) + end + end + minetest.register_craft({ + output = "technic:"..name.."_locked_chest", + type = "shapeless", + recipe = {"basic_materials:padlock","technic:"..name.."_chest"} + }) + minetest.register_craft({ + output = "technic:"..name.."_protected_chest", + type = "shapeless", + recipe = {"default:copper_ingot", "technic:"..name.."_chest"} + }) + minetest.register_craft({ + output = "technic:"..name.."_chest", + type = "shapeless", + recipe = {"technic:"..name.."_locked_chest"} + }) + minetest.register_craft({ + output = "technic:"..name.."_chest", + type = "shapeless", + recipe = {"technic:"..name.."_protected_chest"} + }) +end + +-- Iron +register_chests("Iron", { + width = 9, + height = 5, + sort = true, + infotext = true, +}) +register_crafts( + "Iron", + minetest.get_modpath("technic_worldgen") and "technic:cast_iron_ingot" or "default:steel_ingot", + "default:chest", + "default:chest_locked", + "protector:chest" +) + +-- Copper +register_chests("Copper", { + width = 12, + height = 5, + sort = true, + infotext = true, + autosort = true, +}) +register_crafts( + "Copper", + "default:copper_ingot", + "technic:iron_chest", + "technic:iron_locked_chest", + "technic:iron_protected_chest" +) + +-- Silver +register_chests("Silver", { + width = 12, + height = 6, + sort = true, + infotext = true, + autosort = true, + quickmove = true, +}) +register_crafts( + "Silver", + "moreores:silver_ingot", + "technic:copper_chest", + "technic:copper_locked_chest", + "technic:copper_protected_chest" +) + +-- Gold +register_chests("Gold", { + width = 15, + height = 6, + sort = true, + infotext = true, + autosort = true, + quickmove = true, + color = true, +}) +register_crafts( + "Gold", + "default:gold_ingot", + minetest.get_modpath("moreores") and "technic:silver_chest" or "technic:copper_chest", + minetest.get_modpath("moreores") and "technic:silver_locked_chest" or "technic:copper_locked_chest", + minetest.get_modpath("moreores") and "technic:silver_protected_chest" or "technic:copper_protected_chest" +) + +-- Mithril +register_chests("Mithril", { + width = 15, + height = 6, + sort = true, + infotext = true, + autosort = true, + quickmove = true, + digilines = true, +}) +register_crafts( + "Mithril", + "moreores:mithril_ingot", + "technic:gold_chest", + "technic:gold_locked_chest", + "technic:gold_protected_chest" +) diff --git a/technic_chests/common.lua b/technic_chests/common.lua deleted file mode 100644 index e0e98b0..0000000 --- a/technic_chests/common.lua +++ /dev/null @@ -1,88 +0,0 @@ -technic.chests.groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, - tubedevice=1, tubedevice_receiver=1} -technic.chests.groups_noinv = {snappy=2, choppy=2, oddly_breakable_by_hand=2, - tubedevice=1, tubedevice_receiver=1, not_in_creative_inventory=1} - -technic.chests.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() - if meta:get_int("splitstacks") == 1 then - stack = stack:peek_item(1) - end - return inv:room_for_item("main",stack) - end, - input_inventory = "main", - connect_sides = {left=1, right=1, front=1, back=1, top=1, bottom=1}, -} - -technic.chests.can_dig = function(pos, player) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:is_empty("main") -end - --- utils for locked chest - -local function inv_change(pos, count, player) - -- Skip check for pipeworks (fake player) - if minetest.is_player(player) and - not default.can_interact_with_node(player, pos) then - return 0 - end - return count -end - -function technic.chests.inv_move(pos, from_list, from_index, to_list, to_index, count, player) - return inv_change(pos, count, player) -end -function technic.chests.inv_put(pos, listname, index, stack, player) - return inv_change(pos, stack:get_count(), player) -end -function technic.chests.inv_take(pos, listname, index, stack, player) - return inv_change(pos, stack:get_count(), player) -end - --- utils for protected chest - -local function inv_change_protected(pos, count, player) - if minetest.is_protected(pos, player:get_player_name()) then - return 0 - end - return count -end - -function technic.chests.inv_move_protected(pos, from_list, from_index, to_list, to_index, count, player) - return inv_change_protected(pos, count, player) -end -function technic.chests.inv_put_protected(pos, listname, index, stack, player) - return inv_change_protected(pos, stack:get_count(), player) -end -function technic.chests.inv_take_protected(pos, listname, index, stack, player) - return inv_change_protected(pos, stack:get_count(), player) -end - --- logging utils - -function technic.chests.on_inv_move(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in chest at " - ..minetest.pos_to_string(pos)) -end - -function technic.chests.on_inv_put(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name() .. - " moves " .. stack:get_name() .. - " to chest at " .. minetest.pos_to_string(pos)) -end - -function technic.chests.on_inv_take(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name() .. - " takes " .. stack:get_name() .. - " from chest at " .. minetest.pos_to_string(pos)) -end diff --git a/technic_chests/copper_chest.lua b/technic_chests/copper_chest.lua deleted file mode 100644 index dea384e..0000000 --- a/technic_chests/copper_chest.lua +++ /dev/null @@ -1,46 +0,0 @@ -minetest.register_craft({ - output = 'technic:copper_chest 1', - recipe = { - {'default:copper_ingot','default:copper_ingot','default:copper_ingot'}, - {'default:copper_ingot','technic:iron_chest','default:copper_ingot'}, - {'default:copper_ingot','default:copper_ingot','default:copper_ingot'}, - } -}) - -minetest.register_craft({ - output = 'technic:copper_locked_chest 1', - recipe = { - {'default:copper_ingot','default:copper_ingot','default:copper_ingot'}, - {'default:copper_ingot','technic:iron_locked_chest','default:copper_ingot'}, - {'default:copper_ingot','default:copper_ingot','default:copper_ingot'}, - } -}) - -minetest.register_craft({ - output = 'technic:copper_locked_chest 1', - type = "shapeless", - recipe = { - 'basic_materials:padlock', - 'technic:copper_chest', - } -}) - -technic.chests:register("Copper", { - width = 12, - height = 5, - sort = true, - autosort = true, - infotext = false, - color = false, - locked = false, -}) - -technic.chests:register("Copper", { - width = 12, - height = 5, - sort = true, - autosort = true, - infotext = false, - color = false, - locked = true, -}) diff --git a/technic_chests/depends.txt b/technic_chests/depends.txt deleted file mode 100644 index ac4a604..0000000 --- a/technic_chests/depends.txt +++ /dev/null @@ -1,9 +0,0 @@ -default -basic_materials -moreblocks? -moreores? -pipeworks? -intllib? -protector? -areas? -tubelib? diff --git a/technic_chests/digilines.lua b/technic_chests/digilines.lua new file mode 100644 index 0000000..b9d2383 --- /dev/null +++ b/technic_chests/digilines.lua @@ -0,0 +1,93 @@ + +function technic.chests.send_digiline_message(pos, event, player, items) + local set_channel = minetest.get_meta(pos):get_string("channel") + local player_name = player and player:get_player_name() or "" + digilines.receptor_send(pos, digilines.rules.default, set_channel, { + event = event, + items = items, + player = player_name, + pos = pos + }) +end + +local function item_matches(item, stack) + -- Same macthing as pipeworks filter injector + local name = stack:get_name() + local wear = stack:get_wear() + return (not item.name or name == item.name) + and (not item.group or (type(item.group) == "string" and minetest.get_item_group(name, item.group) ~= 0)) + and (not item.wear or (type(item.wear) == "number" and wear == item.wear) or (type(item.wear) == "table" + and (not item.wear[1] or (type(item.wear[1]) == "number" and item.wear[1] <= wear)) + and (not item.wear[2] or (type(item.wear[2]) == "number" and wear < item.wear[2])))) + and (not item.metadata or (type(item.metadata) == "string" and stack:get_metadata() == item.metadata)) +end + +function technic.chests.digiline_effector(pos, _, channel, msg) + local meta = minetest.get_meta(pos) + local set_channel = meta:get_string("channel") + if channel ~= set_channel then + return + end + if type(msg) ~= "table" or not msg.command then + return + end + local inv = meta:get_inventory() + + if msg.command == "sort" then + technic.chests.sort_inv(inv, meta:get_int("sort_mode")) + + elseif msg.command == "is_empty" then + local empty = inv:is_empty("main") + digilines.receptor_send(pos, digilines.rules.default, set_channel, empty) + + elseif msg.command == "get_list" then + local inv_table = {} + local list = inv:get_list("main") + if list then + for _,stack in ipairs(list) do + if not stack:is_empty() then + table.insert(inv_table, stack:get_name().." "..stack:get_count()) + else + table.insert(inv_table, "") + end + end + end + digilines.receptor_send(pos, digilines.rules.default, set_channel, inv_table) + + elseif msg.command == "get_stack" and type(msg.index) == "number" then + local stack = inv:get_stack("main", msg.index):to_table() + digilines.receptor_send(pos, digilines.rules.default, set_channel, stack) + + elseif msg.command == "contains_item" and (type(msg.item) == "string" or type(msg.item) == "table") then + local contains = inv:contains_item("main", msg.item) + digilines.receptor_send(pos, digilines.rules.default, set_channel, contains) + + elseif msg.command == "room_for_item" and (type(msg.item) == "string" or type(msg.item) == "table") then + local room = inv:room_for_item("main", msg.item) + digilines.receptor_send(pos, digilines.rules.default, set_channel, room) + + elseif msg.command == "count_item" and (type(msg.item) == "string" or type(msg.item) == "table") then + local count = 0 + local list = inv:get_list("main") + if list then + if type(msg.item) == "string" then + local itemstack = ItemStack(msg.item) + msg.item = { + name = itemstack:get_name(), + count = itemstack:get_count(), + wear = string.match(msg.item, "%S*:%S*%s%d%s(%d)") and itemstack:get_wear(), + metadata = string.match(msg.item, "%S*:%S*%s%d%s%d(%s.*)") and itemstack:get_meta():get_string("") + } + end + for _,stack in pairs(list) do + if not stack:is_empty() and item_matches(msg.item, stack) then + count = count + stack:get_count() + end + end + if msg.item.count and type(msg.item.count) == "number" and msg.item.count > 1 then + count = math.floor(count / msg.item.count) + end + end + digilines.receptor_send(pos, digilines.rules.default, set_channel, count) + end +end diff --git a/technic_chests/formspec.lua b/technic_chests/formspec.lua new file mode 100644 index 0000000..869efb6 --- /dev/null +++ b/technic_chests/formspec.lua @@ -0,0 +1,252 @@ + +local S = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end +--local S = minetest.get_translator("technic_chests") + +local has_pipeworks = minetest.get_modpath("pipeworks") +local has_digilines = minetest.get_modpath("digilines") + +local function get_pipeworks_fs(x, y, meta) + -- Use a container to reposition the pipeworks button. + return "container["..x..","..(y - 4.3).."]".. + pipeworks.fs_helpers.cycling_button( + meta, + pipeworks.button_base, + "splitstacks", + { + pipeworks.button_off, + pipeworks.button_on + } + )..pipeworks.button_label.."container_end[]" +end + +local function get_color_fs(x, y, meta) + local fs = "" + for a = 0, 3 do + for b = 0, 3 do + fs = fs.."image_button["..(x + b * 0.73)..","..(y + 0.1 + a * 0.79)..";0.8,0.8;".. + "technic_colorbutton"..(a * 4 + b)..".png;color_button"..(a * 4 + b + 1)..";]" + end + end + local selected = meta:get_int("color") + local color + if technic.chests.colors[selected] then + color = technic.chests.colors[selected][2] + else + color = S("None") + end + return fs.."label["..(x + 0.1)..","..(y + 3.4)..";"..S("Selected Color: %s"):format(color).."]" +end + +local function get_quickmove_fs(x, y) + return "button["..x..","..y..";3,1;existing_to_chest;"..S("Move existing to Chest").."]".. + "label["..(x + 0.1)..","..(y + 1.15)..";"..S("Move specific")..":\n("..S("Drop to move")..")]".. + "list[context;quickmove;"..(x + 1.8)..","..(y + 1.15)..";1,1]".. + "button["..x..","..(y + 2.3)..";3,1;all_to_chest;"..S("Move all to Chest").."]".. + "button["..x..","..(y + 3.2)..";3,1;all_to_inv;"..S("Move all to Inventory").."]" +end + +local function get_digilines_fs(x, y, meta) + local channel = minetest.formspec_escape(meta:get_string("channel")) + local put = meta:get_int("send_put") == 1 and "true" or "false" + local take = meta:get_int("send_take") == 1 and "true" or "false" + local inject = meta:get_int("send_inject") == 1 and "true" or "false" + local pull = meta:get_int("send_pull") == 1 and "true" or "false" + local overflow = meta:get_int("send_overflow") == 1 and "true" or "false" + return "field["..(x + 0.3)..","..(y + 0.5)..";3,1;channel;Digiline Channel:;"..channel.."]".. + "button["..(x + 0.5)..","..(y + 1.1)..";2,1;save_channel;Save Channel]".. + "checkbox["..(x + 0.1)..","..(y + 1.8)..";send_put;"..S("Send player put messages")..";"..put.."]".. + "checkbox["..(x + 0.1)..","..(y + 2.2)..";send_take;"..S("Send player take messages")..";"..take.."]".. + "checkbox["..(x + 0.1)..","..(y + 2.6)..";send_inject;"..S("Send tube inject messages")..";"..inject.."]".. + "checkbox["..(x + 0.1)..","..(y + 3.0)..";send_pull;"..S("Send tube pull messages")..";"..pull.."]".. + "checkbox["..(x + 0.1)..","..(y + 3.4)..";send_overflow;"..S("Send overflow messages")..";"..overflow.."]" +end + +local function get_infotext_fs(editing, meta) + local infotext = minetest.formspec_escape(meta:get_string("infotext")) + if editing then + return "image_button[0,0.1;0.8,0.8;technic_checkmark_icon.png;save_infotext;]".. + "field[1,0.3;4,1;infotext;;"..infotext.."]" + else + return "image_button[0,0.1;0.8,0.8;technic_pencil_icon.png;edit_infotext;]".. + "label[1,0;"..infotext.."]" + end +end + +local function get_autosort_fs(x, meta) + if meta:get_int("autosort") == 1 then + return "button["..x..",0;2,1;autosort;"..S("Auto-sort is On").."]" + else + return "button["..x..",0;2,1;autosort;"..S("Auto-sort is Off").."]" + end +end + +local function get_sort_fs(x, meta) + local mode = meta:get_int("sort_mode") + local fs = "button["..(x + 2)..",0;1,1;sort;"..S("Sort").."]" + if mode == 1 then + return fs.."button["..x..",0;2,1;sort_mode;"..S("Sort by Quantity").."]" + elseif mode == 2 then + return fs.."button["..x..",0;2,1;sort_mode;"..S("Sort by Type").."]" + elseif mode == 3 then + return fs.."button["..x..",0;2,1;sort_mode;"..S("Sort by Wear").."]" + else + return fs.."button["..x..",0;2,1;sort_mode;"..S("Sort by Item").."]" + end +end + +function technic.chests.get_formspec(data) + local formspec = {} + local top_width = (data.infotext and 6 or 0) + (data.autosort and 2 or 0) + (data.sort and 3 or 0) + local bottom_width = (data.quickmove and 3 or 0) + ((data.color or data.digilines) and 3 or 0) + 8 + local width = math.max(top_width, bottom_width, data.width) + local padding = (width - bottom_width) / 2 + if data.quickmove and (data.color or data.digilines) then + padding = (width - bottom_width) / 4 + elseif data.quickmove or data.color or data.digilines then + padding = (width - bottom_width) / 3 + end + local player_inv_left = padding + if data.quickmove then + player_inv_left = padding + 3 + padding + end + local player_inv_top = data.height + (has_pipeworks and 1.6 or 1.3) + local height = data.height + (has_pipeworks and 5.4 or 5.1) + local chest_inv_left = (width - data.width) / 2 + formspec.base = + "size["..width..","..height.."]".. + "list[context;main;"..chest_inv_left..",1;"..data.width..","..data.height..";]".. + "list[current_player;main;"..player_inv_left..","..player_inv_top..";8,4;]".. + "listring[context;main]".. + "listring[current_player;main]".. + default.get_hotbar_bg(player_inv_left, player_inv_top) + if data.quickmove then + formspec.base = formspec.base..get_quickmove_fs(padding, data.height + 1.2) + end + formspec.padding = padding + formspec.width = width + return formspec +end + +function technic.chests.update_formspec(pos, data, edit_infotext) + local formspec = data.formspec.base + local meta = minetest.get_meta(pos) + if data.infotext then + formspec = formspec..get_infotext_fs(edit_infotext, meta) + end + if data.sort then + formspec = formspec..get_sort_fs(data.formspec.width - 3, meta) + if data.autosort then + formspec = formspec..get_autosort_fs(data.formspec.width - 5, meta) + end + end + if has_pipeworks then + local offset = data.quickmove and (data.formspec.padding * 2 + 3) or data.formspec.padding + formspec = formspec..get_pipeworks_fs(offset, data.height + 1, meta) + end + if data.color or (data.digilines and has_digilines) then + local offset = data.quickmove and (data.formspec.padding * 3 + 11) or (data.formspec.padding * 2 + 8) + if data.color then + formspec = formspec..get_color_fs(offset, data.height + 1.2, meta) + else + formspec = formspec..get_digilines_fs(offset, data.height + 1.2, meta) + end + end + meta:set_string("formspec", formspec) +end + +function technic.chests.get_receive_fields(data) + return function(pos, formname, fields, player) + if not fields or not player then + return + end + local meta = minetest.get_meta(pos) + local chest_inv = meta:get_inventory() + local player_inv = player:get_inventory() + if fields.quit then + if meta:get_int("autosort") == 1 then + technic.chests.sort_inv(chest_inv, meta:get_int("sort_mode")) + end + technic.chests.update_formspec(pos, data) + return + end + if not technic.chests.change_allowed(pos, player, data.locked, data.protected) then + return + end + if has_pipeworks then + pipeworks.fs_helpers.on_receive_fields(pos, fields) + end + if data.sort then + if fields.sort then + technic.chests.sort_inv(chest_inv, meta:get_int("sort_mode")) + end + if fields.sort_mode then + local value = meta:get_int("sort_mode") + 1 + if value < 0 or value > 3 then + value = 0 + end + meta:set_int("sort_mode", value) + end + end + if data.autosort and fields.autosort then + local value = meta:get_int("autosort") == 1 and 0 or 1 + meta:set_int("autosort", value) + end + if data.quickmove then + if fields.all_to_chest then + local moved_items = technic.chests.move_inv(player_inv, chest_inv) + if has_digilines and meta:get_int("send_put") == 1 then + technic.chests.send_digiline_message(pos, "put", player, moved_items) + end + technic.chests.log_inv_change(pos, player:get_player_name(), "put", "stuff") + elseif fields.all_to_inv then + local moved_items = technic.chests.move_inv(chest_inv, player_inv) + if has_digilines and meta:get_int("send_take") == 1 then + technic.chests.send_digiline_message(pos, "take", player, moved_items) + end + technic.chests.log_inv_change(pos, player:get_player_name(), "take", "stuff") + elseif fields.existing_to_chest then + local items = technic.chests.get_inv_items(chest_inv) + local moved_items = technic.chests.move_inv(player_inv, chest_inv, items) + if has_digilines and meta:get_int("send_put") == 1 then + technic.chests.send_digiline_message(pos, "put", player, moved_items) + end + technic.chests.log_inv_change(pos, player:get_player_name(), "put", "stuff") + end + end + if data.color then + for i = 1, 16 do + if fields["color_button"..i] then + local node = minetest.get_node(pos) + if technic.chests.colors[i] then + node.name = data.node_name.."_"..technic.chests.colors[i][1] + else + node.name = data.node_name + end + minetest.swap_node(pos, node) + meta:set_string("color", i) + break + end + end + end + if data.digilines and has_digilines then + if fields.save_channel and fields.channel then + meta:set_string("channel", fields.channel) + end + for _,setting in pairs({"send_put", "send_take", "send_inject", "send_pull", "send_overflow"}) do + if fields[setting] then + local value = fields[setting] == "true" and 1 or 0 + meta:set_int(setting, value) + end + end + end + if data.infotext then + if fields.edit_infotext then + technic.chests.update_formspec(pos, data, true) + return + elseif fields.save_infotext and fields.infotext then + meta:set_string("infotext", fields.infotext) + end + end + technic.chests.update_formspec(pos, data) + end +end diff --git a/technic_chests/gold_chest.lua b/technic_chests/gold_chest.lua deleted file mode 100644 index e308c8b..0000000 --- a/technic_chests/gold_chest.lua +++ /dev/null @@ -1,57 +0,0 @@ - -local material_list -if minetest.get_modpath("moreores") then - material_list = { 'silver' } -else - -- Make the gold chest obtainable for mere mortals (the silver chest is not obtainable) - material_list = { 'copper', 'silver' } -end - -for _, material in ipairs(material_list) do - minetest.register_craft({ - output = 'technic:gold_chest', - recipe = { - {'default:gold_ingot','default:gold_ingot','default:gold_ingot'}, - {'default:gold_ingot',"technic:"..material.."_chest",'default:gold_ingot'}, - {'default:gold_ingot','default:gold_ingot','default:gold_ingot'}, - } - }) - - minetest.register_craft({ - output = 'technic:gold_locked_chest', - recipe = { - {'default:gold_ingot','default:gold_ingot','default:gold_ingot'}, - {'default:gold_ingot',"technic:"..material.."_locked_chest",'default:gold_ingot'}, - {'default:gold_ingot','default:gold_ingot','default:gold_ingot'}, - } - }) -end - -minetest.register_craft({ - output = 'technic:gold_locked_chest', - type = "shapeless", - recipe = { - 'basic_materials:padlock', - 'technic:gold_chest', - } -}) - -technic.chests:register("Gold", { - width = 15, - height = 6, - sort = true, - autosort = true, - infotext = true, - color = true, - locked = false, -}) - -technic.chests:register("Gold", { - width = 15, - height = 6, - sort = true, - autosort = true, - infotext = true, - color = true, - locked = true, -}) diff --git a/technic_chests/init.lua b/technic_chests/init.lua index 188e516..1cd0534 100644 --- a/technic_chests/init.lua +++ b/technic_chests/init.lua @@ -1,82 +1,83 @@ --- Minetest 0.4.6 mod: technic_chests --- namespace: technic --- (c) 2012-2013 by RealBadAngel + +local S = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end +--local S = minetest.get_translator("technic_chests") local modpath = minetest.get_modpath("technic_chests") technic = rawget(_G, "technic") or {} technic.chests = {} -dofile(modpath.."/common.lua") -dofile(modpath.."/register.lua") -dofile(modpath.."/iron_chest.lua") -dofile(modpath.."/copper_chest.lua") -dofile(modpath.."/silver_chest.lua") -dofile(modpath.."/gold_chest.lua") -dofile(modpath.."/mithril_chest.lua") +technic.chests.colors = { + {"black", S("Black")}, + {"blue", S("Blue")}, + {"brown", S("Brown")}, + {"cyan", S("Cyan")}, + {"dark_green", S("Dark Green")}, + {"dark_grey", S("Dark Grey")}, + {"green", S("Green")}, + {"grey", S("Grey")}, + {"magenta", S("Magenta")}, + {"orange", S("Orange")}, + {"pink", S("Pink")}, + {"red", S("Red")}, + {"violet", S("Violet")}, + {"white", S("White")}, + {"yellow", S("Yellow")}, +} --- undo all of the locked wooden chest recipes created by default and --- moreblocks, and just make them use a padlock. - -if minetest.get_modpath("moreblocks") then - minetest.clear_craft({ - type = "shapeless", - recipe = { - "default:chest", - "default:gold_ingot", - } - }) - - minetest.clear_craft({ - type = "shapeless", - recipe = { - "default:chest", - "default:bronze_ingot", - } - }) - - minetest.clear_craft({ - type = "shapeless", - recipe = { - "default:chest", - "default:copper_ingot", - } - }) +function technic.chests.change_allowed(pos, player, owned, protected) + if owned then + if minetest.is_player(player) and not default.can_interact_with_node(player, pos) then + return false + end + elseif protected then + if minetest.is_protected(pos, player:get_player_name()) then + return false + end + end + return true end -minetest.clear_craft({ - type = "shapeless", - recipe = { - "default:chest", - "default:steel_ingot", - } -}) +if minetest.get_modpath("digilines") then + dofile(modpath.."/digilines.lua") +end -minetest.clear_craft({output = "default:chest_locked"}) +dofile(modpath.."/formspec.lua") +dofile(modpath.."/inventory.lua") +dofile(modpath.."/register.lua") +dofile(modpath.."/chests.lua") -minetest.register_craft({ - output = "default:chest_locked", - recipe = { - { "group:wood", "group:wood", "group:wood" }, - { "group:wood", "basic_materials:padlock", "group:wood" }, - { "group:wood", "group:wood", "group:wood" } - } -}) - -minetest.register_craft({ - output = "default:chest_locked", - type = "shapeless", - recipe = { - "default:chest", - "basic_materials:padlock" - } -}) +-- Undo all of the locked wooden chest recipes, and just make them use a padlock. +minetest.register_on_mods_loaded(function() + minetest.clear_craft({output = "default:chest_locked"}) + minetest.register_craft({ + output = "default:chest_locked", + recipe = { + { "group:wood", "group:wood", "group:wood" }, + { "group:wood", "basic_materials:padlock", "group:wood" }, + { "group:wood", "group:wood", "group:wood" } + } + }) + minetest.register_craft({ + output = "default:chest_locked", + type = "shapeless", + recipe = { + "default:chest", + "basic_materials:padlock" + } + }) +end) +-- Conversion for old chests minetest.register_lbm({ - name = "technic_chests:fix_wooden_chests", - nodenames = {"default:chest"}, + name = "technic_chests:old_chest_conversion", + nodenames = {"group:technic_chest"}, + run_at_every_load = false, action = function(pos, node) - local meta = minetest.get_meta(pos) - meta:set_string("formspec", "") - end + -- Use `on_construct` function because that has data from register function + local def = minetest.registered_nodes[node.name] + if def and def.on_construct then + def.on_construct(pos) + end + end, }) diff --git a/technic_chests/inventory.lua b/technic_chests/inventory.lua new file mode 100644 index 0000000..0f5f692 --- /dev/null +++ b/technic_chests/inventory.lua @@ -0,0 +1,142 @@ + +-- Table to define order of type sorting +local itemtypes = { + node = 1, + tool = 2, + craft = 3, + none = 4 +} + +function technic.chests.sort_inv(inv, mode) + local list = inv:get_list("main") + if not list then return end + local items = {} + for _,stack in pairs(list) do + if not stack:is_empty() then + local name = stack:get_name() + local wear = stack:get_wear() + local meta = stack:get_metadata() + local count = stack:get_count() + local def = minetest.registered_items[name] + local itemtype = (def and itemtypes[def.type]) and def.type or "none" + local key = string.format("%s %05d %s", name, wear, meta) + if not items[key] then + items[key] = { + stacks = {stack}, + wear = wear, + count = count, + itemtype = itemtype, + key = key, + } + else + items[key].count = items[key].count + count + table.insert(items[key].stacks, stack) + end + end + end + local unique_items = {} + for k,v in pairs(items) do + table.insert(unique_items, v) + end + if mode == 1 then + -- Quantity + table.sort(unique_items, function(a, b) + if a.count ~= b.count then + return a.count > b.count + end + return a.key < b.key + end) + elseif mode == 2 then + -- Type + table.sort(unique_items, function(a, b) + if itemtypes[a.itemtype] ~= itemtypes[b.itemtype] then + return itemtypes[a.itemtype] < itemtypes[b.itemtype] + end + return a.key < b.key + end) + elseif mode == 3 then + -- Wear + table.sort(unique_items, function(a, b) + if a.itemtype == "tool" and b.itemtype == "tool" then + if a.wear ~= b.wear then + return a.wear < b.wear + end + return a.key < b.key + elseif a.itemtype == "tool" or b.itemtype == "tool" then + return a.itemtype == "tool" + end + return a.key < b.key + end) + else + -- Item + table.sort(unique_items, function(a, b) + return a.key < b.key + end) + end + inv:set_list("main", {}) + for _,item in ipairs(unique_items) do + for _,stack in ipairs(item.stacks) do + inv:add_item("main", stack) + end + end +end + +function technic.chests.get_inv_items(inv) + local list = inv:get_list("main") + if not list then return {} end + local keys = {} + for _,stack in pairs(list) do + if not stack:is_empty() then + keys[stack:get_name()] = true + end + end + local items = {} + for k,_ in pairs(keys) do + items[#items + 1] = k + end + return items +end + +function technic.chests.move_inv(from_inv, to_inv, filter) + local list = from_inv:get_list("main") + if not list then return {} end + local moved_items = {} + for i,stack in ipairs(list) do + if not stack:is_empty() then + local move_stack = false + local name = stack:get_name() + if name == filter or not filter then + move_stack = true + elseif type(filter) == "table" then + for _,k in pairs(filter) do + if name == k then + move_stack = true + break + end + end + end + if move_stack then + local leftover = to_inv:add_item("main", stack) + if not leftover:is_empty() then + from_inv:set_stack("main", i, leftover) + stack:set_count(stack:get_count() - leftover:get_count()) + else + from_inv:set_stack("main", i, "") + end + table.insert(moved_items, stack:to_table()) + end + end + end + return moved_items +end + +function technic.chests.log_inv_change(pos, name, change, items) + local spos = minetest.pos_to_string(pos) + if change == "move" then + minetest.log("action", name.." moves "..items.." in chest at "..spos) + elseif change == "put" then + minetest.log("action", name.." puts "..items.." into chest at "..spos) + elseif change == "take" then + minetest.log("action", name.." takes "..items.." from chest at "..spos) + end +end diff --git a/technic_chests/iron_chest.lua b/technic_chests/iron_chest.lua deleted file mode 100644 index 2287448..0000000 --- a/technic_chests/iron_chest.lua +++ /dev/null @@ -1,53 +0,0 @@ -local cast_iron_ingot -if minetest.get_modpath("technic_worldgen") then - cast_iron_ingot = "technic:cast_iron_ingot" -else - cast_iron_ingot = "default:steel_ingot" -end - -minetest.register_craft({ - output = 'technic:iron_chest 1', - recipe = { - {cast_iron_ingot,cast_iron_ingot,cast_iron_ingot}, - {cast_iron_ingot,'default:chest',cast_iron_ingot}, - {cast_iron_ingot,cast_iron_ingot,cast_iron_ingot}, - } -}) - -minetest.register_craft({ - output = 'technic:iron_locked_chest 1', - recipe = { - {cast_iron_ingot,cast_iron_ingot,cast_iron_ingot}, - {cast_iron_ingot,'default:chest_locked',cast_iron_ingot}, - {cast_iron_ingot,cast_iron_ingot,cast_iron_ingot}, - } -}) - -minetest.register_craft({ - output = 'technic:iron_locked_chest 1', - type = "shapeless", - recipe = { - 'basic_materials:padlock', - 'technic:iron_chest', - } -}) - -technic.chests:register("Iron", { - width = 9, - height = 5, - sort = true, - autosort = false, - infotext = false, - color = false, - locked = false, -}) - -technic.chests:register("Iron", { - width = 9, - height = 5, - sort = true, - autosort = false, - infotext = false, - color = false, - locked = true, -}) diff --git a/technic_chests/mithril_chest.lua b/technic_chests/mithril_chest.lua deleted file mode 100644 index 71b11a6..0000000 --- a/technic_chests/mithril_chest.lua +++ /dev/null @@ -1,71 +0,0 @@ -if minetest.get_modpath("moreores") then - minetest.register_craft({ - output = 'technic:mithril_chest 1', - recipe = { - {'moreores:mithril_ingot','moreores:mithril_ingot','moreores:mithril_ingot'}, - {'moreores:mithril_ingot','technic:gold_chest','moreores:mithril_ingot'}, - {'moreores:mithril_ingot','moreores:mithril_ingot','moreores:mithril_ingot'}, - } - }) - - minetest.register_craft({ - output = 'technic:mithril_locked_chest 1', - recipe = { - {'moreores:mithril_ingot','moreores:mithril_ingot','moreores:mithril_ingot'}, - {'moreores:mithril_ingot','technic:gold_locked_chest','moreores:mithril_ingot'}, - {'moreores:mithril_ingot','moreores:mithril_ingot','moreores:mithril_ingot'}, - } - }) -end - -minetest.register_craft({ - output = 'technic:mithril_locked_chest 1', - type = "shapeless", - recipe = { - 'basic_materials:padlock', - 'technic:mithril_chest', - } -}) - --- plain chest -technic.chests:register("Mithril", { - width = 15, - height = 6, - sort = true, - autosort = true, - infotext = false, - color = false, - locked = false, -}) - --- owned locked chest -technic.chests:register("Mithril", { - width = 15, - height = 6, - sort = true, - autosort = true, - infotext = false, - color = false, - locked = true, -}) - -if minetest.get_modpath("protector") or minetest.get_modpath("areas") then - -- protected chest (works with any protection mod that overrides minetest.is_protected) - technic.chests:register("Mithril", { - width = 15, - height = 6, - sort = true, - autosort = true, - infotext = false, - color = false, - protected = true, - }) - - minetest.register_craft({ - output = 'technic:mithril_protected_chest 1', - recipe = { - {'basic_materials:padlock'}, - {'technic:mithril_locked_chest'}, - } - }) -end diff --git a/technic_chests/mod.conf b/technic_chests/mod.conf index 99048c3..1afe533 100644 --- a/technic_chests/mod.conf +++ b/technic_chests/mod.conf @@ -1,3 +1,3 @@ name = technic_chests depends = default, basic_materials -optional_depends = moreblocks, moreores, pipeworks, intllib, tubelib +optional_depends = moreores, pipeworks, protector, digilines, intllib diff --git a/technic_chests/register.lua b/technic_chests/register.lua index 12b024b..8861539 100644 --- a/technic_chests/register.lua +++ b/technic_chests/register.lua @@ -1,452 +1,242 @@ + local S = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end +--local S = minetest.get_translator("technic_chests") -local pipeworks = rawget(_G, "pipeworks") -local fs_helpers = rawget(_G, "fs_helpers") -local tubelib_exists = minetest.global_exists("tubelib") +local has_pipeworks = minetest.get_modpath("pipeworks") +local has_digilines = minetest.get_modpath("digilines") +local has_protector = minetest.get_modpath("protector") -local has_protector_mod = minetest.get_modpath("protector") +local tube_entry = has_pipeworks and "^pipeworks_tube_connection_metallic.png" or "" +local protector_overlay = has_protector and "^protector_logo.png" or "^technic_protector_overlay.png" -local allow_label = "" -local tube_entry = "" -local shift_edit_field = 0 - -if not minetest.get_modpath("pipeworks") then - -- Pipeworks is not installed. Simulate using a dummy table... - pipeworks = {} - fs_helpers = {} - local pipeworks_meta = {} - setmetatable(pipeworks, pipeworks_meta) - local dummy = function() - end - pipeworks_meta.__index = function(table, key) - print("[technic_chests] WARNING: variable or method '"..key.."' not present in dummy pipeworks table - assuming it is a method...") - pipeworks[key] = dummy - return dummy - end - pipeworks.after_place = dummy - pipeworks.after_dig = dummy - fs_helpers.cycling_button = function() return "" end -else - fs_helpers = pipeworks.fs_helpers - allow_label = "label[0.9,0.36;Allow splitting incoming stacks from tubes]" - shift_edit_field = 3 - tube_entry = "^pipeworks_tube_connection_metallic.png" -end - -local chest_mark_colors = { - {"black", S("Black")}, - {"blue", S("Blue")}, - {"brown", S("Brown")}, - {"cyan", S("Cyan")}, - {"dark_green", S("Dark Green")}, - {"dark_grey", S("Dark Grey")}, - {"green", S("Green")}, - {"grey", S("Grey")}, - {"magenta", S("Magenta")}, - {"orange", S("Orange")}, - {"pink", S("Pink")}, - {"red", S("Red")}, - {"violet", S("Violet")}, - {"white", S("White")}, - {"yellow", S("Yellow")}, +local node_groups = { + snappy = 2, + choppy = 2, + oddly_breakable_by_hand = 2, + tubedevice = 1, + tubedevice_receiver = 1, + technic_chest = 1, } +local node_groups_no_inv = { + snappy = 2, + choppy = 2, + oddly_breakable_by_hand = 2, + tubedevice = 1, + tubedevice_receiver = 1, + technic_chest = 1, + not_in_creative_inventory = 1, +} -local function colorid_to_postfix(id) - return chest_mark_colors[id] and "_"..chest_mark_colors[id][1] or "" +local function get_tiles(name, data, color) + local tiles = { + "technic_"..name.."_chest_top.png"..tube_entry, + "technic_"..name.."_chest_top.png"..tube_entry, + "technic_"..name.."_chest_side.png"..tube_entry, + "technic_"..name.."_chest_side.png"..tube_entry, + "technic_"..name.."_chest_side.png"..tube_entry, + "technic_"..name.."_chest_front.png" + } + if data.color and color then + tiles[6] = tiles[6].."^technic_chest_overlay_"..technic.chests.colors[color][1]..".png" + end + if data.locked then + tiles[6] = tiles[6].."^technic_"..name.."_chest_lock_overlay.png" + elseif data.protected then + tiles[6] = tiles[6]..protector_overlay + end + return tiles end - -local function get_color_buttons(coleft, lotop) - local buttons_string = "" - for y = 0, 3 do - for x = 0, 3 do - local file_name = "technic_colorbutton"..(y * 4 + x)..".png" - buttons_string = buttons_string.."image_button[" - ..(coleft + 0.1 + x * 0.7)..","..(lotop + 0.1 + y * 0.7) - ..";0.8,0.8;"..file_name..";color_button" - ..(y * 4 + x + 1)..";]" - end - end - return buttons_string -end - - -local function check_color_buttons(pos, meta, chest_name, fields) - for i = 1, 16 do - if fields["color_button"..i] then - local node = minetest.get_node(pos) - node.name = chest_name..colorid_to_postfix(i) - minetest.swap_node(pos, node) - meta:set_string("color", i) - return - end - end -end - -local function set_formspec(pos, data, page) - local meta = minetest.get_meta(pos) - local formspec = data.base_formspec - formspec = formspec..fs_helpers.cycling_button( - meta, - "image_button[0,0.35;1,0.6", - "splitstacks", - { - pipeworks.button_off, - pipeworks.button_on - } - )..allow_label - - if data.autosort then - local status = meta:get_int("autosort") - formspec = formspec.."button["..(data.hileft+2)..","..(data.height+1.1)..";3,0.8;autosort_to_"..(1-status)..";"..S("Auto-sort is %s"):format(status == 1 and S("On") or S("Off")).."]" - end - if data.infotext then - local formspec_infotext = minetest.formspec_escape(meta:get_string("infotext")) - if page == "main" then - formspec = formspec.."image_button["..(shift_edit_field+data.hileft+2.1)..",0.1;0.8,0.8;" - .."technic_pencil_icon.png;edit_infotext;]" - .."label["..(shift_edit_field+data.hileft+3)..",0;"..formspec_infotext.."]" - elseif page == "edit_infotext" then - formspec = formspec.."image_button["..(shift_edit_field+data.hileft+2.1)..",0.1;0.8,0.8;" - .."technic_checkmark_icon.png;save_infotext;]" - .."field["..(shift_edit_field+data.hileft+3.3)..",0.2;4.8,1;" - .."infotext_box;"..S("Edit chest description:")..";" - ..formspec_infotext.."]" - end - end - if data.color then - local colorID = meta:get_int("color") - local colorName - if chest_mark_colors[colorID] then - colorName = chest_mark_colors[colorID][2] - else - colorName = S("None") - end - formspec = formspec.."label["..(data.coleft+0.2)..","..(data.lotop+3)..";"..S("Color Filter: %s"):format(colorName).."]" - end - meta:set_string("formspec", formspec) -end - -local function sort_inventory(inv) - local inlist = inv:get_list("main") - local typecnt = {} - local typekeys = {} - for _, st in ipairs(inlist) do - if not st:is_empty() then - local n = st:get_name() - local w = st:get_wear() - local m = st:get_metadata() - local k = string.format("%s %05d %s", n, w, m) - if not typecnt[k] then - typecnt[k] = {st} - table.insert(typekeys, k) - else - table.insert(typecnt[k], st) - end - end - end - table.sort(typekeys) - inv:set_list("main", {}) - for _, k in ipairs(typekeys) do - for _, item in ipairs(typecnt[k]) do - inv:add_item("main", item) - end - end -end - -local function get_receive_fields(name, data, locked) - local lname = name:lower() - return function(pos, formname, fields, sender) - local meta = minetest.get_meta(pos) - - if locked then - -- locked chest, check accessing player - local owner = meta:get_string("owner") - if owner ~= sender:get_player_name() then - -- non-owner, abort - return - end - end - - local page = "main" - - local owner = meta:get_string("owner") - if owner ~= "" then - -- prevent modification of locked chests - if owner ~= sender:get_player_name() then return end - elseif not fields.quit then - -- prevent modification of protected chests - if minetest.is_protected(pos, sender:get_player_name()) then return end - end - - if fields.sort or (data.autosort and fields.quit and meta:get_int("autosort") == 1) then - sort_inventory(meta:get_inventory()) - end - if fields.edit_infotext then - page = "edit_infotext" - end - if fields.autosort_to_1 then meta:set_int("autosort", 1) end - if fields.autosort_to_0 then meta:set_int("autosort", 0) end - if fields.infotext_box then - meta:set_string("infotext", fields.infotext_box) - end - if data.color then - -- This sets the node - local nn = "technic:"..lname..(data.locked and "_locked" or "").."_chest" - check_color_buttons(pos, meta, nn, fields) - end - if fields["fs_helpers_cycling:0:splitstacks"] - or fields["fs_helpers_cycling:1:splitstacks"] then - if not pipeworks.may_configure(pos, sender) then return end - fs_helpers.on_receive_fields(pos, fields) - end - - meta:get_inventory():set_size("main", data.width * data.height) - set_formspec(pos, data, page) - end -end - -function technic.chests:definition(name, data) +function technic.chests.register_chest(name, data) local lname = name:lower() name = S(name) - local d = {} - for k, v in pairs(data) do d[k] = v end - data = d - - data.lowidth = 8 - data.ovwidth = math.max(data.lowidth, data.width) - data.hileft = (data.ovwidth - data.width) / 2 - data.loleft = (data.ovwidth - data.lowidth) / 2 - if data.color then - if data.lowidth + 3 <= data.ovwidth then - data.coleft = data.ovwidth - 3 - if data.loleft + data.lowidth > data.coleft then - data.loleft = data.coleft - data.lowidth - end - else - data.loleft = 0 - data.coleft = data.lowidth - data.ovwidth = data.lowidth + 3 - end - end - data.lotop = data.height + 2 - data.ovheight = data.lotop + 4 - - local locked_after_place = nil - local front = {"technic_"..lname.."_chest_front.png"} - data.base_formspec = "size["..data.ovwidth..","..data.ovheight.."]".. - "label[0,0;"..S("%s Chest"):format(name).."]".. - "list[context;main;"..data.hileft..",1;"..data.width..","..data.height..";]".. - "list[current_player;main;"..data.loleft..","..data.lotop..";8,4;]".. - "background[-0.19,-0.25;"..(data.ovwidth+0.4)..","..(data.ovheight+0.75)..";technic_chest_form_bg.png]".. - "background["..data.hileft..",1;"..data.width..","..data.height..";technic_"..lname.."_chest_inventory.png]".. - "background["..data.loleft..","..data.lotop..";8,4;technic_main_inventory.png]".. - "listring[]" - - if data.sort then - data.base_formspec = data.base_formspec.."button["..data.hileft..","..(data.height+1.1)..";1,0.8;sort;"..S("Sort").."]" - end - if data.color then - data.base_formspec = data.base_formspec..get_color_buttons(data.coleft, data.lotop) - end - if data.locked then - locked_after_place = function(pos, placer) - local meta = minetest.get_meta(pos) - meta:set_string("owner", placer:get_player_name() or "") - meta:set_string("infotext", - S("%s Locked Chest (owned by %s)") - :format(name, meta:get_string("owner"))) - pipeworks.after_place(pos) - end - else - locked_after_place = pipeworks.after_place - end - - if data.locked then - table.insert(front, "technic_"..lname.."_chest_lock_overlay.png") - end - - if data.protected and has_protector_mod then - -- use overlay from protector mod - table.insert(front, "protector_logo.png") - end - - - local desc - if data.locked then - desc = S("%s Locked Chest"):format(name) + data.node_name = "technic:"..lname.."_locked_chest" + data.description = S("%s Locked Chest"):format(name) elseif data.protected then - desc = S("%s Protected Chest"):format(name) + data.node_name = "technic:"..lname.."_protected_chest" + data.description = S("%s Protected Chest"):format(name) else - desc = S("%s Chest"):format(name) - end - - local tentry = tube_entry - if tube_entry ~= "" then - if lname == "wooden" then - tentry = "^pipeworks_tube_connection_wooden.png" - elseif lname == "mithril" then - tentry = "^pipeworks_tube_connection_stony.png" - end + data.node_name = "technic:"..lname.."_chest" + data.description = S("%s Chest"):format(name) end + data.formspec = technic.chests.get_formspec(data) local def = { - description = desc, - tiles = { - "technic_"..lname.."_chest_top.png"..tentry, - "technic_"..lname.."_chest_top.png"..tentry, - "technic_"..lname.."_chest_side.png"..tentry, - "technic_"..lname.."_chest_side.png"..tentry, - "technic_"..lname.."_chest_side.png"..tentry, - table.concat(front, "^") - }, + description = data.description, + tiles = get_tiles(lname, data), paramtype2 = "facedir", - groups = self.groups, - tube = self.tube, legacy_facedir_simple = true, + groups = node_groups, sounds = default.node_sound_wood_defaults(), - after_place_node = locked_after_place, - after_dig_node = pipeworks.after_dig, - - on_construct = function(pos) + drop = data.node_name, + after_place_node = function(pos, placer) local meta = minetest.get_meta(pos) - meta:set_string("infotext", S("%s Chest"):format(name)) - set_formspec(pos, data, "main") - local inv = meta:get_inventory() - inv:set_size("main", data.width * data.height) + if data.locked then + local owner = placer:get_player_name() or "" + meta:set_string("owner", owner) + meta:set_string("infotext", S("%s Locked Chest (owned by %s)"):format(name, owner)) + else + meta:set_string("infotext", data.description) + end + if has_pipeworks then + pipeworks.after_place(pos) + end + end, + after_dig_node = function(pos) + if has_pipeworks then + pipeworks.after_dig(pos) + end + end, + tube = { + insert_object = function(pos, node, stack) + local meta = minetest.get_meta(pos) + if data.digilines and has_digilines and meta:get_int("send_inject") then + technic.chests.send_digiline_message(pos, "inject", nil, {stack:to_table()}) + end + technic.chests.log_inv_change(pos, "pipeworks tube", "put", stack:get_name()) + return meta:get_inventory():add_item("main", stack) + end, + can_insert = function(pos, node, stack) + local meta = minetest.get_meta(pos) + if meta:get_int("splitstacks") == 1 then + stack = stack:peek_item(1) + end + local can_insert = meta:get_inventory():room_for_item("main", stack) + if not can_insert and data.digilines and has_digilines and meta:get_int("send_overflow") then + technic.chests.send_digiline_message(pos, "overflow", nil, {stack:to_table()}) + end + return can_insert + end, + remove_items = function(pos, node, stack) + local meta = minetest.get_meta(pos) + local removed = meta:get_inventory():remove_item("main", stack) + if data.digilines and has_digilines and meta:get_int("send_pull") then + technic.chests.send_digiline_message(pos, "pull", nil, {removed:to_table()}) + end + technic.chests.log_inv_change(pos, "pipeworks tube", "take", stack:get_name()) + return removed + end, + input_inventory = "main", + connect_sides = {left=1, right=1, front=1, back=1, top=1, bottom=1}, + }, + on_construct = function(pos) + local inv = minetest.get_meta(pos):get_inventory() + inv:set_size("main", data.width * data.height) + if data.quickmove then + inv:set_size("quickmove", 1) + end + technic.chests.update_formspec(pos, data) + end, + can_dig = function(pos, player) + if not technic.chests.change_allowed(pos, player, data.locked, data.protected) then + return false + end + return minetest.get_meta(pos):get_inventory():is_empty("main") + end, + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + if not technic.chests.change_allowed(pos, player, data.locked, data.protected) then + return 0 + end + if data.quickmove and to_list == "quickmove" then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack("main", from_index) + local moved_items = technic.chests.move_inv(inv, player:get_inventory(), stack:get_name()) + if data.digilines and has_digilines and meta:get_int("send_take") == 1 then + technic.chests.send_digiline_message(pos, "take", player, moved_items) + end + technic.chests.log_inv_change(pos, player:get_player_name(), "take", "stuff") + return 0 + end + return count + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if not technic.chests.change_allowed(pos, player, data.locked, data.protected) then + return 0 + end + if data.quickmove and listname == "quickmove" then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local moved_items = technic.chests.move_inv(player:get_inventory(), inv, stack:get_name()) + if data.digilines and has_digilines and meta:get_int("send_put") == 1 then + technic.chests.send_digiline_message(pos, "put", player, moved_items) + end + technic.chests.log_inv_change(pos, player:get_player_name(), "put", "stuff") + return 0 + end + return stack:get_count() + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if not technic.chests.change_allowed(pos, player, data.locked, data.protected) then + return 0 + end + return stack:get_count() + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + technic.chests.log_inv_change(pos, player:get_player_name(), "move", "stuff") + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + if data.digilines and has_digilines and minetest.get_meta(pos):get_int("send_put") == 1 then + technic.chests.send_digiline_message(pos, "put", player, {stack:to_table()}) + end + technic.chests.log_inv_change(pos, player:get_player_name(), "put", stack:get_name()) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + if data.digilines and has_digilines and minetest.get_meta(pos):get_int("send_take") == 1 then + technic.chests.send_digiline_message(pos, "take", player, {stack:to_table()}) + end + technic.chests.log_inv_change(pos, player:get_player_name(), "take", stack:get_name()) end, - can_dig = self.can_dig, - on_receive_fields = get_receive_fields(name, data, data.locked), - on_metadata_inventory_move = self.on_inv_move, - on_metadata_inventory_put = self.on_inv_put, - on_metadata_inventory_take = self.on_inv_take, on_blast = function(pos) + if data.locked or data.protected then + return + end local drops = {} default.get_inventory_drops(pos, "main", drops) - drops[#drops+1] = "technic:"..name:lower()..(data.locked and "_locked" or "").."_chest" + drops[#drops+1] = data.node_name minetest.remove_node(pos) return drops end, + on_receive_fields = technic.chests.get_receive_fields(data), } if data.locked then - def.allow_metadata_inventory_move = self.inv_move - def.allow_metadata_inventory_put = self.inv_put - def.allow_metadata_inventory_take = self.inv_take - def.on_blast = function() end - def.can_dig = function(pos,player) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - return inv:is_empty("main") and player and player:is_player() and default.can_interact_with_node(player, pos) - end def.on_skeleton_key_use = function(pos, player, newsecret) + -- Copied from default chests.lua local meta = minetest.get_meta(pos) local owner = meta:get_string("owner") - local name = player:get_player_name() - - -- verify placer is owner of lockable chest + local player_name = player:get_player_name() if owner ~= name then - minetest.record_protection_violation(pos, name) - minetest.chat_send_player(name, "You do not own this chest.") + minetest.record_protection_violation(pos, player_name) + minetest.chat_send_player(player_name, "You do not own this chest.") return nil end - local secret = meta:get_string("key_lock_secret") if secret == "" then secret = newsecret meta:set_string("key_lock_secret", secret) end - return secret, "a locked chest", owner end - elseif data.protected then - def.allow_metadata_inventory_move = self.inv_move_protected - def.allow_metadata_inventory_put = self.inv_put_protected - def.allow_metadata_inventory_take = self.inv_take_protected - def.on_blast = function() end - def.can_dig = function(pos,player) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - return inv:is_empty("main") and not minetest.is_protected(pos, player:get_player_name()) - end end - return def -end - -local _TUBELIB_CALLBACKS = { - on_pull_item = function(pos, side, player_name) - if not minetest.is_protected(pos, player_name) then - local inv = minetest.get_meta(pos):get_inventory() - for _, stack in pairs(inv:get_list("main")) do - if not stack:is_empty() then - return inv:remove_item("main", stack:get_name()) - end - end - end - return nil - end, - on_push_item = function(pos, side, item, player_name) - local inv = minetest.get_meta(pos):get_inventory() - if inv:room_for_item("main", item) then - inv:add_item("main", item) - return true - end - return false - end, - on_unpull_item = function(pos, side, item, player_name) - local inv = minetest.get_meta(pos):get_inventory() - if inv:room_for_item("main", item) then - inv:add_item("main", item) - return true - end - return false - end, -} - -function technic.chests:register(name, data) - local def = technic.chests:definition(name, data) - - -- prefix - local nn = "technic:"..name:lower() - - if data.locked then - -- locked chest - nn = nn .. "_locked" - - elseif data.protected then - -- protected chest - nn = nn .. "_protected" + if data.digilines and has_digilines then + def.digiline = { + receptor = {}, + effector = { + action = technic.chests.digiline_effector + }, + } end - - -- suffix - nn = nn .. "_chest" - - minetest.register_node(":"..nn, def) - - if tubelib_exists then - tubelib.register_node(nn, {}, _TUBELIB_CALLBACKS) - end - + minetest.register_node(":"..data.node_name, def) if data.color then - local mk_front - if string.find(def.tiles[6], "%^") then - mk_front = function (overlay) return def.tiles[6]:gsub("%^", "^"..overlay.."^") end - else - mk_front = function (overlay) return def.tiles[6].."^"..overlay end - end for i = 1, 15 do - local postfix = colorid_to_postfix(i) local colordef = {} for k, v in pairs(def) do colordef[k] = v end - colordef.drop = nn - colordef.groups = self.groups_noinv - colordef.tiles = { def.tiles[1], def.tiles[2], def.tiles[3], def.tiles[4], def.tiles[5], mk_front("technic_chest_overlay"..postfix..".png") } - minetest.register_node(":"..nn..postfix, colordef) - if tubelib_exists then - tubelib.register_node(nn..postfix, {}, _TUBELIB_CALLBACKS) - end + colordef.groups = node_groups_no_inv + colordef.tiles = get_tiles(lname, data, i) + minetest.register_node(":"..data.node_name.."_"..technic.chests.colors[i][1], colordef) end end end diff --git a/technic_chests/silver_chest.lua b/technic_chests/silver_chest.lua deleted file mode 100644 index 3cf83c5..0000000 --- a/technic_chests/silver_chest.lua +++ /dev/null @@ -1,48 +0,0 @@ -if minetest.get_modpath("moreores") then - minetest.register_craft({ - output = 'technic:silver_chest', - recipe = { - {'moreores:silver_ingot','moreores:silver_ingot','moreores:silver_ingot'}, - {'moreores:silver_ingot','technic:copper_chest','moreores:silver_ingot'}, - {'moreores:silver_ingot','moreores:silver_ingot','moreores:silver_ingot'}, - } - }) - - minetest.register_craft({ - output = 'technic:silver_locked_chest', - recipe = { - {'moreores:silver_ingot','moreores:silver_ingot','moreores:silver_ingot'}, - {'moreores:silver_ingot','technic:copper_locked_chest','moreores:silver_ingot'}, - {'moreores:silver_ingot','moreores:silver_ingot','moreores:silver_ingot'}, - } - }) -end - -minetest.register_craft({ - output = 'technic:silver_locked_chest', - type = "shapeless", - recipe = { - 'basic_materials:padlock', - 'technic:silver_chest', - } -}) - -technic.chests:register("Silver", { - width = 12, - height = 6, - sort = true, - autosort = true, - infotext = true, - color = false, - locked = false, -}) - -technic.chests:register("Silver", { - width = 12, - height = 6, - sort = true, - autosort = true, - infotext = true, - color = false, - locked = true, -}) diff --git a/technic_chests/textures/technic_protector_overlay.png b/technic_chests/textures/technic_protector_overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..c6f6f51bf4ebc7b91a725e6eaa5ca4c7bac98232 GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa2=EDUy?yr<0~3Q^fbYBob62ij zv2pYIa~IA$eDa|0`4SVL8pe_!zhDN3XE)M-90gAo#}JO|$q5R45*r*O6ITYbRdY^R jsL`T#Na}!t9s|Rhb4>3pFnezSs%7wW^>bP0l+XkKcs?!v literal 0 HcmV?d00001 From 9b6bc4f3028c01e4907085c928a210b98979b94f Mon Sep 17 00:00:00 2001 From: OgelGames Date: Thu, 12 Nov 2020 18:26:43 +1100 Subject: [PATCH 2/4] update luacheck --- .luacheckrc | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index e61836f..839ac0f 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -10,29 +10,27 @@ globals = { } read_globals = { + -- Lua string = {fields = {"split", "trim"}}, table = {fields = {"copy", "getn"}}, - - "intllib", "VoxelArea", - "default", "stairsplus", - + + -- Minetest "PseudoRandom", "ItemStack", - "mg", "tubelib", "vector", - - "moretrees", "bucket", - "unified_inventory", "digilines", - - "pipeworks", "screwdriver", - "VoxelManip", "unifieddyes", - - "Settings", "mesecon", - "digiline_remote", - - "protector", "isprotect", - "homedecor_expect_infinite_stacks", - "monitoring", "drawers" + "VoxelArea", "VoxelManip", + "Settings", "vector", + + -- Mods + "default", "stairsplus", + "screwdriver", "bucket", + "digilines", "pipeworks", + "mesecon", "moretrees", + "unified_inventory", "protector", + "unifieddyes", "digiline_remote", + "monitoring", "drawers", "mg", + + -- Only used in technic/machines/MV/lighting.lua (disabled) + "isprotect", "homedecor_expect_infinite_stacks", + + -- TODO: Remove after translation update + "intllib" } - --- Remove after chests update -files["technic_chests/register.lua"].ignore = { "fs_helpers", "name", "locked_after_place" } -files["technic_chests/register.lua"].max_line_length = false From d4193d254cfa95fb4ce560396bd3aba629a7524a Mon Sep 17 00:00:00 2001 From: OgelGames Date: Thu, 12 Nov 2020 18:28:08 +1100 Subject: [PATCH 3/4] move unused textures should probably be deleted at some stage, along with all the other unused textures in the mod... --- .../textures/{ => old}/technic_chest_form_bg.png | Bin .../{ => old}/technic_copper_chest_inventory.png | Bin .../textures/{ => old}/technic_form_bg.png | Bin .../{ => old}/technic_gold_chest_inventory.png | Bin .../{ => old}/technic_iron_chest_inventory.png | Bin .../textures/{ => old}/technic_main_inventory.png | Bin .../{ => old}/technic_mithril_chest_inventory.png | Bin .../{ => old}/technic_silver_chest_inventory.png | Bin .../{ => old}/technic_wooden_chest_inventory.png | Bin 9 files changed, 0 insertions(+), 0 deletions(-) rename technic_chests/textures/{ => old}/technic_chest_form_bg.png (100%) rename technic_chests/textures/{ => old}/technic_copper_chest_inventory.png (100%) rename technic_chests/textures/{ => old}/technic_form_bg.png (100%) rename technic_chests/textures/{ => old}/technic_gold_chest_inventory.png (100%) rename technic_chests/textures/{ => old}/technic_iron_chest_inventory.png (100%) rename technic_chests/textures/{ => old}/technic_main_inventory.png (100%) rename technic_chests/textures/{ => old}/technic_mithril_chest_inventory.png (100%) rename technic_chests/textures/{ => old}/technic_silver_chest_inventory.png (100%) rename technic_chests/textures/{ => old}/technic_wooden_chest_inventory.png (100%) diff --git a/technic_chests/textures/technic_chest_form_bg.png b/technic_chests/textures/old/technic_chest_form_bg.png similarity index 100% rename from technic_chests/textures/technic_chest_form_bg.png rename to technic_chests/textures/old/technic_chest_form_bg.png diff --git a/technic_chests/textures/technic_copper_chest_inventory.png b/technic_chests/textures/old/technic_copper_chest_inventory.png similarity index 100% rename from technic_chests/textures/technic_copper_chest_inventory.png rename to technic_chests/textures/old/technic_copper_chest_inventory.png diff --git a/technic_chests/textures/technic_form_bg.png b/technic_chests/textures/old/technic_form_bg.png similarity index 100% rename from technic_chests/textures/technic_form_bg.png rename to technic_chests/textures/old/technic_form_bg.png diff --git a/technic_chests/textures/technic_gold_chest_inventory.png b/technic_chests/textures/old/technic_gold_chest_inventory.png similarity index 100% rename from technic_chests/textures/technic_gold_chest_inventory.png rename to technic_chests/textures/old/technic_gold_chest_inventory.png diff --git a/technic_chests/textures/technic_iron_chest_inventory.png b/technic_chests/textures/old/technic_iron_chest_inventory.png similarity index 100% rename from technic_chests/textures/technic_iron_chest_inventory.png rename to technic_chests/textures/old/technic_iron_chest_inventory.png diff --git a/technic_chests/textures/technic_main_inventory.png b/technic_chests/textures/old/technic_main_inventory.png similarity index 100% rename from technic_chests/textures/technic_main_inventory.png rename to technic_chests/textures/old/technic_main_inventory.png diff --git a/technic_chests/textures/technic_mithril_chest_inventory.png b/technic_chests/textures/old/technic_mithril_chest_inventory.png similarity index 100% rename from technic_chests/textures/technic_mithril_chest_inventory.png rename to technic_chests/textures/old/technic_mithril_chest_inventory.png diff --git a/technic_chests/textures/technic_silver_chest_inventory.png b/technic_chests/textures/old/technic_silver_chest_inventory.png similarity index 100% rename from technic_chests/textures/technic_silver_chest_inventory.png rename to technic_chests/textures/old/technic_silver_chest_inventory.png diff --git a/technic_chests/textures/technic_wooden_chest_inventory.png b/technic_chests/textures/old/technic_wooden_chest_inventory.png similarity index 100% rename from technic_chests/textures/technic_wooden_chest_inventory.png rename to technic_chests/textures/old/technic_wooden_chest_inventory.png From b8220766e5140b4c3b64abf1ad150010c12a7647 Mon Sep 17 00:00:00 2001 From: OgelGames Date: Thu, 12 Nov 2020 18:29:02 +1100 Subject: [PATCH 4/4] improve chests color overlay and button textures --- .../textures/technic_chest_overlay_black.png | Bin 234 -> 132 bytes .../textures/technic_chest_overlay_blue.png | Bin 234 -> 132 bytes .../textures/technic_chest_overlay_brown.png | Bin 234 -> 132 bytes .../textures/technic_chest_overlay_cyan.png | Bin 234 -> 132 bytes .../technic_chest_overlay_dark_green.png | Bin 234 -> 132 bytes .../technic_chest_overlay_dark_grey.png | Bin 234 -> 132 bytes .../textures/technic_chest_overlay_green.png | Bin 234 -> 132 bytes .../textures/technic_chest_overlay_grey.png | Bin 234 -> 132 bytes .../textures/technic_chest_overlay_magenta.png | Bin 234 -> 132 bytes .../textures/technic_chest_overlay_orange.png | Bin 234 -> 132 bytes .../textures/technic_chest_overlay_pink.png | Bin 234 -> 132 bytes .../textures/technic_chest_overlay_red.png | Bin 234 -> 132 bytes .../textures/technic_chest_overlay_violet.png | Bin 234 -> 132 bytes .../textures/technic_chest_overlay_white.png | Bin 234 -> 132 bytes .../textures/technic_chest_overlay_yellow.png | Bin 234 -> 132 bytes .../textures/technic_colorbutton0.png | Bin 105 -> 120 bytes .../textures/technic_colorbutton1.png | Bin 105 -> 120 bytes .../textures/technic_colorbutton10.png | Bin 105 -> 120 bytes .../textures/technic_colorbutton11.png | Bin 105 -> 120 bytes .../textures/technic_colorbutton12.png | Bin 105 -> 120 bytes .../textures/technic_colorbutton13.png | Bin 105 -> 120 bytes .../textures/technic_colorbutton14.png | Bin 105 -> 120 bytes .../textures/technic_colorbutton2.png | Bin 105 -> 120 bytes .../textures/technic_colorbutton3.png | Bin 89 -> 120 bytes .../textures/technic_colorbutton4.png | Bin 105 -> 120 bytes .../textures/technic_colorbutton5.png | Bin 105 -> 120 bytes .../textures/technic_colorbutton6.png | Bin 105 -> 120 bytes .../textures/technic_colorbutton7.png | Bin 105 -> 120 bytes .../textures/technic_colorbutton8.png | Bin 105 -> 120 bytes .../textures/technic_colorbutton9.png | Bin 105 -> 120 bytes 30 files changed, 0 insertions(+), 0 deletions(-) diff --git a/technic_chests/textures/technic_chest_overlay_black.png b/technic_chests/textures/technic_chest_overlay_black.png index d8bc5e822ca1851ab118ec2d0e16c5eb22d3dc12..5a4c807a7a71821e3c9f86fd7a6345ec632f469e 100644 GIT binary patch delta 103 zcmaFG*upqLC4sRx$lZxy-8q?;3=9lx0X`wFKpF^^rtdrtq?k&A{DK+&M^9AR3gpRo zx;TbNOifOZ@M#d_nedZCNU6aoQPkmjQ=|O@qgQW6?CB`8Ap00i_>zopr0M@=7 ALjV8( delta 206 zcmV;<05SiB0qOyeB!5m&OjJbx0000001^@srln-2rDdk2Zm6eJsi;}7uU@gRTeGlb zv$1Eiv1qljXSK3wwXcD}oH!M}RJzN@_tholG@ zoO?>HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m1B___)@vE$qW}N^07*qo IM6N<$g1FsYwg3PC diff --git a/technic_chests/textures/technic_chest_overlay_blue.png b/technic_chests/textures/technic_chest_overlay_blue.png index c6d4297c42895b949e1e127acf48e81fc29bdb3c..730a35b4be274f78a17a118aa354fece4a72e06f 100644 GIT binary patch delta 103 zcmaFG*upqLC4sRx$lZxy-8q?;3=9lx0X`wFK$?N!e@AMV6Od*q3GxeO_#Zt{X)BN? z=jq}YA~7{NLBgj&kY~bA4k4umr$kYQ>rIIoaSRNc91N1m8cD}oH!M}RJzk z0d!JMQvg8b*k%9#07^+jK~#9!#Y|NKfKUu#IJ;Z#e^9%9|3_~f0BoA4>N@_tholG@ zoO?>HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m1CV6_;_gm0g#Z8m07*qo IM6N<$f`GJNW&i*H diff --git a/technic_chests/textures/technic_chest_overlay_brown.png b/technic_chests/textures/technic_chest_overlay_brown.png index 189b51618373518865c840d4dfc9d27ac84a8f54..e2ffad480261a5201b242d901c7aa1b74a130234 100644 GIT binary patch delta 103 zcmaFG*upqLC4sRx$lZxy-8q?;3=9lx0X`wFKswEsK{hNq7sz5N3GxeO_#Zt{X)BN? z=jq}YA~7{NLBgj&kY~bA4k4umr$kYQ>rIIoaSRNc91N1m8cD}oH!M}RJzN@_tholG@ zoO?>HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m1B___)@vE$qW}N^07*qo IM6N<$g0SmgIsgCw diff --git a/technic_chests/textures/technic_chest_overlay_cyan.png b/technic_chests/textures/technic_chest_overlay_cyan.png index 6fb7568e36ab135a3cfef1d19b35255368b706c2..1b5ae827d91685bf84a08e2717a847413a4c9fc7 100644 GIT binary patch delta 103 zcmaFG*upqLC4sRx$lZxy-8q?;3=9lx0X`wFK$_wIe`&|n20#W=NswPK!~f`sN?UcD}oH!M}RJzN@_tholG@ zoO?>HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m1CV6_;_gm0g#Z8m07*qo IM6N<$f_>g%cmMzZ diff --git a/technic_chests/textures/technic_chest_overlay_dark_green.png b/technic_chests/textures/technic_chest_overlay_dark_green.png index 4f4fb2bb12ae9be8ca8d5b54fd53370c0c674702..0c257e18255d3c9f2dd24fee503ca65f1ec9973a 100644 GIT binary patch delta 103 zcmaFG*upqLC4sRx$lZxy-8q?;3=9lx0X`wFK$;cD}oH!M}RJzN@_tholG@ zoO?>HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m1B___)@vE$qW}N^07*qo IM6N<$g4{S@tpET3 diff --git a/technic_chests/textures/technic_chest_overlay_dark_grey.png b/technic_chests/textures/technic_chest_overlay_dark_grey.png index a8ca5858b574d7dff976cd20235ed61a59ce13d3..8b62f162e6091b20b1b4a30e55271f5418958524 100644 GIT binary patch delta 103 zcmaFG*upqLC4sRx$lZxy-8q?;3=9lx0X`wFKsq2GK!SVreISdeB*-tA;eYf*rL91o zoTrOph{V+71PPx8L7oXeIfRrNoDxMHt~VuW#4#{%axh3LZ&+dsRLS7!>gTe~DWM4f D*A5&! delta 206 zcmV;<05SiB0qOyeB!5m&OjJbx003fQVr^}0rln-2rDdk2Zm6eJsi;}7uU@gRTeGlb zv$1Eiv1qljXSK3wwXcD}oH!M}RJzN@_tholG@ zoO?>HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m1B___)@vE$qW}N^07*qo IM6N<$f^8&W7ytkO diff --git a/technic_chests/textures/technic_chest_overlay_green.png b/technic_chests/textures/technic_chest_overlay_green.png index 97091252e539087565c5dfea8a5212c9d16ddad2..ffc1f83e8ba67735f5c79ff50552288c08729719 100644 GIT binary patch delta 103 zcmaFG*upqLC4sRx$lZxy-8q?;3=9lx0X`wFK$_t{gPF6-ULb?1B*-tA;eYf*rL91o zoTrOph{V+71PPx8L7oXeIfRrNoDxMHt~VuW#4#{%axh3LZ&+dsGQrc;&t;ucLK6Ve CXdEa2 delta 206 zcmV;<05SiB0qOyeB!5m&OjJbx002th7E1pMrln-2rDdk2Zm6eJsi;}7uU@gRTeGlb zv$1Eiv1qljXSK3wwXcD}oH!M}RJzN@_tholG@ zoO?>HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m1B___)@vE$qW}N^07*qo IM6N<$f~HepdjJ3c diff --git a/technic_chests/textures/technic_chest_overlay_grey.png b/technic_chests/textures/technic_chest_overlay_grey.png index 0e5da713592270e63b2472c583dbe9cc5746141d..d56819be36a12a75810a5316e9d67af95f763025 100644 GIT binary patch delta 103 zcmaFG*upqLC4sRx$lZxy-8q?;3=9lx0X`wFKzhM~1uW-&uLH7}N`m}?8U9C4RN4yU z$$7dshDc0JPLS|v5agNglS4?U!6{MH;d)b|MjQhJCkKP1@`feGK$Q%hu6{1-oD!M< DS^XXg delta 206 zcmV;<05SiB0qOyeB!5m&OjJbx004=JiIkL-rln-2rDdk2Zm6eJsi;}7uU@gRTeGlb zv$1Eiv1qljXSK3wwXcD}oH!M}RJzN@_tholG@ zoO?>HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m1B___)@vE$qW}N^07*qo IM6N<$f)j^f^8f$< diff --git a/technic_chests/textures/technic_chest_overlay_magenta.png b/technic_chests/textures/technic_chest_overlay_magenta.png index 1a6eb97fe6a086ca27020e393f5b9e189098ee89..36a035980d2fc5cc89205ab0c1d693e0fff6d51a 100644 GIT binary patch delta 103 zcmaFG*upqLC4sRx$lZxy-8q?;3=9lx0X`wFK>9z!f3v?y>wzq$k|4iehX2tMm9_$T za-J@ZAre!Q6C`{Z1bHU>tDnm{r-UW| DR52a# delta 206 zcmV;<05SiB0qOyeB!5m&OjJbx005??WTvHMrloGEr&Ot^S+K8Ov9MdSuw}EcXSA_s zwX$cmvTC)nYPPd(x3p}xwr#k!aJaT{y}EY3yLG|8dcnYX#>ITo6`=Y6wucVz{{R30 z0d!JMQvg8b*k%9#07^+jK~#9!#Y|NKfKUv=+1<+Se^9%9|3_~f0Bo8k;yV7lhomYQ zoO?>HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m0}& diff --git a/technic_chests/textures/technic_chest_overlay_orange.png b/technic_chests/textures/technic_chest_overlay_orange.png index 7a79117b01a6ca1ad7065d4e45b2a57457dd8836..7ab424540936b6ed226988785ea5abbbe5884058 100644 GIT binary patch delta 103 zcmaFG*upqLC4sRx$lZxy-8q?;3=9lx0X`wFK>B|JgF=mHCXmHc666=m@IQK@(pDf( z&eO#)L}F@kf`m_lAkT!K970MBPKlxp*P9YG;ush>IT$3BH!Lv*s$}qV^>bP0l+XkK D-iRDX delta 206 zcmV;<05SiB0qOyeB!5m&OjJbx005??WTvHMrloGEr&Ot^S+K8Ov9MdSuw}EcXSA_s zwX$cmvTC)nYPPd(x3p}xwr#k!aJaT{y}EY3yLG|8dcnYX#>ITtfhFsVCTSH)p#T5? z0d!JMQvg8b*k%9#07^+jK~#9!#Y|NKfKUv=+1<+Se^9%9|3_~f0Bo8k;yV7lhomYQ zoO?>HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m0}&GiN|CcPzhyz(nB|(0{4F97iDs2Vw zE0dBYN8ph^Z$S3j3^P6IT{YKs4Bj#o3*F#rGn z0d!JMQvg8b*k%9#07^+jK~#9!#Y|NKfKUv=+1<+Se^9%9|3_~f0Bo8k;yV7lhomYQ zoO?>HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m0}&9xegY^GiB_NBbB*-tA;eYf*rL91o zoTrOph{V+71PPx8L7oXeIfRrNoDxMHt~VuW#4#{%axh3LZ&+dsRLS7!>gTe~DWM4f D>LMI> delta 206 zcmV;<05SiB0qOyeB!5m&OjJbx005??WTvHMrloGEr&Ot^S+K8Ov9MdSuw}EcXSA_s zwX$cmvTC)nYPPd(x3p}xwr#k!aJaT{y}EY3yLG|8dcnYX#>ITu3HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m0}&gTe~DWM4f D`db{d delta 206 zcmV;<05SiB0qOyeB!5m&OjJbx005dO>ZYY+rln=3rEaGw|EQ-_si;}7uU@gRTeGlb zv$1Eiv1qljXSK3wwXcD}oH!M}RJzGjx|4VPqzYAnBl?3?(GyIR9sI(Qx zlk;?O43U_coFL)TAjmV}Cx?(ygHxiY!}X>_jW`AdP7Vf1IT-=;;6d|D9MR0ssI2 z0d!JMQvg8b*k%9#07^+jK~#9!#Y|NKfKUv=+1<+Se^9%9|3_~f0Bo8k;yV7lhomYQ zoO?>HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m0}&GiGhK}0>0YDa0NswPK!~f`sN?UIT<>L~yJD8#CM7ytkO z0d!JMQvg8b*k%9#07^+jK~#9!#Y|NKfKUv=+1<+Se^9%9|3_~f0Bo8k;yV7lhomYQ zoO?>HjjZ-HZO%{Ek85k%^RVy0a8iyPD0a~rmqkfd<}r*m0}&$7T^=&%5d*L0|SHa@;Wvk#aI&L7tG-B>_!@pBk1Yk7*cU7`2b7LiG&JH b0XBw&lMJh*=O=FiN-}u5`njxgN@xNANa_~G diff --git a/technic_chests/textures/technic_colorbutton1.png b/technic_chests/textures/technic_colorbutton1.png index 5497c53deeacc9e433dd1f5b0ca6068481978c63..83556efd99333f12e6a088c537755fac6ea18604 100644 GIT binary patch delta 89 zcmd0-n4l8ESRCZ;#IWw1%u5Ca2DSj75LY10!0^8#HOvV}GnEAS1vC7Qo~X1H$P@B( paSV}|nw)Teq31-x4o(3khJ=$0tB$YsKLC_v@O1TaS?83{1OSF=8r1** delta 74 zcmb=(oS@>$7T^=&%5d*LlhpsqJp1h!7#J8!g8YIR9G=}s19AjCT^vIyZY3XJ={b>5 c!70GTkZ_V=mGu1NZ9qu|Pgg&ebxsLQ0H9hJMF0Q* diff --git a/technic_chests/textures/technic_colorbutton10.png b/technic_chests/textures/technic_colorbutton10.png index d659c8cf285ae60154942891c3d7741630751e61..9f84d6dee8a7bcfdd5361a6d3f7d0595359ee143 100644 GIT binary patch delta 89 zcmd0-n4l8ESRCZ;#IWw1%u5Ca2DSj75LY1mf5ZPv7H7nPET)nmzhH*{(G!)n0(nB7 pE{-7*QA*ug2l#E@{3Vb$@~{s(}v44$rjF6*2Ung9p<9P9u9 delta 74 zcmb=(oS@>$7T^=&%5d-h>x4}!ntnJiFfcHd1o;IsI6S+N2IL5Ox;TbZ+)6&c(sLrA cf>VHvA>ky$D(U&j+klb`p00i_>zopr0Q2@4tpET3 diff --git a/technic_chests/textures/technic_colorbutton11.png b/technic_chests/textures/technic_colorbutton11.png index bce51dd53b0bbc40370a6fbc709d88d3bd3f1368..cf5e4c97ff8aa5fc180689fc77b50b7771492ce2 100644 GIT binary patch delta 89 zcmd0-n4l8ESRCZ;#IWw1%u5Ca2DSj75LY1mpMgR8f3Fgd#Z(gH7tHWKdZN-+AWz8C p#W6%;YI4E>hMp4%J2(ZH7!po0tUA8h{{T>y!PC{xWt~$(69AX68yNrq delta 74 zcmb=(oS@>$7T^=&%5d-he}0CNmdKI;Vst0FSvB@c;k- diff --git a/technic_chests/textures/technic_colorbutton12.png b/technic_chests/textures/technic_colorbutton12.png index bb1137c866421590b287d1b3c9471c70dfe611b3..e04032eafd925c1b4e03e964951576da19c9c4cc 100644 GIT binary patch delta 89 zcmd0-n4l8ESRCZ;#IWw1%u5Ca2DSj75LY1G&+tEqhwDF(#Z(gH7tHWKdZN-+AWz8C p#W6%;YI4E>hMp4%J2(ZH7!po0tUA8h{{T>y!PC{xWt~$(69A$7T^=&%5d+014}i(CWjdV0|R48kY6x^!?PP{K#riNi(^Q|t>gnNJtq<> cI0e`k5>7I#lAfQu4JgUr>FVdQ&MBb@081Gb!vFvP diff --git a/technic_chests/textures/technic_colorbutton13.png b/technic_chests/textures/technic_colorbutton13.png index 551404f94b9e53a522fe2b8ab6e808f2ba51591f..b26007d4ef1047d2dbb95c46023a04fe9813f3a8 100644 GIT binary patch delta 89 zcmd0-n4l8ESRCZ;#IWw1%u5Ca2DSj75LY1m|NsA`H|O64vY1MO{DK+&M^9AR3giiS qx;TbNOifNWz|eCdVF#xG6GOsDhE>N``yT+xGI+ZBxvX$7T^=&%5d*L5co<)h%hiPFqQ=Q1v5B2yO9Ru2zt6WhE&{2KETp*BB6p) afQ=#HB*QA{`N`XWk_?`%elF{r5}E+lN*Nsh diff --git a/technic_chests/textures/technic_colorbutton14.png b/technic_chests/textures/technic_colorbutton14.png index ebc890cd261afc64fc5f36bdd03e4772be8a4588..9af3a01a756ff665e65ec781c0b7a21b4c82bbe2 100644 GIT binary patch delta 89 zcmd0-n4l8ESRCZ;#IWw1%u5Ca2DSj75LY1m|35>=?ScRxi>V~YFPPzf^hBktK%S7N pi(`ny)Z~N%3_T|jc5n(XF(jO1Sap20{{f&ZgQu&X%Q~loCIISQ9C82v delta 74 zcmb=(oS@>$7T^=&%5d-h|389?ZAVrxFfcHd1o;IsI6S+N2IL5Ox;TbZ+)6&c(sLrA cf>VHvA>ky$D(U&j+klb`p00i_>zopr0OfTVZ2$lO diff --git a/technic_chests/textures/technic_colorbutton2.png b/technic_chests/textures/technic_colorbutton2.png index fc3da7e7e9ec9ab4e17dd432d1502469423edf95..a9f2622342763adec09c7eab832cf6d577948ee8 100644 GIT binary patch delta 89 zcmd0-n4l8ESRCZ;#IWw1%u5Ca2DSj75LY0bX3QWPmYoY^F_i@Q1vC7Qo~X1H$P@B( paSV}|nw)Teq31-x4o(3khJ=$0tB$YsKLC_v@O1TaS?83{1OQ;?8Z`g_ delta 74 zcmb=(oS@>$7T^=&%5d+0yNlMdVuLFT3=E7VL4Lsu4$p3+0Xc%6E{-7;w~`OA^qfej c;1pnENI1!`N_u|sHlQSfr>mdKI;Vst0JQrUpa1{> diff --git a/technic_chests/textures/technic_colorbutton3.png b/technic_chests/textures/technic_colorbutton3.png index 65f60fa2417964d7f079f950a2153a545258d735..14e6318696e603f253190bd5d29cb16ecbebed08 100644 GIT binary patch delta 100 zcma#7m>?O?%)r2)q01i(q!^2X+?^QKos)S98i6P-6!>Z$}{SN?T89ZJ6T-G@yGywnsOdK!( delta 69 zcmb=3oFM7I#=yWJ|M`C+kW%n;aSW-rm7K8S`+Oyy$7T^=&%5d+$jGyupHuKjE3=E7VL4Lsu4$p3+0Xc%6E{-7;w~`OA^qfej c;1pnENI1!`N_u|sHlQSfr>mdKI;Vst0C(3HmjD0& diff --git a/technic_chests/textures/technic_colorbutton5.png b/technic_chests/textures/technic_colorbutton5.png index d36eb3d1f3042d6fb438dcc930c2fc6d48b288a8..9db1f17916d94575fc3216bca5334db0cfa8b306 100644 GIT binary patch delta 89 zcmd0-n4l8ESRCZ;#IWw1%u5Ca2DSj75LX}_5D*~2J^Mb8#Z(gH7tHWKdZN-+AWz8C p#W6%;YI4E>hMp4%J2(ZH7!po0tUA8h{{T>y!PC{xWt~$(699)`8r}c^ delta 74 zcmb=(oS@>$7T^=&%5d+0SX9{aQ@PR%3=E7VL4Lsu4$p3+0Xc%6E{-7;w~`OA^qfej c;1pnENI1!`N_u|sHlQSfr>mdKI;Vst0I|#%jQ{`u diff --git a/technic_chests/textures/technic_colorbutton6.png b/technic_chests/textures/technic_colorbutton6.png index 1874356bd69e2602db72b20063827b755ef3f612..fdedfa4b003d56cb26c19f69c33509c7bb79cfae 100644 GIT binary patch delta 89 zcmd0-n4l8ESRCZ;#IWw1%u5Ca2DSj75LY10@SnlV*<~+~!Bi6D7tHWKdZN-+AWz8C p#W6%;YI4E>hMp4%J2(ZH7!po0tUA8h{{T>y!PC{xWt~$(699v%8p;3w delta 74 zcmb=(oS@>$7T^=&%5d+$>qUmeSC1AmFfcHd1o;IsI6S+N2IL5Ox;TbZ+)6&c(sLrA cf>VHvA>ky$D(U&j+klb`p00i_>zopr0M7&&6aWAK diff --git a/technic_chests/textures/technic_colorbutton7.png b/technic_chests/textures/technic_colorbutton7.png index 01cad3663e9c226ce233081cd34e9350452f17cd..138fef11391122562cf8a2da38091898e8c75cf6 100644 GIT binary patch delta 89 zcmd0-n4l8ESRCZ;#IWw1%u5Ca2DSj75LY0*V8H^GbHCRCSxhBCe!&d?qbDkD1@eSE qT^vIsrY0vGVCXrKu!B>8i6P-6!>Z$}{SN?T89ZJ6T-G@yGywqgm>jGC delta 74 zcmb=(oS@>$7T^=&%5d-h_U+q?%{vY=FfcHd1o;IsI6S+N2IL5Ox;TbZ+)6&c(sLrA cf>VHvA>ky$D(U&j+klb`p00i_>zopr0OSoBXaE2J diff --git a/technic_chests/textures/technic_colorbutton8.png b/technic_chests/textures/technic_colorbutton8.png index 4ef53ab41fe566355c69f31f9f3730a0428c4723..c740315dad17f34e4625e6331ee4f11965b9c23b 100644 GIT binary patch delta 89 zcmd0-n4l8ESRCZ;#IWw1%u5Ca2DSj75LY1mpW(mR-=y_G7E?)(UogY}=!r^Ofjl8k p7sn8ZsmTck7$7T^=&%5d-hA%VHvA>ky$D(U&j+klb`p00i_>zopr0J=sPuK)l5 diff --git a/technic_chests/textures/technic_colorbutton9.png b/technic_chests/textures/technic_colorbutton9.png index db64417b0c129f93c0e7d9b8c999b6f26beace78..b078dc7d2fb8ef7b319ab5ed480f89d64ebc450f 100644 GIT binary patch delta 89 zcmd0-n4l8ESRCZ;#IWw1%u5Ca2DSj75LY1mzkxxaMl=)1Vk!yp3ugEqJyB^ZkSFBn p;us<^H96q`L(hqX9h?G83<)P0RvlmMe*h@U;OXk;vd$@?2>^~t8tMQ5 delta 74 zcmb=(oS@>$7T^=&%5d-h|C#zfa@`&>FfcHd1o;IsI6S+N2IL5Ox;TbZ+)6&c(sLrA cf>VHvA>ky$D(U&j+klb`p00i_>zopr0Pz1Ap#T5?