mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge #5802
5802: Running, sitting and AFK anim. states r=def- a=VoxelDoesCode Added in two more animation states, for running at a fast enough speed and for when you're AFK. Both of these states are bi-directional, and actually mirror very well inside the code. The running animation I feel like gives a better explanation for how fast you're going, and stopping now would result in skidding. Old run cycle, which is just really fast walk: https://user-images.githubusercontent.com/95713843/188262126-a2f63f92-88b5-408e-a1dd-af9288541c54.mp4 New run cycle: https://user-images.githubusercontent.com/95713843/188262128-d7734eb7-fd43-4a6d-8605-c76b78ac759b.mp4 An AFK tee will also sit down and put its weapon behind its back; if not firing it. Very fitting with the many chairs and tables in maps. ![unknown](https://user-images.githubusercontent.com/95713843/188262188-1b6591a6-7a88-4fd3-8c25-fb150a28ed0f.png) ## Checklist - [x] Tested the change ingame - [x] Provided screenshots if it is a visual change - [ ] Tested in combination with possibly related configuration options - [ ] Written a unit test (especially base/) or added coverage to integration test - [ ] Considered possible null pointers and out of bounds array indexing - [x] Changed no physics that affect existing maps - [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional) Co-authored-by: VoxelDoesCode <bluheadcat@gmail.com>
This commit is contained in:
commit
b3f8e37dc6
|
@ -466,6 +466,18 @@ anim.back_foot.frames.Add(AnimKeyframe(0, -3, 0, -0.1))
|
|||
anim.front_foot.frames.Add(AnimKeyframe(0, 3, 0, -0.1))
|
||||
container.animations.Add(anim)
|
||||
|
||||
anim = Animation("sit_left")
|
||||
anim.body.frames.Add(AnimKeyframe(0, 0, 3, 0))
|
||||
anim.back_foot.frames.Add(AnimKeyframe(0, -12, 0, 0.1))
|
||||
anim.front_foot.frames.Add(AnimKeyframe(0, -8, 0, 0.1))
|
||||
container.animations.Add(anim)
|
||||
|
||||
anim = Animation("sit_right")
|
||||
anim.body.frames.Add(AnimKeyframe(0, 0, 3, 0))
|
||||
anim.back_foot.frames.Add(AnimKeyframe(0, 12, 0, -0.1))
|
||||
anim.front_foot.frames.Add(AnimKeyframe(0, 8, 0, -0.1))
|
||||
container.animations.Add(anim)
|
||||
|
||||
anim = Animation("walk")
|
||||
anim.body.frames.Add(AnimKeyframe(0.0, 0, 0, 0))
|
||||
anim.body.frames.Add(AnimKeyframe(0.2, 0,-1, 0))
|
||||
|
@ -489,6 +501,52 @@ anim.front_foot.frames.Add(AnimKeyframe(0.8, 8, 0, 0))
|
|||
anim.front_foot.frames.Add(AnimKeyframe(1.0,-10,-4, 0.2))
|
||||
container.animations.Add(anim)
|
||||
|
||||
anim = Animation("run_left")
|
||||
anim.body.frames.Add(AnimKeyframe(0.0, 0, -2, 0))
|
||||
anim.body.frames.Add(AnimKeyframe(0.2, 0, 0, 0))
|
||||
anim.body.frames.Add(AnimKeyframe(0.4, 0, 0, 0))
|
||||
anim.body.frames.Add(AnimKeyframe(0.6, 0, -2, 0))
|
||||
anim.body.frames.Add(AnimKeyframe(0.8, 0, 0, 0))
|
||||
anim.body.frames.Add(AnimKeyframe(1.0, 0, -2, 0))
|
||||
|
||||
anim.back_foot.frames.Add(AnimKeyframe(0.0, 18, -11, -0.27))
|
||||
anim.back_foot.frames.Add(AnimKeyframe(0.2, 6, 0, 0))
|
||||
anim.back_foot.frames.Add(AnimKeyframe(0.4, -7, 0, 0))
|
||||
anim.back_foot.frames.Add(AnimKeyframe(0.6, -13, -4.5, 0.05))
|
||||
anim.back_foot.frames.Add(AnimKeyframe(0.8, 0, -11, -0.2))
|
||||
anim.back_foot.frames.Add(AnimKeyframe(1.0, 18, -11, -0.27))
|
||||
|
||||
anim.front_foot.frames.Add(AnimKeyframe(0.0, -13, -4.5, 0.05))
|
||||
anim.front_foot.frames.Add(AnimKeyframe(0.2, -14, -7, 0.1))
|
||||
anim.front_foot.frames.Add(AnimKeyframe(0.4, 11, -13, -0.3))
|
||||
anim.front_foot.frames.Add(AnimKeyframe(0.6, 18, -11, -0.27))
|
||||
anim.front_foot.frames.Add(AnimKeyframe(0.8, 3, 0, -0.02))
|
||||
anim.front_foot.frames.Add(AnimKeyframe(1.0, -13, -4.5, 0.05))
|
||||
container.animations.Add(anim)
|
||||
|
||||
anim = Animation("run_right")
|
||||
anim.body.frames.Add(AnimKeyframe(0.0, 0, -2, 0))
|
||||
anim.body.frames.Add(AnimKeyframe(0.2, 0, 0, 0))
|
||||
anim.body.frames.Add(AnimKeyframe(0.4, 0, -2, 0))
|
||||
anim.body.frames.Add(AnimKeyframe(0.6, 0, 0, 0))
|
||||
anim.body.frames.Add(AnimKeyframe(0.8, 0, 0, 0))
|
||||
anim.body.frames.Add(AnimKeyframe(1.0, 0, -2, 0))
|
||||
|
||||
anim.back_foot.frames.Add(AnimKeyframe(0.0, -18, -11, 0.27))
|
||||
anim.back_foot.frames.Add(AnimKeyframe(0.2, 0, -11, 0.2))
|
||||
anim.back_foot.frames.Add(AnimKeyframe(0.4, 13, -4.5, -0.05))
|
||||
anim.back_foot.frames.Add(AnimKeyframe(0.6, 7, 0, 0))
|
||||
anim.back_foot.frames.Add(AnimKeyframe(0.8, -6, 0, 0))
|
||||
anim.back_foot.frames.Add(AnimKeyframe(1.0, -18, -11, 0.27))
|
||||
|
||||
anim.front_foot.frames.Add(AnimKeyframe(0.0, 13, -4.5, -0.05))
|
||||
anim.front_foot.frames.Add(AnimKeyframe(0.2, -3, 0, 0.02))
|
||||
anim.front_foot.frames.Add(AnimKeyframe(0.4, -18, -11, 0.27))
|
||||
anim.front_foot.frames.Add(AnimKeyframe(0.6, -11, -13, 0.3))
|
||||
anim.front_foot.frames.Add(AnimKeyframe(0.8, 14, -7, -0.1))
|
||||
anim.front_foot.frames.Add(AnimKeyframe(1.0, 13, -4.5, -0.05))
|
||||
container.animations.Add(anim)
|
||||
|
||||
anim = Animation("hammer_swing")
|
||||
anim.attach.frames.Add(AnimKeyframe(0.0, 0, 0, -0.10))
|
||||
anim.attach.frames.Add(AnimKeyframe(0.3, 0, 0, 0.25))
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <engine/demo.h>
|
||||
#include <engine/graphics.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include <game/gamecore.h>
|
||||
#include <game/generated/client_data.h>
|
||||
#include <game/generated/protocol.h>
|
||||
|
||||
|
@ -22,6 +23,7 @@
|
|||
#include "players.h"
|
||||
|
||||
#include <base/color.h>
|
||||
#include <base/math.h>
|
||||
|
||||
void CPlayers::RenderHand(CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float AngleOffset, vec2 PostRotOffset, float Alpha)
|
||||
{
|
||||
|
@ -408,26 +410,46 @@ void CPlayers::RenderPlayer(
|
|||
|
||||
RenderInfo.m_GotAirJump = Player.m_Jumped & 2 ? 0 : 1;
|
||||
|
||||
RenderInfo.m_FeetFlipped = false;
|
||||
|
||||
bool Stationary = Player.m_VelX <= 1 && Player.m_VelX >= -1;
|
||||
bool InAir = !Collision()->CheckPoint(Player.m_X, Player.m_Y + 16);
|
||||
bool Running = Player.m_VelX >= 5000 || Player.m_VelX <= -5000;
|
||||
bool WantOtherDir = (Player.m_Direction == -1 && Vel.x > 0) || (Player.m_Direction == 1 && Vel.x < 0);
|
||||
bool Inactive = m_pClient->m_aClients[ClientID].m_Afk || m_pClient->m_aClients[ClientID].m_Paused;
|
||||
|
||||
// evaluate animation
|
||||
float WalkTime = fmod(Position.x, 100.0f) / 100.0f;
|
||||
if(WalkTime < 0)
|
||||
{
|
||||
float RunTime = fmod(Position.x, 250.0f) / 250.0f;
|
||||
|
||||
// Don't do a moon walk outside the left border
|
||||
if(WalkTime < 0)
|
||||
WalkTime += 1;
|
||||
}
|
||||
if(RunTime < 0)
|
||||
RunTime += 1;
|
||||
|
||||
CAnimState State;
|
||||
State.Set(&g_pData->m_aAnimations[ANIM_BASE], 0);
|
||||
|
||||
if(InAir)
|
||||
State.Add(&g_pData->m_aAnimations[ANIM_INAIR], 0, 1.0f); // TODO: some sort of time here
|
||||
else if(Stationary)
|
||||
{
|
||||
if(Inactive)
|
||||
{
|
||||
State.Add(Direction.x < 0 ? &g_pData->m_aAnimations[ANIM_SIT_LEFT] : &g_pData->m_aAnimations[ANIM_SIT_RIGHT], 0, 1.0f); // TODO: some sort of time here
|
||||
RenderInfo.m_FeetFlipped = true;
|
||||
}
|
||||
else
|
||||
State.Add(&g_pData->m_aAnimations[ANIM_IDLE], 0, 1.0f); // TODO: some sort of time here
|
||||
}
|
||||
else if(!WantOtherDir)
|
||||
{
|
||||
if(Running)
|
||||
State.Add(Player.m_VelX < 0 ? &g_pData->m_aAnimations[ANIM_RUN_LEFT] : &g_pData->m_aAnimations[ANIM_RUN_RIGHT], RunTime, 1.0f);
|
||||
else
|
||||
State.Add(&g_pData->m_aAnimations[ANIM_WALK], WalkTime, 1.0f);
|
||||
}
|
||||
|
||||
if(Player.m_Weapon == WEAPON_HAMMER)
|
||||
State.Add(&g_pData->m_aAnimations[ANIM_HAMMER_SWING], clamp(LastAttackTime * 5.0f, 0.0f, 1.0f), 1.0f);
|
||||
|
@ -470,27 +492,37 @@ void CPlayers::RenderPlayer(
|
|||
vec2 Dir = Direction;
|
||||
float Recoil = 0.0f;
|
||||
vec2 WeaponPosition;
|
||||
bool IsSit = Inactive && !InAir && Stationary;
|
||||
|
||||
if(Player.m_Weapon == WEAPON_HAMMER)
|
||||
{
|
||||
// Static position for hammer
|
||||
// static position for hammer
|
||||
WeaponPosition = Position + vec2(State.GetAttach()->m_X, State.GetAttach()->m_Y);
|
||||
WeaponPosition.y += g_pData->m_Weapons.m_aId[CurrentWeapon].m_Offsety;
|
||||
// if attack is under way, bash stuffs
|
||||
if(Direction.x < 0)
|
||||
{
|
||||
Graphics()->QuadsSetRotation(-pi / 2 - State.GetAttach()->m_Angle * pi * 2);
|
||||
WeaponPosition.x -= g_pData->m_Weapons.m_aId[CurrentWeapon].m_Offsetx;
|
||||
}
|
||||
else
|
||||
if(IsSit)
|
||||
WeaponPosition.y += 3.0f;
|
||||
|
||||
// if active and attack is under way, bash stuffs
|
||||
if(!Inactive || LastAttackTime < m_pClient->m_aTuning[g_Config.m_ClDummy].GetWeaponFireDelay(Player.m_Weapon))
|
||||
{
|
||||
if(Direction.x < 0)
|
||||
Graphics()->QuadsSetRotation(-pi / 2 - State.GetAttach()->m_Angle * pi * 2);
|
||||
else
|
||||
Graphics()->QuadsSetRotation(-pi / 2 + State.GetAttach()->m_Angle * pi * 2);
|
||||
}
|
||||
else
|
||||
Graphics()->QuadsSetRotation(Direction.x < 0 ? 100.0f : 500.0f);
|
||||
|
||||
Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, WeaponPosition.x, WeaponPosition.y);
|
||||
}
|
||||
else if(Player.m_Weapon == WEAPON_NINJA)
|
||||
{
|
||||
WeaponPosition = Position;
|
||||
WeaponPosition.y += g_pData->m_Weapons.m_aId[CurrentWeapon].m_Offsety;
|
||||
if(IsSit)
|
||||
WeaponPosition.y += 3.0f;
|
||||
|
||||
if(Direction.x < 0)
|
||||
{
|
||||
|
@ -561,6 +593,8 @@ void CPlayers::RenderPlayer(
|
|||
Recoil = sinf(a * pi);
|
||||
WeaponPosition = Position + Dir * g_pData->m_Weapons.m_aId[CurrentWeapon].m_Offsetx - Dir * Recoil * 10.0f;
|
||||
WeaponPosition.y += g_pData->m_Weapons.m_aId[CurrentWeapon].m_Offsety;
|
||||
if(IsSit)
|
||||
WeaponPosition.y += 3.0f;
|
||||
if(Player.m_Weapon == WEAPON_GUN && g_Config.m_ClOldGunPosition)
|
||||
WeaponPosition.y -= 8;
|
||||
Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, WeaponPosition.x, WeaponPosition.y);
|
||||
|
|
|
@ -43,10 +43,18 @@ void CRenderTools::Init(IGraphics *pGraphics, ITextRender *pTextRender)
|
|||
Graphics()->QuadsSetSubset(0, 0, 1, 1);
|
||||
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f);
|
||||
|
||||
// Feet
|
||||
Graphics()->QuadsSetSubset(0, 0, 1, 1);
|
||||
QuadContainerAddSprite(m_TeeQuadContainerIndex, -32.f, -16.f, 64.f, 32.f);
|
||||
Graphics()->QuadsSetSubset(0, 0, 1, 1);
|
||||
QuadContainerAddSprite(m_TeeQuadContainerIndex, -32.f, -16.f, 64.f, 32.f);
|
||||
|
||||
// Mirrored Feet
|
||||
Graphics()->QuadsSetSubsetFree(1, 0, 0, 0, 0, 1, 1, 1);
|
||||
QuadContainerAddSprite(m_TeeQuadContainerIndex, -32.f, -16.f, 64.f, 32.f);
|
||||
Graphics()->QuadsSetSubsetFree(1, 0, 0, 0, 0, 1, 1, 1);
|
||||
QuadContainerAddSprite(m_TeeQuadContainerIndex, -32.f, -16.f, 64.f, 32.f);
|
||||
|
||||
Graphics()->QuadContainerUpload(m_TeeQuadContainerIndex);
|
||||
}
|
||||
|
||||
|
@ -297,6 +305,7 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
|
|||
int QuadOffset = 2;
|
||||
int EyeQuadOffset = 0;
|
||||
int TeeEye = 0;
|
||||
|
||||
switch(Emote)
|
||||
{
|
||||
case EMOTE_PAIN:
|
||||
|
@ -338,6 +347,10 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
|
|||
float h = BaseSize / 2;
|
||||
|
||||
int QuadOffset = 7;
|
||||
if(Dir.x < 0 && pInfo->m_FeetFlipped)
|
||||
{
|
||||
QuadOffset += 2;
|
||||
}
|
||||
|
||||
Graphics()->QuadsSetRotation(pFoot->m_Angle * pi * 2);
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
float m_Size;
|
||||
int m_GotAirJump;
|
||||
int m_TeeRenderFlags;
|
||||
bool m_FeetFlipped;
|
||||
};
|
||||
|
||||
// Tee Render Flags
|
||||
|
|
|
@ -62,6 +62,20 @@ int CTuningParams::PossibleTunings(const char *pStr, IConsole::FPossibleCallback
|
|||
return Index;
|
||||
}
|
||||
|
||||
float CTuningParams::GetWeaponFireDelay(int Weapon) const
|
||||
{
|
||||
switch(Weapon)
|
||||
{
|
||||
case WEAPON_HAMMER: return (float)m_HammerHitFireDelay / 1000.0f;
|
||||
case WEAPON_GUN: return (float)m_GunFireDelay / 1000.0f;
|
||||
case WEAPON_SHOTGUN: return (float)m_ShotgunFireDelay / 1000.0f;
|
||||
case WEAPON_GRENADE: return (float)m_GrenadeFireDelay / 1000.0f;
|
||||
case WEAPON_LASER: return (float)m_LaserFireDelay / 1000.0f;
|
||||
case WEAPON_NINJA: return (float)m_NinjaFireDelay / 1000.0f;
|
||||
default: dbg_assert(false, "invalid weapon"); return 0.0f; // this value should not be reached
|
||||
}
|
||||
}
|
||||
|
||||
float VelocityRamp(float Value, float Start, float Range, float Curvature)
|
||||
{
|
||||
if(Value < Start)
|
||||
|
|
|
@ -66,6 +66,7 @@ public:
|
|||
bool Get(const char *pName, float *pValue) const;
|
||||
static const char *Name(int Index) { return ms_apNames[Index]; }
|
||||
int PossibleTunings(const char *pStr, IConsole::FPossibleCallback pfnCallback = IConsole::EmptyPossibleCommandCallback, void *pUser = nullptr);
|
||||
float GetWeaponFireDelay(int Weapon) const;
|
||||
};
|
||||
|
||||
inline void StrToInts(int *pInts, int Num, const char *pStr)
|
||||
|
|
Loading…
Reference in a new issue