Player API: Animation-dependent collisionbox and eye_height

Backwards compatible with previous model definition format.
For the Minetest Game player model, this avoids dead players having
obstructive tall collision and selection boxes.
This commit is contained in:
paramat 2020-09-25 16:09:24 +01:00
parent dd91a1bfe5
commit fc86bf5a5f
3 changed files with 70 additions and 18 deletions

View file

@ -476,15 +476,48 @@ The player API can register player models and update the player's appearance.
animation_speed = 30, -- Default animation speed, in FPS
textures = {"character.png", }, -- Default array of textures
visual_size = {x = 1, y = 1}, -- Used to scale the model
stepheight = 0.6, -- In nodes
animations = {
-- <anim_name> = {x = <start_frame>, y = <end_frame>},
foo = {x = 0, y = 19},
bar = {x = 20, y = 39},
-- ...
-- The first 5 animations are required by the API
stand = {x = 0, y = 79},
lay = {x = 162, y = 166},
walk = {x = 168, y = 187},
mine = {x = 189, y = 198},
walk_mine = {x = 200, y = 219},
-- The `sit` animation is only required by other Minetest Game mods
sit = {x = 81, y = 160},
-- More animations can be added
},
collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}, -- In nodes from feet position
stepheight = 0.6, -- In nodes
eye_height = 1.47, -- In nodes above feet position
collisionbox = {
-- Defined for each animation
-- <anim_name> = {<xmin>, <ymin>, <zmin>, <xmax>, <ymax>, <zmax>},
-- Min/max positions are in nodes from feet position
stand = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
walk = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
mine = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
walk_mine = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
lay = {-0.6, 0.0, -0.6, 0.6, 0.3, 0.6},
sit = {-0.3, 0.0, -0.3, 0.3, 1.0, 0.3},
},
eye_height = {
-- Defined for each animation
-- In nodes above feet position
stand = 1.47,
walk = 1.47,
mine = 1.47,
walk_mine = 1.47,
lay = 0.3,
sit = 0.8,
},
}
Alternatively, `collisionbox` and `eye_height` can be defined as single values applied
to all animations:
{
collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
eye_height = 1.47,
}

View file

@ -1,13 +1,10 @@
-- Minetest 0.4 mod: player
-- See README.txt for licensing and other information.
player_api = {}
-- Player animation blending
-- Note: This is currently broken due to a bug in Irrlicht, leave at 0
local animation_blend = 0
player_api.registered_models = { }
player_api.registered_models = {}
-- Local for speed.
local models = player_api.registered_models
@ -40,14 +37,13 @@ function player_api.set_model(player, model_name)
if player_model[name] == model_name then
return
end
-- collisionbox and eye_height are set in set_animation()
player:set_properties({
mesh = model_name,
textures = player_textures[name] or model.textures,
visual = "mesh",
visual_size = model.visual_size or {x = 1, y = 1},
collisionbox = model.collisionbox or {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
stepheight = model.stepheight or 0.6,
eye_height = model.eye_height or 1.47,
})
player_api.set_animation(player, "stand")
else
@ -72,6 +68,7 @@ function player_api.set_textures(player, textures)
end
function player_api.set_animation(player, anim_name, speed)
-- Return if animation already applied to player
local name = player:get_player_name()
if player_anim[name] == anim_name then
return
@ -83,6 +80,17 @@ function player_api.set_animation(player, anim_name, speed)
local anim = model.animations[anim_name]
player_anim[name] = anim_name
player:set_animation(anim, speed or model.animation_speed, animation_blend)
-- Set animation-dependent properties
local eyeh
if type(model.eye_height) == "table" then
eyeh = model.eye_height[anim_name]
else -- number
eyeh = model.eye_height
end
player:set_properties({
collisionbox = model.collisionbox[anim_name] or model.collisionbox,
eye_height = eyeh,
})
end
minetest.register_on_leaveplayer(function(player)

View file

@ -1,13 +1,11 @@
-- player/init.lua
dofile(minetest.get_modpath("player_api") .. "/api.lua")
-- Default player appearance
player_api.register_model("character.b3d", {
animation_speed = 30,
textures = {"character.png"},
stepheight = 0.6,
animations = {
-- Standard animations.
stand = {x = 0, y = 79},
lay = {x = 162, y = 166},
walk = {x = 168, y = 187},
@ -15,9 +13,22 @@ player_api.register_model("character.b3d", {
walk_mine = {x = 200, y = 219},
sit = {x = 81, y = 160},
},
collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
stepheight = 0.6,
eye_height = 1.47,
collisionbox = {
stand = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
walk = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
mine = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
walk_mine = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
lay = {-0.6, 0.0, -0.6, 0.6, 0.3, 0.6},
sit = {-0.3, 0.0, -0.3, 0.3, 1.0, 0.3},
},
eye_height = {
stand = 1.47,
walk = 1.47,
mine = 1.47,
walk_mine = 1.47,
lay = 0.3,
sit = 0.8,
},
})
-- Update appearance when the player joins