Compare commits

..

15 Commits

Author SHA1 Message Date
673922371c Add enchanting mod support 2025-04-19 17:13:34 +02:00
Juraj Vajda
0d589e69b3 Update luacheck 2025-04-07 00:38:49 -04:00
Juraj Vajda
8935043ed4 Update license year 2025-04-07 00:25:32 -04:00
Juraj Vajda
e2cf02d026 Update CI script 2025-04-07 00:24:55 -04:00
Juraj Vajda
0365b8043b Cleanup screenshot files 2025-04-07 00:21:38 -04:00
Juraj Vajda
ba1d30909b Rename minetest API convention to core 2025-04-07 00:19:12 -04:00
Juraj Vajda
82973b6462 Add API method for getting glint texture 2025-04-07 00:18:53 -04:00
Juraj Vajda
ecdf5a83d1 fix typo 2024-01-30 11:56:41 -05:00
Juraj Vajda
af26c6ed76 Add grindstone 2023-12-14 16:48:02 -05:00
Juraj Vajda
3ee6bb7b80 Update readme and cdb 2023-12-14 16:34:33 -05:00
Juraj Vajda
84df66325e Add grindstone 2023-12-14 16:28:48 -05:00
Juraj Vajda
737e2f3cba Add grindstone 2023-12-14 16:27:25 -05:00
Juraj Vajda
693ace14c2 Add tool texture overlay when enchanted 2023-12-07 10:47:30 -05:00
Juraj Vajda
f4ed507897 Add missing use_texture_alpha 2023-04-01 14:40:34 -04:00
Juraj Vajda
01703cb0a3 3 Add support for item_drop mod 2023-02-26 15:45:25 +00:00
37 changed files with 1626 additions and 198 deletions

View File

@ -13,5 +13,6 @@
"media_license": "CC-BY-SA-4.0", "media_license": "CC-BY-SA-4.0",
"repo": "https://bitbucket.org/minetest_gamers/x_enchanting/src/master/", "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",
"video_url": "https://youtu.be/JXF-GrQ9Uxs?si=dsgxDMXtm90ovE3D",
"forums": 28861 "forums": 28861
} }

View File

