Added tt support, made enchanted bows function properly

This commit is contained in:
Elias Fleckenstein 2020-10-27 19:53:49 +01:00
parent 1cef707c6c
commit a76fb8dd57
8 changed files with 126 additions and 50 deletions

View File

@ -86,7 +86,7 @@ function mcl_enchanting.get_enchantments(itemstack)
return minetest.deserialize(itemstack:get_meta():get_string("mcl_enchanting:enchantments")) or {} return minetest.deserialize(itemstack:get_meta():get_string("mcl_enchanting:enchantments")) or {}
end 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)) return itemstack:get_meta():set_string("mcl_enchanting:enchantments", minetest.serialize(enchantments))
end end
@ -156,12 +156,12 @@ function mcl_enchanting.can_enchant(itemstack, enchantment, level)
end end
function mcl_enchanting.enchant(itemstack, enchantment, level) 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()}) itemstack:set_name(mcl_enchanting.get_enchanted_itemstring(itemstack:get_name()))
local enchantments = mcl_enchanting.get_enchantments(enchanted_itemstack) local enchantments = mcl_enchanting.get_enchantments(itemstack)
enchantments[enchantment] = level enchantments[enchantment] = level
mcl_enchanting.set_enchantments(enchanted_itemstack, enchantments) mcl_enchanting.set_enchantments(itemstack, enchantments)
mcl_enchanting.reload_enchantments(enchanted_itemstack, enchantments) mcl_enchanting.reload_enchantments(itemstack, enchantments)
return enchanted_itemstack return itemstack
end end
function mcl_enchanting.reload_enchantments(itemstack, enchantments) function mcl_enchanting.reload_enchantments(itemstack, enchantments)
@ -172,4 +172,5 @@ function mcl_enchanting.reload_enchantments(itemstack, enchantments)
func(itemstack, level, itemdef) func(itemstack, level, itemdef)
end end
end end
tt.reload_itemstack_description(itemstack)
end end

View File

@ -10,6 +10,7 @@ dofile(modpath .. "/enchantments.lua")
dofile(modpath .. "/features.lua") dofile(modpath .. "/features.lua")
dofile(modpath .. "/core.lua") dofile(modpath .. "/core.lua")
dofile(modpath .. "/command.lua") dofile(modpath .. "/command.lua")
dofile(modpath .. "/tt.lua")
-- dofile(modpath .. "/ui.lua") -- dofile(modpath .. "/ui.lua")
-- dofile(modpath .. "/fx.lua") -- dofile(modpath .. "/fx.lua")
-- dofile(modpath .. "/book.lua") -- dofile(modpath .. "/book.lua")

View File

@ -1,5 +1,5 @@
name = mcl_enchanting name = mcl_enchanting
description = The rewrite of the Enchanting mod for MineClone2 description = The rewrite of the Enchanting mod for MineClone2
depends = mcl_formspec, _mcl_autogroup depends = mcl_formspec, tt
optional_depends = screwdriver optional_depends = screwdriver
author = Fleckenstein author = Fleckenstein

View File

@ -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)

View File

