diff --git a/game_api.txt b/game_api.txt index 6a013224..0495b29b 100644 --- a/game_api.txt +++ b/game_api.txt @@ -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 = , y = , collisionbox = model collisionbox, eye_height = model eye height}, + -- [anim_name] = { + -- x = , + -- y = , + -- collisionbox = , -- (optional) + -- eye_height = , -- (optional) + -- -- suspend client side animations while this one is active (optional) + -- override_local = + -- }, stand = ..., lay = ..., walk = ..., mine = ..., walk_mine = ..., -- required animations sit = ... -- used by boats and other MTG mods }, diff --git a/mods/player_api/api.lua b/mods/player_api/api.lua index f341e6ea..d7aab4ed 100644 --- a/mods/player_api/api.lua +++ b/mods/player_api/api.lua @@ -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 diff --git a/mods/player_api/init.lua b/mods/player_api/init.lua index 6bc3c821..f258aea7 100644 --- a/mods/player_api/init.lua +++ b/mods/player_api/init.lua @@ -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,