mirror of
https://bitbucket.org/minetest_gamers/x_enchanting.git
synced 2025-06-28 22:06:17 +02:00
Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
769af761f1 | |||
55cb91917a | |||
1dd7beaae0 | |||
db8d3e7a29 |
@ -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
|
||||
}
|
||||
|
@ -16,13 +16,14 @@ exclude_files = {
|
||||
}
|
||||
|
||||
globals = {
|
||||
'minetest',
|
||||
'XEnchanting'
|
||||
}
|
||||
|
||||
read_globals = {
|
||||
"DIR_DELIM", "INIT",
|
||||
|
||||
"minetest", "core",
|
||||
"core",
|
||||
"dump", "dump2",
|
||||
|
||||
"Raycast",
|
||||
|
13
README.md
13
README.md
@ -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
46
api.lua
@ -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,
|
||||
|
41
init.lua
41
init.lua
@ -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
144
table.lua
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user