From a76fb8dd57f563d13c132f6852d210d5d98ed530 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 27 Oct 2020 19:53:49 +0100 Subject: [PATCH] Added tt support, made enchanted bows function properly --- mods/CORE/_mcl_enchanting/core.lua | 13 +++--- mods/CORE/_mcl_enchanting/init.lua | 1 + mods/CORE/_mcl_enchanting/mod.conf | 2 +- mods/CORE/_mcl_enchanting/tt.lua | 15 +++++++ mods/HELP/mcl_tt/snippets_base.lua | 16 +++---- mods/HELP/tt/API.md | 11 ++++- mods/HELP/tt/init.lua | 71 +++++++++++++++++++----------- mods/ITEMS/mcl_bows/bow.lua | 47 ++++++++++++++++---- 8 files changed, 126 insertions(+), 50 deletions(-) create mode 100644 mods/CORE/_mcl_enchanting/tt.lua diff --git a/mods/CORE/_mcl_enchanting/core.lua b/mods/CORE/_mcl_enchanting/core.lua index 52cbe53b34..38a5e1767e 100644 --- a/mods/CORE/_mcl_enchanting/core.lua +++ b/mods/CORE/_mcl_enchanting/core.lua @@ -86,7 +86,7 @@ function mcl_enchanting.get_enchantments(itemstack) return minetest.deserialize(itemstack:get_meta():get_string("mcl_enchanting:enchantments")) or {} end -function mcl_enchanting.set_enchantments(itemstack, enchantments, data) +function mcl_enchanting.set_enchantments(itemstack, enchantments) return itemstack:get_meta():set_string("mcl_enchanting:enchantments", minetest.serialize(enchantments)) end @@ -156,12 +156,12 @@ function mcl_enchanting.can_enchant(itemstack, enchantment, level) end function mcl_enchanting.enchant(itemstack, enchantment, level) - local enchanted_itemstack = ItemStack({name = mcl_enchanting.get_enchanted_itemstring(itemstack:get_name()), wear = itemstack:get_wear(), metadata = itemstack:get_metadata()}) - local enchantments = mcl_enchanting.get_enchantments(enchanted_itemstack) + itemstack:set_name(mcl_enchanting.get_enchanted_itemstring(itemstack:get_name())) + local enchantments = mcl_enchanting.get_enchantments(itemstack) enchantments[enchantment] = level - mcl_enchanting.set_enchantments(enchanted_itemstack, enchantments) - mcl_enchanting.reload_enchantments(enchanted_itemstack, enchantments) - return enchanted_itemstack + mcl_enchanting.set_enchantments(itemstack, enchantments) + mcl_enchanting.reload_enchantments(itemstack, enchantments) + return itemstack end function mcl_enchanting.reload_enchantments(itemstack, enchantments) @@ -172,4 +172,5 @@ function mcl_enchanting.reload_enchantments(itemstack, enchantments) func(itemstack, level, itemdef) end end + tt.reload_itemstack_description(itemstack) end diff --git a/mods/CORE/_mcl_enchanting/init.lua b/mods/CORE/_mcl_enchanting/init.lua index 4d693f952d..80b171db1a 100644 --- a/mods/CORE/_mcl_enchanting/init.lua +++ b/mods/CORE/_mcl_enchanting/init.lua @@ -10,6 +10,7 @@ dofile(modpath .. "/enchantments.lua") dofile(modpath .. "/features.lua") dofile(modpath .. "/core.lua") dofile(modpath .. "/command.lua") +dofile(modpath .. "/tt.lua") -- dofile(modpath .. "/ui.lua") -- dofile(modpath .. "/fx.lua") -- dofile(modpath .. "/book.lua") diff --git a/mods/CORE/_mcl_enchanting/mod.conf b/mods/CORE/_mcl_enchanting/mod.conf index 237db41186..8dfe4e94fd 100644 --- a/mods/CORE/_mcl_enchanting/mod.conf +++ b/mods/CORE/_mcl_enchanting/mod.conf @@ -1,5 +1,5 @@ name = mcl_enchanting description = The rewrite of the Enchanting mod for MineClone2 -depends = mcl_formspec, _mcl_autogroup +depends = mcl_formspec, tt optional_depends = screwdriver author = Fleckenstein diff --git a/mods/CORE/_mcl_enchanting/tt.lua b/mods/CORE/_mcl_enchanting/tt.lua new file mode 100644 index 0000000000..41ceb6249d --- /dev/null +++ b/mods/CORE/_mcl_enchanting/tt.lua @@ -0,0 +1,15 @@ +function mcl_enchanting.enchantments_snippet(_, _, itemstack) + if not itemstack then + return + end + local enchantments = mcl_enchanting.get_enchantments(itemstack) + local text = "" + for enchantment, level in pairs(enchantments) do + text = text .. mcl_enchanting.get_enchantment_description(enchantment, level) .. "\n" + end + if text ~= "" then + return text, false + end +end + +table.insert(tt.registered_snippets, 1, mcl_enchanting.enchantments_snippet) diff --git a/mods/HELP/mcl_tt/snippets_base.lua b/mods/HELP/mcl_tt/snippets_base.lua index 376f00f2c9..a3470b5c14 100644 --- a/mods/HELP/mcl_tt/snippets_base.lua +++ b/mods/HELP/mcl_tt/snippets_base.lua @@ -35,12 +35,12 @@ local function newline(str) end -- Digging capabilities of tool -tt.register_snippet(function(itemstring) +tt.register_snippet(function(itemstring, toolcaps) local def = minetest.registered_items[itemstring] - if not def.tool_capabilities then + if not toolcaps then return end - local groupcaps = def.tool_capabilities.groupcaps + local groupcaps = toolcaps.groupcaps if not groupcaps then return end @@ -105,8 +105,8 @@ tt.register_snippet(function(itemstring) -- Capabilities minestring = minestring .. capstr -- Max. drop level - local mdl = def.tool_capabilities.max_drop_level - if not def.tool_capabilities.max_drop_level then + local mdl = toolcaps.max_drop_level + if not toolcaps.max_drop_level then mdl = 0 end minestring = minestring .. S("Block breaking strength: @1", mdl) @@ -114,8 +114,8 @@ tt.register_snippet(function(itemstring) local weaponstring = "" -- Weapon stats - if def.tool_capabilities.damage_groups then - for group, damage in pairs(def.tool_capabilities.damage_groups) do + if toolcaps.damage_groups then + for group, damage in pairs(toolcaps.damage_groups) do local msg if group == "fleshy" then if damage >= 0 then @@ -127,7 +127,7 @@ tt.register_snippet(function(itemstring) weaponstring = newline(weaponstring) weaponstring = weaponstring .. msg end - local full_punch_interval = def.tool_capabilities.full_punch_interval + local full_punch_interval = toolcaps.full_punch_interval if not full_punch_interval then full_punch_interval = 1 end diff --git a/mods/HELP/tt/API.md b/mods/HELP/tt/API.md index a510553ce1..37f34d335c 100644 --- a/mods/HELP/tt/API.md +++ b/mods/HELP/tt/API.md @@ -13,8 +13,9 @@ Once this mod had overwritten the `description` field of an item was overwritten ## `tt.register_snippet(func)` Register a custom snippet function. -`func` is a function of the form `func(itemstring)`. -It will be called for (nearly) every itemstring. +`func` is a function of the form `func(itemstring, tool_capabilities, itemstack)`. +It will be called for (nearly) every itemstring at startup and when `tt.reload_itemstack_description` is called for an itemstack. +The `itemstack` parameter is only present when the snippet is called via `tt.reload_itemstack_description` and contains the itemstack. Returns: Two values, the first one is required. 1st return value: A string you want to append to this item or `nil` if nothing shall be appended. @@ -29,3 +30,9 @@ tt.register_snippet(function(itemstring) end end) ``` + +## `tt.reload_itemstack_description(itemstack)` + +This function will dynamically reload the itemstack description, +it becomes handy when `ìtemstack:get_meta():set_tool_capabilities(...)` was used +or if some snippets are based on metadata. diff --git a/mods/HELP/tt/init.lua b/mods/HELP/tt/init.lua index a79bf27b59..d1bb6d6b8b 100644 --- a/mods/HELP/tt/init.lua +++ b/mods/HELP/tt/init.lua @@ -14,33 +14,41 @@ dofile(minetest.get_modpath(minetest.get_current_modname()).."/snippets.lua") -- Apply item description updates +local function apply_snippets(desc, itemstring, toolcaps, itemstack) + local first = true + -- Apply snippets + for s=1, #tt.registered_snippets do + local str, snippet_color = tt.registered_snippets[s](itemstring, toolcaps, itemstack) + if snippet_color == nil then + snippet_color = tt.COLOR_DEFAULT + elseif snippet_color == false then + snippet_color = false + end + if str then + if first then + first = false + end + desc = desc .. "\n" + if snippet_color then + desc = desc .. minetest.colorize(snippet_color, str) + else + desc = desc .. str + end + end + end + return desc +end + +local function should_change(itemstring, def) + return itemstring ~= "" and itemstring ~= "air" and itemstring ~= "ignore" and itemstring ~= "unknown" and def ~= nil and def.description ~= nil and def.description ~= "" and def._tt_ignore ~= true +end + local function append_snippets() for itemstring, def in pairs(minetest.registered_items) do - if itemstring ~= "" and itemstring ~= "air" and itemstring ~= "ignore" and itemstring ~= "unknown" and def ~= nil and def.description ~= nil and def.description ~= "" and def._tt_ignore ~= true then - local desc = def.description - local orig_desc = desc - local first = true - -- Apply snippets - for s=1, #tt.registered_snippets do - local str, snippet_color = tt.registered_snippets[s](itemstring) - if snippet_color == nil then - snippet_color = tt.COLOR_DEFAULT - elseif snippet_color == false then - snippet_color = false - end - if str then - if first then - first = false - end - desc = desc .. "\n" - if snippet_color then - desc = desc .. minetest.colorize(snippet_color, str) - else - desc = desc .. str - end - end - end - if desc ~= def.description then + if should_change(itemstring, def) then + local orig_desc = def.description + local desc = apply_snippets(orig_desc, itemstring, def.tool_capabilities, nil) + if desc ~= orig_desc then minetest.override_item(itemstring, { description = desc, _tt_original_description = orig_desc }) end end @@ -48,3 +56,16 @@ local function append_snippets() end minetest.register_on_mods_loaded(append_snippets) + +tt.reload_itemstack_description = function(itemstack) + local itemstring = itemstack:get_name() + local def = itemstack:get_definition() + if should_change(itemstring, def) then + local meta = itemstack:get_meta() + local orig_desc = def._tt_original_description + local desc = apply_snippets(orig_desc, itemstring, itemstack:get_tool_capabilities(), itemstack) + if desc ~= orig_desc then + meta:set_string("description", desc) + end + end +end diff --git a/mods/ITEMS/mcl_bows/bow.lua b/mods/ITEMS/mcl_bows/bow.lua index 0368a4215b..dc7334f312 100644 --- a/mods/ITEMS/mcl_bows/bow.lua +++ b/mods/ITEMS/mcl_bows/bow.lua @@ -130,6 +130,9 @@ local reset_bows = function(player) if stack:get_name()=="mcl_bows:bow_0" or stack:get_name()=="mcl_bows:bow_1" or stack:get_name()=="mcl_bows:bow_2" then stack:set_name("mcl_bows:bow") list[place] = stack + elseif stack:get_name()=="mcl_bows:bow_0_enchanted" or stack:get_name()=="mcl_bows:bow_1_enchanted" or stack:get_name()=="mcl_bows:bow_2_enchanted" then + stack:set_name("mcl_bows:bow_enchanted") + list[place] = stack end end inv:set_list("main", list) @@ -159,7 +162,11 @@ for level=0, 2 do groups = {not_in_creative_inventory=1, not_in_craft_guide=1, bow=1}, on_drop = function(itemstack, dropper, pos) reset_bow_state(dropper) - itemstack:set_name("mcl_bows:bow") + if minetest.get_item_group(itemstack:get_name(), "enchanted") > 0 then + itemstack:set_name("mcl_bows:bow_enchanted") + else + itemstack:set_name("mcl_bows:bow") + end minetest.item_drop(itemstack, dropper, pos) itemstack:take_item() return itemstack @@ -176,9 +183,11 @@ controls.register_on_release(function(player, key, time) if key~="RMB" then return end local inv = minetest.get_inventory({type="player", name=player:get_player_name()}) local wielditem = player:get_wielded_item() - if (wielditem:get_name()=="mcl_bows:bow_0" or wielditem:get_name()=="mcl_bows:bow_1" or wielditem:get_name()=="mcl_bows:bow_2") then + if (wielditem:get_name()=="mcl_bows:bow_0" or wielditem:get_name()=="mcl_bows:bow_1" or wielditem:get_name()=="mcl_bows:bow_2" or + wielditem:get_name()=="mcl_bows:bow_0_enchanted" or wielditem:get_name()=="mcl_bows:bow_1_enchanted" or wielditem:get_name()=="mcl_bows:bow_2_enchanted") then local has_shot = false - + + local enchanted = minetest.get_item_group(wielditem:get_name(), "enchanted") > 0 local speed, damage local p_load = bow_load[player:get_player_name()] local charge @@ -217,8 +226,13 @@ controls.register_on_release(function(player, key, time) end has_shot = player_shoot_arrow(wielditem, player, speed, damage, is_critical) - - wielditem:set_name("mcl_bows:bow") + + if enchanted then + wielditem:set_name("mcl_bows:bow_enchanted") + else + wielditem:set_name("mcl_bows:bow") + end + if has_shot and not minetest.is_creative_enabled(player:get_player_name()) then wielditem:add_wear(65535/BOW_DURABILITY) end @@ -235,8 +249,13 @@ controls.register_on_hold(function(player, key, time) end local inv = minetest.get_inventory({type="player", name=name}) local wielditem = player:get_wielded_item() - if bow_load[name] == nil and wielditem:get_name()=="mcl_bows:bow" and (creative or get_arrow(player)) then - wielditem:set_name("mcl_bows:bow_0") + if bow_load[name] == nil and (wielditem:get_name()=="mcl_bows:bow" or wielditem:get_name()=="mcl_bows:bow_enchanted") and (creative or get_arrow(player)) then + local enchanted = (wielditem:get_name()=="mcl_bows:bow_enchanted") + if enchanted then + wielditem:set_name("mcl_bows:bow_0_enchanted") + else + wielditem:set_name("mcl_bows:bow_0") + end player:set_wielded_item(wielditem) if minetest.get_modpath("playerphysics") then -- Slow player down when using bow @@ -249,12 +268,18 @@ controls.register_on_hold(function(player, key, time) if type(bow_load[name]) == "number" then if wielditem:get_name() == "mcl_bows:bow_0" and minetest.get_us_time() - bow_load[name] >= BOW_CHARGE_TIME_HALF then wielditem:set_name("mcl_bows:bow_1") + elseif wielditem:get_name() == "mcl_bows:bow_0_enchanted" and minetest.get_us_time() - bow_load[name] >= BOW_CHARGE_TIME_HALF then + wielditem:set_name("mcl_bows:bow_1_enchanted") elseif wielditem:get_name() == "mcl_bows:bow_1" and minetest.get_us_time() - bow_load[name] >= BOW_CHARGE_TIME_FULL then wielditem:set_name("mcl_bows:bow_2") + elseif wielditem:get_name() == "mcl_bows:bow_1_enchanted" and minetest.get_us_time() - bow_load[name] >= BOW_CHARGE_TIME_FULL then + wielditem:set_name("mcl_bows:bow_2_enchanted") end else if wielditem:get_name() == "mcl_bows:bow_0" or wielditem:get_name() == "mcl_bows:bow_1" or wielditem:get_name() == "mcl_bows:bow_2" then wielditem:set_name("mcl_bows:bow") + elseif wielditem:get_name() == "mcl_bows:bow_0_enchanted" or wielditem:get_name() == "mcl_bows:bow_1_enchanted" or wielditem:get_name() == "mcl_bows:bow_2_enchanted" then + wielditem:set_name("mcl_bows:bow_enchanted") end end player:set_wielded_item(wielditem) @@ -270,7 +295,7 @@ minetest.register_globalstep(function(dtime) local wielditem = player:get_wielded_item() local wieldindex = player:get_wield_index() local controls = player:get_player_control() - if type(bow_load[name]) == "number" and ((wielditem:get_name()~="mcl_bows:bow_0" and wielditem:get_name()~="mcl_bows:bow_1" and wielditem:get_name()~="mcl_bows:bow_2") or wieldindex ~= bow_index[name]) then + if type(bow_load[name]) == "number" and ((wielditem:get_name()~="mcl_bows:bow_0" and wielditem:get_name()~="mcl_bows:bow_1" and wielditem:get_name()~="mcl_bows:bow_2" and wielditem:get_name()~="mcl_bows:bow_0_enchanted" and wielditem:get_name()~="mcl_bows:bow_1_enchanted" and wielditem:get_name()~="mcl_bows:bow_2_enchanted") or wieldindex ~= bow_index[name]) then reset_bow_state(player, true) end end @@ -309,6 +334,12 @@ minetest.register_craft({ burntime = 15, }) +minetest.register_craft({ + type = "fuel", + recipe = "mcl_bows:bow_enchanted", + burntime = 15, +}) + -- Add entry aliases for the Help if minetest.get_modpath("doc") then doc.add_entry_alias("tools", "mcl_bows:bow", "tools", "mcl_bows:bow_0")