@ -3,27 +3,26 @@ allow_defined_top = true
max_line_length = false max_line_length = false
exclude_files = { exclude_files = {
'./scripts', "./scripts",
'./bin', "./bin",
'./logs', "./logs",
'./node_modules', "./node_modules",
'./sounds', "./sounds",
'./textures', "./textures",
'./models', "./models",
'./docs', "./docs",
'./locale', "./locale",
'./types', "./types",
} }
globals = { globals = {
'minetest', "core",
'XEnchanting' "XEnchanting"
} }
read_globals = { read_globals = {
"DIR_DELIM", "INIT", "DIR_DELIM", "INIT",
"core",
"dump", "dump2", "dump", "dump2",
"Raycast", "Raycast",

View File

@ -453,3 +453,104 @@ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES. DAMAGES.
### Textures
**CC-BY-SA-4.0, Pixel Perfection by XSSheep**, https://minecraft.curseforge.com/projects/pixel-perfection-freshly-updated
- x_enchanting_symbol_1.png
- x_enchanting_symbol_2.png
- x_enchanting_symbol_3.png
- x_enchanting_symbol_4.png
- x_enchanting_symbol_5.png
- x_enchanting_symbol_6.png
- x_enchanting_symbol_7.png
- x_enchanting_symbol_8.png
- x_enchanting_symbol_9.png
- x_enchanting_symbol_10.png
- x_enchanting_symbol_11.png
- x_enchanting_symbol_12.png
- x_enchanting_symbol_13.png
- x_enchanting_symbol_14.png
- x_enchanting_symbol_15.png
- x_enchanting_symbol_16.png
- x_enchanting_symbol_17.png
- x_enchanting_symbol_18.png
- x_enchanting_symbol_19.png
- x_enchanting_symbol_20.png
- x_enchanting_symbol_21.png
- x_enchanting_symbol_22.png
- x_enchanting_symbol_23.png
- x_enchanting_symbol_24.png
- x_enchanting_symbol_25.png
- x_enchanting_symbol_26.png
**CC-BY-SA-4.0, by SaKeL**
- x_enchanting_image_button_disabled.png
- x_enchanting_image_button.png
- x_enchanting_image_trade_1.png -- Derived from a texture by VanessaE (CC BY-SA 3.0)
- x_enchanting_image_trade_2.png -- Derived from a texture by VanessaE (CC BY-SA 3.0)
- x_enchanting_image_trade_3.png -- Derived from a texture by VanessaE (CC BY-SA 3.0)
- x_enchanting_scroll_handles_mesh.png -- Derived from a textures by paramat (CC BY-SA 3.0) and TumeniNodes (CC BY-SA 3.0)
- x_enchanting_scroll_mesh.png -- Derived from a texture TumeniNodes (CC BY-SA 3.0)
- x_enchanting_scroll_particle.png
- x_enchanting_table.png
- x_enchanting_gui_slot_bg.png -- Derived from texture Pixel Perfection by XSSheep (CC-BY-SA-4.0)
- x_enchanting_gui_cloth_bg.png -- Derived from texture Pixel Perfection by XSSheep (CC-BY-SA-4.0)
- x_enchanting_gui_cloth_trade_bg.png -- Derived from texture Pixel Perfection by XSSheep (CC-BY-SA-4.0)
- x_enchanting_gui_formbg.png -- Derived from texture Pixel Perfection by XSSheep (CC-BY-SA-4.0)
- x_enchanting_gui_hb_bg.png -- Derived from texture Pixel Perfection by XSSheep (CC-BY-SA-4.0)
### Models
**CC-BY-SA-4.0, by SaKeL**
- x_enchanting_scroll.b3d
- x_enchanting_table.obj
### Sounds
**CC-BY-3.0, Kostas17**, https://freesound.org
- x_enchanting_enchant.ogg
**CC0-1.0, Zeinel**, https://freesound.org
- x_enchanting_scroll.1.ogg
- x_enchanting_scroll.2.ogg
- x_enchanting_scroll.3.ogg
- x_enchanting_scroll.4.ogg
- x_enchanting_scroll.5.ogg
- x_enchanting_scroll.6.ogg
- x_enchanting_scroll.7.ogg
- x_enchanting_scroll.8.ogg
- x_enchanting_scroll.9.ogg
**CC0-1.0, by Fission9**, https://freesound.org
- x_enchanting_wood_footstep.1.ogg
- x_enchanting_wood_footstep.2.ogg
- x_enchanting_wood_footstep.3.ogg
- x_enchanting_wood_footstep.4.ogg
- x_enchanting_wood_footstep.5.ogg
- x_enchanting_wood_footstep.6.ogg
**CC0-1.0, by igroglaz**, https://freesound.org
- x_enchanting_wood_hit.1.ogg
- x_enchanting_wood_hit.2.ogg
- x_enchanting_wood_hit.3.ogg
- x_enchanting_wood_hit.4.ogg
- x_enchanting_wood_hit.5.ogg
- x_enchanting_wood_hit.6.ogg
**CC-BY-4.0, by RICHERlandTV**, https://freesound.org
- x_enchanting_wood_place.1.ogg
- x_enchanting_wood_place.2.ogg
- x_enchanting_wood_place.3.ogg
**CC-BY-4.0, by tim.kahn**, https://freesound.org/people/tim.kahn/sounds/35829/
- x_enchanting_disenchant.ogg

View File

@ -17,8 +17,8 @@ Adds Enchanting Mechanics and API.
* enchanted items have detailed enchantments description/short description * enchanted items have detailed enchantments description/short description
* mesh node model * mesh node model
* mesh entity model and animations * mesh entity model and animations
* tool texture will have enchanted glint
NOTE: item inventory/wield image will not be adjusted until this feature is supported by MT engine, see: https://github.com/minetest/minetest/issues/5686 * adds grind stone to remove enchantments (excluding curses)
## How To ## How To
@ -185,80 +185,3 @@ end
### Code ### Code
GNU Lesser General Public License v2.1 or later (see included LICENSE file) GNU Lesser General Public License v2.1 or later (see included LICENSE file)
### Textures
**CC-BY-SA-4.0, Pixel Perfection by XSSheep**, https://minecraft.curseforge.com/projects/pixel-perfection-freshly-updated
- x_enchanting_symbol_1.png
- x_enchanting_symbol_2.png
- x_enchanting_symbol_3.png
- x_enchanting_symbol_4.png
- x_enchanting_symbol_5.png
- x_enchanting_symbol_6.png
- x_enchanting_symbol_7.png
- x_enchanting_symbol_8.png
- x_enchanting_symbol_9.png
- x_enchanting_symbol_10.png
- x_enchanting_symbol_11.png
- x_enchanting_symbol_12.png
- x_enchanting_symbol_13.png
- x_enchanting_symbol_14.png
- x_enchanting_symbol_15.png
- x_enchanting_symbol_16.png
- x_enchanting_symbol_17.png
- x_enchanting_symbol_18.png
- x_enchanting_symbol_19.png
- x_enchanting_symbol_20.png
- x_enchanting_symbol_21.png
- x_enchanting_symbol_22.png
- x_enchanting_symbol_23.png
- x_enchanting_symbol_24.png
- x_enchanting_symbol_25.png
- x_enchanting_symbol_26.png
**CC-BY-SA-4.0, by SaKeL**
- x_enchanting_image_button_disabled.png
- x_enchanting_image_button.png
- x_enchanting_image_trade_1.png -- Derived from a texture by VanessaE (CC BY-SA 3.0)
- x_enchanting_image_trade_2.png -- Derived from a texture by VanessaE (CC BY-SA 3.0)
- x_enchanting_image_trade_3.png -- Derived from a texture by VanessaE (CC BY-SA 3.0)
- x_enchanting_scroll_handles_mesh.png -- Derived from a textures by paramat (CC BY-SA 3.0) and TumeniNodes (CC BY-SA 3.0)
- x_enchanting_scroll_mesh.png -- Derived from a texture TumeniNodes (CC BY-SA 3.0)
- x_enchanting_scroll_particle.png
- x_enchanting_table.png
- x_enchanting_gui_slot_bg.png -- Derived from texture Pixel Perfection by XSSheep (CC-BY-SA-4.0)
- x_enchanting_gui_cloth_bg.png -- Derived from texture Pixel Perfection by XSSheep (CC-BY-SA-4.0)
- x_enchanting_gui_cloth_trade_bg.png -- Derived from texture Pixel Perfection by XSSheep (CC-BY-SA-4.0)
- x_enchanting_gui_formbg.png -- Derived from texture Pixel Perfection by XSSheep (CC-BY-SA-4.0)
- x_enchanting_gui_hb_bg.png -- Derived from texture Pixel Perfection by XSSheep (CC-BY-SA-4.0)
### Models
**CC-BY-SA-4.0, by SaKeL**
- x_enchanting_scroll.b3d
- x_enchanting_table.obj
### Sounds
**CC-BY-3.0, Kostas17**, https://freesound.org
- x_enchanting_enchant.ogg
**CC0-1.0, Zeinel**, https://freesound.org
- x_enchanting_scroll.1.ogg
- x_enchanting_scroll.2.ogg
- x_enchanting_scroll.3.ogg
- x_enchanting_scroll.4.ogg
- x_enchanting_scroll.5.ogg
- x_enchanting_scroll.6.ogg
- x_enchanting_scroll.7.ogg
- x_enchanting_scroll.8.ogg
- x_enchanting_scroll.9.ogg
## Installation
see: https://wiki.minetest.net/Installing_Mods

150
api.lua
View File

@ -1,6 +1,6 @@
--[[ --[[
X Enchanting. Adds Enchanting Mechanics and API. X Enchanting. Adds Enchanting Mechanics and API.
Copyright (C) 2023 SaKeL <juraj.vajda@gmail.com> Copyright (C) 2025 SaKeL
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -16,7 +16,7 @@
License along with this library; if not, write to juraj.vajda@gmail.com License along with this library; if not, write to juraj.vajda@gmail.com
--]] --]]
local S = minetest.get_translator(minetest.get_current_modname()) local S = core.get_translator(core.get_current_modname())
---@type XEnchanting ---@type XEnchanting
XEnchanting = { XEnchanting = {
@ -195,7 +195,8 @@ XEnchanting = {
weight = 1, weight = 1,
secondary = true, secondary = true,
-- all applicable -- all applicable
groups = nil groups = nil,
cursed = true
}, },
knockback = { knockback = {
name = S('Knockback'), name = S('Knockback'),
@ -319,15 +320,15 @@ end
---@diagnostic disable-next-line: unused-local ---@diagnostic disable-next-line: unused-local
function XEnchanting.has_tool_group(self, name) function XEnchanting.has_tool_group(self, name)
if minetest.get_item_group(name, 'pickaxe') > 0 then if core.get_item_group(name, 'pickaxe') > 0 then
return 'pickaxe' return 'pickaxe'
elseif minetest.get_item_group(name, 'shovel') > 0 then elseif core.get_item_group(name, 'shovel') > 0 then
return 'shovel' return 'shovel'
elseif minetest.get_item_group(name, 'axe') > 0 then elseif core.get_item_group(name, 'axe') > 0 then
return 'axe' return 'axe'
elseif minetest.get_item_group(name, 'sword') > 0 then elseif core.get_item_group(name, 'sword') > 0 then
return 'sword' return 'sword'
elseif minetest.get_item_group(name, 'bow') > 0 then elseif core.get_item_group(name, 'bow') > 0 then
return 'bow' return 'bow'
end end
@ -335,7 +336,7 @@ function XEnchanting.has_tool_group(self, name)
end end
function XEnchanting.set_tool_enchantability(self, tool_def) function XEnchanting.set_tool_enchantability(self, tool_def)
if minetest.get_item_group(tool_def.name, 'enchantability') > 0 then if core.get_item_group(tool_def.name, 'enchantability') > 0 then
-- enchantability is already set, we dont need to override the item -- enchantability is already set, we dont need to override the item
return return
end end
@ -346,7 +347,7 @@ function XEnchanting.set_tool_enchantability(self, tool_def)
_enchantability = self.tools_enchantability[tool_def.name] _enchantability = self.tools_enchantability[tool_def.name]
end end
minetest.override_item(tool_def.name, { core.override_item(tool_def.name, {
groups = mergeTables(tool_def.groups, { enchantability = _enchantability }) groups = mergeTables(tool_def.groups, { enchantability = _enchantability })
}) })
end end
@ -505,7 +506,7 @@ function XEnchanting.get_enchanted_descriptions(self, enchantments)
end end
end end
enchantments_desc = '\n' .. minetest.colorize('#AE81FF', S('Enchanted')) enchantments_desc = '\n' .. core.colorize('#AE81FF', S('Enchanted'))
.. '\n' .. table.concat(enchantments_desc, '\n') .. '\n' .. table.concat(enchantments_desc, '\n')
enchantments_desc_masked = table.concat(enchantments_desc_masked, '') .. '..?' enchantments_desc_masked = table.concat(enchantments_desc_masked, '') .. '..?'
@ -515,6 +516,10 @@ function XEnchanting.get_enchanted_descriptions(self, enchantments)
} }
end end
function XEnchanting.get_glint_texture_modifier(self, image)
return image .. '^((' .. image .. '^[contrast:127:127)^[mask:x_enchanting_glint.png^[opacity:80)'
end
function XEnchanting.set_enchanted_tool(self, pos, itemstack, level, player_name) function XEnchanting.set_enchanted_tool(self, pos, itemstack, level, player_name)
local data = self.form_context[player_name].data local data = self.form_context[player_name].data
@ -525,9 +530,9 @@ function XEnchanting.set_enchanted_tool(self, pos, itemstack, level, player_name
local capabilities = data.slots[level].tool_cap_data local capabilities = data.slots[level].tool_cap_data
local description = data.slots[level].descriptions.enchantments_desc local description = data.slots[level].descriptions.enchantments_desc
local final_enchantments = data.slots[level].final_enchantments local final_enchantments = data.slots[level].final_enchantments
local inv = minetest.get_meta(pos):get_inventory() local inv = core.get_meta(pos):get_inventory()
local tool_def = minetest.registered_tools[itemstack:get_name()] local tool_def = core.registered_tools[itemstack:get_name()]
local node_meta = minetest.get_meta(pos) local node_meta = core.get_meta(pos)
if not tool_def then if not tool_def then
return return
@ -550,7 +555,23 @@ function XEnchanting.set_enchanted_tool(self, pos, itemstack, level, player_name
stack_meta:set_string('description', itemstack:get_description() .. '\n' .. description) stack_meta:set_string('description', itemstack:get_description() .. '\n' .. description)
stack_meta:set_string('short_description', S('Enchanted') .. ' ' .. itemstack:get_short_description()) stack_meta:set_string('short_description', S('Enchanted') .. ' ' .. itemstack:get_short_description())
stack_meta:set_int('is_enchanted', 1) stack_meta:set_int('is_enchanted', 1)
stack_meta:set_string('x_enchanting', minetest.serialize(final_enchantments_meta)) stack_meta:set_string('x_enchanting', core.serialize(final_enchantments_meta))
if tool_def and tool_def.inventory_image and tool_def.inventory_image ~= '' then
stack_meta:set_string('inventory_image', tool_def.inventory_image .. '^((' .. tool_def.inventory_image .. '^[contrast:127:127)^[mask:x_enchanting_glint.png^[opacity:80)')
end
if tool_def and tool_def.inventory_overlay and tool_def.inventory_overlay ~= '' then
stack_meta:set_string('inventory_overlay', tool_def.inventory_overlay .. '^((' .. tool_def.inventory_overlay .. '^[contrast:127:127)^[mask:x_enchanting_glint.png^[opacity:80)')
end
if tool_def and tool_def.wield_image and tool_def.wield_image ~= '' then
stack_meta:set_string('wield_image', tool_def.wield_image .. '^((' .. tool_def.wield_image .. '^[contrast:127:127)^[mask:x_enchanting_glint.png^[opacity:80)')
end
if tool_def and tool_def.wield_overlay and tool_def.wield_overlay ~= '' then
stack_meta:set_string('wield_overlay', tool_def.wield_overlay .. '^((' .. tool_def.wield_overlay .. '^[contrast:127:127)^[mask:x_enchanting_glint.png^[opacity:80)')
end
inv:set_stack('item', 1, itemstack) inv:set_stack('item', 1, itemstack)
@ -564,7 +585,7 @@ function XEnchanting.set_enchanted_tool(self, pos, itemstack, level, player_name
local formspec = self:get_formspec(pos, player_name) local formspec = self:get_formspec(pos, player_name)
node_meta:set_string('formspec', formspec) node_meta:set_string('formspec', formspec)
minetest.sound_play('x_enchanting_enchant', { core.sound_play('x_enchanting_enchant', {
gain = 0.3, gain = 0.3,
pos = pos, pos = pos,
max_hear_distance = 10 max_hear_distance = 10
@ -588,7 +609,7 @@ function XEnchanting.set_enchanted_tool(self, pos, itemstack, level, player_name
glow = 1 glow = 1
} }
if minetest.has_feature({ dynamic_add_media_table = true, particlespawner_tweenable = true }) then if core.has_feature({ dynamic_add_media_table = true, particlespawner_tweenable = true }) then
-- new syntax, after v5.6.0 -- new syntax, after v5.6.0
particlespawner_def = { particlespawner_def = {
amount = 50, amount = 50,
@ -620,7 +641,7 @@ function XEnchanting.set_enchanted_tool(self, pos, itemstack, level, player_name
} }
end end
minetest.add_particlespawner(particlespawner_def) core.add_particlespawner(particlespawner_def)
end end
function XEnchanting.get_enchantment_data(self, player, nr_of_bookshelfs, tool_def) function XEnchanting.get_enchantment_data(self, player, nr_of_bookshelfs, tool_def)
@ -648,7 +669,7 @@ function XEnchanting.get_enchantment_data(self, player, nr_of_bookshelfs, tool_d
else else
---@diagnostic disable-next-line: unused-local ---@diagnostic disable-next-line: unused-local
for i, group in ipairs(enchantment_def.groups) do for i, group in ipairs(enchantment_def.groups) do
if minetest.get_item_group(tool_def.name, group) > 0 then if core.get_item_group(tool_def.name, group) > 0 then
group_enchantments[enchantment_name] = enchantment_def group_enchantments[enchantment_name] = enchantment_def
break break
end end
@ -673,7 +694,7 @@ function XEnchanting.get_enchantment_data(self, player, nr_of_bookshelfs, tool_d
local chosen_enchantment_level = slot_lvl local chosen_enchantment_level = slot_lvl
-- Applying modifiers to the enchantment level -- Applying modifiers to the enchantment level
local enchantability = minetest.get_item_group(tool_def.name, 'enchantability') local enchantability = core.get_item_group(tool_def.name, 'enchantability')
-- Generate a random number between 1 and 1+(enchantability/2), with a triangular distribution -- Generate a random number between 1 and 1+(enchantability/2), with a triangular distribution
local rand_enchantability = 1 + math.random(enchantability / 4 + 1) + math.random(enchantability / 4 + 1) local rand_enchantability = 1 + math.random(enchantability / 4 + 1) + math.random(enchantability / 4 + 1)
-- Choose the enchantment level -- Choose the enchantment level
@ -858,12 +879,13 @@ local function get_list_bg(x, y)
return out return out
end end
local function get_formspec_bg(player_name) local function get_formspec_bg(player_name, bg_img)
local info = minetest.get_player_information(player_name) local bg_image = bg_img and bg_img or 'x_enchanting_gui_formbg.png'
local bg = 'background[5,5;1,1;x_enchanting_gui_formbg.png;true]' local info = core.get_player_information(player_name)
local bg = 'background[5,5;1,1;' .. bg_image .. ';true]'
if info.formspec_version > 1 then if info.formspec_version > 1 then
bg = 'background9[5,5;1,1;x_enchanting_gui_formbg.png;true;10]' bg = 'background9[5,5;1,1;' .. bg_image .. ';true;10]'
end end
return bg return bg
@ -871,7 +893,7 @@ end
function XEnchanting.get_formspec(self, pos, player_name, data) function XEnchanting.get_formspec(self, pos, player_name, data)
local spos = pos.x .. ',' .. pos.y .. ',' .. pos.z local spos = pos.x .. ',' .. pos.y .. ',' .. pos.z
local inv = minetest.get_meta(pos):get_inventory() local inv = core.get_meta(pos):get_inventory()
---@diagnostic disable-next-line: codestyle-check ---@diagnostic disable-next-line: codestyle-check
local model_scroll_open = 'model[0,0;2,3;x_enchanting_table;x_enchanting_scroll.b3d;x_enchanting_scroll_mesh.png,x_enchanting_scroll_handles_mesh.png,x_enchanting_scroll_mesh.png;89,0;false;false;' .. self.scroll_animations.scroll_open_idle[1].x .. ',' .. self.scroll_animations.scroll_open_idle[1].y .. ';0]' local model_scroll_open = 'model[0,0;2,3;x_enchanting_table;x_enchanting_scroll.b3d;x_enchanting_scroll_mesh.png,x_enchanting_scroll_handles_mesh.png,x_enchanting_scroll_mesh.png;89,0;false;false;' .. self.scroll_animations.scroll_open_idle[1].x .. ',' .. self.scroll_animations.scroll_open_idle[1].y .. ';0]'
---@diagnostic disable-next-line: codestyle-check ---@diagnostic disable-next-line: codestyle-check
@ -912,10 +934,10 @@ function XEnchanting.get_formspec(self, pos, player_name, data)
if inv:get_stack('trade', 1):get_count() >= i then if inv:get_stack('trade', 1):get_count() >= i then
---@diagnostic disable-next-line: codestyle-check ---@diagnostic disable-next-line: codestyle-check
formspec[#formspec + 1] = 'image_button[3.125,' .. -0.5 + i .. ';5.125,1;x_enchanting_image_button.png;slot_' .. i .. ';' .. slot.descriptions.enchantments_desc_masked .. minetest.formspec_escape(' [' .. slot.level .. ']') .. ']' formspec[#formspec + 1] = 'image_button[3.125,' .. -0.5 + i .. ';5.125,1;x_enchanting_image_button.png;slot_' .. i .. ';' .. slot.descriptions.enchantments_desc_masked .. core.formspec_escape(' [' .. slot.level .. ']') .. ']'
else else
---@diagnostic disable-next-line: codestyle-check ---@diagnostic disable-next-line: codestyle-check
formspec[#formspec + 1] = 'image_button[3.125,' .. -0.5 + i .. ';5.125,1;x_enchanting_image_button_disabled.png;slot_' .. i .. ';' .. slot.descriptions.enchantments_desc_masked .. minetest.formspec_escape(' [' .. slot.level .. ']') .. ']' formspec[#formspec + 1] = 'image_button[3.125,' .. -0.5 + i .. ';5.125,1;x_enchanting_image_button_disabled.png;slot_' .. i .. ';' .. slot.descriptions.enchantments_desc_masked .. core.formspec_escape(' [' .. slot.level .. ']') .. ']'
end end
formspec[#formspec + 1] = 'image[2.3,' .. -0.5 + i .. ';1,1;x_enchanting_image_trade_' .. i .. '.png;]' formspec[#formspec + 1] = 'image[2.3,' .. -0.5 + i .. ';1,1;x_enchanting_image_trade_' .. i .. '.png;]'
@ -950,3 +972,77 @@ function XEnchanting.get_formspec(self, pos, player_name, data)
return table.concat(formspec, '') return table.concat(formspec, '')
end end
function XEnchanting.get_grindstone_formspec(self, pos, player_name, data)
local _data = data or {}
local spos = pos.x .. ',' .. pos.y .. ',' .. pos.z
local model = 'model[0,0;2,3;x_enchanting_grindstone;x_enchanting_grindstone.obj;x_enchanting_grindstone_mesh.png;0,0;true;false;]'
local formspec = {}
formspec[#formspec + 1] = 'size[8,9]'
formspec[#formspec + 1] = 'bgcolor[#080808BB;true]'
formspec[#formspec + 1] = 'listcolors[#FFFFFF00;#FFFFFF1A;#FFFFFF00;#30434C;#FFF]'
formspec[#formspec + 1] = get_formspec_bg(player_name)
formspec[#formspec + 1] = 'style_type[label;font=mono,bold]'
formspec[#formspec + 1] = 'style[slot_1,slot_2,slot_3;font=mono,bold;textcolor=#4D413A]'
formspec[#formspec + 1] = 'label[0, 0;' .. S('Disenchant') .. ']'
-- item
formspec[#formspec + 1] = 'list[nodemeta:' .. spos .. ';item;0.5, 2.5;1, 1;]'
formspec[#formspec + 1] = 'image[0.5, 2.5;1,1;x_enchanting_gui_cloth_bg.png]'
-- result
if _data.result_disabled then
formspec[#formspec + 1] = 'image[4.75, 1.25;1.5,1.5;x_enchanting_gui_cloth_bg_corssed.png]'
else
formspec[#formspec + 1] = 'list[nodemeta:' .. spos .. ';result;5, 1.5;1, 1;]'
formspec[#formspec + 1] = 'image[5, 1.5;1,1;x_enchanting_gui_cloth_bg.png]'
end
-- inventories
formspec[#formspec + 1] = 'list[current_player;main;0, 4.85;8, 1;]'
formspec[#formspec + 1] = 'list[current_player;main;0, 6.08;8, 3;8]'
formspec[#formspec + 1] = 'listring[nodemeta:' .. spos .. ';result]'
formspec[#formspec + 1] = 'listring[current_player;main]'
formspec[#formspec + 1] = 'listring[nodemeta:' .. spos .. ';item]'
formspec[#formspec + 1] = 'listring[current_player;main]'
formspec[#formspec + 1] = get_hotbar_bg(0, 4.85)
formspec[#formspec + 1] = get_list_bg(0, 6.08)
formspec[#formspec + 1] = model
return table.concat(formspec, '')
end
function XEnchanting.has_all_cursed_ench(self, itemstack)
if itemstack:is_empty() then
return false
end
local item_stack_meta = itemstack:get_meta()
local stack_enchantment_data = core.deserialize(item_stack_meta:get_string('x_enchanting')) or {}
local stack_enchantment_data_length = get_table_length(stack_enchantment_data)
local cursed_ench = 0
-- Get cursed enchantments
for id, value in pairs(stack_enchantment_data) do
local ench_def = self.enchantment_defs[id]
if ench_def.cursed then
cursed_ench = cursed_ench + 1
end
end
return cursed_ench == stack_enchantment_data_length
end
--
-- Sounds
--
function XEnchanting.node_sound_wood_defaults(table)
table = table or {}
table.footstep = table.footstep or { name = 'x_enchanting_wood_footstep', gain = 0.15 }
table.dig = table.dig or { name = 'x_enchanting_wood_hit', gain = 0.5 }
table.dug = table.dug or { name = 'x_enchanting_wood_place', gain = 0.1 }
table.place = table.place or { name = 'x_enchanting_wood_place', gain = 0.15 }
return table
end

BIN
assets/promo_scene.blend Normal file

Binary file not shown.

Binary file not shown.

380
grindstone.lua Normal file
View File

@ -0,0 +1,380 @@
---@diagnostic disable
--[[
X Enchanting. Adds Enchanting Mechanics and API.
Copyright (C) 2025 SaKeL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to juraj.vajda@gmail.com
--]]
local S = core.get_translator(core.get_current_modname())
----
--- Grindstone Node
----
core.register_node('x_enchanting:grindstone', {
description = S('Grindstone'),
short_description = S('Grindstone'),
drawtype = 'mesh',
mesh = 'x_enchanting_grindstone.obj',
tiles = { 'x_enchanting_grindstone_mesh.png' },
inventory_image = 'x_enchanting_grindstone_item.png',
use_texture_alpha = 'clip',
paramtype = 'light',
paramtype2 = 'facedir',
walkable = true,
wield_scale = { x = 2, y = 2, z = 2 },
selection_box = {
type = 'fixed',
fixed = { -1 / 2, -1 / 2, -1 / 2, 1 / 2, 1 / 2 - 1 / 16, 1 / 2 }
},
collision_box = {
type = 'fixed',
fixed = { -1 / 2, -1 / 2, -1 / 2, 1 / 2, 1 / 2 - 1 / 16, 1 / 2 }
},
sounds = XEnchanting.node_sound_wood_defaults(),
is_ground_content = false,
groups = { choppy = 2, oddly_breakable_by_hand = 2 },
stack_max = 1,
mod_origin = 'x_enchanting',
---@param pos Vector
on_construct = function(pos)
local meta = core.get_meta(pos)
local inv = meta:get_inventory()
meta:set_string('infotext', S('Grindstone'))
meta:set_string('owner', '')
inv:set_size('item', 1)
inv:set_size('result', 1)
end,
---@param pos Vector
---@param placer ObjectRef | nil
---@param itemstack ItemStack
---@param pointed_thing PointedThingDef
---@diagnostic disable-next-line: unused-local
after_place_node = function(pos, placer, itemstack, pointed_thing)
local meta = core.get_meta(pos)
if not placer then
return
end
local player_name = placer:get_player_name()
meta:set_string('owner', player_name)
meta:set_string('infotext', S('Grindstone') .. ' (' .. S('owned by') .. ' ' .. player_name .. ')')
local formspec = XEnchanting:get_grindstone_formspec(pos, player_name)
meta:set_string('formspec', formspec)
end,
---@param pos Vector
---@param node NodeDef
---@param clicker ObjectRef
---@param itemstack ItemStack
---@param pointed_thing? PointedThingDef
---@diagnostic disable-next-line: unused-local
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local meta = core.get_meta(pos)
local p_name = clicker:get_player_name()
local inv = meta:get_inventory()
local item_stack = inv:get_stack('item', 1)
local has_all_cursed_ench = XEnchanting:has_all_cursed_ench(item_stack)
if core.is_protected(pos, p_name) then
return itemstack
end
core.sound_play('x_enchanting_wood_hit', {
gain = 0.5,
pos = pos,
max_hear_distance = 10
}, true)
local formspec = XEnchanting:get_grindstone_formspec(pos, p_name, { result_disabled = has_all_cursed_ench })
meta:set_string('formspec', formspec)
return itemstack
end,
---@param pos Vector
---@param intensity? number
---@return table | nil
---@diagnostic disable-next-line: unused-local
on_blast = function(pos, intensity)
if core.is_protected(pos, '') then
return
end
local drops = {}
local inv = core.get_meta(pos):get_inventory()
local stack_item = inv:get_stack('item', 1)
if not stack_item:is_empty() then
drops[#drops + 1] = stack_item:to_table()
end
drops[#drops + 1] = 'x_enchanting:grindstone'
core.remove_node(pos)
return drops
end,
---@param pos Vector
---@param player? ObjectRef
can_dig = function(pos, player)
if not player then
return false
end
local inv = core.get_meta(pos):get_inventory()
return inv:is_empty('item')
and inv:is_empty('result')
and not core.is_protected(pos, player:get_player_name())
end,
---@diagnostic disable-next-line: unused-local
on_rotate = function(pos, node, user, mode, new_param2)
return false
end,
---@param pos Vector
---@param listname string
---@param index number
---@param stack ItemStack
---@param player ObjectRef
---@diagnostic disable-next-line: unused-local
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
local st_meta = stack:get_meta()
local is_enchanted = st_meta:get_int('is_enchanted')
if listname == 'item' and is_enchanted == 1 then
return stack:get_count()
end
return 0
end,
---@param pos Vector
---@param listname string
---@param index number
---@param stack ItemStack
---@param player ObjectRef
---@diagnostic disable-next-line: unused-local
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
return stack:get_count()
end,
---@param pos Vector
---@param from_list string
---@param from_index number
---@param to_list string
---@param to_index number
---@param count number
---@param player ObjectRef
---@diagnostic disable-next-line: unused-local
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
return 0
end,
---@param pos Vector
---@param listname string
---@param index number
---@param stack ItemStack
---@param player ObjectRef
---@diagnostic disable-next-line: unused-local
on_metadata_inventory_put = function(pos, listname, index, stack, player)
--
-- Create new itemstack with removed enchantments (excl. curses) and populate the result slot with this new item
--
local meta = core.get_meta(pos)
local p_name = player:get_player_name()
local inv = meta:get_inventory()
local item_stack = inv:get_stack('item', 1)
local item_stack_meta = item_stack:get_meta()
local is_enchanted = item_stack_meta:get_int('is_enchanted')
local stack_enchantment_data = core.deserialize(item_stack_meta:get_string('x_enchanting')) or {}
local has_all_cursed_ench = XEnchanting:has_all_cursed_ench(item_stack)
if not inv:is_empty('item') and is_enchanted == 1 and not has_all_cursed_ench then
-- Discenchanted item
local has_curse = false
local current_enchantments = {}
for id, value in pairs(stack_enchantment_data) do
-- Remove enchantment meta data (excl. cursed)
local ench_def = XEnchanting.enchantment_defs[id]
if not ench_def.cursed then
item_stack_meta:set_float('is_' .. id, 0)
stack_enchantment_data[id] = nil
else
has_curse = true
end
-- Get descriptions
if stack_enchantment_data[id] then
local level
-- Find level
for i, v in ipairs(ench_def.level_def) do
if v == value.value then
level = i
break
end
end
table.insert(current_enchantments, {
id = id,
value = value.value,
level = level,
secondary = ench_def.secondary,
incompatible = ench_def.incompatible
})
end
end
if not has_curse then
-- Reset meta data if not cursed
item_stack_meta:set_string('inventory_image', '')
item_stack_meta:set_string('inventory_overlay', '')
item_stack_meta:set_string('wield_image', '')
item_stack_meta:set_string('wield_overlay', '')
item_stack_meta:set_string('description', '')
item_stack_meta:set_string('short_description', '')
item_stack_meta:set_int('is_enchanted', 0)
end
local descriptions = XEnchanting:get_enchanted_descriptions(current_enchantments)
-- Upgrade description with remaining enchantments
if #current_enchantments > 0 then
local item_stack_def = core.registered_tools[item_stack:get_name()]
item_stack_meta:set_string('description', (item_stack_def and item_stack_def.description or '') .. '\n' .. descriptions.enchantments_desc)
end
item_stack_meta:set_tool_capabilities(nil)
item_stack_meta:set_string('x_enchanting', core.serialize(stack_enchantment_data))
inv:set_stack('result', 1, item_stack)
end
local formspec = XEnchanting:get_grindstone_formspec(pos, p_name, { result_disabled = has_all_cursed_ench })
meta:set_string('formspec', formspec)
end,
---@param pos Vector
---@param listname string
---@param index number
---@param stack ItemStack
---@param player ObjectRef
---@diagnostic disable-next-line: unused-local
on_metadata_inventory_take = function(pos, listname, index, stack, player)
local meta = core.get_meta(pos)
local p_name = player:get_player_name()
local inv = meta:get_inventory()
local result_stack = inv:get_stack('result', 1)
local item_stack = inv:get_stack('item', 1)
local item_stack_meta = item_stack:get_meta()
local has_all_cursed_ench = XEnchanting:has_all_cursed_ench(item_stack)
local stack_enchantment_data = core.deserialize(item_stack_meta:get_string('x_enchanting')) or {}
local result_payment_stack = ItemStack({ name = 'default:mese_crystal_fragment' })
if item_stack:is_empty() or has_all_cursed_ench then
-- Remove result item
inv:remove_item('result', result_stack)
end
-- Collect total result
local result_total = 0
if result_total == 0 then
-- get payback result (excl. cursed enchantments) from the original item
for id, value in pairs(stack_enchantment_data) do
local ench_def = XEnchanting.enchantment_defs[id]
local lvl_index
if not ench_def.cursed then
-- find level index
for i, v in ipairs(ench_def.level_def) do
if v == stack_enchantment_data[id].value then
lvl_index = i
end
end
end
if lvl_index then
local final_level_range = ench_def.final_level_range[lvl_index]
local range_max = final_level_range[1] + final_level_range[2]
local range_min = math.floor(range_max / 2)
local result = math.random(range_min, range_max)
result_total = result_total + result
end
end
if result_total > result_payment_stack:get_stack_max() then
result_total = result_payment_stack:get_stack_max()
elseif result_total == 0 then
result_total = 1
end
end
result_total = math.floor(result_total / 10)
result_payment_stack:set_count(result_total)
if listname == 'result' and result_stack:is_empty() then
-- Drop payment result
inv:set_stack('item', 1, ItemStack(''))
core.item_drop(result_payment_stack, player, player:get_pos())
core.sound_play('x_enchanting_disenchant', {
gain = 0.3,
pos = pos,
max_hear_distance = 10
}, true)
-- particles
local particlespawner_def = {
amount = 50,
time = 0.5,
minpos = { x = pos.x - 0.5, y = pos.y + 0.5, z = pos.z - 0.5 },
maxpos = { x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5 },
minvel = { x = -1.5, y = -0.5, z = -1.5 },
maxvel = { x = 1.5, y = -1.5, z = 1.5 },
minacc = { x = -3.5, y = -6.5, z = -3.5 },
maxacc = { x = 5.5, y = -7.5, z = 5.5 },
minexptime = 0.5,
maxexptime = 1,
minsize = 0.5,
maxsize = 1,
texture = 'x_enchanting_scroll_particle.png^[colorize:#FFE5C2:256',
glow = 1
}
core.add_particlespawner(particlespawner_def)
end
local formspec = XEnchanting:get_grindstone_formspec(pos, p_name)
meta:set_string('formspec', formspec)
end
})
----
-- Recipe
---
core.register_craft({
output = 'x_enchanting:grindstone',
recipe = {
{ 'group:stick', 'stairs:slab_stone', 'group:stick' },
{ 'group:wood', '', 'group:wood' }
}
})

View File

@ -1,6 +1,6 @@
--[[ --[[
X Enchanting. Adds Enchanting Mechanics and API. X Enchanting. Adds Enchanting Mechanics and API.
Copyright (C) 2023 SaKeL <juraj.vajda@gmail.com> Copyright (C) 2025 SaKeL
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -16,11 +16,12 @@
License along with this library; if not, write to juraj.vajda@gmail.com License along with this library; if not, write to juraj.vajda@gmail.com
--]] --]]
local path = minetest.get_modpath('x_enchanting') local path = core.get_modpath('x_enchanting')
local mod_start_time = minetest.get_us_time() local mod_start_time = core.get_us_time()
dofile(path .. '/api.lua') dofile(path .. '/api.lua')
dofile(path .. '/table.lua') dofile(path .. '/table.lua')
dofile(path .. '/grindstone.lua')
---Check if string X starts with string Y ---Check if string X starts with string Y
---@param str string ---@param str string
@ -30,23 +31,23 @@ local function starts_with(str, start)
return str:sub(1, #start) == start return str:sub(1, #start) == start
end end
minetest.register_on_mods_loaded(function() core.register_on_mods_loaded(function()
-- Tools override -- Tools override
for name, tool_def in pairs(minetest.registered_tools) do for name, tool_def in pairs(core.registered_tools) do
if XEnchanting:has_tool_group(name) then if XEnchanting:has_tool_group(name) then
XEnchanting:set_tool_enchantability(tool_def) XEnchanting:set_tool_enchantability(tool_def)
end end
end end
-- Ores override - Fortune -- Ores override - Fortune
for _, def in pairs(minetest.registered_ores) do for _, def in pairs(core.registered_ores) do
if not XEnchanting.registered_ores[def.ore] then if not XEnchanting.registered_ores[def.ore] then
XEnchanting.registered_ores[def.ore] = true XEnchanting.registered_ores[def.ore] = true
end end
end end
-- Entities override - Looting -- Entities override - Looting
for name, def in pairs(minetest.registered_entities) do for name, def in pairs(core.registered_entities) do
if starts_with(name, 'mobs_animal:') if starts_with(name, 'mobs_animal:')
or starts_with(name, 'mobs_monster:') or starts_with(name, 'mobs_monster:')
then then
@ -102,7 +103,7 @@ minetest.register_on_mods_loaded(function()
stack:set_count(stack:get_count() * chance) stack:set_count(stack:get_count() * chance)
if stack:get_count() > 0 then if stack:get_count() > 0 then
minetest.item_drop(stack, puncher, pos) core.item_drop(stack, puncher, pos)
end end
end end
end end
@ -160,7 +161,7 @@ minetest.register_on_mods_loaded(function()
stack:set_count(stack:get_count() * chance) stack:set_count(stack:get_count() * chance)
if stack:get_count() > 0 then if stack:get_count() > 0 then
minetest.item_drop(stack, puncher, pos) core.item_drop(stack, puncher, pos)
end end
end end
end end
@ -172,7 +173,7 @@ minetest.register_on_mods_loaded(function()
end) end)
---@diagnostic disable-next-line: unused-local ---@diagnostic disable-next-line: unused-local
minetest.register_on_joinplayer(function(player, last_login) core.register_on_joinplayer(function(player, last_login)
XEnchanting.form_context[player:get_player_name()] = nil XEnchanting.form_context[player:get_player_name()] = nil
if not XEnchanting.player_seeds[player:get_player_name()] then if not XEnchanting.player_seeds[player:get_player_name()] then
@ -181,20 +182,20 @@ minetest.register_on_joinplayer(function(player, last_login)
end) end)
---@diagnostic disable-next-line: unused-local ---@diagnostic disable-next-line: unused-local
minetest.register_on_leaveplayer(function(player, timed_out) core.register_on_leaveplayer(function(player, timed_out)
XEnchanting.form_context[player:get_player_name()] = nil XEnchanting.form_context[player:get_player_name()] = nil
end) end)
local old_handle_node_drops = minetest.handle_node_drops local old_handle_node_drops = core.handle_node_drops
function minetest.handle_node_drops(pos, drops, digger) function core.handle_node_drops(pos, drops, digger)
if not digger if not digger
or not digger:is_player() or not digger:is_player()
then then
return old_handle_node_drops(pos, drops, digger) return old_handle_node_drops(pos, drops, digger)
end end
local node = minetest.get_node(pos) local node = core.get_node(pos)
local wield_stack = digger:get_wielded_item() local wield_stack = digger:get_wielded_item()
local wield_stack_meta = wield_stack:get_meta() local wield_stack_meta = wield_stack:get_meta()
@ -206,13 +207,13 @@ function minetest.handle_node_drops(pos, drops, digger)
for _, itemstring in ipairs(drops) do for _, itemstring in ipairs(drops) do
if XEnchanting.registered_ores[node.name] if XEnchanting.registered_ores[node.name]
or minetest.get_item_group(node.name, 'stone') > 0 or core.get_item_group(node.name, 'stone') > 0
or minetest.get_item_group(node.name, 'soil') > 0 or core.get_item_group(node.name, 'soil') > 0
or minetest.get_item_group(node.name, 'sand') > 0 or core.get_item_group(node.name, 'sand') > 0
or minetest.get_item_group(node.name, 'snowy') > 0 or core.get_item_group(node.name, 'snowy') > 0
or minetest.get_item_group(node.name, 'slippery') > 0 or core.get_item_group(node.name, 'slippery') > 0
or minetest.get_item_group(node.name, 'tree') > 0 or core.get_item_group(node.name, 'tree') > 0
or minetest.get_item_group(node.name, 'leaves') > 0 or core.get_item_group(node.name, 'leaves') > 0
then then
local tool_capabilities = wield_stack:get_tool_capabilities() local tool_capabilities = wield_stack:get_tool_capabilities()
local stack = ItemStack(itemstring) local stack = ItemStack(itemstring)
@ -237,7 +238,7 @@ function minetest.handle_node_drops(pos, drops, digger)
local silk_touch = wield_stack_meta:get_float('is_silk_touch') local silk_touch = wield_stack_meta:get_float('is_silk_touch')
if silk_touch > 0 if silk_touch > 0
and minetest.get_item_group(node.name, 'no_silktouch') == 0 and core.get_item_group(node.name, 'no_silktouch') == 0
then then
-- drop raw item/node -- drop raw item/node
return old_handle_node_drops(pos, { ItemStack(node.name) }, digger) return old_handle_node_drops(pos, { ItemStack(node.name) }, digger)
@ -247,7 +248,7 @@ function minetest.handle_node_drops(pos, drops, digger)
end end
---@diagnostic disable-next-line: unused-local ---@diagnostic disable-next-line: unused-local
minetest.register_on_player_hpchange(function(player, hp_change, reason) core.register_on_player_hpchange(function(player, hp_change, reason)
-- Curse of Vanishing -- Curse of Vanishing
if (player:get_hp() + hp_change) <= 0 then if (player:get_hp() + hp_change) <= 0 then
-- Going to die -- Going to die
@ -272,9 +273,9 @@ minetest.register_on_player_hpchange(function(player, hp_change, reason)
end, true) end, true)
-- Knockback (only for players) -- Knockback (only for players)
local old_calculate_knockback = minetest.calculate_knockback local old_calculate_knockback = core.calculate_knockback
function minetest.calculate_knockback(player, hitter, time_from_last_punch, function core.calculate_knockback(player, hitter, time_from_last_punch,
tool_capabilities, dir, distance, damage) tool_capabilities, dir, distance, damage)
if hitter and hitter:is_player() then if hitter and hitter:is_player() then
local hitter_wield_stack = hitter:get_wielded_item() local hitter_wield_stack = hitter:get_wielded_item()
@ -306,6 +307,6 @@ function minetest.calculate_knockback(player, hitter, time_from_last_punch,
tool_capabilities, dir, distance, damage) tool_capabilities, dir, distance, damage)
end end
local mod_end_time = (minetest.get_us_time() - mod_start_time) / 1000000 local mod_end_time = (core.get_us_time() - mod_start_time) / 1000000
print('[Mod] x_enchanting loaded.. [' .. mod_end_time .. 's]') print('[Mod] x_enchanting loaded.. [' .. mod_end_time .. 's]')

View File

@ -1,6 +1,6 @@
name = x_enchanting name = x_enchanting
description = Adds Enchanting Mechanics and API. description = Adds Enchanting Mechanics and API.
depends = depends =
optional_depends = xdecor, item_drop optional_depends = xdecor, item_drop, stairs, enchanting
supported_games = minetest_game supported_games = minetest_game
min_minetest_version = 5.4 min_minetest_version = 5.4

View File

@ -0,0 +1,928 @@
# Blender v2.83.20 OBJ File: 'x_enchanting_grindstone.blend'
# www.blender.org
mtllib x_enchanting_grindstone.mtl
o x_enchanting_grindstone.vox
v 0.125000 -0.499000 0.437500
v 0.187500 -0.499000 0.312500
v 0.125000 -0.499000 -0.375000
v 0.125000 -0.499000 -0.437500
v 0.125000 -0.311500 0.375000
v -0.250000 -0.311500 0.312500
v 0.187500 -0.311500 0.312500
v 0.187500 -0.311500 -0.312500
v 0.125000 -0.311500 -0.437500
v -0.250000 -0.311500 -0.312500
v 0.187500 -0.249000 0.375000
v 0.187500 -0.186500 0.375000
v -0.250000 -0.186500 0.312500
v -0.250000 -0.186500 -0.312500
v -0.250000 -0.124000 0.312500
v 0.187500 -0.186500 -0.312500
v -0.312500 -0.124000 0.500000
v 0.187500 -0.124000 0.187500
v -0.312500 -0.061500 0.062500
v 0.187500 -0.061500 0.062500
v -0.125000 -0.061500 -0.062500
v 0.187500 -0.124000 -0.312500
v -0.312500 -0.124000 -0.500000
v -0.312500 0.001000 0.500000
v -0.312500 -0.061500 -0.062500
v 0.187500 0.001000 -0.062500
v -0.312500 0.001000 -0.500000
v -0.375000 0.063500 -0.062500
v -0.125000 -0.311500 0.062500
v 0.312500 0.376000 -0.062500
v -0.187500 -0.499000 0.312500
v -0.187500 -0.499000 -0.312500
v -0.187500 -0.499000 -0.375000
v -0.125000 -0.499000 -0.375000
v -0.187500 -0.311500 -0.312500
v -0.187500 -0.311500 0.312500
v -0.187500 -0.311500 0.062500
v 0.250000 -0.311500 -0.312500
v -0.187500 -0.186500 0.312500
v -0.187500 -0.186500 0.375000
v -0.187500 -0.186500 0.062500
v -0.187500 -0.186500 -0.375000
v -0.187500 -0.186500 -0.312500
v 0.250000 -0.186500 -0.312500
v -0.187500 -0.124000 0.312500
v -0.187500 -0.124000 0.125000
v 0.125000 -0.061500 0.062500
v 0.125000 -0.311500 0.062500
v -0.187500 -0.061500 -0.062500
v 0.312500 -0.124000 -0.500000
v 0.312500 0.001000 0.500000
v -0.187500 -0.061500 0.062500
v -0.187500 0.001000 0.125000
v 0.125000 -0.061500 -0.062500
v 0.125000 0.063500 0.062500
v 0.437500 0.251000 0.062500
v 0.437500 0.251000 -0.062500
v 0.500000 0.376000 -0.062500
v 0.250000 -0.499000 0.437500
v 0.187500 -0.499000 -0.312500
v 0.250000 -0.499000 -0.312500
v 0.187500 -0.499000 -0.375000
v -0.125000 -0.311500 0.437500
v -0.125000 -0.311500 -0.375000
v 0.125000 -0.186500 0.437500
v -0.125000 -0.186500 -0.375000
v 0.062500 -0.186500 -0.375000
v 0.125000 -0.186500 -0.375000
v 0.250000 -0.124000 0.437500
v -0.187500 -0.124000 -0.312500
v -0.250000 -0.124000 -0.312500
v -0.125000 -0.124000 -0.375000
v -0.187500 -0.124000 0.500000
v 0.312500 -0.124000 0.500000
v 0.187500 0.001000 0.062500
v 0.312500 -0.061500 0.062500
v -0.375000 0.063500 0.062500
v -0.187500 0.001000 0.062500
v 0.500000 0.251000 0.062500
v 0.500000 0.376000 0.062500
v -0.125000 -0.499000 0.375000
v 0.125000 -0.499000 0.375000
v -0.250000 -0.499000 0.312500
v -0.250000 -0.499000 -0.437500
v -0.125000 -0.499000 -0.437500
v -0.125000 -0.311500 0.375000
v -0.125000 -0.311500 -0.312500
v 0.125000 -0.186500 0.375000
v 0.125000 -0.249000 0.375000
v 0.125000 -0.186500 -0.437500
v -0.125000 -0.186500 0.375000
v 0.187500 -0.186500 0.312500
v 0.250000 -0.124000 0.312500
v 0.125000 -0.124000 -0.437500
v -0.125000 -0.124000 0.375000
v -0.187500 0.001000 0.375000
v 0.312500 -0.061500 -0.062500
v 0.437500 -0.061500 -0.062500
v -0.312500 0.001000 -0.062500
v -0.187500 0.001000 -0.062500
v -0.125000 0.063500 -0.062500
v 0.312500 0.063500 -0.062500
v 0.312500 0.001000 -0.062500
v 0.500000 0.251000 -0.062500
v -0.125000 0.313500 -0.312500
v -0.250000 -0.499000 0.437500
v -0.187500 -0.499000 0.375000
v -0.125000 -0.499000 0.437500
v 0.187500 -0.499000 0.375000
v 0.250000 -0.499000 0.312500
v -0.250000 -0.499000 -0.312500
v 0.250000 -0.499000 -0.437500
v 0.125000 -0.311500 0.437500
v -0.125000 -0.311500 0.312500
v 0.250000 -0.311500 0.312500
v -0.125000 -0.311500 -0.437500
v 0.062500 -0.311500 -0.375000
v 0.125000 -0.311500 -0.375000
v -0.250000 -0.124000 0.437500
v -0.187500 -0.124000 0.437500
v -0.125000 -0.124000 0.500000
v 0.125000 -0.124000 0.437500
v -0.125000 -0.124000 0.437500
v 0.125000 -0.124000 0.375000
v 0.187500 -0.124000 0.312500
v 0.250000 -0.124000 -0.312500
v 0.125000 -0.124000 -0.375000
v -0.250000 -0.124000 -0.437500
v -0.125000 -0.124000 -0.437500
v 0.250000 -0.124000 -0.437500
v -0.375000 -0.061500 0.062500
v -0.125000 -0.061500 0.062500
v 0.437500 -0.061500 0.062500
v -0.375000 -0.061500 -0.062500
v 0.187500 -0.061500 -0.062500
v -0.125000 -0.186500 0.437500
v 0.250000 -0.186500 0.312500
v -0.125000 -0.186500 -0.437500
v 0.187500 0.001000 0.375000
v 0.187500 0.001000 0.187500
v -0.312500 0.001000 0.062500
v 0.312500 0.001000 0.062500
v -0.187500 0.001000 -0.375000
v 0.187500 0.001000 -0.375000
v 0.312500 0.001000 -0.500000
v 0.312500 0.063500 0.062500
v -0.125000 0.313500 0.312500
v -0.125000 0.313500 -0.062500
v 0.312500 0.376000 0.062500
v -0.125000 0.063500 0.062500
v 0.125000 -0.311500 -0.312500
v 0.125000 0.063500 -0.062500
v 0.125000 0.313500 -0.312500
v 0.125000 -0.311500 0.312500
v 0.125000 0.313500 0.312500
v 0.125000 0.313500 -0.062500
vt 0.781250 0.968750
vt 0.843750 0.812500
vt 0.843750 0.968750
vt 0.625000 0.437500
vt 0.625000 0.375000
vt 0.593750 0.421875
vt 0.968750 0.453125
vt 1.000000 0.500000
vt 0.968750 0.421875
vt 0.437500 0.687500
vt 0.562500 0.843750
vt 0.437500 0.843750
vt 0.718750 0.062500
vt 0.687500 0.109375
vt 0.718750 0.109375
vt 0.562500 0.093750
vt 0.687500 0.078125
vt 0.687500 0.093750
vt 0.437500 0.343750
vt 0.437500 0.500000
vt 0.375000 0.468750
vt 0.625000 0.093750
vt 0.593750 0.109375
vt 0.625000 0.109375
vt 0.625000 0.171875
vt 0.593750 0.187500
vt 0.625000 0.187500
vt 0.718750 0.500000
vt 0.718750 0.468750
vt 0.656250 0.468750
vt 0.593750 0.218750
vt 0.625000 0.375000
vt 0.593750 0.375000
vt 0.468750 0.671875
vt 0.406250 0.671875
vt 0.187500 0.656250
vt 0.625000 0.500000
vt 0.468750 0.468750
vt 0.593750 0.468750
vt 0.750000 0.796875
vt 0.687500 0.859375
vt 0.687500 0.796875
vt 0.718750 0.859375
vt 0.718750 0.937500
vt 0.656250 0.890625
vt 0.718750 0.140625
vt 0.687500 0.187500
vt 0.718750 0.187500
vt 0.093750 0.593750
vt 0.312500 0.593750
vt 0.312500 0.625000
vt 0.968750 0.421875
vt 1.000000 0.453125
vt 0.968750 0.453125
vt 0.562500 0.093750
vt 0.593750 0.140625
vt 0.562500 0.140625
vt 0.625000 0.453125
vt 0.656250 0.468750
vt 0.625000 0.500000
vt 0.687500 0.750000
vt 0.750000 0.734375
vt 0.750000 0.750000
vt 0.625000 0.109375
vt 0.656250 0.093750
vt 0.656250 0.109375
vt 0.625000 0.187500
vt 0.656250 0.171875
vt 0.656250 0.187500
vt 0.125000 0.843750
vt 0.125000 0.906250
vt 0.187500 0.906250
vt 0.468750 0.640625
vt 0.406250 0.640625
vt 0.187500 0.625000
vt 0.625000 0.734375
vt 0.687500 0.812500
vt 0.625000 0.812500
vt 0.437500 0.500000
vt 0.625000 0.500000
vt 0.593750 0.468750
vt 0.062500 0.468750
vt 0.000000 0.500000
vt 0.000000 0.343750
vt 0.750000 0.562500
vt 0.937500 0.562500
vt 0.843750 0.593750
vt 0.125000 0.937500
vt 0.000000 0.843750
vt 0.000000 1.000000
vt 0.500000 0.343750
vt 0.531250 0.390625
vt 0.500000 0.390625
vt 0.687500 0.218750
vt 0.718750 0.265625
vt 0.687500 0.265625
vt 0.531250 0.109375
vt 0.562500 0.093750
vt 0.562500 0.109375
vt 0.625000 0.296875
vt 0.656250 0.281250
vt 0.656250 0.296875
vt 0.562500 0.734375
vt 0.625000 0.812500
vt 0.562500 0.812500
vt 0.218750 0.546875
vt 0.281250 0.593750
vt 0.218750 0.578125
vt 0.156250 0.671875
vt 0.187500 0.687500
vt 0.062500 0.687500
vt 0.750000 0.765625
vt 0.687500 0.765625
vt 0.437500 0.375000
vt 0.468750 0.375000
vt 0.468750 0.421875
vt 0.718750 0.265625
vt 0.687500 0.312500
vt 0.718750 0.312500
vt 0.562500 0.281250
vt 0.531250 0.265625
vt 0.562500 0.265625
vt 0.656250 0.296875
vt 0.625000 0.312500
vt 0.656250 0.312500
vt 0.687500 0.828125
vt 0.625000 0.859375
vt 0.625000 0.828125
vt 0.531250 0.546875
vt 0.593750 0.593750
vt 0.531250 0.578125
vt 0.187500 0.781250
vt 0.312500 0.687500
vt 0.312500 0.843750
vt 0.562500 0.171875
vt 0.593750 0.218750
vt 0.562500 0.218750
vt 0.656250 0.984375
vt 0.718750 0.984375
vt 0.656250 0.968750
vt 0.312500 0.625000
vt 0.625000 0.593750
vt 0.625000 0.625000
vt 0.000000 0.640625
vt 0.125000 0.640625
vt 0.031250 0.656250
vt 0.312500 0.843750
vt 0.437500 0.687500
vt 0.312500 0.687500
vt 0.656250 0.234375
vt 0.625000 0.218750
vt 0.625000 0.250000
vt 0.468750 0.421875
vt 0.468750 0.406250
vt 0.500000 0.406250
vt 0.562500 0.062500
vt 0.687500 0.078125
vt 0.687500 0.062500
vt 0.687500 0.281250
vt 0.687500 0.265625
vt 0.656250 0.265625
vt 0.531250 0.328125
vt 0.500000 0.328125
vt 0.500000 0.234375
vt 0.687500 0.140625
vt 0.593750 0.156250
vt 0.562500 0.140625
vt 0.593750 0.218750
vt 0.562500 0.375000
vt 0.593750 0.375000
vt 0.562500 0.156250
vt 0.562500 0.171875
vt 0.593750 0.171875
vt 0.468750 0.312500
vt 0.500000 0.296875
vt 0.500000 0.312500
vt 0.531250 0.203125
vt 0.500000 0.109375
vt 0.468750 0.093750
vt 0.531250 0.093750
vt 0.000000 0.187500
vt 0.031250 0.234375
vt 0.031250 0.296875
vt 0.750000 0.750000
vt 0.687500 0.734375
vt 0.625000 0.703125
vt 0.687500 0.703125
vt 0.625000 0.703125
vt 0.687500 0.687500
vt 0.687500 0.703125
vt 0.625000 0.812500
vt 0.687500 0.828125
vt 0.625000 0.828125
vt 0.625000 0.687500
vt 0.562500 0.734375
vt 0.562500 0.687500
vt 0.562500 0.859375
vt 0.625000 0.812500
vt 0.625000 0.859375
vt 0.531250 0.171875
vt 0.500000 0.125000
vt 0.531250 0.125000
vt 0.187500 0.687500
vt 0.187500 0.750000
vt 0.125000 0.750000
vt 0.437500 0.937500
vt 0.437500 1.000000
vt 0.312500 1.000000
vt 0.562500 0.906250
vt 0.437500 0.843750
vt 0.437500 0.906250
vt 0.750000 0.781250
vt 0.937500 0.781250
vt 0.937500 0.812500
vt 0.781250 0.812500
vt 0.750000 0.812500
vt 0.750000 1.000000
vt 0.750000 0.968750
vt 0.937500 1.000000
vt 0.937500 0.968750
vt 0.468750 0.375000
vt 0.437500 0.375000
vt 0.468750 0.421875
vt 0.437500 0.453125
vt 0.468750 0.453125
vt 0.593750 0.453125
vt 0.593750 0.437500
vt 0.593750 0.375000
vt 1.000000 0.375000
vt 0.968750 0.375000
vt 0.656250 0.421875
vt 0.656250 0.375000
vt 0.843750 0.484375
vt 0.843750 0.500000
vt 0.968750 0.468750
vt 0.781250 0.500000
vt 0.781250 0.484375
vt 0.625000 0.453125
vt 0.656250 0.453125
vt 0.562500 0.687500
vt 0.687500 0.062500
vt 0.562500 0.078125
vt 0.375000 0.375000
vt 0.250000 0.375000
vt 0.218750 0.343750
vt 0.218750 0.375000
vt 0.218750 0.500000
vt 0.281250 0.468750
vt 0.218750 0.468750
vt 0.593750 0.093750
vt 0.593750 0.171875
vt 0.625000 0.218750
vt 0.406250 0.687500
vt 0.187500 0.687500
vt 0.687500 0.656250
vt 0.687500 0.687500
vt 0.468750 0.687500
vt 0.593750 0.375000
vt 0.625000 0.375000
vt 0.593750 0.421875
vt 0.437500 0.500000
vt 0.437500 0.453125
vt 0.468750 0.453125
vt 0.562500 0.453125
vt 0.562500 0.421875
vt 0.593750 0.453125
vt 0.750000 0.859375
vt 0.750000 0.968750
vt 0.656250 0.968750
vt 0.562500 0.890625
vt 0.562500 0.859375
vt 0.593750 0.875000
vt 0.593750 0.859375
vt 0.656250 0.875000
vt 0.656250 0.859375
vt 0.750000 0.937500
vt 0.687500 0.140625
vt 0.000000 0.625000
vt 0.000000 0.593750
vt 0.062500 0.593750
vt 0.968750 0.375000
vt 1.000000 0.375000
vt 1.000000 0.500000
vt 0.843750 0.500000
vt 0.968750 0.468750
vt 0.843750 0.484375
vt 0.781250 0.484375
vt 0.781250 0.500000
vt 0.750000 0.500000
vt 0.750000 0.468750
vt 0.781250 0.453125
vt 0.781250 0.421875
vt 0.593750 0.093750
vt 0.625000 0.375000
vt 0.656250 0.375000
vt 0.656250 0.421875
vt 0.656250 0.453125
vt 0.687500 0.734375
vt 0.625000 0.093750
vt 0.625000 0.171875
vt 0.187500 0.937500
vt 0.312500 0.843750
vt 0.187500 1.000000
vt 0.312500 1.000000
vt 0.406250 0.656250
vt 0.187500 0.656250
vt 0.687500 0.625000
vt 0.687500 0.656250
vt 0.468750 0.656250
vt 0.687500 0.734375
vt 0.468750 0.468750
vt 0.218750 0.343750
vt 0.062500 0.375000
vt 0.218750 0.375000
vt 0.218750 0.468750
vt 0.218750 0.500000
vt 0.843750 0.750000
vt 0.937500 0.750000
vt 0.937500 0.781250
vt 0.750000 0.781250
vt 0.750000 0.750000
vt 0.781250 0.750000
vt 0.781250 0.593750
vt 0.750000 0.593750
vt 0.937500 0.593750
vt 0.531250 0.343750
vt 0.718750 0.218750
vt 0.531250 0.093750
vt 0.625000 0.281250
vt 0.625000 0.734375
vt 0.031250 0.593750
vt 0.031250 0.500000
vt 0.093750 0.546875
vt 0.093750 0.500000
vt 0.093750 0.578125
vt 0.093750 0.593750
vt 0.062500 0.593750
vt 0.218750 0.500000
vt 0.281250 0.500000
vt 0.218750 0.593750
vt 0.156250 0.656250
vt 0.187500 0.656250
vt 0.062500 0.656250
vt 0.093750 0.671875
vt 0.093750 0.656250
vt 0.687500 0.265625
vt 0.531250 0.281250
vt 0.625000 0.296875
vt 0.687500 0.859375
vt 0.406250 0.578125
vt 0.406250 0.593750
vt 0.343750 0.593750
vt 0.343750 0.500000
vt 0.406250 0.546875
vt 0.406250 0.500000
vt 0.531250 0.500000
vt 0.593750 0.500000
vt 0.531250 0.593750
vt 0.125000 0.843750
vt 0.125000 0.781250
vt 0.593750 0.171875
vt 0.593750 0.921875
vt 0.593750 1.000000
vt 0.656250 1.000000
vt 0.562500 0.890625
vt 0.562500 0.921875
vt 0.656250 0.890625
vt 0.718750 1.000000
vt 0.750000 1.000000
vt 0.750000 0.968750
vt 0.312500 0.593750
vt 0.031250 0.671875
vt 0.000000 0.671875
vt 0.125000 0.671875
vt 0.093750 0.656250
vt 0.093750 0.671875
vt 0.437500 0.843750
vt 0.656250 0.218750
vt 0.687500 0.250000
vt 0.687500 0.234375
vt 0.531250 0.421875
vt 0.562500 0.078125
vt 0.656250 0.250000
vt 0.625000 0.250000
vt 0.625000 0.281250
vt 0.500000 0.171875
vt 0.687500 0.156250
vt 0.562500 0.156250
vt 0.562500 0.218750
vt 0.687500 0.171875
vt 0.687500 0.156250
vt 0.468750 0.296875
vt 0.468750 0.109375
vt 0.500000 0.187500
vt 0.468750 0.234375
vt 0.437500 0.296875
vt 0.437500 0.234375
vt 0.468750 0.328125
vt 0.500000 0.343750
vt 0.468750 0.203125
vt 0.406250 0.328125
vt 0.000000 0.343750
vt 0.312500 0.312500
vt 0.406250 0.312500
vt 0.406250 0.203125
vt 0.406250 0.218750
vt 0.343750 0.218750
vt 0.093750 0.328125
vt 0.093750 0.312500
vt 0.093750 0.203125
vt 0.093750 0.218750
vt 0.031250 0.328125
vt 0.062500 0.234375
vt 0.062500 0.296875
vt 0.031250 0.203125
vt 0.687500 0.750000
vt 0.625000 0.734375
vt 0.625000 0.687500
vt 0.687500 0.812500
vt 0.625000 0.734375
vt 0.562500 0.812500
vt 0.000000 0.687500
vt 0.000000 0.843750
vt 0.312500 0.937500
vt 0.437500 0.843750
vt 0.437500 1.000000
vt 0.562500 1.000000
vt 0.562500 0.843750
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 -1.0000 0.0000
usemtl grindstone
s off
f 13/1/1 10/2/1 6/3/1
f 11/4/2 109/5/2 5/6/2
f 16/7/1 144/8/1 8/9/1
f 114/10/3 155/11/3 147/12/3
f 113/13/1 82/14/1 1/15/1
f 65/16/4 91/17/4 136/18/4
f 24/19/4 51/20/4 139/21/4
f 122/22/1 88/23/1 65/24/1
f 127/25/1 90/26/1 68/27/1
f 140/28/1 18/29/1 125/30/1
f 44/31/4 92/32/4 137/33/4
f 19/34/1 25/35/1 23/36/1
f 144/37/3 72/38/3 127/39/3
f 77/40/4 101/41/4 28/42/4
f 133/43/3 56/44/3 146/45/3
f 118/46/1 4/47/1 3/48/1
f 121/49/3 74/50/3 51/51/3
f 35/52/5 42/53/5 43/54/5
f 86/55/5 108/56/5 81/57/5
f 40/58/5 45/59/5 96/60/5
f 49/61/6 132/62/6 52/63/6
f 91/64/5 123/65/5 136/66/5
f 138/67/5 72/68/5 66/69/5
f 48/70/1 47/71/1 54/72/1
f 97/73/5 76/74/5 74/75/5
f 57/76/5 133/77/5 98/78/5
f 96/79/2 139/80/2 124/81/2
f 144/82/4 145/83/4 27/84/4
f 69/85/5 59/86/5 115/87/5
f 55/88/1 154/89/1 155/90/1
f 35/91/3 111/92/3 32/93/3
f 38/94/3 60/95/3 61/96/3
f 43/97/3 71/98/3 14/99/3
f 44/100/3 22/101/3 16/102/3
f 102/103/1 149/104/1 30/105/1
f 113/106/3 69/107/3 65/108/3
f 78/109/3 150/110/3 77/111/3
f 131/112/1 28/42/1 134/113/1
f 33/114/3 34/115/3 64/116/3
f 7/117/2 110/118/2 2/119/2
f 15/120/2 39/121/2 13/122/2
f 125/123/2 137/124/2 92/125/2
f 80/126/5 104/127/5 58/128/5
f 116/129/2 128/130/2 138/131/2
f 150/132/1 114/133/1 147/134/1
f 116/135/5 34/136/5 85/137/5
f 103/138/2 26/139/2 102/140/2
f 145/141/2 23/142/2 27/143/2
f 28/144/2 101/145/2 99/146/2
f 105/147/2 151/148/2 87/149/2
f 109/150/6 110/151/6 59/152/6
f 85/153/6 34/154/6 33/155/6
f 5/156/6 63/157/6 86/158/6
f 61/159/6 60/160/6 62/161/6
f 10/162/6 35/163/6 37/164/6
f 138/165/4 67/166/4 90/167/4
f 8/168/6 115/169/6 7/170/6
f 9/171/6 118/172/6 117/173/6
f 120/174/6 121/175/6 73/176/6
f 13/122/4 39/121/4 41/177/4
f 107/178/6 108/179/6 106/180/6
f 50/181/6 94/182/6 129/183/6
f 134/113/6 19/184/6 131/112/6
f 76/185/6 98/186/6 133/187/6
f 54/188/6 20/189/6 47/190/6
f 104/191/6 56/192/6 57/193/6
f 149/194/4 58/195/4 30/196/4
f 102/197/4 55/198/4 146/199/4
f 6/200/2 31/201/2 83/202/2
f 29/203/1 132/204/1 21/205/1
f 156/206/4 153/207/4 105/208/4
f 48/209/6 114/210/6 29/211/6
f 128/212/1 84/213/1 10/2/1
f 84/213/1 111/214/1 10/2/1
f 14/215/1 71/216/1 128/212/1
f 119/217/1 15/218/1 13/1/1
f 14/215/1 128/212/1 10/2/1
f 106/219/1 119/217/1 6/3/1
f 119/217/1 13/1/1 6/3/1
f 13/1/1 14/215/1 10/2/1
f 6/3/1 83/220/1 106/219/1
f 81/221/2 107/222/2 86/223/2
f 107/222/2 40/224/2 86/223/2
f 91/225/2 88/226/2 89/227/2
f 109/5/2 82/228/2 5/6/2
f 5/6/2 86/223/2 89/227/2
f 86/223/2 40/224/2 91/225/2
f 89/227/2 86/223/2 91/225/2
f 89/227/2 11/4/2 5/6/2
f 62/229/1 60/230/1 8/9/1
f 7/231/1 2/232/1 109/5/1
f 144/8/1 62/229/1 8/9/1
f 7/231/1 109/5/1 11/4/1
f 135/233/1 26/234/1 22/235/1
f 26/234/1 144/8/1 22/235/1
f 140/28/1 75/236/1 20/237/1
f 18/29/1 140/28/1 20/237/1
f 22/235/1 18/29/1 135/233/1
f 18/29/1 20/237/1 135/233/1
f 12/238/1 92/239/1 11/4/1
f 92/239/1 16/7/1 8/9/1
f 11/4/1 92/239/1 7/231/1
f 16/7/1 22/235/1 144/8/1
f 8/9/1 7/231/1 92/239/1
f 114/10/3 154/240/3 155/11/3
f 113/13/1 5/241/1 82/14/1
f 65/16/4 88/242/4 91/17/4
f 96/243/4 53/244/4 141/245/4
f 53/244/4 78/246/4 141/245/4
f 96/243/4 141/245/4 24/19/4
f 51/20/4 142/247/4 140/248/4
f 142/247/4 75/249/4 140/248/4
f 140/248/4 139/21/4 51/20/4
f 139/21/4 96/243/4 24/19/4
f 122/22/1 124/250/1 88/23/1
f 127/25/1 94/251/1 90/26/1
f 92/239/1 12/238/1 125/30/1
f 12/238/1 139/80/1 125/30/1
f 139/80/1 140/28/1 125/30/1
f 44/31/4 16/252/4 92/32/4
f 25/35/1 99/253/1 27/254/1
f 17/255/1 24/256/1 19/34/1
f 24/256/1 141/257/1 19/34/1
f 25/35/1 27/254/1 23/36/1
f 17/255/1 19/34/1 23/36/1
f 3/258/3 62/259/3 118/260/3
f 62/259/3 144/37/3 118/260/3
f 143/261/3 42/262/3 72/38/3
f 42/262/3 66/263/3 72/38/3
f 67/264/3 117/265/3 118/260/3
f 68/266/3 67/264/3 118/260/3
f 144/37/3 143/261/3 72/38/3
f 127/39/3 68/266/3 144/37/3
f 68/266/3 118/260/3 144/37/3
f 77/40/4 150/267/4 101/41/4
f 80/268/3 149/269/3 56/44/3
f 149/269/3 146/45/3 56/44/3
f 55/270/3 47/271/3 75/272/3
f 47/271/3 20/273/3 75/272/3
f 146/45/3 55/270/3 75/272/3
f 142/274/3 76/275/3 133/43/3
f 146/45/3 75/272/3 142/274/3
f 56/44/3 79/276/3 80/268/3
f 142/274/3 133/43/3 146/45/3
f 118/46/1 9/277/1 4/47/1
f 51/51/3 24/278/3 121/49/3
f 24/278/3 17/279/3 73/280/3
f 73/280/3 121/49/3 24/278/3
f 32/281/5 33/282/5 35/52/5
f 33/282/5 42/53/5 35/52/5
f 143/283/5 100/284/5 70/285/5
f 100/284/5 49/286/5 70/285/5
f 52/287/5 78/288/5 53/289/5
f 52/287/5 53/289/5 46/290/5
f 52/287/5 46/290/5 49/286/5
f 46/290/5 70/285/5 49/286/5
f 43/54/5 41/291/5 37/292/5
f 43/54/5 37/292/5 35/52/5
f 143/283/5 70/285/5 42/53/5
f 70/285/5 43/54/5 42/53/5
f 86/55/5 63/293/5 108/56/5
f 107/294/5 31/295/5 36/296/5
f 36/296/5 37/292/5 41/291/5
f 36/296/5 41/291/5 39/297/5
f 40/58/5 107/294/5 36/296/5
f 46/290/5 53/289/5 45/59/5
f 53/289/5 96/60/5 45/59/5
f 36/296/5 39/297/5 40/58/5
f 39/297/5 45/59/5 40/58/5
f 49/61/6 21/298/6 132/62/6
f 91/64/5 95/299/5 123/65/5
f 138/67/5 129/300/5 72/68/5
f 54/72/1 152/301/1 151/302/1
f 152/301/1 156/303/1 153/304/1
f 151/302/1 152/301/1 153/304/1
f 151/302/1 48/70/1 54/72/1
f 142/305/5 51/306/5 76/74/5
f 51/306/5 74/75/5 76/74/5
f 50/307/5 145/308/5 97/73/5
f 145/308/5 103/309/5 97/73/5
f 50/307/5 97/73/5 74/75/5
f 57/76/5 56/310/5 133/77/5
f 95/311/2 91/225/2 40/224/2
f 139/80/2 12/238/2 124/81/2
f 12/238/2 11/4/2 88/226/2
f 124/81/2 12/238/2 88/226/2
f 11/4/2 89/227/2 88/226/2
f 95/311/2 40/224/2 96/79/2
f 124/81/2 95/311/2 96/79/2
f 27/84/4 99/312/4 143/313/4
f 99/312/4 100/314/4 143/313/4
f 26/315/4 103/316/4 144/82/4
f 103/316/4 145/83/4 144/82/4
f 27/84/4 143/313/4 144/82/4
f 38/317/5 61/318/5 112/319/5
f 112/319/5 130/320/5 38/317/5
f 130/320/5 126/321/5 44/322/5
f 130/320/5 44/322/5 38/317/5
f 137/323/5 93/324/5 69/85/5
f 38/317/5 44/322/5 137/323/5
f 59/86/5 110/325/5 115/87/5
f 115/87/5 38/317/5 137/323/5
f 137/323/5 69/85/5 115/87/5
f 156/303/1 152/301/1 55/88/1
f 47/71/1 48/70/1 154/89/1
f 155/90/1 156/303/1 55/88/1
f 55/88/1 47/71/1 154/89/1
f 35/91/3 10/326/3 111/92/3
f 38/94/3 8/327/3 60/95/3
f 43/97/3 70/328/3 71/98/3
f 44/100/3 126/329/3 22/101/3
f 102/103/1 146/330/1 149/104/1
f 119/331/3 106/332/3 63/333/3
f 106/332/3 108/334/3 63/333/3
f 136/335/3 123/336/3 120/337/3
f 120/337/3 119/331/3 136/335/3
f 119/331/3 63/333/3 136/335/3
f 113/106/3 1/338/3 59/339/3
f 69/107/3 122/340/3 65/108/3
f 65/108/3 136/335/3 63/333/3
f 113/106/3 59/339/3 69/107/3
f 65/108/3 63/333/3 113/106/3
f 78/109/3 52/341/3 132/342/3
f 77/111/3 131/343/3 141/344/3
f 131/343/3 19/345/3 141/344/3
f 78/109/3 132/342/3 150/110/3
f 77/111/3 141/344/3 78/109/3
f 131/112/1 77/40/1 28/42/1
f 64/116/3 117/265/3 67/264/3
f 66/263/3 42/262/3 64/116/3
f 42/262/3 33/114/3 64/116/3
f 64/116/3 67/264/3 66/263/3
f 7/117/2 115/346/2 110/118/2
f 15/120/2 45/347/2 39/121/2
f 125/123/2 93/348/2 137/124/2
f 80/126/5 79/349/5 104/127/5
f 90/350/2 94/351/2 130/352/2
f 130/352/2 112/353/2 9/354/2
f 112/353/2 4/355/2 9/354/2
f 90/350/2 130/352/2 9/354/2
f 116/129/2 85/356/2 84/357/2
f 90/350/2 9/354/2 116/129/2
f 128/130/2 129/358/2 138/131/2
f 138/131/2 90/350/2 116/129/2
f 116/129/2 84/357/2 128/130/2
f 148/359/1 101/360/1 150/132/1
f 132/204/1 29/203/1 114/133/1
f 147/134/1 148/359/1 150/132/1
f 150/132/1 132/204/1 114/133/1
f 116/135/5 64/361/5 34/136/5
f 57/362/2 98/363/2 102/140/2
f 98/363/2 97/364/2 103/138/2
f 98/363/2 103/138/2 102/140/2
f 58/365/2 104/366/2 57/362/2
f 102/140/2 30/367/2 57/362/2
f 30/367/2 58/365/2 57/362/2
f 135/368/2 54/369/2 26/139/2
f 54/369/2 152/370/2 26/139/2
f 26/139/2 152/370/2 102/140/2
f 145/141/2 50/371/2 23/142/2
f 25/372/2 134/373/2 99/146/2
f 134/373/2 28/144/2 99/146/2
f 101/145/2 21/374/2 100/375/2
f 21/374/2 49/376/2 100/375/2
f 101/145/2 100/375/2 99/146/2
f 105/147/2 153/377/2 151/148/2
f 109/150/6 2/378/6 110/151/6
f 59/152/6 1/379/6 109/150/6
f 1/379/6 82/380/6 109/150/6
f 32/93/6 111/92/6 33/155/6
f 111/92/6 84/381/6 33/155/6
f 84/381/6 85/153/6 33/155/6
f 5/156/6 113/382/6 63/157/6
f 3/383/6 4/384/6 62/161/6
f 4/384/6 112/385/6 62/161/6
f 112/385/6 61/159/6 62/161/6
f 36/386/6 6/200/6 37/164/6
f 6/200/6 10/162/6 37/164/6
f 66/387/4 67/166/4 138/165/4
f 67/166/4 68/388/4 90/167/4
f 8/168/6 38/389/6 115/169/6
f 64/390/6 116/391/6 117/173/6
f 116/391/6 9/171/6 117/173/6
f 120/174/6 123/392/6 121/175/6
f 41/177/4 43/97/4 14/99/4
f 14/99/4 13/122/4 41/177/4
f 107/178/6 81/393/6 108/179/6
f 106/180/6 83/202/6 107/178/6
f 83/202/6 31/201/6 107/178/6
f 74/394/6 121/175/6 122/395/6
f 121/175/6 123/392/6 122/395/6
f 123/392/6 95/396/6 124/397/6
f 123/392/6 124/397/6 122/395/6
f 120/174/6 73/176/6 119/398/6
f 73/176/6 17/399/6 119/398/6
f 74/394/6 122/395/6 69/400/6
f 119/398/6 17/399/6 15/401/6
f 17/399/6 23/402/6 15/401/6
f 46/403/6 45/404/6 15/401/6
f 50/181/6 74/394/6 93/405/6
f 74/394/6 69/400/6 93/405/6
f 93/405/6 125/406/6 18/407/6
f 46/403/6 15/401/6 71/408/6
f 15/401/6 23/402/6 71/408/6
f 71/408/6 70/409/6 46/403/6
f 50/181/6 93/405/6 126/410/6
f 93/405/6 18/407/6 126/410/6
f 18/407/6 22/411/6 126/410/6
f 128/412/6 71/408/6 23/402/6
f 127/413/6 72/414/6 129/183/6
f 129/183/6 128/412/6 23/402/6
f 50/181/6 126/410/6 130/415/6
f 94/182/6 127/413/6 129/183/6
f 50/181/6 130/415/6 94/182/6
f 129/183/6 23/402/6 50/181/6
f 134/113/6 25/416/6 19/184/6
f 76/185/6 97/417/6 98/186/6
f 54/188/6 135/418/6 20/189/6
f 104/191/6 79/419/6 56/192/6
f 149/194/4 80/420/4 58/195/4
f 102/197/4 152/421/4 55/198/4
f 6/200/2 36/386/2 31/201/2
f 21/205/1 101/360/1 87/422/1
f 101/360/1 148/359/1 105/423/1
f 87/422/1 101/360/1 105/423/1
f 87/422/1 29/203/1 21/205/1
f 105/208/4 148/424/4 156/206/4
f 148/424/4 147/134/4 156/206/4
f 147/134/4 155/425/4 156/206/4
f 29/211/6 87/426/6 151/427/6
f 48/209/6 154/428/6 114/210/6
f 29/211/6 151/427/6 48/209/6

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 385 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 KiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -1,6 +1,6 @@
/** /**
* Deploy code to CDB * Deploy code to CDB
* Copyright (C) 2023 SaKeL <juraj.vajda@gmail.com> * Copyright (C) 2025 SaKeL
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -29,7 +29,7 @@ try {
ref: 'master' ref: 'master'
} }
const response = await fetch('https://content.minetest.net/api/packages/SaKeL/x_enchanting/releases/new/', { const response = await fetch('https://content.luanti.org/api/packages/SaKeL/x_enchanting/releases/new/', {
method: 'POST', method: 'POST',
body: JSON.stringify(body), body: JSON.stringify(body),
headers: { headers: {

View File

@ -1,6 +1,6 @@
/** /**
* Run LUA diagnostics in continuous integration * Run LUA diagnostics in continuous integration
* Copyright (C) 2023 SaKeL <juraj.vajda@gmail.com> * Copyright (C) 2025 SaKeL
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

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.

Binary file not shown.

View File

@ -1,6 +1,7 @@
---@diagnostic disable
--[[ --[[
X Enchanting. Adds Enchanting Mechanics and API. X Enchanting. Adds Enchanting Mechanics and API.
Copyright (C) 2023 SaKeL <juraj.vajda@gmail.com> Copyright (C) 2025 SaKeL
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -16,21 +17,19 @@
License along with this library; if not, write to juraj.vajda@gmail.com License along with this library; if not, write to juraj.vajda@gmail.com
--]] --]]
---@diagnostic disable-next-line local S = core.get_translator(core.get_current_modname())
screwdriver = minetest.global_exists('screwdriver') and screwdriver --[[@as MtgScrewdriver]]
local S = minetest.get_translator(minetest.get_current_modname())
---- ----
--- Table Node --- Table Node
---- ----
minetest.register_node('x_enchanting:table', { core.register_node('x_enchanting:table', {
description = S('Enchanting Table'), description = S('Enchanting Table'),
short_description = S('Enchanting Table'), short_description = S('Enchanting Table'),
drawtype = 'mesh', drawtype = 'mesh',
mesh = 'x_enchanting_table.obj', mesh = 'x_enchanting_table.obj',
tiles = { 'x_enchanting_table.png' }, tiles = { 'x_enchanting_table.png' },
use_texture_alpha = 'clip',
paramtype = 'light', paramtype = 'light',
paramtype2 = 'facedir', paramtype2 = 'facedir',
walkable = true, walkable = true,
@ -64,15 +63,15 @@ minetest.register_node('x_enchanting:table', {
light_source = 6, light_source = 6,
---@param pos Vector ---@param pos Vector
on_construct = function(pos) on_construct = function(pos)
local meta = minetest.get_meta(pos) local meta = core.get_meta(pos)
local inv = meta:get_inventory() local inv = meta:get_inventory()
meta:set_string('infotext', S('Enchanting Table')) meta:set_string('infotext', S('Enchanting Table'))
meta:set_string('owner', '') meta:set_string('owner', '')
inv:set_size('item', 1) inv:set_size('item', 1)
inv:set_size('trade', 1) inv:set_size('trade', 1)
minetest.add_entity({ x = pos.x, y = pos.y + 0.7, z = pos.z }, 'x_enchanting:table_scroll') core.add_entity({ x = pos.x, y = pos.y + 0.7, z = pos.z }, 'x_enchanting:table_scroll')
minetest.get_node_timer(pos):start(5) core.get_node_timer(pos):start(5)
end, end,
---@param pos Vector ---@param pos Vector
---@param placer ObjectRef | nil ---@param placer ObjectRef | nil
@ -80,7 +79,7 @@ minetest.register_node('x_enchanting:table', {
---@param pointed_thing PointedThingDef ---@param pointed_thing PointedThingDef
---@diagnostic disable-next-line: unused-local ---@diagnostic disable-next-line: unused-local
after_place_node = function(pos, placer, itemstack, pointed_thing) after_place_node = function(pos, placer, itemstack, pointed_thing)
local meta = minetest.get_meta(pos) local meta = core.get_meta(pos)
if not placer then if not placer then
return return
@ -101,34 +100,34 @@ minetest.register_node('x_enchanting:table', {
---@param pointed_thing? PointedThingDef ---@param pointed_thing? PointedThingDef
---@diagnostic disable-next-line: unused-local ---@diagnostic disable-next-line: unused-local
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local meta = minetest.get_meta(pos) local meta = core.get_meta(pos)
local p_name = clicker:get_player_name() local p_name = clicker:get_player_name()
if minetest.is_protected(pos, p_name) then if core.is_protected(pos, p_name) then
return itemstack return itemstack
end end
minetest.sound_play('x_enchanting_scroll', { core.sound_play('x_enchanting_scroll', {
gain = 0.3, gain = 0.3,
pos = pos, pos = pos,
max_hear_distance = 10 max_hear_distance = 10
}, true) }, true)
-- bookshelfs -- bookshelfs
local bookshelfs = minetest.find_nodes_in_area( local bookshelfs = core.find_nodes_in_area(
{ x = pos.x - 2, y = pos.y, z = pos.z - 2 }, { x = pos.x - 2, y = pos.y, z = pos.z - 2 },
{ x = pos.x + 2, y = pos.y + 2, z = pos.z + 2 }, { x = pos.x + 2, y = pos.y + 2, z = pos.z + 2 },
{ 'default:bookshelf', 'group:bookshelf' } { 'default:bookshelf', 'group:bookshelf' }
) )
local inv = minetest.get_meta(pos):get_inventory() local inv = core.get_meta(pos):get_inventory()
if not inv:is_empty('item') and inv:get_stack('item', 1):get_meta():get_int('is_enchanted') ~= 1 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 item_stack = inv:get_stack('item', 1)
local data = XEnchanting:get_enchantment_data( local data = XEnchanting:get_enchantment_data(
clicker, clicker,
#bookshelfs, #bookshelfs,
minetest.registered_tools[item_stack:get_name()] core.registered_tools[item_stack:get_name()]
) )
local formspec = XEnchanting:get_formspec(pos, p_name, data) local formspec = XEnchanting:get_formspec(pos, p_name, data)
@ -146,12 +145,12 @@ minetest.register_node('x_enchanting:table', {
---@return table | nil ---@return table | nil
---@diagnostic disable-next-line: unused-local ---@diagnostic disable-next-line: unused-local
on_blast = function(pos, intensity) on_blast = function(pos, intensity)
if minetest.is_protected(pos, '') then if core.is_protected(pos, '') then
return return
end end
local drops = {} local drops = {}
local inv = minetest.get_meta(pos):get_inventory() local inv = core.get_meta(pos):get_inventory()
local stack_item = inv:get_stack('item', 1) local stack_item = inv:get_stack('item', 1)
local stack_trade = inv:get_stack('trade', 1) local stack_trade = inv:get_stack('trade', 1)
@ -164,7 +163,7 @@ minetest.register_node('x_enchanting:table', {
end end
drops[#drops + 1] = 'x_enchanting:table' drops[#drops + 1] = 'x_enchanting:table'
minetest.remove_node(pos) core.remove_node(pos)
return drops return drops
end, end,
@ -175,11 +174,11 @@ minetest.register_node('x_enchanting:table', {
return false return false
end end
local inv = minetest.get_meta(pos):get_inventory() local inv = core.get_meta(pos):get_inventory()
return inv:is_empty('item') return inv:is_empty('item')
and inv:is_empty('trade') and inv:is_empty('trade')
and not minetest.is_protected(pos, player:get_player_name()) and not core.is_protected(pos, player:get_player_name())
end, end,
---@diagnostic disable-next-line: unused-local ---@diagnostic disable-next-line: unused-local
on_rotate = function(pos, node, user, mode, new_param2) on_rotate = function(pos, node, user, mode, new_param2)
@ -190,10 +189,10 @@ minetest.register_node('x_enchanting:table', {
---@diagnostic disable-next-line: unused-local ---@diagnostic disable-next-line: unused-local
on_timer = function(pos, elapsed) on_timer = function(pos, elapsed)
-- entity -- entity
local table_scroll = minetest.get_objects_inside_radius(pos, 0.9) local table_scroll = core.get_objects_inside_radius(pos, 0.9)
if #table_scroll == 0 then if #table_scroll == 0 then
minetest.add_entity({ x = pos.x, y = pos.y + 0.7, z = pos.z }, 'x_enchanting:table_scroll') core.add_entity({ x = pos.x, y = pos.y + 0.7, z = pos.z }, 'x_enchanting:table_scroll')
end end
local particlespawner_def = { local particlespawner_def = {
@ -213,7 +212,7 @@ minetest.register_node('x_enchanting:table', {
glow = 1 glow = 1
} }
if minetest.has_feature({ dynamic_add_media_table = true, particlespawner_tweenable = true }) then if core.has_feature({ dynamic_add_media_table = true, particlespawner_tweenable = true }) then
-- new syntax, after v5.6.0 -- new syntax, after v5.6.0
particlespawner_def = { particlespawner_def = {
amount = 50, amount = 50,
@ -244,10 +243,10 @@ minetest.register_node('x_enchanting:table', {
} }
end end
minetest.add_particlespawner(particlespawner_def) core.add_particlespawner(particlespawner_def)
---bookshelfs ---bookshelfs
local bookshelfs = minetest.find_nodes_in_area( local bookshelfs = core.find_nodes_in_area(
{ x = pos.x - 2, y = pos.y, z = pos.z - 2 }, { x = pos.x - 2, y = pos.y, z = pos.z - 2 },
{ x = pos.x + 2, y = pos.y + 2, z = pos.z + 2 }, { x = pos.x + 2, y = pos.y + 2, z = pos.z + 2 },
{ 'default:bookshelf', 'group:bookshelf' } { 'default:bookshelf', 'group:bookshelf' }
@ -268,8 +267,8 @@ minetest.register_node('x_enchanting:table', {
local rand2 = math.random(10, 500) / 100 local rand2 = math.random(10, 500) / 100
local rand3 = math.random(50, 200) / 100 local rand3 = math.random(50, 200) / 100
minetest.after(rand2, function() core.after(rand2, function()
minetest.add_particle({ core.add_particle({
pos = pos_random, pos = pos_random,
velocity = { x = x, y = 2 - y, z = z }, velocity = { x = x, y = 2 - y, z = z },
acceleration = { x = 0, y = rand1, z = 0 }, acceleration = { x = 0, y = rand1, z = 0 },
@ -285,7 +284,7 @@ minetest.register_node('x_enchanting:table', {
end, end,
---@param pos Vector ---@param pos Vector
on_destruct = function(pos) on_destruct = function(pos)
for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 0.9)) do for _, obj in ipairs(core.get_objects_inside_radius(pos, 0.9)) do
if obj if obj
and obj:get_luaentity() and obj:get_luaentity()
and obj:get_luaentity().name == 'x_enchanting:table_scroll' and obj:get_luaentity().name == 'x_enchanting:table_scroll'
@ -307,14 +306,14 @@ minetest.register_node('x_enchanting:table', {
local is_enchanted = st_meta:get_int('is_enchanted') local is_enchanted = st_meta:get_int('is_enchanted')
if listname == 'item' if listname == 'item'
and minetest.get_item_group(st_name, 'enchantability') > 0 and core.get_item_group(st_name, 'enchantability') > 0
and is_enchanted ~= 1 and is_enchanted ~= 1
then then
return stack:get_count() return stack:get_count()
elseif listname == 'trade' elseif listname == 'trade'
and ( and (
st_name == 'default:mese_crystal' st_name == 'default:mese_crystal'
or minetest.get_item_group(st_name, 'enchanting_trade') > 0 or core.get_item_group(st_name, 'enchanting_trade') > 0
) )
and is_enchanted ~= 1 and is_enchanted ~= 1
then then
@ -337,7 +336,7 @@ minetest.register_node('x_enchanting:table', {
elseif listname == 'trade' elseif listname == 'trade'
and ( and (
st_name == 'default:mese_crystal' st_name == 'default:mese_crystal'
or minetest.get_item_group(st_name, 'enchanting_trade') > 0 or core.get_item_group(st_name, 'enchanting_trade') > 0
) )
then then
return stack:get_count() return stack:get_count()
@ -363,7 +362,7 @@ minetest.register_node('x_enchanting:table', {
---@param player ObjectRef ---@param player ObjectRef
---@diagnostic disable-next-line: unused-local ---@diagnostic disable-next-line: unused-local
on_metadata_inventory_put = function(pos, listname, index, stack, player) on_metadata_inventory_put = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos) local meta = core.get_meta(pos)
local p_name = player:get_player_name() local p_name = player:get_player_name()
local inv = meta:get_inventory() local inv = meta:get_inventory()
local item_stack = inv:get_stack('item', 1) local item_stack = inv:get_stack('item', 1)
@ -372,7 +371,7 @@ minetest.register_node('x_enchanting:table', {
if not inv:is_empty('item') and is_enchanted == 0 then if not inv:is_empty('item') and is_enchanted == 0 then
-- bookshelfs -- bookshelfs
local bookshelfs = minetest.find_nodes_in_area( local bookshelfs = core.find_nodes_in_area(
{ x = pos.x - 2, y = pos.y, z = pos.z - 2 }, { x = pos.x - 2, y = pos.y, z = pos.z - 2 },
{ x = pos.x + 2, y = pos.y + 2, z = pos.z + 2 }, { x = pos.x + 2, y = pos.y + 2, z = pos.z + 2 },
{ 'default:bookshelf', 'group:bookshelf' } { 'default:bookshelf', 'group:bookshelf' }
@ -381,7 +380,7 @@ minetest.register_node('x_enchanting:table', {
local data = XEnchanting:get_enchantment_data( local data = XEnchanting:get_enchantment_data(
player, player,
#bookshelfs, #bookshelfs,
minetest.registered_tools[item_stack:get_name()] core.registered_tools[item_stack:get_name()]
) )
local formspec = XEnchanting:get_formspec(pos, p_name, data) local formspec = XEnchanting:get_formspec(pos, p_name, data)
@ -399,7 +398,7 @@ minetest.register_node('x_enchanting:table', {
---@param player ObjectRef ---@param player ObjectRef
---@diagnostic disable-next-line: unused-local ---@diagnostic disable-next-line: unused-local
on_metadata_inventory_take = function(pos, listname, index, stack, player) on_metadata_inventory_take = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos) local meta = core.get_meta(pos)
local p_name = player:get_player_name() local p_name = player:get_player_name()
local inv = meta:get_inventory() local inv = meta:get_inventory()
local item_stack = inv:get_stack('item', 1) local item_stack = inv:get_stack('item', 1)
@ -408,7 +407,7 @@ minetest.register_node('x_enchanting:table', {
if not inv:is_empty('item') and is_enchanted == 0 then if not inv:is_empty('item') and is_enchanted == 0 then
-- bookshelfs -- bookshelfs
local bookshelfs = minetest.find_nodes_in_area( local bookshelfs = core.find_nodes_in_area(
{ x = pos.x - 2, y = pos.y, z = pos.z - 2 }, { x = pos.x - 2, y = pos.y, z = pos.z - 2 },
{ x = pos.x + 2, y = pos.y + 2, z = pos.z + 2 }, { x = pos.x + 2, y = pos.y + 2, z = pos.z + 2 },
{ 'default:bookshelf', 'group:bookshelf' } { 'default:bookshelf', 'group:bookshelf' }
@ -417,7 +416,7 @@ minetest.register_node('x_enchanting:table', {
local data = XEnchanting:get_enchantment_data( local data = XEnchanting:get_enchantment_data(
player, player,
#bookshelfs, #bookshelfs,
minetest.registered_tools[item_stack:get_name()] core.registered_tools[item_stack:get_name()]
) )
local formspec = XEnchanting:get_formspec(pos, p_name, data) local formspec = XEnchanting:get_formspec(pos, p_name, data)
@ -456,7 +455,7 @@ minetest.register_node('x_enchanting:table', {
return return
end end
local inv = minetest.get_meta(pos):get_inventory() local inv = core.get_meta(pos):get_inventory()
if inv:is_empty('trade') or inv:is_empty('item') then if inv:is_empty('trade') or inv:is_empty('item') then
return return
@ -489,7 +488,7 @@ minetest.register_node('x_enchanting:table', {
--- Entity (Scroll) --- Entity (Scroll)
---- ----
minetest.register_entity('x_enchanting:table_scroll', { core.register_entity('x_enchanting:table_scroll', {
initial_properties = { initial_properties = {
visual = 'mesh', visual = 'mesh',
mesh = 'x_enchanting_scroll.b3d', mesh = 'x_enchanting_scroll.b3d',
@ -544,7 +543,7 @@ minetest.register_entity('x_enchanting:table_scroll', {
-- table -- table
if self._tablechecktimer <= 0 then if self._tablechecktimer <= 0 then
self._tablechecktimer = 5 self._tablechecktimer = 5
local node = minetest.get_node({ x = pos.x, y = pos.y - 0.7, z = pos.z }) local node = core.get_node({ x = pos.x, y = pos.y - 0.7, z = pos.z })
if node.name ~= 'x_enchanting:table' then if node.name ~= 'x_enchanting:table' then
-- remove entity when no table under it -- remove entity when no table under it
@ -555,7 +554,7 @@ minetest.register_entity('x_enchanting:table_scroll', {
-- player -- player
if self._playerchecktimer <= 0 then if self._playerchecktimer <= 0 then
self._playerchecktimer = 1 self._playerchecktimer = 1
local objects = minetest.get_objects_inside_radius(pos, 5) local objects = core.get_objects_inside_radius(pos, 5)
-- inital value -- inital value
local shortest_distance = 10 local shortest_distance = 10
@ -588,7 +587,7 @@ minetest.register_entity('x_enchanting:table_scroll', {
self._scroll_closed = false self._scroll_closed = false
self.object:set_animation(unpack(XEnchanting.scroll_animations.scroll_open)) self.object:set_animation(unpack(XEnchanting.scroll_animations.scroll_open))
minetest.sound_play('x_enchanting_scroll', { core.sound_play('x_enchanting_scroll', {
gain = 0.3, gain = 0.3,
pos = pos, pos = pos,
max_hear_distance = 10 max_hear_distance = 10
@ -597,7 +596,7 @@ minetest.register_entity('x_enchanting:table_scroll', {
self._scroll_closed = true self._scroll_closed = true
self.object:set_animation(unpack(XEnchanting.scroll_animations.scroll_close)) self.object:set_animation(unpack(XEnchanting.scroll_animations.scroll_close))
minetest.sound_play('x_enchanting_scroll', { core.sound_play('x_enchanting_scroll', {
gain = 0.3, gain = 0.3,
pos = pos, pos = pos,
max_hear_distance = 10 max_hear_distance = 10
@ -608,7 +607,7 @@ minetest.register_entity('x_enchanting:table_scroll', {
-- rotation -- rotation
if self._player and self._player:get_pos() then if self._player and self._player:get_pos() then
local direction = vector.direction(pos, self._player:get_pos()) local direction = vector.direction(pos, self._player:get_pos())
self.object:set_yaw(minetest.dir_to_yaw(direction)) self.object:set_yaw(core.dir_to_yaw(direction))
else else
self.object:set_rotation({ self.object:set_rotation({
x = self._last_rotation.x, x = self._last_rotation.x,
@ -634,17 +633,17 @@ minetest.register_entity('x_enchanting:table_scroll', {
-- Recipe -- Recipe
--- ---
if minetest.get_modpath('xdecor') then if core.get_modpath('xdecor') or core.get_modpath('enchanting') then
minetest.register_craft({ core.register_craft({
output = 'x_enchanting:table', output = 'x_enchanting:table',
recipe = { recipe = {
{ 'default:book', '', '' }, { 'default:book', '', '' },
{ 'default:diamond', 'default:obsidian', 'default:diamond' }, { 'default:diamond', 'xdecor:enchantment_table', 'default:diamond' },
{ 'default:obsidian', 'default:obsidian', 'default:obsidian' } { 'default:obsidian', 'default:obsidian', 'default:obsidian' }
} }
}) })
else else
minetest.register_craft({ core.register_craft({
output = 'x_enchanting:table', output = 'x_enchanting:table',
recipe = { recipe = {
{ '', 'default:book', '' }, { '', 'default:book', '' },

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B