Override local_animation settings for certain animations

This makes the lay/sit animation work on the local client (in third-person).
This commit is contained in:
sfan5 2022-01-18 19:18:44 +01:00
parent 6623dec567
commit acc918436a
3 changed files with 42 additions and 15 deletions

@ -462,6 +462,12 @@ The player API can register player models and update the player's appearance.
* `player`: PlayerRef
* `textures`: array of textures. If nil, the default from the model def is used
* `player_api.set_textures(player, index, texture)`
* Sets one of the player textures
* `player`: PlayerRef
* `index`: Index into array of all textures
* `texture`: the texture string
* `player_api.get_animation(player)`
* Returns a table containing fields `model`, `textures` and `animation`
* Any of the fields of the returned table may be nil
@ -480,7 +486,14 @@ The player API can register player models and update the player's appearance.
animation_speed = 30, -- Default animation speed, in keyframes per second
textures = {"character.png"}, -- Default array of textures
animations = {
-- [anim_name] = {x = <start_frame>, y = <end_frame>, collisionbox = model collisionbox, eye_height = model eye height},
-- [anim_name] = {
-- x = <start_frame>,
-- y = <end_frame>,
-- collisionbox = <model collisionbox>, -- (optional)
-- eye_height = <model eye height>, -- (optional)
-- -- suspend client side animations while this one is active (optional)
-- override_local = <true/false>
-- },
stand = ..., lay = ..., walk = ..., mine = ..., walk_mine = ..., -- required animations
sit = ... -- used by boats and other MTG mods
},

@ -33,6 +33,8 @@ function player_api.register_model(name, def)
for animation_name, animation in pairs(def.animations) do
animation.eye_height = animation.eye_height or def.eye_height
animation.collisionbox = animation.collisionbox or def.collisionbox
animation.override_local = animation.override_local or false
for _, other_animation in pairs(def.animations) do
if other_animation._equals then
if collisionbox_equals(animation.collisionbox, other_animation.collisionbox)
@ -65,6 +67,8 @@ function player_api.set_model(player, model_name)
if player_data.model == model_name then
return
end
player_data.model = model_name
local model = models[model_name]
if model then
player:set_properties({
@ -74,15 +78,7 @@ function player_api.set_model(player, model_name)
visual_size = model.visual_size,
stepheight = model.stepheight
})
local animations = model.animations
player:set_local_animation(
animations.stand,
animations.walk,
animations.mine,
animations.walk_mine,
model.animation_speed or 30
)
-- sets collisionbox & eye_height
-- sets local_animation, collisionbox & eye_height
player_api.set_animation(player, "stand")
else
player:set_properties({
@ -94,7 +90,6 @@ function player_api.set_model(player, model_name)
eye_height = 1.625,
})
end
player_data.model = model_name
end
function player_api.get_textures(player)
@ -127,12 +122,29 @@ function player_api.set_animation(player, anim_name, speed)
if player_data.animation == anim_name and player_data.animation_speed == speed then
return
end
local previous_anim_equals = (model.animations[player_data.animation] or {})._equals
local previous_anim = model.animations[player_data.animation] or {}
local anim = model.animations[anim_name]
player_data.animation = anim_name
player_data.animation_speed = speed
-- If necessary change the local animation (only seen by the client of *that* player)
-- `override_local` <=> suspend local animations while this one is active
-- (this is basically a hack, proper engine feature needed...)
if anim.override_local ~= previous_anim.override_local then
if anim.override_local then
local none = {x=0, y=0}
player:set_local_animation(none, none, none, none, 1)
else
local a = model.animations -- (not specific to the animation being set)
player:set_local_animation(
a.stand, a.walk, a.mine, a.walk_mine,
model.animation_speed or 30
)
end
end
-- Set the animation seen by everyone else
player:set_animation(anim, speed, animation_blend)
if anim._equals ~= previous_anim_equals then
-- Update related properties if they changed
if anim._equals ~= previous_anim._equals then
player:set_properties({
collisionbox = anim.collisionbox,
eye_height = anim.eye_height

@ -7,11 +7,13 @@ player_api.register_model("character.b3d", {
animations = {
-- Standard animations.
stand = {x = 0, y = 79},
lay = {x = 162, y = 166, collisionbox = {-0.6, 0.0, -0.6, 0.6, 0.3, 0.6}, eye_height = 0.3},
lay = {x = 162, y = 166, eye_height = 0.3, override_local = true,
collisionbox = {-0.6, 0.0, -0.6, 0.6, 0.3, 0.6}},
walk = {x = 168, y = 187},
mine = {x = 189, y = 198},
walk_mine = {x = 200, y = 219},
sit = {x = 81, y = 160, collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.0, 0.3}, eye_height = 0.8}
sit = {x = 81, y = 160, eye_height = 0.8, override_local = true,
collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.0, 0.3}}
},
collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
stepheight = 0.6,