From fc86bf5a5fa92401b2a376026ab4cb8a0466a55c Mon Sep 17 00:00:00 2001 From: paramat Date: Fri, 25 Sep 2020 16:09:24 +0100 Subject: [PATCH] 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. --- game_api.txt | 45 ++++++++++++++++++++++++++++++++++------ mods/player_api/api.lua | 20 ++++++++++++------ mods/player_api/init.lua | 23 ++++++++++++++------ 3 files changed, 70 insertions(+), 18 deletions(-) diff --git a/game_api.txt b/game_api.txt index bddf7e27..bc0b2dde 100644 --- a/game_api.txt +++ b/game_api.txt @@ -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 = { -- = {x = , y = }, - 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 + -- = {, , , , , }, + -- 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, } diff --git a/mods/player_api/api.lua b/mods/player_api/api.lua index 0aee048e..69b2428f 100644 --- a/mods/player_api/api.lua +++ b/mods/player_api/api.lua @@ -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) diff --git a/mods/player_api/init.lua b/mods/player_api/init.lua index 1176b0ea..be78ed24 100644 --- a/mods/player_api/init.lua +++ b/mods/player_api/init.lua @@ -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