1
0
mirror of https://bitbucket.org/minetest_gamers/x_enchanting.git synced 2025-06-28 22:06:17 +02:00

Compare commits

...

6 Commits

26 changed files with 304 additions and 98 deletions

View File

@ -12,5 +12,6 @@
"license": "LGPL-2.1-or-later",
"media_license": "CC-BY-SA-4.0",
"repo": "https://bitbucket.org/minetest_gamers/x_enchanting/src/master/",
"issue_tracker": "https://bitbucket.org/minetest_gamers/x_enchanting/issues?status=new&status=open"
"issue_tracker": "https://bitbucket.org/minetest_gamers/x_enchanting/issues?status=new&status=open",
"forums": 28861
}

View File

@ -16,13 +16,14 @@ exclude_files = {
}
globals = {
'minetest',
'XEnchanting'
}
read_globals = {
"DIR_DELIM", "INIT",
"minetest", "core",
"core",
"dump", "dump2",
"Raycast",

View File

@ -62,6 +62,18 @@ Increases the item's durability.
Increases the player's mining speed. Also adds mining groupcaps to item, e.g. enchanted wood pickaxe can mine level 1 nodes (e.g. obsidian) after enchantment.
#### Silk Touch
Causes certain blocks to drop themselves as items instead of their usual drops when mined. Mods can prevent this behaviour with adding group `{ no_silktouch = 1 }` to the nodes.
#### Curse of Vanishing
Causes the item to disappear on death.
### Knockback
Increases knockback (players only).
## Dependencies
- none
@ -129,11 +141,11 @@ GNU Lesser General Public License v2.1 or later (see included LICENSE file)
### Sounds
**Mixkit Sound Effects Free License**, Sound effects obtained from https://mixkit.co
**CC-BY-3.0, Kostas17**, https://freesound.org
- x_enchanting_enchant.ogg
**Standard License**, Sound effects obtained from https://mixkit.co
**CC0-1.0, Zeinel**, https://freesound.org
- x_enchanting_scroll.1.ogg
- x_enchanting_scroll.2.ogg
@ -144,11 +156,6 @@ GNU Lesser General Public License v2.1 or later (see included LICENSE file)
- x_enchanting_scroll.7.ogg
- x_enchanting_scroll.8.ogg
- x_enchanting_scroll.9.ogg
- x_enchanting_scroll.10.ogg
- x_enchanting_scroll.11.ogg
- x_enchanting_scroll.12.ogg
- x_enchanting_scroll.13.ogg
- x_enchanting_scroll.14.ogg
## Installation

209
api.lua
View File

@ -115,10 +115,45 @@ XEnchanting = {
[5] = 45,
},
weight = 10
}
},
silk_touch = {
name = S('Silk Touch'),
final_level_range = {
[1] = { 15, 65 }
},
level_def = {
[1] = 1
},
weight = 1,
secondary = true
},
curse_of_vanishing = {
name = S('Curse of Vanishing'),
final_level_range = {
[1] = { 25, 50 }
},
level_def = {
[1] = 1
},
weight = 1,
secondary = true
},
knockback = {
name = S('Knockback'),
final_level_range = {
[1] = { 5, 55 },
[2] = { 25, 75 }
},
-- increase %
level_def = {
[1] = 105,
[2] = 190
},
weight = 5
},
},
randomseed = os.time(),
form_context = {},
player_seeds = {},
scroll_animations = {
scroll_open = { { x = 1, y = 40 }, 80, 0, false },
scroll_close = { { x = 45, y = 84 }, 80, 0, false },
@ -136,6 +171,18 @@ local function mergeTables(t1, t2)
return t1
end
---Gets length of hashed table
---@param table any
---@return integer
local function get_table_length(table)
local length = 0
for _ in pairs(table) do
length = length + 1
end
return length
end
function XEnchanting.has_tool_group(self, name)
if minetest.get_item_group(name, 'pickaxe') > 0 then
return 'pickaxe'
@ -167,8 +214,6 @@ end
function XEnchanting.get_enchanted_tool_capabilities(self, tool_def, enchantments)
local tool_stack = ItemStack({ name = tool_def.name })
local tool_capabilities = tool_stack:get_tool_capabilities()
local enchantments_desc = {}
local enchantments_desc_masked = {}
for i, enchantment in ipairs(enchantments) do
-- Efficiency
@ -236,18 +281,6 @@ function XEnchanting.get_enchanted_tool_capabilities(self, tool_def, enchantment
tool_capabilities.full_punch_interval = new_fpi
end
if tool_capabilities.groupcaps or tool_capabilities.full_punch_interval then
enchantments_desc[#enchantments_desc + 1] = self.enchantment_defs[enchantment.id].name
.. ' '
.. self.roman_numbers[enchantment.level]
if #enchantments_desc_masked == 0 then
enchantments_desc_masked[#enchantments_desc_masked + 1] = self.enchantment_defs[enchantment.id].name
.. ' '
.. self.roman_numbers[enchantment.level]
end
end
end
-- Unbreaking
@ -272,18 +305,6 @@ function XEnchanting.get_enchanted_tool_capabilities(self, tool_def, enchantment
tool_capabilities.punch_attack_uses = new_uses
end
if tool_capabilities.groupcaps or tool_capabilities.punch_attack_uses then
enchantments_desc[#enchantments_desc + 1] = self.enchantment_defs[enchantment.id].name
.. ' '
.. self.roman_numbers[enchantment.level]
if #enchantments_desc_masked == 0 then
enchantments_desc_masked[#enchantments_desc_masked + 1] = self.enchantment_defs[enchantment.id].name
.. ' '
.. self.roman_numbers[enchantment.level]
end
end
end
-- Sharpness
@ -294,16 +315,6 @@ function XEnchanting.get_enchanted_tool_capabilities(self, tool_def, enchantment
tool_capabilities.damage_groups[group_name] = new_damage
end
enchantments_desc[#enchantments_desc + 1] = self.enchantment_defs[enchantment.id].name
.. ' '
.. self.roman_numbers[enchantment.level]
if #enchantments_desc_masked == 0 then
enchantments_desc_masked[#enchantments_desc_masked + 1] = self.enchantment_defs[enchantment.id].name
.. ' '
.. self.roman_numbers[enchantment.level]
end
end
-- Fortune
@ -312,15 +323,40 @@ function XEnchanting.get_enchanted_tool_capabilities(self, tool_def, enchantment
local new_max_drop_level = old_max_drop_level + enchantment.value
tool_capabilities.max_drop_level = new_max_drop_level
end
end
return tool_capabilities
end
function XEnchanting.get_randomseed(self)
return tonumber(tostring(os.time()):reverse():sub(1, 9)) --[[@as integer]]
end
function XEnchanting.get_enchanted_descriptions(self, enchantments)
local enchantments_desc = {}
local enchantments_desc_masked = {}
for i, enchantment in ipairs(enchantments) do
local add_roman_numbers = true
if get_table_length(self.enchantment_defs[enchantment.id].final_level_range) == 1 then
add_roman_numbers = false
end
if add_roman_numbers then
enchantments_desc[#enchantments_desc + 1] = self.enchantment_defs[enchantment.id].name
.. ' '
.. self.roman_numbers[enchantment.level]
else
enchantments_desc[#enchantments_desc + 1] = self.enchantment_defs[enchantment.id].name
end
if #enchantments_desc_masked == 0 then
enchantments_desc_masked[#enchantments_desc_masked + 1] = self.enchantment_defs[enchantment.id].name
.. ' '
.. self.roman_numbers[enchantment.level]
if #enchantments_desc_masked == 0 and not enchantment.secondary then
enchantments_desc_masked[#enchantments_desc_masked + 1] = self.enchantment_defs[enchantment.id].name
if add_roman_numbers then
enchantments_desc_masked[#enchantments_desc_masked + 1] = ' ' .. self.roman_numbers[enchantment.level]
end
end
end
@ -330,7 +366,6 @@ function XEnchanting.get_enchanted_tool_capabilities(self, tool_def, enchantment
enchantments_desc_masked = table.concat(enchantments_desc_masked, '') .. '...?'
return {
tool_capabilities = tool_capabilities,
enchantments_desc = enchantments_desc,
enchantments_desc_masked = enchantments_desc_masked
}
@ -338,8 +373,13 @@ end
function XEnchanting.set_enchanted_tool(self, pos, itemstack, level, player_name)
local data = self.form_context[player_name].data
local capabilities = data.slots[level].tool_cap_data.tool_capabilities
local description = data.slots[level].tool_cap_data.enchantments_desc
if not data then
return
end
local capabilities = data.slots[level].tool_cap_data
local description = data.slots[level].descriptions.enchantments_desc
local final_enchantments = data.slots[level].final_enchantments
local inv = minetest.get_meta(pos):get_inventory()
local tool_def = minetest.registered_tools[itemstack:get_name()]
@ -351,6 +391,10 @@ function XEnchanting.set_enchanted_tool(self, pos, itemstack, level, player_name
local stack_meta = itemstack:get_meta()
for i, enchantment in ipairs(final_enchantments) do
stack_meta:set_float('is_' .. enchantment.id, enchantment.value)
end
stack_meta:set_tool_capabilities(capabilities)
stack_meta:set_string('description', itemstack:get_description() .. '\n' .. description)
stack_meta:set_string('short_description', S('Enchanted') .. ' ' .. itemstack:get_short_description())
@ -364,7 +408,7 @@ function XEnchanting.set_enchanted_tool(self, pos, itemstack, level, player_name
inv:set_stack('trade', 1, trade_stack)
-- set new seed
self.randomseed = tonumber(tostring(os.time()):reverse():sub(1, 9)) --[[@as number]]
self.player_seeds[player_name] = self:get_randomseed()
local formspec = self:get_formspec(pos, player_name)
node_meta:set_string('formspec', formspec)
@ -376,7 +420,10 @@ function XEnchanting.set_enchanted_tool(self, pos, itemstack, level, player_name
}, true)
end
function XEnchanting.get_enchantment_data(self, nr_of_bookshelfs, tool_def)
function XEnchanting.get_enchantment_data(self, player, nr_of_bookshelfs, tool_def)
local p_name = player:get_player_name()
local randomseed = self.player_seeds[p_name] or self:get_randomseed()
math.randomseed(randomseed)
local _nr_of_bookshelfs = nr_of_bookshelfs
local data = {
slots = {}
@ -391,7 +438,6 @@ function XEnchanting.get_enchantment_data(self, nr_of_bookshelfs, tool_def)
----
-- Base enchantment
math.randomseed(self.randomseed)
local base = math.random(1, 8) + math.floor(_nr_of_bookshelfs / 2) + math.random(0, _nr_of_bookshelfs)
local top_slot_base_level = math.floor(math.max(base / 3, 1))
local middle_slot_base_level = math.floor((base * 2) / 3 + 1)
@ -406,12 +452,10 @@ function XEnchanting.get_enchantment_data(self, nr_of_bookshelfs, tool_def)
-- Applying modifiers to the enchantment level
local enchantability = minetest.get_item_group(tool_def.name, 'enchantability')
-- Generate a random number between 1 and 1+(enchantability/2), with a triangular distribution
math.randomseed(self.randomseed)
local rand_enchantability = 1 + math.random(enchantability / 4 + 1) + math.random(enchantability / 4 + 1)
-- Choose the enchantment level
local k = chosen_enchantment_level + rand_enchantability
-- A random bonus, between .85 and 1.15
math.randomseed(self.randomseed)
local rand_bonus_percent = 1 + ((math.random(0, 99) / 100) + (math.random(0, 99) / 100) - 1) * 0.15
-- Finally, we calculate the level
local final_level = math.round(k * rand_bonus_percent)
@ -424,6 +468,7 @@ function XEnchanting.get_enchantment_data(self, nr_of_bookshelfs, tool_def)
-- 2 Find possible enchantments
----
---@type Enchantment[]
local possible_enchantments = {}
-- Get level
@ -432,6 +477,7 @@ function XEnchanting.get_enchantment_data(self, nr_of_bookshelfs, tool_def)
for enchantment_name, enchantment_def in pairs(self.enchantment_defs) do
local levels = {}
-- find matching levels
for level, final_level_range in ipairs(enchantment_def.final_level_range) do
local min = final_level_range[1]
local max = final_level_range[2]
@ -441,13 +487,15 @@ function XEnchanting.get_enchantment_data(self, nr_of_bookshelfs, tool_def)
end
end
-- pick the highest level
local level = levels[#levels]
if level then
table.insert(possible_enchantments, {
id = enchantment_name,
value = enchantment_def.level_def[level],
level = level
level = level,
secondary = enchantment_def.secondary
})
end
end
@ -456,6 +504,7 @@ function XEnchanting.get_enchantment_data(self, nr_of_bookshelfs, tool_def)
-- 3 Select a set of enchantments from the list
----
---@type Enchantment[]
local final_enchantments = {}
local total_weight = 0
@ -464,18 +513,58 @@ function XEnchanting.get_enchantment_data(self, nr_of_bookshelfs, tool_def)
total_weight = total_weight + self.enchantment_defs[enchantment.id].weight
end
math.randomseed(self.randomseed)
-- Pick a random integer in the half range [0; total_weight] as a number `rand_weight`
local rand_weight = math.random(0, total_weight / 2)
-- local probability = (final_level + 1) / 50
local probability_level = final_level
local possible_enchantments_excl_secodnary = {}
-- select final enchantments
for _, enchantment in pairs(possible_enchantments) do
if not enchantment.secondary then
table.insert(possible_enchantments_excl_secodnary, enchantment)
end
end
-- Select final enchantments
-- Iterate through each enchantment in the list, subtracting its weight from `rand_weight`.
-- If `rand_weight` is now negative, select the current enchantment.
for j = 1, #possible_enchantments, 1 do
math.randomseed(self.randomseed)
local rand_ench_idx = math.random(1, #possible_enchantments)
local rand_ench = possible_enchantments[rand_ench_idx]
table.remove(possible_enchantments, rand_ench_idx)
if j == 1 then
-- Dont add cursed/secondary enchantment as first pick
rand_ench_idx = math.random(1, #possible_enchantments_excl_secodnary)
rand_ench = possible_enchantments_excl_secodnary[rand_ench_idx]
for idx, value in pairs(possible_enchantments) do
if rand_ench.id == value.id then
table.remove(possible_enchantments, idx)
end
end
table.insert(final_enchantments, rand_ench)
else
local probability = (probability_level + 1) / 50
table.remove(possible_enchantments, rand_ench_idx)
table.insert(final_enchantments, rand_ench)
-- With probability (`final_level` + 1) / 50, keep going. Otherwise, stop picking bonus enchantments.
local rand_probability = math.random()
if rand_probability < probability then
-- Divide the `final_level` in half, rounded down
-- (this does not affect the possible enchantments themselves,
-- because they were all pre-calculated in Step Two).
break
end
-- Repeat from the beginning.
probability_level = probability_level / 2
end
rand_weight = rand_weight - self.enchantment_defs[rand_ench.id].weight
table.insert(final_enchantments, rand_ench)
-- If `rand_weight` is now negative, select the current enchantment and stop.
if rand_weight < 0 then
@ -484,11 +573,13 @@ function XEnchanting.get_enchantment_data(self, nr_of_bookshelfs, tool_def)
end
local tool_cap_data = self:get_enchanted_tool_capabilities(tool_def, final_enchantments)
local descriptions = self:get_enchanted_descriptions(final_enchantments)
table.insert(data.slots, i, {
level = slot_lvl,
final_enchantments = final_enchantments,
tool_cap_data = tool_cap_data
tool_cap_data = tool_cap_data,
descriptions = descriptions
})
end
@ -530,10 +621,10 @@ function XEnchanting.get_formspec(self, pos, player_name, data)
if inv:get_stack('trade', 1):get_count() >= i then
---@diagnostic disable-next-line: codestyle-check
formspec[#formspec + 1] = 'image_button[2.5,' .. -0.5 + i .. ';5,1;x_enchanting_image_button.png;slot_' .. i .. ';' .. slot.tool_cap_data.enchantments_desc_masked .. ' ' .. minetest.colorize('#FFFF00', S('level') .. ': ' .. slot.level) .. ']'
formspec[#formspec + 1] = 'image_button[2.5,' .. -0.5 + i .. ';5,1;x_enchanting_image_button.png;slot_' .. i .. ';' .. slot.descriptions.enchantments_desc_masked .. ' ' .. minetest.colorize('#FFFF00', S('level') .. ': ' .. slot.level) .. ']'
else
---@diagnostic disable-next-line: codestyle-check
formspec[#formspec + 1] = 'image_button[2.5,' .. -0.5 + i .. ';5,1;x_enchanting_image_button_disabled.png;slot_' .. i .. ';' .. slot.tool_cap_data.enchantments_desc_masked .. ' ' .. minetest.colorize('#FFFF00', S('level') .. ': ' .. slot.level) .. ']'
formspec[#formspec + 1] = 'image_button[2.5,' .. -0.5 + i .. ';5,1;x_enchanting_image_button_disabled.png;slot_' .. i .. ';' .. slot.descriptions.enchantments_desc_masked .. ' ' .. minetest.colorize('#FFFF00', S('level') .. ': ' .. slot.level) .. ']'
end
formspec[#formspec + 1] = 'image[2.5,' .. -0.5 + i .. ';1,1;x_enchanting_image_trade_' .. i .. '.png;]'

View File

@ -17,12 +17,105 @@ end)
minetest.register_on_joinplayer(function(player, last_login)
XEnchanting.form_context[player:get_player_name()] = nil
if not XEnchanting.player_seeds[player:get_player_name()] then
XEnchanting.player_seeds[player:get_player_name()] = XEnchanting.get_randomseed()
end
end)
minetest.register_on_leaveplayer(function(player, timed_out)
XEnchanting.form_context[player:get_player_name()] = nil
end)
-- Silk Touch
local old_handle_node_drops = minetest.handle_node_drops
function minetest.handle_node_drops(pos, drops, digger)
if not digger
or not digger:is_player()
then
return old_handle_node_drops(pos, drops, digger)
end
local wield_stack = digger:get_wielded_item()
local wield_stack_meta = wield_stack:get_meta()
if wield_stack_meta:get_float('is_silk_touch') == 0 then
return old_handle_node_drops(pos, drops, digger)
end
local node = minetest.get_node(pos)
if minetest.get_item_group(node.name, 'no_silktouch') == 1 then
return old_handle_node_drops(pos, drops, digger)
end
-- drop raw item/node
return old_handle_node_drops(pos, { ItemStack(node.name) }, digger)
end
minetest.register_on_player_hpchange(function(player, hp_change, reason)
if (player:get_hp() + hp_change) <= 0 then
-- Going to die
local player_inv = player:get_inventory() --[[@as InvRef]]
-- Curse of Vanishing
local player_inventory_lists = { 'main', 'craft' }
for _, list_name in ipairs(player_inventory_lists) do
if not player_inv:is_empty(list_name) then
for i = 1, player_inv:get_size(list_name) do
local stack = player_inv:get_stack(list_name, i)
local stack_meta = stack:get_meta()
if stack_meta:get_float('is_curse_of_vanishing') > 0 then
player_inv:set_stack(list_name, i, ItemStack(''))
end
end
player_inv:set_list(list_name, {})
end
end
end
return hp_change
end, true)
-- Knockback (only for players)
local old_calculate_knockback = minetest.calculate_knockback
function minetest.calculate_knockback(player, hitter, time_from_last_punch,
tool_capabilities, dir, distance, damage)
if hitter and hitter:is_player() then
local hitter_wield_stack = hitter:get_wielded_item()
local hitter_wield_stack_meta = hitter_wield_stack:get_meta()
local ench_knockback = hitter_wield_stack_meta:get_float('is_knockback')
if ench_knockback > 0 then
local orig_knockback = old_calculate_knockback(
player,
hitter,
time_from_last_punch,
tool_capabilities,
dir,
distance,
damage
)
orig_knockback = orig_knockback + 1
local new_knockback = orig_knockback + (orig_knockback * (ench_knockback / 100))
player:add_velocity(vector.new(0, new_knockback, 0))
return new_knockback
end
end
return old_calculate_knockback(player, hitter, time_from_last_punch,
tool_capabilities, dir, distance, damage)
end
local mod_end_time = (minetest.get_us_time() - mod_start_time) / 1000000
print('[Mod] x_enchanting loaded.. [' .. mod_end_time .. 's]')

View File

@ -3,6 +3,9 @@ Sharpness=
Fortune=
Unbreaking=
Efficiency=
Silk Touch=
Curse of Vanishing=
Knockback=
Enchanted=
Enchant=
level=

View File

@ -3,6 +3,9 @@ Sharpness=Ostrosť
Fortune=Šťastie
Unbreaking=Nelámavosť
Efficiency=Výkonnosť
Silk Touch=Hodvábny dotyk
Curse of Vanishing=Kliatba zmiznutia
Knockback=Spätný úder
Enchanted=Očarený
Enchant=Očarovať
level=level

View File

@ -60,6 +60,7 @@ extract.on('end', () => {
process.exit(1)
}
console.log(`${command} --logpath "${logPath}" --check "${cwd}"`)
console.log(`\n${stdout}`)
if (fs.existsSync('./logs/check.json')) {

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -102,9 +102,13 @@ minetest.register_node('x_enchanting:table', {
local inv = minetest.get_meta(pos):get_inventory()
if not inv:is_empty('item') then
if not inv:is_empty('item') and inv:get_stack('item', 1):get_meta():get_int('is_enchanted') ~= 1 then
local item_stack = inv:get_stack('item', 1)
local data = XEnchanting:get_enchantment_data(#bookshelfs, minetest.registered_tools[item_stack:get_name()])
local data = XEnchanting:get_enchantment_data(
clicker,
#bookshelfs,
minetest.registered_tools[item_stack:get_name()]
)
local formspec = XEnchanting:get_formspec(pos, p_name, data)
meta:set_string('formspec', formspec)
@ -343,7 +347,11 @@ minetest.register_node('x_enchanting:table', {
)
local item_stack = inv:get_stack('item', 1)
local data = XEnchanting:get_enchantment_data(#bookshelfs, minetest.registered_tools[item_stack:get_name()])
local data = XEnchanting:get_enchantment_data(
player,
#bookshelfs,
minetest.registered_tools[item_stack:get_name()]
)
local formspec = XEnchanting:get_formspec(pos, p_name, data)
meta:set_string('formspec', formspec)
@ -372,7 +380,11 @@ minetest.register_node('x_enchanting:table', {
)
local item_stack = inv:get_stack('item', 1)
local data = XEnchanting:get_enchantment_data(#bookshelfs, minetest.registered_tools[item_stack:get_name()])
local data = XEnchanting:get_enchantment_data(
player,
#bookshelfs,
minetest.registered_tools[item_stack:get_name()]
)
local formspec = XEnchanting:get_formspec(pos, p_name, data)
meta:set_string('formspec', formspec)
@ -416,9 +428,8 @@ minetest.register_node('x_enchanting:table', {
end
local trade_stack = inv:get_stack('trade', 1)
local data = XEnchanting.form_context[p_name].data
if trade_stack:get_count() < selected_slot or not data then
if trade_stack:get_count() < selected_slot then
return
end

View File

@ -87,7 +87,11 @@
---@field place_node fun(pos: Vector, node: SetNodeTable): nil Place node with the same effects that a player would cause
---@field add_particle fun(def: ParticleDef): nil
---@field registered_tools table<string, ItemDef> Map of registered tool definitions, indexed by name
---@field registered_entities table<string, ObjectRef> Map of registered entity definitions, indexed by name
---@field has_feature fun(args: table<string, boolean> | string): boolean | table returns `boolean, missing_features`, `arg`: string or table in format `{foo=true, bar=true}`, `missing_features`: `{foo=true, bar=true}`
---@field handle_node_drops fun(pos: Vector, drops: string[], digger: ObjectRef) `drops`: list of itemstrings. Handles drops from nodes after digging: Default action is to put them into digger's inventory. Can be overridden to get different functionality (e.g. dropping items on ground)
---@field register_on_dieplayer fun(func: fun(player: ObjectRef, reason?: string)): nil Called when a player dies. `reason`: a PlayerHPChangeReason table, see register_on_player_hpchange
---@field register_on_player_hpchange fun(func: fun(player, hp_change, reason), modifier): number Called when the player gets damaged or healed. `player`: ObjectRef of the player. `hp_change`: the amount of change. Negative when it is damage.. `reason`: a PlayerHPChangeReason table.. The `type` field will have one of the following values: `set_hp`: A mod or the engine called `set_hp` without giving a type - use this for custom damage types.. `punch`: Was punched. `reason.object` will hold the puncher, or nil if none. `fall`, `node_damage`: `damage_per_second` from a neighbouring node. `reason.node` will hold the node name or nil. `drown` `respawn`. Any of the above types may have additional fields from mods. `reason.from` will be `mod` or `engine`. `modifier`: when true, the function should return the actual `hp_change`. Note: modifiers only get a temporary `hp_change` that can be modified by later modifiers. Modifiers can return true as a second argument to stop the execution of further functions. Non-modifiers receive the final HP change calculated by the modifiers.
---Minetest settings
---@class MinetestSettings

View File

@ -4,55 +4,46 @@
---@class XEnchanting
---@field tools_enchantability table<string, number> Add enchantability to default tools. key/value = tool_name/enchantibility value
---@field roman_numbers table<number, string> Convert Arabic numbers to Roman numbers
---@field enchantment_defs table<'sharpness' | 'fortune' | 'unbreaking' | 'efficiency', EnchantmentDef>
---@field enchantment_defs table<'sharpness' | 'fortune' | 'unbreaking' | 'efficiency' | 'silk_touch' | 'curse_of_vanishing' | 'knockback', EnchantmentDef>
---@field has_tool_group fun(self: XEnchanting, name: string): string | boolean Check if tool has one of the known tool groups, returns `false` otherwise.
---@field set_tool_enchantability fun(self: XEnchanting, tool_def: ItemDef): nil Sets `enchantibility` group and values from base table (`XEnchanting.tools_enchantability`) to all registered tools (atching known group names). If tool has already `enchantibility` group defined it will take the defined value insted.
---@field get_enchanted_tool_capabilities fun(self: XEnchanting, tool_def: ItemDef, enchantments: Enchantments[]): GetEnchantedToolCapabilitiesReturn Applies enchantments to item tool capabilities.
---@field get_enchanted_tool_capabilities fun(self: XEnchanting, tool_def: ItemDef, enchantments: Enchantment[]): ToolCapabilitiesDef Applies enchantments to item tool capabilities.
---@field set_enchanted_tool fun(self: XEnchanting, pos: Vector, itemstack: ItemStack, level: number, player_name: string): nil Set choosen enchantment and its modified tool capabilities to itemstack and `item` inventory. This will also get new `randomseed`.
---@field get_enchantment_data fun(self: XEnchanting, nr_of_bookshelfs: number, tool_def: ItemDef): EnchantmentData Algoritm to get aplicable random enchantments.
---@field get_formspec fun(self: XEnchanting, pos: Vector, player_name: string, data?: EnchantmentData): string Builds and returns `formspec` string
---@field get_enchantment_data fun(self: XEnchanting, player: ObjectRef, nr_of_bookshelfs: number, tool_def: ItemDef): EnchantmentData Algoritm to get aplicable random enchantments.
---@field get_formspec fun(self: XEnchanting, pos: Vector, player_name: string, data: EnchantmentData | nil): string Builds and returns `formspec` string
---@field form_context table<string, FormContextDef> Additional form data for player.
---@field scroll_animations table<string, table> Parameters for `ObjectRef` `set_animation` method
---@field player_seeds table<string, number | integer>
---Enchantment definition
---@class EnchantmentDef
---@field name string Readable name of the enchantment
---@field final_level_range table<number, number[]> Level range
---@field level_def table<number, number> Level bonus
---@field level_def table<number, number> Level bonus. Value will be set in item meta as float.
---@field weight number Enchantment weight
---@field randomseed number Math random seed. Will change after item was enchanted.
---@field form_context table<string, FormContextDef> Additional form data for player.
---@field scroll_animations table<string, table> Parameters for `ObjectRef` `set_animation` method
---@field secondary boolean Will not appear in masked description and can be applied only as additional enchantment by probability chance.
---Form context
---@class FormContextDef
---@field pos Vector Formspec/node form position
---@field data EnchantmentDataSlot Enchantment data
---@class GetEnchantedToolCapabilitiesReturn
---@field tool_capabilities ToolCapabilitiesDef
---@field enchantments_desc string
---@field enchantments_desc_masked string
---@field data EnchantmentData | nil Enchantment data
---@class EnchantmentData
---@field slots EnchantmentDataSlot[]
---@class Enchantments
---@class Enchantment
---@field id string
---@field value number
---@field level number
---@class ToolCapData
---@field enchantments_desc string Masket description before enchanting
---@field enchantments_desc_masked string Description added to item description definition after enchanting
---@field tool_capabilities ToolCapabilitiesDef Modified tool capabilities with applied enchantment
---@field secondary boolean Will not appear in masked description and can be applied only as additional enchantment by probability chance.
---@class EnchantmentDataSlot
---@field final_enchantments Enchantments[]
---@field tool_cap_data ToolCapData
---@field level number
---@field final_enchantments Enchantment[]
---@field tool_cap_data ToolCapabilitiesDef
---@field descriptions {["enchantments_desc"]: string, ["enchantments_desc_masked"]: string }