diff --git a/metal_melter/caster.lua b/metal_melter/caster.lua index 4fb670e..82ca360 100644 --- a/metal_melter/caster.lua +++ b/metal_melter/caster.lua @@ -37,6 +37,7 @@ function metal_caster.get_metal_caster_formspec_default() "list[context;bucket_out;4.75,1.4;2,2;]".. "image[5.75,0.2;1,1;gui_furnace_arrow_bg.png^[transformR270]".. "image[5.75,1.4;1,1;gui_furnace_arrow_bg.png^[transformR90]".. + "button[6.68,2.48;1.33,1;dump;Dump]".. "list[current_player;main;0,4.25;8,1;]".. "list[current_player;main;0,5.5;8,3;8]".. "listring[context;coolant]".. diff --git a/metal_melter/melter.lua b/metal_melter/melter.lua index 75a4bd2..426d561 100644 --- a/metal_melter/melter.lua +++ b/metal_melter/melter.lua @@ -64,6 +64,7 @@ function metal_melter.get_metal_melter_formspec_default() "list[context;bucket_out;4.75,1.4;2,2;]".. "image[5.75,0.2;1,1;gui_furnace_arrow_bg.png^[transformR270]".. "image[5.75,1.4;1,1;gui_furnace_arrow_bg.png^[transformR90]".. + "button[6.68,2.48;1.33,1;dump;Dump]".. "list[current_player;main;0,4.25;8,1;]".. "list[current_player;main;0,5.5;8,3;8]".. "listring[context;heat]".. diff --git a/tinkering/nodes/tool_station.lua b/tinkering/nodes/tool_station.lua new file mode 100644 index 0000000..923c152 --- /dev/null +++ b/tinkering/nodes/tool_station.lua @@ -0,0 +1,261 @@ +-- TODO: Repair +tool_station = {} + +function tool_station.get_tool_type_list(ix, iy, mx) + local formspec = "" + local x = 0 + local y = 0 + + formspec = formspec..("button[%d,%d;1,1;anvil;Anvil]"):format(x + ix, y + iy) + x = x + 1 + + for t, tool in pairs(tinkering.tools) do + local toolmod = tool.mod_name or "tinkering" + formspec = formspec.. ("item_image_button[%d,%d;1,1;%s;%s;]"):format(x + ix, y + iy, toolmod..":steel_"..t, t) + formspec = formspec.. ("tooltip[%s;%s]"):format(t, tool.description) + x = x + 1 + if x >= mx then + y = y + 1 + x = 0 + end + end + + return formspec +end + +function tool_station.get_formspec() + local tool_list = tool_station.get_tool_type_list(8, 0, 5) + return "size[13,8.5]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "list[context;input;1,0.25;3,3;]".. + "list[context;output;5,1.25;1,1;]".. + "image[4,1.25;1,1;gui_furnace_arrow_bg.png^[transformR270]".. + "list[current_player;main;0,4.25;8,1;]".. + "list[current_player;main;0,5.5;8,3;8]".. + tool_list.. + "listring[context;input]".. + "listring[current_player;main]".. + "listring[context;output]".. + "listring[current_player;main]".. + default.get_hotbar_bg(0, 4.25) +end + +local function get_metalgroup(groups) + if not groups then return nil end + for g,i in pairs(groups) do + if g:find("metal_") == 1 then + return g:gsub("^metal_", "") + end + end + return nil +end + +-- Get tool components from specified stacks +function tool_station.get_types(list, tool_type) + local tool = tinkering.tools[tool_type] + if not tool then return nil end + + local result = {} + local items_required = {} + + for _,stack in pairs(list) do + local stack_name = stack:get_name() + for tt, ty in pairs(tool.components) do + local in_grp = minetest.get_item_group(stack_name, "tc_"..ty) > 0 + if in_grp then + local mtg = get_metalgroup(minetest.registered_items[stack_name].groups) + if mtg ~= nil then + result[tt] = mtg + + if not items_required[stack_name] then + items_required[stack_name] = 0 + end + + items_required[stack_name] = items_required[stack_name] + 1 + end + end + end + end + + return result, items_required +end + +local function handle_take_output(pos, listname) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + local tooltype = meta:get_string("tool_type") + + if tooltype ~= "" then + local list = inv:get_list(listname) + local types, items = tool_station.get_types(list, tooltype) + if not types then return end + local res = {} + + for _,stack in pairs(list) do + local stack_name = stack:get_name() + if items[stack_name] then + if not res[stack_name] then + res[stack_name] = items[stack_name] + end + + if res[stack_name] > 0 then + if stack:get_count() > res[stack_name] then + stack:set_count(stack:get_count() - res[stack_name]) + res[stack_name] = 0 + else + res[stack_name] = res[stack_name] - stack:get_count() + stack:clear() + end + end + end + end + + inv:set_list(listname, list) + end +end + +local function on_timer(pos, elapsed) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local refresh = false + + local output = nil + + -- Get selected tool type + local tool_type = meta:get_string("tool_type") + + if tool_type ~= "" then + local list = inv:get_list("input") + local results = tool_station.get_types(list, tool_type) + if results then + -- Attempt to create the tool with the provided materials + local tool_res = tinkering.create_tool(tool_type, results, true) + if tool_res then + output = tool_res + end + end + end + + if output then + inv:set_list("output", {output}) + else + inv:set_list("output", {}) + end + + return refresh +end + +local function allow_metadata_inventory_put (pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + + if listname == "output" then + return 0 + end + + return stack:get_count() +end + +local function allow_metadata_inventory_move (pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(from_list, from_index) + return allow_metadata_inventory_put(pos, to_list, to_index, stack, player) +end + +local function allow_metadata_inventory_take (pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + + return stack:get_count() +end + +local function on_construct(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", tool_station.get_formspec()) + + -- Create inventory + local inv = meta:get_inventory() + inv:set_size('input', 9) + inv:set_size('output', 1) + + -- Set tool type meta + meta:set_string("tool_type", "") +end + +local function on_take(pos, listname, index, stack, player) + local inv = minetest.get_meta(pos):get_inventory() + + if listname == "output" then + handle_take_output(pos, "input") + end + + minetest.get_node_timer(pos):start(0.02) +end + +local function can_dig(pos, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:is_empty("input") and inv:is_empty("output") +end + +local function on_receive_fields(pos, formname, fields, sender) + if sender and minetest.is_protected(pos, sender:get_player_name()) then + return 0 + end + + local meta = minetest.get_meta(pos) + if fields["anvil"] then + meta:set_string("tool_type", "") + else + for name,_ in pairs(fields) do + if tinkering.tools[name] then + meta:set_string("tool_type", name) + break + end + end + end + + minetest.get_node_timer(pos):start(0.02) +end + +minetest.register_node("tinkering:tool_station", { + description = "Tool Station", + tiles = { + "tinkering_workbench_top.png", "tinkering_bench_bottom.png", + "tinkering_bench_side.png", "tinkering_bench_side.png", + "tinkering_bench_side.png", "tinkering_bench_side.png" + }, + drawtype = "nodebox", + paramtype = "light", + node_box = tinkering.bench, + + on_construct = on_construct, + legacy_facedir_simple = true, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), + + can_dig = can_dig, + on_timer = on_timer, + on_construct = on_construct, + on_receive_fields = on_receive_fields, + + on_metadata_inventory_move = function(pos) + minetest.get_node_timer(pos):start(0.05) + end, + on_metadata_inventory_put = function(pos) + minetest.get_node_timer(pos):start(0.05) + end, + on_metadata_inventory_take = on_take, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_take = allow_metadata_inventory_take, + allow_metadata_inventory_move = allow_metadata_inventory_move, + + groups = {choppy = 2, oddly_breakable_by_hand = 2} +}) diff --git a/tinkering/nodesitems.lua b/tinkering/nodesitems.lua index e69de29..a529ef0 100644 --- a/tinkering/nodesitems.lua +++ b/tinkering/nodesitems.lua @@ -0,0 +1,15 @@ + +-- Common nodebox +tinkering.bench = { + type = "fixed", + fixed = { + {-0.5000, 0.3125, -0.5000, 0.5000, 0.5000, 0.5000}, + {-0.5000, -0.5000, -0.5000, -0.3125, 0.3125, -0.3125}, + {0.3125, -0.5000, -0.5000, 0.5000, 0.3125, -0.3125}, + {-0.5000, -0.5000, 0.3125, -0.3125, 0.3125, 0.5000}, + {0.3125, -0.5000, 0.3125, 0.5000, 0.3125, 0.5000} + } +} + +-- Tool Station +dofile(tinkering.modpath.."/nodes/tool_station.lua") diff --git a/tinkering/register.lua b/tinkering/register.lua index 04dc60e..d25d7d3 100644 --- a/tinkering/register.lua +++ b/tinkering/register.lua @@ -76,9 +76,13 @@ local function create_material_component(data) local name = data.name local mod = data.mod_name + local groups = {tinker_component = 1} + groups["tc_"..data.component] = 1 + groups["metal_"..data.metal] = 1 + minetest.register_craftitem(mod..":"..name, { description = desc, - groups = {tinker_component = 1}, + groups = groups, inventory_image = data.image }) end @@ -115,6 +119,8 @@ function tinkering.register_component(name, data) create_material_component({ name = component, + component = name, + metal = m, mod_name = mod, description = data.description:format(s.name), image = tinkering.color_filter(data.image, s.color) @@ -218,14 +224,9 @@ end function tinkering.compose_tool_texture(tooltype, main, rod) local mat_main = tinkering.materials[main] local mat_rod = tinkering.materials[rod] + local tool_data = tinkering.tools[tooltype].textures - local tool_data = tinkering.tools[tooltype] - - local main_tex = tool_data.textures.main .."\\^[multiply\\:".. mat_main.color - local rod_tex = tool_data.textures.second .."\\^[multiply\\:".. mat_rod.color - local align = tool_data.textures.offset - - return "[combine:16x16:"..align.."="..main_tex..":0,0="..rod_tex + return tinkering.combine_textures(tool_data.main, tool_data.second, mat_main.color, mat_rod.color, tool_data.offset) end local function quickcopy(t) @@ -302,14 +303,18 @@ function tinkering.tool_definition(tool_type, materials) local tool_tree = { description = name, tool_capabilities = capabilities, - groups = {tinker_tool = 1}, + groups = {tinker_tool = 1, ["metal_"..materials.main] = 1}, inventory_image = tinkering.compose_tool_texture(tool_type, materials.main, materials.rod) } -- Store materials to use in metadata local tink_mats = "" - for _,m in pairs(materials) do - tink_mats = tink_mats..","..m + for i, m in pairs(materials) do + if i == 1 then + tink_mats = m + else + tink_mats = tink_mats..","..m + end end return tool_tree, tink_mats, tags @@ -382,6 +387,10 @@ function tinkering.create_tool(tool_type, materials, want_tool, custom_name, ove meta:set_tool_capabilities(tool_def.tool_capabilities) meta:set_string("materials", mat_names) + if tool_def["wear"] then + tool:set_wear(tool_def.wear) + end + return tool end diff --git a/tinkering/textures/tinkering_bench_bottom.png b/tinkering/textures/tinkering_bench_bottom.png new file mode 100644 index 0000000..50e90aa Binary files /dev/null and b/tinkering/textures/tinkering_bench_bottom.png differ diff --git a/tinkering/textures/tinkering_bench_side.png b/tinkering/textures/tinkering_bench_side.png new file mode 100644 index 0000000..905784b Binary files /dev/null and b/tinkering/textures/tinkering_bench_side.png differ diff --git a/tinkering/textures/tinkering_workbench_top.png b/tinkering/textures/tinkering_workbench_top.png new file mode 100644 index 0000000..c50afc5 Binary files /dev/null and b/tinkering/textures/tinkering_workbench_top.png differ diff --git a/tinkering/util.lua b/tinkering/util.lua index 66234d7..05bc64a 100644 --- a/tinkering/util.lua +++ b/tinkering/util.lua @@ -2,3 +2,10 @@ function tinkering.color_filter(texture, color) return texture.."^[multiply:"..color end + +function tinkering.combine_textures(tex1, tex2, color1, color2, offset, dp) + local main_tex = tex1 .."\\^[multiply\\:".. color1 + local rod_tex = tex2 .."\\^[multiply\\:".. color2 + + return "[combine:16x16:"..offset.."="..main_tex..":0,0="..rod_tex +end