quiver inventory - initial commit sfinv
This commit is contained in:
parent
bb67e0469e
commit
9a95e998a3
250
api.lua
250
api.lua
|
@ -1,3 +1,5 @@
|
|||
sfinv = sfinv--[[@as Sfinv]]
|
||||
|
||||
---Check if table contains value
|
||||
---@param table table
|
||||
---@param value string|number
|
||||
|
@ -286,11 +288,15 @@ function XBows.register_arrow(self, name, def)
|
|||
local mod_name = def.custom.mod_name or 'x_bows'
|
||||
def.custom.name = mod_name .. ':' .. name
|
||||
def.description = def.description or name
|
||||
def.short_description = def.short_description or name
|
||||
def.custom.tool_capabilities = def.custom.tool_capabilities or {
|
||||
full_punch_interval = 1,
|
||||
max_drop_level = 0,
|
||||
damage_groups = {fleshy=2}
|
||||
}
|
||||
def.custom.description_abilities = minetest.colorize('#00FF00', 'Damage: '
|
||||
.. def.custom.tool_capabilities.damage_groups.fleshy) .. '\n' .. minetest.colorize('#00BFFF', 'Charge Time: '
|
||||
.. def.custom.tool_capabilities.full_punch_interval .. 's')
|
||||
def.groups = mergeTables({arrow = 1, flammable = 1}, def.groups or {})
|
||||
def.custom.particle_effect = def.custom.particle_effect or 'arrow'
|
||||
def.custom.particle_effect_crit = def.custom.particle_effect_crit or 'arrow_crit'
|
||||
|
@ -304,10 +310,8 @@ function XBows.register_arrow(self, name, def)
|
|||
self.registered_arrows[def.custom.name] = def
|
||||
|
||||
minetest.register_craftitem(def.custom.name, {
|
||||
description = def.description .. '\n' .. minetest.colorize('#00FF00', 'Damage: '
|
||||
.. def.custom.tool_capabilities.damage_groups.fleshy) .. '\n' .. minetest.colorize('#00BFFF', 'Charge Time: '
|
||||
.. def.custom.tool_capabilities.full_punch_interval .. 's'),
|
||||
short_description = def.description,
|
||||
description = def.description .. '\n' .. def.custom.description_abilities,
|
||||
short_description = def.short_description,
|
||||
inventory_image = def.inventory_image,
|
||||
groups = def.groups
|
||||
})
|
||||
|
@ -1814,12 +1818,25 @@ end
|
|||
---@param quiver_is_closed? boolean
|
||||
---@return nil
|
||||
function XBowsQuiver.save(self, inv, player, quiver_is_closed)
|
||||
local player_inv = player:get_inventory()
|
||||
local player_inv = player:get_inventory()--[[@as InvRef]]
|
||||
local inv_loc = inv:get_location()
|
||||
local quiver_item_name = quiver_is_closed and 'x_bows:quiver' or 'x_bows:quiver_open'
|
||||
local player_quiver_inv_stack = player_inv:get_stack('x_bows:quiver_inv', 1)
|
||||
|
||||
---find matching quiver item in players inventory with the open formspec name
|
||||
if player_inv and player_inv:contains_item('main', quiver_item_name) then
|
||||
if not player_quiver_inv_stack:is_empty() and player_quiver_inv_stack:get_meta():get_string('quiver_id') == inv_loc.name then
|
||||
local st_meta = player_quiver_inv_stack:get_meta()
|
||||
---save inventory items in quiver item meta
|
||||
local string_from_inventory_result = self:get_string_from_inv(inv)
|
||||
|
||||
st_meta:set_string('quiver_items', string_from_inventory_result.inv_string)
|
||||
|
||||
---update description
|
||||
local new_description = player_quiver_inv_stack:get_short_description()..'\n'..string_from_inventory_result.content_description..'\n'
|
||||
|
||||
st_meta:set_string('description', new_description)
|
||||
player_inv:set_stack('x_bows:quiver_inv', 1, player_quiver_inv_stack)
|
||||
elseif player_inv and player_inv:contains_item('main', quiver_item_name) then
|
||||
---find matching quiver item in players inventory with the open formspec name
|
||||
local inv_list = player_inv:get_list('main')
|
||||
|
||||
for i, st in ipairs(inv_list) do
|
||||
|
@ -1849,11 +1866,16 @@ end
|
|||
---@param player ObjectRef
|
||||
---@return boolean
|
||||
function XBowsQuiver.quiver_can_allow(self, inv, player)
|
||||
local player_inv = player:get_inventory()
|
||||
local player_inv = player:get_inventory()--[[@as InvRef]]
|
||||
local inv_loc = inv:get_location()
|
||||
local player_quiver_inv_stack = player_inv:get_stack('x_bows:quiver_inv', 1)
|
||||
|
||||
---find matching quiver item in players inventory with the open formspec name
|
||||
if player_inv and player_inv:contains_item('main', 'x_bows:quiver_open') then
|
||||
if not player_quiver_inv_stack:is_empty() and player_quiver_inv_stack:get_meta():get_string('quiver_id') == inv_loc.name then
|
||||
---find quiver in player `quiver_inv` inv list
|
||||
return true
|
||||
elseif player_inv and player_inv:contains_item('main', 'x_bows:quiver_open') then
|
||||
---find quiver in player `main` inv list
|
||||
---matching quiver item in players inventory with the open formspec name
|
||||
local inv_list = player_inv:get_list('main')
|
||||
|
||||
for i, st in ipairs(inv_list) do
|
||||
|
@ -1901,3 +1923,211 @@ function XBows.open_quiver(self, itemstack, user)
|
|||
minetest.show_formspec(pname, quiver_id, XBowsQuiver:get_formspec(quiver_id))
|
||||
return itemstack
|
||||
end
|
||||
|
||||
---Register sfinv page
|
||||
---@param self XBowsQuiver
|
||||
function XBowsQuiver.sfinv_register_page(self)
|
||||
sfinv.register_page('x_bows:quiver_page', {
|
||||
title = 'X Bows',
|
||||
get = function(this, player, context)
|
||||
local formspec = {
|
||||
---arrow
|
||||
'label[0,0;Arrows you are wearing:]',
|
||||
'list[current_player;x_bows:arrow_inv;0,0.5;1,1;]',
|
||||
'image[0,0.5;1,1;x_bows_arrow_slot.png;]',
|
||||
'listring[current_player;x_bows:arrow_inv]',
|
||||
'listring[current_player;main]',
|
||||
---quiver
|
||||
'label[0,1.5;Quiver you are wearing:]',
|
||||
'list[current_player;x_bows:quiver_inv;0,2;1,1;]',
|
||||
'image[0,2;1,1;x_bows_quiver_slot.png]',
|
||||
'listring[current_player;x_bows:quiver_inv]',
|
||||
'listring[current_player;main]',
|
||||
}
|
||||
|
||||
if not context._itemstack_arrow then
|
||||
context._itemstack_arrow = player:get_inventory():get_stack('x_bows:arrow_inv', 1)
|
||||
end
|
||||
|
||||
if not context._itemstack_quiver then
|
||||
context._itemstack_quiver = player:get_inventory():get_stack('x_bows:quiver_inv', 1)
|
||||
end
|
||||
|
||||
if context._itemstack_arrow and not context._itemstack_arrow:is_empty() then
|
||||
local x_bows_registered_arrow_def = self.registered_arrows[context._itemstack_arrow:get_name()]
|
||||
|
||||
if x_bows_registered_arrow_def then
|
||||
formspec[#formspec + 1] = 'label[2.5,0;' .. minetest.formspec_escape(context._itemstack_arrow:get_short_description()) .. '\n'.. minetest.formspec_escape(x_bows_registered_arrow_def.custom.description_abilities) ..']'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if context._itemstack_quiver and not context._itemstack_quiver:is_empty() then
|
||||
local st_meta = context._itemstack_quiver:get_meta()
|
||||
local quiver_id = st_meta:get_string('quiver_id')
|
||||
|
||||
---description
|
||||
formspec[#formspec + 1] = 'label[2.5,1.5;' .. minetest.formspec_escape(context._itemstack_quiver:get_short_description()) .. ']'
|
||||
formspec[#formspec + 1] = 'list[detached:'..quiver_id..';main;0,3.2;3,1;]'
|
||||
formspec[#formspec + 1] = 'listring[detached:'..quiver_id..';main]'
|
||||
formspec[#formspec + 1] = 'listring[current_player;main]'
|
||||
end
|
||||
|
||||
return sfinv.make_formspec(player, context, table.concat(formspec, ''), true)
|
||||
end,
|
||||
on_enter = function(this, player, context)
|
||||
if not context._itemstack_quiver then
|
||||
context._itemstack_quiver = player:get_inventory():get_stack('x_bows:quiver_inv', 1)
|
||||
end
|
||||
|
||||
if context._itemstack_quiver and not context._itemstack_quiver:is_empty() then
|
||||
local st_meta = context._itemstack_quiver:get_meta()
|
||||
local quiver_id = st_meta:get_string('quiver_id')
|
||||
|
||||
self:get_or_create_detached_inv(
|
||||
quiver_id,
|
||||
player:get_player_name(),
|
||||
st_meta:get_string('quiver_items')
|
||||
)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info)
|
||||
---arrow inventory
|
||||
if action == 'move' and inventory_info.to_list == 'x_bows:arrow_inv' then
|
||||
local stack = inventory:get_stack(inventory_info.from_list, inventory_info.from_index)
|
||||
|
||||
if minetest.get_item_group(stack:get_name(), 'arrow') ~= 0 then
|
||||
return inventory_info.count
|
||||
else
|
||||
return 0
|
||||
end
|
||||
elseif action == 'move' and inventory_info.from_list == 'x_bows:arrow_inv' then
|
||||
local stack = inventory:get_stack(inventory_info.from_list, inventory_info.from_index)
|
||||
|
||||
if minetest.get_item_group(stack:get_name(), 'arrow') ~= 0 then
|
||||
return inventory_info.count
|
||||
else
|
||||
return 0
|
||||
end
|
||||
elseif action == 'put' and inventory_info.listname == 'x_bows:arrow_inv' then
|
||||
if minetest.get_item_group(inventory_info.stack:get_name(), 'arrow') ~= 0 then
|
||||
return inventory_info.stack:get_count()
|
||||
else
|
||||
return 0
|
||||
end
|
||||
elseif action == 'take' and inventory_info.listname == 'x_bows:arrow_inv' then
|
||||
if minetest.get_item_group(inventory_info.stack:get_name(), 'arrow') ~= 0 then
|
||||
return inventory_info.stack:get_count()
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
---quiver inventory
|
||||
if action == 'move' and inventory_info.to_list == 'x_bows:quiver_inv' then
|
||||
local stack = inventory:get_stack(inventory_info.from_list, inventory_info.from_index)
|
||||
if minetest.get_item_group(stack:get_name(), 'quiver') ~= 0 then
|
||||
return inventory_info.count
|
||||
else
|
||||
return 0
|
||||
end
|
||||
elseif action == 'move' and inventory_info.from_list == 'x_bows:quiver_inv' then
|
||||
local stack = inventory:get_stack(inventory_info.from_list, inventory_info.from_index)
|
||||
if minetest.get_item_group(stack:get_name(), 'quiver') ~= 0 then
|
||||
return inventory_info.count
|
||||
else
|
||||
return 0
|
||||
end
|
||||
elseif action == 'put' and inventory_info.listname == 'x_bows:quiver_inv' then
|
||||
if minetest.get_item_group(inventory_info.stack:get_name(), 'quiver') ~= 0 then
|
||||
return inventory_info.stack:get_count()
|
||||
else
|
||||
return 0
|
||||
end
|
||||
elseif action == 'take' and inventory_info.listname == 'x_bows:quiver_inv' then
|
||||
if minetest.get_item_group(inventory_info.stack:get_name(), 'quiver') ~= 0 then
|
||||
return inventory_info.stack:get_count()
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
return inventory_info.count or inventory_info.stack:get_count()
|
||||
end)
|
||||
|
||||
minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info)
|
||||
---arrow
|
||||
if action == 'move' and inventory_info.to_list == 'x_bows:arrow_inv' then
|
||||
local stack = inventory:get_stack(inventory_info.to_list, inventory_info.to_index)
|
||||
local context = sfinv.get_or_create_context(player)
|
||||
context._itemstack_arrow = stack
|
||||
sfinv.set_context(player, context)
|
||||
sfinv.set_player_inventory_formspec(player)
|
||||
elseif action == 'move' and inventory_info.from_list == 'x_bows:arrow_inv' then
|
||||
local stack = inventory:get_stack(inventory_info.from_list, inventory_info.from_index)
|
||||
local context = sfinv.get_or_create_context(player)
|
||||
|
||||
context._itemstack_arrow = stack
|
||||
sfinv.set_context(player, context)
|
||||
sfinv.set_player_inventory_formspec(player)
|
||||
elseif action == 'put' and inventory_info.listname == 'x_bows:arrow_inv' then
|
||||
local context = sfinv.get_or_create_context(player)
|
||||
|
||||
context._itemstack_arrow = inventory_info.stack
|
||||
sfinv.set_context(player, context)
|
||||
sfinv.set_player_inventory_formspec(player)
|
||||
elseif action == 'take' and inventory_info.listname == 'x_bows:arrow_inv' then
|
||||
local context = sfinv.get_or_create_context(player)
|
||||
context._itemstack_arrow = nil
|
||||
sfinv.set_context(player, context)
|
||||
sfinv.set_player_inventory_formspec(player)
|
||||
end
|
||||
|
||||
---quiver
|
||||
if action == 'move' and inventory_info.to_list == 'x_bows:quiver_inv' then
|
||||
local stack = inventory:get_stack(inventory_info.to_list, inventory_info.to_index)
|
||||
local context = sfinv.get_or_create_context(player)
|
||||
local st_meta = stack:get_meta()
|
||||
local player_name = player:get_player_name()
|
||||
local quiver_id = st_meta:get_string('quiver_id')
|
||||
|
||||
if quiver_id == '' then
|
||||
quiver_id = stack:get_name()..'_'..uuid()
|
||||
st_meta:set_string('quiver_id', quiver_id)
|
||||
inventory:set_stack(inventory_info.to_list, inventory_info.to_index, stack)
|
||||
end
|
||||
|
||||
self:get_or_create_detached_inv(
|
||||
quiver_id,
|
||||
player_name,
|
||||
st_meta:get_string('quiver_items')
|
||||
)
|
||||
|
||||
context._itemstack_quiver = stack
|
||||
sfinv.set_context(player, context)
|
||||
sfinv.set_player_inventory_formspec(player)
|
||||
elseif action == 'move' and inventory_info.from_list == 'x_bows:quiver_inv' then
|
||||
local stack = inventory:get_stack(inventory_info.from_list, inventory_info.from_index)
|
||||
local context = sfinv.get_or_create_context(player)
|
||||
|
||||
context._itemstack_quiver = stack
|
||||
sfinv.set_context(player, context)
|
||||
sfinv.set_player_inventory_formspec(player)
|
||||
elseif action == 'put' and inventory_info.listname == 'x_bows:quiver_inv' then
|
||||
local context = sfinv.get_or_create_context(player)
|
||||
|
||||
if minetest.get_item_group(inventory_info.stack:get_name(), 'quiver') ~= 0 then
|
||||
context._itemstack_quiver = inventory_info.stack
|
||||
sfinv.set_context(player, context)
|
||||
sfinv.set_player_inventory_formspec(player)
|
||||
end
|
||||
elseif action == 'take' and inventory_info.listname == 'x_bows:quiver_inv' then
|
||||
local context = sfinv.get_or_create_context(player)
|
||||
context._itemstack_quiver = nil
|
||||
sfinv.set_context(player, context)
|
||||
sfinv.set_player_inventory_formspec(player)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
|
11
init.lua
11
init.lua
|
@ -5,6 +5,7 @@ minetest = minetest--[[@as Minetest]]
|
|||
ItemStack = ItemStack--[[@as ItemStack]]
|
||||
vector = vector--[[@as Vector]]
|
||||
default = default--[[@as MtgDefault]]
|
||||
sfinv = sfinv--[[@as Sfinv]]
|
||||
|
||||
math.randomseed(tonumber(tostring(os.time()):reverse():sub(1, 9))--[[@as number]])
|
||||
|
||||
|
@ -19,6 +20,16 @@ dofile(path .. '/arrow.lua')
|
|||
dofile(path .. '/items.lua')
|
||||
dofile(path .. '/quiver.lua')
|
||||
|
||||
XBowsQuiver:sfinv_register_page()
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local inv_quiver = player:get_inventory()--[[@as InvRef]]
|
||||
local inv_arrow = player:get_inventory()--[[@as InvRef]]
|
||||
|
||||
inv_quiver:set_size('x_bows:quiver_inv', 1 * 1)
|
||||
inv_arrow:set_size('x_bows:arrow_inv', 1 * 1)
|
||||
end)
|
||||
|
||||
---backwards compatibility
|
||||
minetest.register_alias('x_bows:arrow_diamond_tipped_poison', 'x_bows:arrow_diamond')
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 119 B |
|
@ -70,6 +70,9 @@
|
|||
---@field dir_to_wallmounted fun(dir: Vector): number Convert a vector to a wallmounted value, used for `paramtype2="wallmounted"`
|
||||
---@field item_place_node fun(itemstack: ItemStack, placer: ObjectRef, pointed_thing: PointedThingDef, param2?: , prevent_after_place?: boolean): Vector|nil Place item as a node, `param2` overrides `facedir` and wallmounted `param2`, `prevent_after_place`: if set to `true`, `after_place_node` is not called or the newly placed node to prevent a callback and placement loop. returns `itemstack, position`, `position`: the location the node was placed to. `nil` if nothing was placed.
|
||||
---@field unregister_item fun(name: string): nil Unregisters the item from the engine, and deletes the entry with key `name` from `minetest.registered_items` and from the associated item table according to its nature: `minetest.registered_nodes`, etc.
|
||||
---@field register_allow_player_inventory_action fun(func: fun(player: ObjectRef, action: string, inventory: InvRef, inventory_info: {["from_list"]: string, ["to_list"]: string, ["from_index"]: number, ["to_index"]: number, ["count"]: number} | {["listname"]: string, ["index"]: number, ["stack"]: ItemStack}): number): nil Determines how much of a stack may be taken, put or moved to a player inventory. `player` (type `ObjectRef`) is the player who modified the inventory, `inventory` (type `InvRef`). List of possible `action` (string) values and their `inventory_info` (table) contents: `move`: `{from_list=string, to_list=string, from_index=number, to_index=number, count=number}`, `put`: `{listname=string, index=number, stack=ItemStack}`, `take`: Same as `put`. Return a numeric value to limit the amount of items to be taken, put or moved. A value of `-1` for `take` will make the source stack infinite.
|
||||
---@field register_on_player_inventory_action fun(func: fun(player: ObjectRef, action: string, inventory: InvRef, inventory_info: {["from_list"]: string, ["to_list"]: string, ["from_index"]: number, ["to_index"]: number, ["count"]: number} | {["listname"]: string, ["index"]: number, ["stack"]: ItemStack}): nil): nil Called after a take, put or move event from/to/in a player inventory. Function arguments: see `minetest.register_allow_player_inventory_action`. Does not accept or handle any return value.
|
||||
---@field formspec_escape fun(str: string): string returns a string, escapes the characters "[", "]", "\", "," and ";", which can not be used in formspecs.
|
||||
|
||||
---Minetest settings
|
||||
---@class MinetestSettings
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
---Sfinv API
|
||||
---@class Sfinv
|
||||
---@field register_page fun(name: string, def: SfinvDef): nil Register a page
|
||||
---@field make_formspec fun(player: ObjectRef, contex: SfinvContext, content: string, show_inv?: boolean, size?: string): nil Adds a theme to a formspec show_inv, defaults to false. Whether to show the player's main inventory size, defaults to `size[8,8.6]` if not specified
|
||||
---@field get_or_create_context fun(player: ObjectRef): SfinvContext Gets the player's context
|
||||
---@field set_context fun(player: ObjectRef, context: SfinvContext): nil
|
||||
---@field get_formspec fun(player: ObjectRef, context: SfinvContext): string Builds current page's formspec
|
||||
---@field set_player_inventory_formspec fun(player: ObjectRef): string (re)builds page formspec and calls set_inventory_formspec().
|
||||
|
||||
|
||||
---Sfinv Definition
|
||||
---@class SfinvDef
|
||||
---@field title string Human readable page name (required)
|
||||
---@field get fun(self: Sfinv, player: ObjectRef, context: SfinvContext): string Returns a formspec string. See formspec variables. (required)
|
||||
---@field is_in_nav fun(self: Sfinv, player: ObjectRef, context: SfinvContext): boolean Return true to show in the navigation (the tab header, by default)
|
||||
---@field on_player_receive_fields fun(self: Sfinv, player: ObjectRef, context: SfinvContext, fields: table): nil On formspec submit.
|
||||
---@field on_enter fun(self: Sfinv, player: ObjectRef, context: SfinvContext): nil Called when the player changes pages, usually using the tabs.
|
||||
---@field on_leave fun(self: Sfinv, player: ObjectRef, context: SfinvContext): nil When leaving this page to go to another, called before other's on_enter
|
||||
|
||||
---Sfinv Context, including: any thing you want to store, sfinv will clear the stored data on log out / log in
|
||||
---@class SfinvContext
|
||||
---@field page string Current page name
|
||||
---@field nav string[] A list of page names
|
||||
---@field nav_titles string[] A list of page titles
|
||||
---@field nav_idx number Current nav index (in nav and nav_titles)
|
|
@ -107,6 +107,7 @@
|
|||
---@field on_hit_entity fun(self: table, pointed_thing_ref: table)
|
||||
---@field on_hit_player fun(self: table, pointed_thing_ref: table)
|
||||
---@field on_after_activate fun(self: table)
|
||||
---@field description_abilities string
|
||||
|
||||
|
||||
---Custom field in ItemDef
|
||||
|
|
Ŝarĝante…
Reference in New Issue