add 3d quiver
This commit is contained in:
parent
b84c0409e8
commit
cf759edfec
|
@ -1,2 +1,4 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
docs/build
|
docs/build
|
||||||
|
*.blend1
|
||||||
|
*.blend2
|
||||||
|
|
|
@ -63,5 +63,8 @@ read_globals = {
|
||||||
"default",
|
"default",
|
||||||
"i3",
|
"i3",
|
||||||
"unified_inventory",
|
"unified_inventory",
|
||||||
"player_api"
|
"player_api",
|
||||||
|
"u_skins",
|
||||||
|
"wardrobe",
|
||||||
|
"3d_armor"
|
||||||
}
|
}
|
||||||
|
|
106
api.lua
106
api.lua
|
@ -32,6 +32,9 @@ XBows = {
|
||||||
player_monoids = minetest.get_modpath('player_monoids'),
|
player_monoids = minetest.get_modpath('player_monoids'),
|
||||||
i3 = minetest.get_modpath('i3'),
|
i3 = minetest.get_modpath('i3'),
|
||||||
unified_inventory = minetest.get_modpath('unified_inventory'),
|
unified_inventory = minetest.get_modpath('unified_inventory'),
|
||||||
|
u_skins = minetest.get_modpath('u_skins'),
|
||||||
|
wardrobe = minetest.get_modpath('wardrobe'),
|
||||||
|
_3d_armor = minetest.get_modpath('3d_armor'),
|
||||||
registered_bows = {},
|
registered_bows = {},
|
||||||
registered_arrows = {},
|
registered_arrows = {},
|
||||||
registered_quivers = {},
|
registered_quivers = {},
|
||||||
|
@ -2157,3 +2160,106 @@ function XBowsQuiver.ui_register_page(self)
|
||||||
tooltip = 'X Bows',
|
tooltip = 'X Bows',
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function XBows.show_3d_quiver(self, player)
|
||||||
|
local p_name = player:get_player_name()
|
||||||
|
local player_textures
|
||||||
|
|
||||||
|
if self._3d_armor then
|
||||||
|
minetest.after(0.1, function()
|
||||||
|
player_textures = {
|
||||||
|
armor.textures[p_name].skin,
|
||||||
|
armor.textures[p_name].armor,
|
||||||
|
armor.textures[p_name].wielditem,
|
||||||
|
'x_bows_quiver_mesh.png'
|
||||||
|
}
|
||||||
|
|
||||||
|
if player_textures then
|
||||||
|
player_api.set_textures(player, player_textures)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
return
|
||||||
|
elseif self.u_skins then
|
||||||
|
local u_skin_texture = u_skins.u_skins[p_name]
|
||||||
|
|
||||||
|
player_textures = {
|
||||||
|
u_skin_texture .. '.png',
|
||||||
|
'x_bows_quiver_mesh.png'
|
||||||
|
}
|
||||||
|
elseif self.wardrobe and wardrobe.playerSkins and wardrobe.playerSkins[p_name] then
|
||||||
|
player_textures = {
|
||||||
|
wardrobe.playerSkins[p_name],
|
||||||
|
'x_bows_quiver_mesh.png'
|
||||||
|
}
|
||||||
|
else
|
||||||
|
local textures = player_api.get_textures(player)
|
||||||
|
|
||||||
|
---cleanup
|
||||||
|
for index, value in ipairs(textures) do
|
||||||
|
if value == 'x_bows_quiver_empty_mesh.png' or value == 'x_bows_quiver_mesh.png' then
|
||||||
|
table.remove(textures, index)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(textures, 'x_bows_quiver_mesh.png')
|
||||||
|
|
||||||
|
player_textures = textures
|
||||||
|
end
|
||||||
|
|
||||||
|
if player_textures then
|
||||||
|
player_api.set_textures(player, player_textures)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function XBows.hide_3d_quiver(self, player)
|
||||||
|
local p_name = player:get_player_name()
|
||||||
|
local player_textures
|
||||||
|
|
||||||
|
if self._3d_armor then
|
||||||
|
minetest.after(0.1, function()
|
||||||
|
player_textures = {
|
||||||
|
armor.textures[p_name].skin,
|
||||||
|
armor.textures[p_name].armor,
|
||||||
|
armor.textures[p_name].wielditem,
|
||||||
|
'x_bows_quiver_empty_mesh.png'
|
||||||
|
}
|
||||||
|
|
||||||
|
if player_textures then
|
||||||
|
player_api.set_textures(player, player_textures)
|
||||||
|
end
|
||||||
|
|
||||||
|
end)
|
||||||
|
|
||||||
|
return
|
||||||
|
elseif self.u_skins then
|
||||||
|
local u_skin_texture = u_skins.u_skins[p_name]
|
||||||
|
|
||||||
|
player_textures = {
|
||||||
|
u_skin_texture .. '.png',
|
||||||
|
'x_bows_quiver_empty_mesh.png'
|
||||||
|
}
|
||||||
|
elseif self.wardrobe and wardrobe.playerSkins and wardrobe.playerSkins[p_name] then
|
||||||
|
player_textures = {
|
||||||
|
wardrobe.playerSkins[p_name],
|
||||||
|
'x_bows_quiver_empty_mesh.png'
|
||||||
|
}
|
||||||
|
else
|
||||||
|
local textures = player_api.get_textures(player)
|
||||||
|
|
||||||
|
---cleanup
|
||||||
|
for index, value in ipairs(textures) do
|
||||||
|
if value == 'x_bows_quiver_mesh.png' or value == 'x_bows_quiver_empty_mesh.png' then
|
||||||
|
table.remove(textures, index)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(textures, 'x_bows_quiver_empty_mesh.png')
|
||||||
|
|
||||||
|
player_textures = textures
|
||||||
|
end
|
||||||
|
|
||||||
|
if player_textures then
|
||||||
|
player_api.set_textures(player, player_textures)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
55
init.lua
55
init.lua
|
@ -6,6 +6,8 @@ ItemStack = ItemStack--[[@as ItemStack]]
|
||||||
vector = vector--[[@as Vector]]
|
vector = vector--[[@as Vector]]
|
||||||
default = default--[[@as MtgDefault]]
|
default = default--[[@as MtgDefault]]
|
||||||
sfinv = sfinv--[[@as Sfinv]]
|
sfinv = sfinv--[[@as Sfinv]]
|
||||||
|
unified_inventory = unified_inventory--[[@as UnifiedInventory]]
|
||||||
|
player_api = player_api--[[@as MtgPlayerApi]]
|
||||||
|
|
||||||
math.randomseed(tonumber(tostring(os.time()):reverse():sub(1, 9))--[[@as number]])
|
math.randomseed(tonumber(tostring(os.time()):reverse():sub(1, 9))--[[@as number]])
|
||||||
|
|
||||||
|
@ -20,7 +22,6 @@ dofile(path .. '/arrow.lua')
|
||||||
dofile(path .. '/items.lua')
|
dofile(path .. '/items.lua')
|
||||||
dofile(path .. '/quiver.lua')
|
dofile(path .. '/quiver.lua')
|
||||||
|
|
||||||
|
|
||||||
if XBows.i3 then
|
if XBows.i3 then
|
||||||
XBowsQuiver:i3_register_page()
|
XBowsQuiver:i3_register_page()
|
||||||
elseif XBows.unified_inventory then
|
elseif XBows.unified_inventory then
|
||||||
|
@ -33,34 +34,48 @@ minetest.register_on_joinplayer(function(player)
|
||||||
local inv_quiver = player:get_inventory()--[[@as InvRef]]
|
local inv_quiver = player:get_inventory()--[[@as InvRef]]
|
||||||
local inv_arrow = player:get_inventory()--[[@as InvRef]]
|
local inv_arrow = player:get_inventory()--[[@as InvRef]]
|
||||||
|
|
||||||
|
if XBows._3d_armor then
|
||||||
|
player_api.set_model(player, 'x_bows_3d_armor_character.b3d')
|
||||||
|
else
|
||||||
|
player_api.set_model(player, 'x_bows_character.b3d')
|
||||||
|
end
|
||||||
|
|
||||||
inv_quiver:set_size('x_bows:quiver_inv', 1 * 1)
|
inv_quiver:set_size('x_bows:quiver_inv', 1 * 1)
|
||||||
inv_arrow:set_size('x_bows:arrow_inv', 1 * 1)
|
inv_arrow:set_size('x_bows:arrow_inv', 1 * 1)
|
||||||
|
|
||||||
local quiver = player:get_inventory():get_stack('x_bows:quiver_inv', 1)
|
local quiver_stack = player:get_inventory():get_stack('x_bows:quiver_inv', 1)
|
||||||
|
|
||||||
if quiver and not quiver:is_empty() then
|
if quiver_stack and not quiver_stack:is_empty() then
|
||||||
local st_meta = quiver:get_meta()
|
local st_meta = quiver_stack:get_meta()
|
||||||
local quiver_id = st_meta:get_string('quiver_id')
|
local quiver_id = st_meta:get_string('quiver_id')
|
||||||
|
|
||||||
|
---create detached inventory
|
||||||
XBowsQuiver:get_or_create_detached_inv(
|
XBowsQuiver:get_or_create_detached_inv(
|
||||||
quiver_id,
|
quiver_id,
|
||||||
player:get_player_name(),
|
player:get_player_name(),
|
||||||
st_meta:get_string('quiver_items')
|
st_meta:get_string('quiver_items')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
---set model textures
|
||||||
|
XBows:show_3d_quiver(player)
|
||||||
|
else
|
||||||
|
---set model textures
|
||||||
|
XBows:hide_3d_quiver(player)
|
||||||
end
|
end
|
||||||
|
|
||||||
player_api.set_model(player, 'x_bows_character.b3d')
|
XBows:reset_charged_bow(player, true)
|
||||||
|
XBowsQuiver:close_quiver(player)
|
||||||
player_api.set_textures(player, {
|
|
||||||
'character.png',
|
|
||||||
'x_bows_quiver_mesh.png'
|
|
||||||
})
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
---player api
|
local model_name = 'x_bows_character.b3d'
|
||||||
player_api.register_model('x_bows_character.b3d', {
|
if XBows._3d_armor then
|
||||||
|
---3d armor
|
||||||
|
model_name = 'x_bows_3d_armor_character.b3d'
|
||||||
|
end
|
||||||
|
|
||||||
|
player_api.register_model(model_name, {
|
||||||
animation_speed = 30,
|
animation_speed = 30,
|
||||||
textures = {"character.png"},
|
textures = {'character.png'},
|
||||||
animations = {
|
animations = {
|
||||||
-- Standard animations.
|
-- Standard animations.
|
||||||
stand = {x = 0, y = 79},
|
stand = {x = 0, y = 79},
|
||||||
|
@ -206,7 +221,11 @@ minetest.register_on_player_inventory_action(function(player, action, inventory,
|
||||||
sfinv.set_player_inventory_formspec(player)
|
sfinv.set_player_inventory_formspec(player)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---set player visual
|
||||||
|
XBows:show_3d_quiver(player)
|
||||||
elseif action == 'move' and inventory_info.from_list == 'x_bows:quiver_inv' then
|
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 XBows.i3 then
|
if XBows.i3 then
|
||||||
i3.set_fs(player)
|
i3.set_fs(player)
|
||||||
elseif XBows.unified_inventory then
|
elseif XBows.unified_inventory then
|
||||||
|
@ -214,6 +233,11 @@ minetest.register_on_player_inventory_action(function(player, action, inventory,
|
||||||
else
|
else
|
||||||
sfinv.set_player_inventory_formspec(player)
|
sfinv.set_player_inventory_formspec(player)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---set player visual
|
||||||
|
if stack:is_empty() then
|
||||||
|
XBows:hide_3d_quiver(player)
|
||||||
|
end
|
||||||
elseif action == 'put' and inventory_info.listname == 'x_bows:quiver_inv' then
|
elseif action == 'put' and inventory_info.listname == 'x_bows:quiver_inv' then
|
||||||
if XBows.i3 then
|
if XBows.i3 then
|
||||||
i3.set_fs(player)
|
i3.set_fs(player)
|
||||||
|
@ -236,11 +260,6 @@ end)
|
||||||
---backwards compatibility
|
---backwards compatibility
|
||||||
minetest.register_alias('x_bows:arrow_diamond_tipped_poison', 'x_bows:arrow_diamond')
|
minetest.register_alias('x_bows:arrow_diamond_tipped_poison', 'x_bows:arrow_diamond')
|
||||||
|
|
||||||
minetest.register_on_joinplayer(function(player)
|
|
||||||
XBows:reset_charged_bow(player, true)
|
|
||||||
XBowsQuiver:close_quiver(player)
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- sneak, fov adjustments when bow is charged
|
-- sneak, fov adjustments when bow is charged
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
bow_charged_timer = bow_charged_timer + dtime
|
bow_charged_timer = bow_charged_timer + dtime
|
||||||
|
|
2
mod.conf
2
mod.conf
|
@ -1,6 +1,6 @@
|
||||||
name = x_bows
|
name = x_bows
|
||||||
description = Adds bow and arrows to Minetest.
|
description = Adds bow and arrows to Minetest.
|
||||||
depends =
|
depends =
|
||||||
optional_depends = default, farming, 3d_armor, mesecons, playerphysics, player_monoids, wool, i3, unified_inventory
|
optional_depends = default, farming, 3d_armor, mesecons, playerphysics, player_monoids, wool, i3, unified_inventory, simple_skins, u_skins, wardrobe
|
||||||
supported_games = minetest_game
|
supported_games = minetest_game
|
||||||
min_minetest_version = 5.4
|
min_minetest_version = 5.4
|
||||||
|
|
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.
After Width: | Height: | Size: 70 B |
|
@ -0,0 +1,32 @@
|
||||||
|
---The player API can register player models and update the player's appearance.
|
||||||
|
---@class MtgPlayerApi
|
||||||
|
---@field globalstep fun(dtime: number, ...): nil The function called by the globalstep that controls player animations. You can override this to replace the globalstep with your own implementation. Receives all args that minetest.register_globalstep() passes
|
||||||
|
---@field register_model fun(name: string, def: MtgPlayerApiModelDef): nil Register a new model to be used by players, `name`: model filename such as "character.x", "foo.b3d", etc., `def`: see [#Model definition] Saved to player_api.registered_models
|
||||||
|
---@field registered_models string[] Get a model's definition, `name`: model filename See [#Model definition]
|
||||||
|
---@field set_model fun(player: ObjectRef, model_name: string): nil Change a player's model, `player`: PlayerRef, `model_name`: model registered with `player_api.register_model`
|
||||||
|
---@field set_animation fun(player: ObjectRef, anim_name: string, speed: number): nil Applies an animation to a player if speed or anim_name differ from the currently playing animation, `player`: PlayerRef, `anim_name`: name of the animation, `speed`: keyframes per second. If nil, the default from the model def is used
|
||||||
|
---@field set_textures fun(player: ObjectRef, textures: string[]): nil Sets player textures `player`: PlayerRef, `textures`: array of textures. If nil, the default from the model def is used
|
||||||
|
---@field set_texture fun(player: ObjectRef, index: number, texture: string): nil Sets one of the player textures, `player`: PlayerRef, `index`: Index into array of all textures, `texture`: the texture string
|
||||||
|
---@field get_textures fun(player: ObjectRef): string[] Returns player textures table
|
||||||
|
---@field get_animation fun(player: ObjectRef): {["model"]: string | nil, ["textures"]: string[] | nil, ["animation"]: table | nil} Returns a table containing fields `model`, `textures` and `animation`. Any of the fields of the returned table may be nil, `player`: PlayerRef
|
||||||
|
---@field player_attached table<string, boolean> A table that maps a player name to a boolean. If the value for a given player is set to true, the default player animations (walking, digging, ...) will no longer be updated, and knockback from damage is prevented for that player. Example of usage: A mod sets a player's value to true when attached to a vehicle.
|
||||||
|
|
||||||
|
|
||||||
|
---Model Definition
|
||||||
|
---@class MtgPlayerApiModelDef
|
||||||
|
---@field animation_speed number Default: 30, animation speed, in keyframes per second
|
||||||
|
---@field textures string[] Default `{"character.png"}`, array of textures
|
||||||
|
---@field animations table<string, MtgPlayerApiAnimationDef>
|
||||||
|
---@field visual_size {["x"]: number, ["y"]: number}
|
||||||
|
---@field collisionbox number[]
|
||||||
|
---@field stepheight number
|
||||||
|
---@field eye_height number
|
||||||
|
|
||||||
|
|
||||||
|
---Model Animation definition
|
||||||
|
---@class MtgPlayerApiAnimationDef
|
||||||
|
---@field x number start frame
|
||||||
|
---@field y number end frame
|
||||||
|
---@field collisionbox number[] | nil
|
||||||
|
---@field eye_height number | nil model eye height
|
||||||
|
---@field override_local boolean | nil suspend client side animations while this one is active (optional)
|
|
@ -0,0 +1,7 @@
|
||||||
|
---Base class Unified Inventory
|
||||||
|
---@class UnifiedInventory
|
||||||
|
---@field set_inventory_formspec fun(player: ObjectRef, formspecname: string): nil
|
||||||
|
---@field register_button fun(name: string, def: table): nil
|
||||||
|
---@field single_slot fun(x: number, y: number): nil
|
||||||
|
---@field register_page fun(name: string, def: table): nil
|
||||||
|
---@field style_full table
|
Ŝarĝante…
Reference in New Issue