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

4 Commits

Author SHA1 Message Date
769af761f1 add silk touch enchant, switch sounds to OSI licensing 2022-11-10 15:26:14 -05:00
55cb91917a add forum id to cdb.json 2022-11-10 10:11:06 -05:00
1dd7beaae0 Use node meta for formspec 2022-11-10 00:15:51 -05:00
db8d3e7a29 Update content 2022-11-09 21:46:19 -05:00
23 changed files with 170 additions and 87 deletions

View File

@ -5,8 +5,6 @@
"short_description": "Adds Enchanting Mechanics and API.",
"dev_state": "MAINTENANCE_ONLY",
"tags": [
"pvp",
"shooter",
"survival",
"tools",
"magic"
@ -14,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,10 @@ 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.
## Dependencies
- none
@ -129,11 +133,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
**Creative Commons License, Kostas17**, https://freesound.org
- x_enchanting_enchant.ogg
**Standard License**, Sound effects obtained from https://mixkit.co
**Creative Commons License, jammaj**, https://freesound.org
- x_enchanting_scroll.1.ogg
- x_enchanting_scroll.2.ogg
@ -144,11 +148,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

46
api.lua
View File

@ -32,14 +32,7 @@ XEnchanting = {
['default:sword_bronze'] = 22,
['default:sword_steel'] = 14,
['default:sword_mese'] = 15,
['default:sword_diamond'] = 10,
-- hoes
['farming:hoe_wood'] = 15,
['farming:hoe_stone'] = 5,
['farming:hoe_steel'] = 14,
['farming:hoe_bronze'] = 22,
['farming:hoe_mese'] = 15,
['farming:hoe_diamond'] = 10,
['default:sword_diamond'] = 10
},
roman_numbers = {
[1] = 'I',
@ -122,6 +115,16 @@ XEnchanting = {
[5] = 45,
},
weight = 10
},
silk_touch = {
name = S('Silk Touch'),
final_level_range = {
[1] = { 15, 65 }
},
level_def = {
[1] = 'silk_touch'
},
weight = 1
}
},
randomseed = os.time(),
@ -330,6 +333,15 @@ function XEnchanting.get_enchanted_tool_capabilities(self, tool_def, enchantment
.. self.roman_numbers[enchantment.level]
end
end
-- Silk Touch
if enchantment.id == 'silk_touch' then
enchantments_desc[#enchantments_desc + 1] = self.enchantment_defs[enchantment.id].name
if #enchantments_desc_masked == 0 then
enchantments_desc_masked[#enchantments_desc_masked + 1] = self.enchantment_defs[enchantment.id].name
end
end
end
enchantments_desc = '\n' .. minetest.colorize('#AE81FF', S('Enchanted'))
@ -343,20 +355,28 @@ function XEnchanting.get_enchanted_tool_capabilities(self, tool_def, enchantment
}
end
function XEnchanting.set_enchanted_tool(self, itemstack, level, player_name)
function XEnchanting.set_enchanted_tool(self, pos, itemstack, level, player_name)
local data = self.form_context[player_name].data
local pos = self.form_context[player_name].pos
local capabilities = data.slots[level].tool_cap_data.tool_capabilities
local description = data.slots[level].tool_cap_data.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()]
local node_meta = minetest.get_meta(pos)
if not tool_def then
return
end
local stack_meta = itemstack:get_meta()
local is_silk_touch = 0
for i, val in ipairs(final_enchantments) do
if val.id == 'silk_touch' then
is_silk_touch = 1
break
end
end
stack_meta:set_tool_capabilities(capabilities)
stack_meta:set_string('description', itemstack:get_description() .. '\n' .. description)
@ -364,6 +384,10 @@ function XEnchanting.set_enchanted_tool(self, itemstack, level, player_name)
stack_meta:set_int('is_enchanted', 1)
stack_meta:set_string('x_enchanting', minetest.serialize({ enchantments = final_enchantments }))
if is_silk_touch > 0 then
stack_meta:set_int('is_silk_touch', 1)
end
inv:set_stack('item', 1, itemstack)
local trade_stack = inv:get_stack('trade', 1)
@ -374,7 +398,7 @@ function XEnchanting.set_enchanted_tool(self, itemstack, level, player_name)
self.randomseed = tonumber(tostring(os.time()):reverse():sub(1, 9)) --[[@as number]]
local formspec = self:get_formspec(pos, player_name)
minetest.show_formspec(player_name, 'x_enchanting:table', formspec)
node_meta:set_string('formspec', formspec)
minetest.sound_play('x_enchanting_enchant', {
gain = 0.3,

View File

@ -23,6 +23,47 @@ 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_int('is_silk_touch') == 0 then
return old_handle_node_drops(pos, drops, digger)
end
local wield_stack_name = wield_stack:get_name()
local node = minetest.get_node(pos)
local silk_touch_group
if minetest.get_item_group(wield_stack_name, 'pickaxe') > 0 then
silk_touch_group = 'cracky'
elseif minetest.get_item_group(wield_stack_name, 'shovel') > 0 then
silk_touch_group = 'crumbly'
elseif minetest.get_item_group(wield_stack_name, 'axe') > 0 then
silk_touch_group = 'choppy'
elseif minetest.get_item_group(wield_stack_name, 'sword') > 0 then
silk_touch_group = 'snappy'
end
if not silk_touch_group
or minetest.get_item_group(node.name, silk_touch_group) == 0
or 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
local mod_end_time = (minetest.get_us_time() - mod_start_time) / 1000000
print('[Mod] x_enchanting loaded.. [' .. mod_end_time .. 's]')

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.

144
table.lua
View File

@ -70,6 +70,9 @@ minetest.register_node('x_enchanting:table', {
meta:set_string('owner', player_name)
meta:set_string('infotext', S('Enchanting Table') .. ' (' .. S('owned by') .. ' ' .. player_name .. ')')
local formspec = XEnchanting:get_formspec(pos, player_name)
meta:set_string('formspec', formspec)
end,
---@param pos Vector
---@param node NodeDef
@ -77,6 +80,7 @@ minetest.register_node('x_enchanting:table', {
---@param itemstack ItemStack
---@param pointed_thing? PointedThingDef
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local meta = minetest.get_meta(pos)
local p_name = clicker:get_player_name()
if minetest.is_protected(pos, p_name) then
@ -103,11 +107,11 @@ minetest.register_node('x_enchanting:table', {
local data = XEnchanting:get_enchantment_data(#bookshelfs, minetest.registered_tools[item_stack:get_name()])
local formspec = XEnchanting:get_formspec(pos, p_name, data)
minetest.show_formspec(p_name, 'x_enchanting:table', formspec)
meta:set_string('formspec', formspec)
else
local formspec = XEnchanting:get_formspec(pos, p_name)
minetest.show_formspec(p_name, 'x_enchanting:table', formspec)
meta:set_string('formspec', formspec)
end
return itemstack
@ -326,8 +330,9 @@ minetest.register_node('x_enchanting:table', {
---@param stack ItemStack
---@param player ObjectRef
on_metadata_inventory_put = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
local p_name = player:get_player_name()
local inv = minetest.get_meta(pos):get_inventory()
local inv = meta:get_inventory()
if not inv:is_empty('item') then
-- bookshelfs
@ -341,11 +346,11 @@ minetest.register_node('x_enchanting:table', {
local data = XEnchanting:get_enchantment_data(#bookshelfs, minetest.registered_tools[item_stack:get_name()])
local formspec = XEnchanting:get_formspec(pos, p_name, data)
minetest.show_formspec(p_name, 'x_enchanting:table', formspec)
meta:set_string('formspec', formspec)
else
local formspec = XEnchanting:get_formspec(pos, p_name)
minetest.show_formspec(p_name, 'x_enchanting:table', formspec)
meta:set_string('formspec', formspec)
end
end,
---@param pos Vector
@ -354,8 +359,9 @@ minetest.register_node('x_enchanting:table', {
---@param stack ItemStack
---@param player ObjectRef
on_metadata_inventory_take = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
local p_name = player:get_player_name()
local inv = minetest.get_meta(pos):get_inventory()
local inv = meta:get_inventory()
if not inv:is_empty('item') then
-- bookshelfs
@ -369,70 +375,70 @@ minetest.register_node('x_enchanting:table', {
local data = XEnchanting:get_enchantment_data(#bookshelfs, minetest.registered_tools[item_stack:get_name()])
local formspec = XEnchanting:get_formspec(pos, p_name, data)
minetest.show_formspec(p_name, 'x_enchanting:table', formspec)
meta:set_string('formspec', formspec)
else
local formspec = XEnchanting:get_formspec(pos, p_name)
minetest.show_formspec(p_name, 'x_enchanting:table', formspec)
meta:set_string('formspec', formspec)
end
end,
-- form receive fields
---@param pos Vector
---@param formname string
---@param fields table
---@param sender ObjectRef
on_receive_fields = function(pos, formname, fields, sender)
local p_name = sender:get_player_name()
if fields.quit then
XEnchanting.form_context[p_name] = nil
return
end
local selected_slot
if fields.slot_1 and fields.slot_1 ~= '' then
selected_slot = 1
elseif fields.slot_2 and fields.slot_2 ~= '' then
selected_slot = 2
elseif fields.slot_3 and fields.slot_3 ~= '' then
selected_slot = 3
end
if not XEnchanting.form_context[p_name] or not selected_slot then
return
end
local inv = minetest.get_meta(pos):get_inventory()
if inv:is_empty('trade') or inv:is_empty('item') then
return
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
return
end
local item_stack = inv:get_stack('item', 1)
local is_enchanted = item_stack:get_meta():get_int('is_enchanted')
if is_enchanted == 1 then
return
end
-- Enchant item
XEnchanting:set_enchanted_tool(
pos,
item_stack,
selected_slot,
p_name
)
end
})
-- form receive fields
---@param player ObjectRef
---@param formname string
---@param fields table
minetest.register_on_player_receive_fields(function(player, formname, fields)
local p_name = player:get_player_name()
if formname ~= 'x_enchanting:table' or fields.quit then
XEnchanting.form_context[p_name] = nil
return
end
local selected_slot
if fields.slot_1 and fields.slot_1 ~= '' then
selected_slot = 1
elseif fields.slot_2 and fields.slot_2 ~= '' then
selected_slot = 2
elseif fields.slot_3 and fields.slot_3 ~= '' then
selected_slot = 3
end
if not XEnchanting.form_context[p_name] or not selected_slot then
return
end
local pos = XEnchanting.form_context[p_name].pos
local inv = minetest.get_meta(pos):get_inventory()
if inv:is_empty('trade') or inv:is_empty('item') then
return
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
return
end
local item_stack = inv:get_stack('item', 1)
local is_enchanted = item_stack:get_meta():get_int('is_enchanted')
if is_enchanted == 1 then
return
end
-- Enchant item
XEnchanting:set_enchanted_tool(
item_stack,
selected_slot,
p_name
)
end)
----
--- Entity (Scroll)
----
@ -530,9 +536,21 @@ minetest.register_entity('x_enchanting:table_scroll', {
if self._player and self._scroll_closed then
self._scroll_closed = false
self.object:set_animation(unpack(XEnchanting.scroll_animations.scroll_open))
minetest.sound_play('x_enchanting_scroll', {
gain = 0.3,
pos = pos,
max_hear_distance = 10
}, true)
elseif not self._player and not self._scroll_closed then
self._scroll_closed = true
self.object:set_animation(unpack(XEnchanting.scroll_animations.scroll_close))
minetest.sound_play('x_enchanting_scroll', {
gain = 0.3,
pos = pos,
max_hear_distance = 10
}, true)
end
end

View File

@ -88,6 +88,7 @@
---@field add_particle fun(def: ParticleDef): nil
---@field registered_tools table<string, ItemDef> Map of registered tool 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)
---Minetest settings
---@class MinetestSettings

View File

@ -4,11 +4,11 @@
---@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', 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 set_enchanted_tool fun(self: XEnchanting, 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 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