local S = minetest.get_translator(minetest.get_current_modname()) local MAX_WEAR = 65535 local function get_grindstone_formspec() return "size[9,8.75]".. "image[3,1.5;1.5,1;gui_crafting_arrow.png]".. "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. "label[1,0.1;"..minetest.formspec_escape(minetest.colorize("#313131", S("Repair & Disenchant"))).."]".. "list[context;main;0,0;8,4;]".. "list[current_player;main;0,4.5;9,3;9]".. mcl_formspec.get_itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.74;9,1;]".. mcl_formspec.get_itemslot_bg(0,7.74,9,1).. "list[context;input;1,1;1,1;]".. mcl_formspec.get_itemslot_bg(1,1,1,1).. "list[context;input;1,2;1,1;1]".. mcl_formspec.get_itemslot_bg(1,2,1,1).. "list[context;output;6,1.5;1,1;]".. mcl_formspec.get_itemslot_bg(6,1.5,1,1).. "listring[context;output]".. "listring[current_player;main]".. "listring[context;input]".. "listring[current_player;main]" end local function create_new_item(name_item, meta, wear) local new_item = ItemStack(name_item) new_item:set_wear(wear) local new_meta = new_item:get_meta() new_meta:set_string("name", meta:get_string("name")) tt.reload_itemstack_description(new_item) return new_item end local function remove_enchant_name(stack) if mcl_enchanting.is_enchanted(stack:get_name()) then local name = stack:get_name() return name.sub(name, 1, -11) else return stack:get_name() end end local function transfer_curse(old_itemstack, new_itemstack) local enchants = mcl_enchanting.get_enchantments(old_itemstack) for enchant, level in pairs(enchants) do if mcl_enchanting.enchantments[enchant].curse == true then new_itemstack = mcl_enchanting.enchant(new_itemstack, enchant, level) end end return new_itemstack end -- Helper function to make sure update_anvil_slots NEVER overstacks the output slot local function fix_stack_size(stack) if not stack or stack == "" then return "" end local count = stack:get_count() local max_count = stack:get_stack_max() if count > max_count then stack:set_count(max_count) count = max_count end return count end local function update_grindstone_slots(meta) local inv = meta:get_inventory() local input1 = inv:get_stack("input", 1) local input2 = inv:get_stack("input", 2) local meta = input1:get_meta() local new_output if (not input1:is_empty() and not input2:is_empty()) then local def1 = input1:get_definition() local def2 = input2:get_definition() local name1 = remove_enchant_name(input1) local name2 = remove_enchant_name(input2) local function calculate_repair(dur1, dur2) local new_durability = (MAX_WEAR - dur1) + (MAX_WEAR - dur2) * 1.05 return math.max(0, math.min(MAX_WEAR, MAX_WEAR - new_durability)) end if def1.type == "tool" and def2.type == "tool" and name1 == name2 then local new_wear = calculate_repair(input1:get_wear(), input2:get_wear()) local new_item = create_new_item(name1, meta, new_wear) if mcl_enchanting.is_enchanted(input1:get_name()) then new_output = transfer_curse(input1, new_item) else new_output = transfer_curse(input2, new_item) end else new_output = "" end elseif (not input1:is_empty() and input2:is_empty()) or (input1:is_empty() and not input2:is_empty()) then if input2:is_empty() then local def1 = input1:get_definition() local meta = input1:get_meta() if def1.type == "tool" and mcl_enchanting.is_enchanted(input1:get_name()) then local name = remove_enchant_name(input1) local wear = input1:get_wear() local new_item = create_new_item(name, meta, wear) new_output = transfer_curse(input1, new_item) else new_output = "" end else local def2 = input2:get_definition() local meta = input2:get_meta() if def2.type == "tool" and mcl_enchanting.is_enchanted(input2:get_name()) then local name = remove_enchant_name(input2) local wear = input2:get_wear() local new_item = create_new_item(name, meta, wear) new_output = transfer_curse(input2, new_item) else new_output = "" end end else new_output = "" end -- Set the new output slot if new_output then fix_stack_size(new_output) inv:set_stack("output", 1, new_output) end end minetest.register_node("mcl_grindstone:grindstone", { description = S("Grindstone"), _tt_help = S("Used to disenchant/fix tools"), _doc_items_longdesc = S("This is currently a decorative block which serves as the weapon smith's work station. In minecraft this is used to disenchant/fix tools howerver this has not yet been implemented"), tiles = { "grindstone_top.png", "grindstone_top.png", "grindstone_side.png", "grindstone_side.png", "grindstone_front.png", "grindstone_front.png" }, drawtype = "nodebox", paramtype2 = "facedir", node_box = { type = "fixed", -- created with nodebox editor fixed = { {-0.25, -0.25, -0.375, 0.25, 0.5, 0.375}, {-0.375, -0.0625, -0.1875, -0.25, 0.3125, 0.1875}, {0.25, -0.0625, -0.1875, 0.375, 0.3125, 0.1875}, {0.25, -0.5, -0.125, 0.375, -0.0625, 0.125}, {-0.375, -0.5, -0.125, -0.25, -0.0625, 0.125}, } }, selection_box = node_box, collision_box = node_box, sounds = mcl_sounds.node_sound_stone_defaults(), groups = {pickaxey = 1, deco_block = 1}, allow_metadata_inventory_take = function(pos, listname, index, stack, player) local name = player:get_player_name() if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) return 0 else return stack:get_count() end end, allow_metadata_inventory_put = function(pos, listname, index, stack, player) local name = player:get_player_name() if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) return 0 elseif listname == "output" then return 0 else return stack:get_count() end end, allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) local name = player:get_player_name() if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) return 0 elseif to_list == "output" then return 0 elseif from_list == "output" and to_list == "input" then local meta = minetest.get_meta(pos) local inv = meta:get_inventory() if inv:get_stack(to_list, to_index):is_empty() then return count else return 0 end else return count end end, on_metadata_inventory_put = function(pos, listname, index, stack, player) local meta = minetest.get_meta(pos) update_grindstone_slots(meta) end, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) local meta = minetest.get_meta(pos) if from_list == "output" and to_list == "input" then local inv = meta:get_inventory() for i=1, inv:get_size("input") do if i ~= to_index then local istack = inv:get_stack("input", i) istack:set_count(math.max(0, istack:get_count() - count)) inv:set_stack("input", i, istack) end end end update_grindstone_slots(meta) end, on_metadata_inventory_take = function(pos, listname, index, stack, player) local meta = minetest.get_meta(pos) if listname == "output" then local inv = meta:get_inventory() local input1 = inv:get_stack("input", 1) local input2 = inv:get_stack("input", 2) if mcl_experience.throw_xp then mcl_experience.throw_xp(pos, math.random(1,6)) end -- Both slots occupied? if not input1:is_empty() and not input2:is_empty() then input1:take_item() input2:take_item() inv:set_stack("input", 1, input1) inv:set_stack("input", 2, input2) else if not input1:is_empty() then input1:set_count(math.max(0, input1:get_count() - stack:get_count())) inv:set_stack("input", 1, input1) end if not input2:is_empty() then input2:set_count(math.max(0, input2:get_count() - stack:get_count())) inv:set_stack("input", 2, input2) end end elseif listname == "input" then update_grindstone_slots(meta) end end, on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() inv:set_size("input", 2) inv:set_size("output", 1) local form = get_grindstone_formspec() meta:set_string("formspec", form) end, on_rightclick = function(pos, node, player, itemstack) if not player:get_player_control().sneak then local meta = minetest.get_meta(pos) update_grindstone_slots(meta) meta:set_string("formspec", get_grindstone_formspec()) end end, _mcl_blast_resistance = 6, _mcl_hardness = 2 }) minetest.register_craft({ output = "mcl_grindstone:grindstone", recipe = { { "mcl_core:stick", "mcl_stairs:slab_stone_rough", "mcl_core:stick"}, { "group:wood", "", "group:wood"}, } })