@ -35,12 +35,12 @@ local function newline(str)
end end
-- Digging capabilities of tool -- Digging capabilities of tool
tt.register_snippet(function(itemstring) tt.register_snippet(function(itemstring, toolcaps)
local def = minetest.registered_items[itemstring] local def = minetest.registered_items[itemstring]
if not def.tool_capabilities then if not toolcaps then
return return
end end
local groupcaps = def.tool_capabilities.groupcaps local groupcaps = toolcaps.groupcaps
if not groupcaps then if not groupcaps then
return return
end end
@ -105,8 +105,8 @@ tt.register_snippet(function(itemstring)
-- Capabilities -- Capabilities
minestring = minestring .. capstr minestring = minestring .. capstr
-- Max. drop level -- Max. drop level
local mdl = def.tool_capabilities.max_drop_level local mdl = toolcaps.max_drop_level
if not def.tool_capabilities.max_drop_level then if not toolcaps.max_drop_level then
mdl = 0 mdl = 0
end end
minestring = minestring .. S("Block breaking strength: @1", mdl) minestring = minestring .. S("Block breaking strength: @1", mdl)
@ -114,8 +114,8 @@ tt.register_snippet(function(itemstring)
local weaponstring = "" local weaponstring = ""
-- Weapon stats -- Weapon stats
if def.tool_capabilities.damage_groups then if toolcaps.damage_groups then
for group, damage in pairs(def.tool_capabilities.damage_groups) do for group, damage in pairs(toolcaps.damage_groups) do
local msg local msg
if group == "fleshy" then if group == "fleshy" then
if damage >= 0 then if damage >= 0 then
@ -127,7 +127,7 @@ tt.register_snippet(function(itemstring)
weaponstring = newline(weaponstring) weaponstring = newline(weaponstring)
weaponstring = weaponstring .. msg weaponstring = weaponstring .. msg
end 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 if not full_punch_interval then
full_punch_interval = 1 full_punch_interval = 1
end end

View File

@ -13,8 +13,9 @@ Once this mod had overwritten the `description` field of an item was overwritten
## `tt.register_snippet(func)` ## `tt.register_snippet(func)`
Register a custom snippet function. Register a custom snippet function.
`func` is a function of the form `func(itemstring)`. `func` is a function of the form `func(itemstring, tool_capabilities, itemstack)`.
It will be called for (nearly) every itemstring. 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. 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. 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
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.

View File

@ -14,33 +14,41 @@ dofile(minetest.get_modpath(minetest.get_current_modname()).."/snippets.lua")
-- Apply item description updates -- 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() local function append_snippets()
for itemstring, def in pairs(minetest.registered_items) do 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 if should_change(itemstring, def) then
local desc = def.description local orig_desc = def.description
local orig_desc = desc local desc = apply_snippets(orig_desc, itemstring, def.tool_capabilities, nil)
local first = true if desc ~= orig_desc then
-- 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
minetest.override_item(itemstring, { description = desc, _tt_original_description = orig_desc }) minetest.override_item(itemstring, { description = desc, _tt_original_description = orig_desc })
end end
end end
@ -48,3 +56,16 @@ local function append_snippets()
end end
minetest.register_on_mods_loaded(append_snippets) 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

View File

@ -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 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") stack:set_name("mcl_bows:bow")
list[place] = stack 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
end end
inv:set_list("main", list) 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}, groups = {not_in_creative_inventory=1, not_in_craft_guide=1, bow=1},
on_drop = function(itemstack, dropper, pos) on_drop = function(itemstack, dropper, pos)
reset_bow_state(dropper) 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) minetest.item_drop(itemstack, dropper, pos)
itemstack:take_item() itemstack:take_item()
return itemstack return itemstack
@ -176,9 +183,11 @@ controls.register_on_release(function(player, key, time)
if key~="RMB" then return end if key~="RMB" then return end
local inv = minetest.get_inventory({type="player", name=player:get_player_name()}) local inv = minetest.get_inventory({type="player", name=player:get_player_name()})
local wielditem = player:get_wielded_item() 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 has_shot = false
local enchanted = minetest.get_item_group(wielditem:get_name(), "enchanted") > 0
local speed, damage local speed, damage
local p_load = bow_load[player:get_player_name()] local p_load = bow_load[player:get_player_name()]
local charge local charge
@ -217,8 +226,13 @@ controls.register_on_release(function(player, key, time)
end end
has_shot = player_shoot_arrow(wielditem, player, speed, damage, is_critical) 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 if has_shot and not minetest.is_creative_enabled(player:get_player_name()) then
wielditem:add_wear(65535/BOW_DURABILITY) wielditem:add_wear(65535/BOW_DURABILITY)
end end
@ -235,8 +249,13 @@ controls.register_on_hold(function(player, key, time)
end end
local inv = minetest.get_inventory({type="player", name=name}) local inv = minetest.get_inventory({type="player", name=name})
local wielditem = player:get_wielded_item() 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 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
wielditem:set_name("mcl_bows:bow_0") 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) player:set_wielded_item(wielditem)
if minetest.get_modpath("playerphysics") then if minetest.get_modpath("playerphysics") then
-- Slow player down when using bow -- 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 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 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") 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 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") 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 end
else 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 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") 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
end end
player:set_wielded_item(wielditem) player:set_wielded_item(wielditem)
@ -270,7 +295,7 @@ minetest.register_globalstep(function(dtime)
local wielditem = player:get_wielded_item() local wielditem = player:get_wielded_item()
local wieldindex = player:get_wield_index() local wieldindex = player:get_wield_index()
local controls = player:get_player_control() 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) reset_bow_state(player, true)
end end
end end
@ -309,6 +334,12 @@ minetest.register_craft({
burntime = 15, burntime = 15,
}) })
minetest.register_craft({
type = "fuel",
recipe = "mcl_bows:bow_enchanted",
burntime = 15,
})
-- Add entry aliases for the Help -- Add entry aliases for the Help
if minetest.get_modpath("doc") then if minetest.get_modpath("doc") then
doc.add_entry_alias("tools", "mcl_bows:bow", "tools", "mcl_bows:bow_0") doc.add_entry_alias("tools", "mcl_bows:bow", "tools", "mcl_bows:bow_0")