Files
2026-05-23 14:19:48 -07:00

913 lines
23 KiB
C++

// Player_Anim.cpp
//
#include "precompiled.h"
#pragma hdrstop
#include "Game_local.h"
/*
================
idPlayer::Torso_Idle
================
*/
stateResult_t idPlayer::Torso_Idle(stateParms_t* parms) {
if (SRESULT_WAIT == Torso_IdleThink(parms)) {
Event_PlayCycle(ANIMCHANNEL_TORSO, "idle", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_TORSO, "Torso_IdleThink", /* parms->blendFrames */ 0);
}
return SRESULT_DONE;
}
/*
================
idPlayer::Torso_IdleThink
================
*/
stateResult_t idPlayer::Torso_IdleThink(stateParms_t* parms) {
if (AI_TELEPORT) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Teleport", 0);
return SRESULT_DONE;
}
if (AI_WEAPON_FIRED) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Fire", 0);
return SRESULT_DONE;
}
//if (AI_ATTACK_HELD && weapon && weapon->wfl.hasWindupAnim) {
// PostAnimState(ANIMCHANNEL_TORSO, "Torso_Fire_Windup", 0);
// return SRESULT_DONE;
//}
if (AI_ATTACK_HELD && HasAnim(ANIMCHANNEL_TORSO, "startfire", false)) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Fire_StartFire", 2);
return SRESULT_DONE;
}
if (AI_PAIN) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Pain", 0);
return SRESULT_DONE;
}
//if (emote != PE_NONE) {
// PostAnimState(ANIMCHANNEL_TORSO, "Torso_Emote", 5);
// return SRESULT_DONE;
//}
return SRESULT_WAIT;
}
/*
================
idPlayer::Torso_Teleport
================
*/
stateResult_t idPlayer::Torso_Teleport(stateParms_t* parms) {
enum {
STAGE_INIT,
STAGE_WAIT
};
switch (parms->stage) {
case STAGE_INIT:
AI_TELEPORT = false;
Event_PlayAnim(ANIMCHANNEL_TORSO, "teleport", /* parms->blendFrames */ 0);
SRESULT_STAGE(STAGE_WAIT);
case STAGE_WAIT:
if (AnimDone(ANIMCHANNEL_TORSO, 4)) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Idle", 4);
return SRESULT_DONE;
}
return SRESULT_WAIT;
}
return SRESULT_ERROR;
}
/*
================
idPlayer::Torso_RaiseWeapon
================
*/
stateResult_t idPlayer::Torso_RaiseWeapon(stateParms_t* parms) {
Event_PlayAnim(ANIMCHANNEL_TORSO, "raise", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_TORSO, "Wait_TorsoAnim", 3);
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Idle", 3);
return SRESULT_DONE;
}
/*
================
idPlayer::Torso_LowerWeapon
================
*/
stateResult_t idPlayer::Torso_LowerWeapon(stateParms_t* parms) {
Event_PlayAnim(ANIMCHANNEL_TORSO, "lower", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_TORSO, "Wait_TorsoAnim", 3);
return SRESULT_DONE;
}
/*
================
idPlayer::Torso_Fire
================
*/
stateResult_t idPlayer::Torso_Fire(stateParms_t* parms) {
enum {
TORSO_FIRE_INIT,
TORSO_FIRE_WAIT,
TORSO_FIRE_AIM,
TORSO_FIRE_AIMWAIT
};
switch (parms->stage) {
// Start the firing sequence
case TORSO_FIRE_INIT:
Event_PlayAnim(ANIMCHANNEL_TORSO, "fire", /* parms->blendFrames */ 0);
AI_WEAPON_FIRED = false;
SRESULT_STAGE(TORSO_FIRE_WAIT);
// Wait for the firing animation to be finished
case TORSO_FIRE_WAIT:
if (AI_WEAPON_FIRED) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Fire", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
if (AnimDone(ANIMCHANNEL_TORSO, /* parms->blendFrames */ 0)) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
return SRESULT_WAIT;
// Keep the gun aimed but dont shoot
case TORSO_FIRE_AIM:
Event_PlayAnim(ANIMCHANNEL_TORSO, "aim", 3);
SRESULT_STAGE(TORSO_FIRE_AIMWAIT);
// Keep the gun aimed as long as the attack button is held and nothing is firing
case TORSO_FIRE_AIMWAIT:
if (AI_WEAPON_FIRED) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Fire", 3);
return SRESULT_DONE;
}
else if (!AI_ATTACK_HELD) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
return SRESULT_WAIT;
}
return SRESULT_DONE;
}
/*
================
idPlayer::Torso_Fire_Windup
================
*/
stateResult_t idPlayer::Torso_Fire_Windup(stateParms_t* parms) {
enum {
TORSO_FIRE_INIT,
TORSO_WINDUP_WAIT,
TORSO_FIRE_LOOP,
TORSO_FIRE_WAIT,
TORSO_WINDDOWN_START,
TORSO_WINDDOWN_WAIT,
TORSO_FIRE_AIM,
TORSO_FIRE_AIMWAIT
};
switch (parms->stage) {
// Start the firing sequence
case TORSO_FIRE_INIT:
//jshepard: HACK for now we're blending here, but we need to support charge up anims here
Event_PlayAnim(ANIMCHANNEL_TORSO, "fire", 4);
AI_WEAPON_FIRED = false;
SRESULT_STAGE(TORSO_WINDUP_WAIT);
// wait for the windup anim to end, or the attackHeld to be false.
case TORSO_WINDUP_WAIT:
if (!AI_ATTACK_HELD) {
SRESULT_STAGE(TORSO_WINDDOWN_START);
}
if (AnimDone(ANIMCHANNEL_TORSO, /* parms->blendFrames */ 0)) {
SRESULT_STAGE(TORSO_FIRE_LOOP);
}
return SRESULT_WAIT;
// play the firing loop
case TORSO_FIRE_LOOP:
if (!AI_ATTACK_HELD) {
SRESULT_STAGE(TORSO_WINDDOWN_START);
}
Event_PlayAnim(ANIMCHANNEL_TORSO, "fire", /* parms->blendFrames */ 0);
SRESULT_STAGE(TORSO_FIRE_WAIT);
// loop the fire anim
case TORSO_FIRE_WAIT:
if (!AI_ATTACK_HELD) {
SRESULT_STAGE(TORSO_WINDDOWN_START);
}
//loop the attack anim
if (AnimDone(ANIMCHANNEL_TORSO, /* parms->blendFrames */ 0)) {
Event_PlayAnim(ANIMCHANNEL_TORSO, "fire", /* parms->blendFrames */ 0);
SRESULT_STAGE(TORSO_FIRE_WAIT);
}
return SRESULT_WAIT;
//wind down
case TORSO_WINDDOWN_START:
//jshepard: HACK just blend back into idle for now, we could support winddown anims here.
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Idle", 4);
AI_WEAPON_FIRED = false;
return SRESULT_DONE;
}
return SRESULT_DONE;
}
/*
================
idPlayer::Torso_Reload
================
*/
stateResult_t idPlayer::Torso_Reload(stateParms_t* parms) {
enum {
TORSO_RELOAD_START,
TORSO_RELOAD_STARTWAIT,
TORSO_RELOAD_LOOP,
TORSO_RELOAD_LOOPWAIT,
TORSO_RELOAD_WAIT,
TORSO_RELOAD_END
};
switch (parms->stage) {
// Start the reload by either playing the reload animation or the reload_start animation
case TORSO_RELOAD_START:
if (HasAnim(ANIMCHANNEL_TORSO, "reload_start", false)) {
Event_PlayAnim(ANIMCHANNEL_TORSO, "reload_start", /* parms->blendFrames */ 0);
SRESULT_STAGE(TORSO_RELOAD_STARTWAIT);
}
Event_PlayAnim(ANIMCHANNEL_TORSO, "reload", /* parms->blendFrames */ 0);
SRESULT_STAGE(TORSO_RELOAD_WAIT);
// Wait for the reload_start animation to finish and transition to reload_loop
case TORSO_RELOAD_STARTWAIT:
if (AnimDone(ANIMCHANNEL_TORSO, 0)) {
SRESULT_STAGE(TORSO_RELOAD_LOOP);
}
else if (AI_WEAPON_FIRED) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Idle", 3);
return SRESULT_DONE;
}
return SRESULT_WAIT;
// Play a single reload from the reload loop
case TORSO_RELOAD_LOOP:
if (!AI_RELOAD) {
SRESULT_STAGE(TORSO_RELOAD_END);
}
Event_PlayAnim(ANIMCHANNEL_TORSO, "reload_loop", 0);
SRESULT_STAGE(TORSO_RELOAD_LOOPWAIT);
// Wait for the looping reload to finish and either start a new one or end the reload
case TORSO_RELOAD_LOOPWAIT:
if (AnimDone(ANIMCHANNEL_TORSO, 0)) {
SRESULT_STAGE(TORSO_RELOAD_LOOP);
}
else if (AI_WEAPON_FIRED) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Idle", 3);
return SRESULT_DONE;
}
return SRESULT_WAIT;
// End the reload
case TORSO_RELOAD_END:
if (AI_WEAPON_FIRED) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Idle", 3);
return SRESULT_DONE;
}
Event_PlayAnim(ANIMCHANNEL_TORSO, "reload_end", 3);
SRESULT_STAGE(TORSO_RELOAD_WAIT);
// Wait for reload to finish (called by both reload_end and reload)
case TORSO_RELOAD_WAIT:
if (AI_WEAPON_FIRED || AnimDone(ANIMCHANNEL_TORSO, 3)) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Idle", 3);
return SRESULT_DONE;
}
return SRESULT_WAIT;
}
return SRESULT_DONE;
}
/*
================
idPlayer::Torso_Pain
================
*/
stateResult_t idPlayer::Torso_Pain(stateParms_t* parms) {
Event_PlayAnim(ANIMCHANNEL_TORSO, painAnim.Length() ? painAnim : "pain", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_TORSO, "Wait_TorsoAnim", 4);
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Idle", 4);
return SRESULT_DONE;
}
/*
================
idPlayer::Torso_Dead
================
*/
stateResult_t idPlayer::Torso_Dead(stateParms_t* parms) {
PostAnimState(ANIMCHANNEL_TORSO, "Wait_Alive", 0);
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Idle", 0);
return SRESULT_DONE;
}
/*
================
idPlayer::Torso_Emote
================
*/
stateResult_t idPlayer::Torso_Emote(stateParms_t* parms) {
#if 0
enum {
STAGE_INIT,
STAGE_WAIT
};
switch (parms->stage) {
case STAGE_INIT:
if (emote == PE_GRAB_A) {
Event_PlayAnim(ANIMCHANNEL_TORSO, "grab_a", /* parms->blendFrames */ 0);
}
else if (emote == PE_GRAB_B) {
Event_PlayAnim(ANIMCHANNEL_TORSO, "grab_b", /* parms->blendFrames */ 0);
}
else if (emote == PE_SALUTE) {
Event_PlayAnim(ANIMCHANNEL_TORSO, "salute", /* parms->blendFrames */ 0);
}
else if (emote == PE_CHEER) {
Event_PlayAnim(ANIMCHANNEL_TORSO, "cheer", /* parms->blendFrames */ 0);
}
else if (emote == PE_TAUNT) {
Event_PlayAnim(ANIMCHANNEL_TORSO, "taunt", /* parms->blendFrames */ 0);
}
emote = PE_NONE;
SRESULT_STAGE(STAGE_WAIT);
case STAGE_WAIT:
if (AnimDone(ANIMCHANNEL_TORSO, /* parms->blendFrames */ 0)) {
PostAnimState(ANIMCHANNEL_TORSO, "Torso_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
return SRESULT_WAIT;
}
return SRESULT_ERROR;
#else
gameLocal.Error("Not implemented!");
return SRESULT_ERROR;
#endif
}
/*
===============================================================================
AI Leg States
===============================================================================
*/
/*
================
idPlayer::IsLegsIdle
================
*/
bool idPlayer::IsLegsIdle(bool crouching) const {
return ((AI_CROUCH == crouching) && AI_ONGROUND && (AI_FORWARD == AI_BACKWARD) && (AI_STRAFE_LEFT == AI_STRAFE_RIGHT));
}
/*
================
idPlayer::Legs_Idle
================
*/
stateResult_t idPlayer::Legs_Idle(stateParms_t* parms) {
enum {
STAGE_INIT,
STAGE_WAIT
};
switch (parms->stage) {
case STAGE_INIT:
if (AI_CROUCH) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Crouch", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
Event_IdleAnim(ANIMCHANNEL_LEGS, "idle");
SRESULT_STAGE(STAGE_WAIT);
case STAGE_WAIT:
// If now crouching go back to idle so we can transition to crouch
if (AI_CROUCH) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Crouch", 4);
return SRESULT_DONE;
}
else if (AI_JUMP) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Jump", 4);
return SRESULT_DONE;
}
else if (!AI_ONGROUND) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Fall", 4);
return SRESULT_DONE;
}
else if (AI_FORWARD && !AI_BACKWARD) {
if (usercmd.buttons & BUTTON_RUN) {
Event_PlayCycle(ANIMCHANNEL_LEGS, "run_forward", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Run_Forward", /* parms->blendFrames */ 0);
}
else {
Event_PlayCycle(ANIMCHANNEL_LEGS, "walk", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Walk_Forward", /* parms->blendFrames */ 0);
}
return SRESULT_DONE;
}
else if (AI_BACKWARD && !AI_FORWARD) {
if (usercmd.buttons & BUTTON_RUN) {
Event_PlayCycle(ANIMCHANNEL_LEGS, "run_backwards", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Run_Backward", /* parms->blendFrames */ 0);
}
else {
Event_PlayCycle(ANIMCHANNEL_LEGS, "walk_backwards", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Walk_Backward", /* parms->blendFrames */ 0);
}
return SRESULT_DONE;
}
else if (AI_STRAFE_LEFT && !AI_STRAFE_RIGHT) {
if (usercmd.buttons & BUTTON_RUN) {
Event_PlayCycle(ANIMCHANNEL_LEGS, "run_strafe_left", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Run_Left", /* parms->blendFrames */ 0);
}
else {
Event_PlayCycle(ANIMCHANNEL_LEGS, "walk_left", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Walk_Left", /* parms->blendFrames */ 0);
}
return SRESULT_DONE;
}
else if (AI_STRAFE_RIGHT && !AI_STRAFE_LEFT) {
if (usercmd.buttons & BUTTON_RUN) {
Event_PlayCycle(ANIMCHANNEL_LEGS, "run_strafe_right", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Run_Right", /* parms->blendFrames */ 0);
}
else {
Event_PlayCycle(ANIMCHANNEL_LEGS, "walk_right", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Walk_Right", /* parms->blendFrames */ 0);
}
return SRESULT_DONE;
}
return SRESULT_WAIT;
}
return SRESULT_ERROR;
}
/*
================
idPlayer::Legs_Crouch_Idle
================
*/
stateResult_t idPlayer::Legs_Crouch_Idle(stateParms_t* parms) {
enum {
STAGE_INIT,
STAGE_WAIT
};
switch (parms->stage) {
case STAGE_INIT:
if (!AI_CROUCH) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Uncrouch", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
Event_PlayCycle(ANIMCHANNEL_LEGS, "crouch", /* parms->blendFrames */ 0);
SRESULT_STAGE(STAGE_WAIT);
case STAGE_WAIT:
if (!AI_CROUCH || AI_JUMP) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Uncrouch", 4);
return SRESULT_DONE;
}
else if ((AI_FORWARD && !AI_BACKWARD) || (AI_STRAFE_LEFT != AI_STRAFE_RIGHT)) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Crouch_Forward", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
else if (AI_BACKWARD && !AI_FORWARD) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Crouch_Backward", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
return SRESULT_WAIT;
}
return SRESULT_ERROR;
}
/*
================
idPlayer::Legs_Crouch
================
*/
stateResult_t idPlayer::Legs_Crouch(stateParms_t* parms) {
enum {
STAGE_INIT,
STAGE_WAIT
};
switch (parms->stage) {
case STAGE_INIT:
Event_PlayAnim(ANIMCHANNEL_LEGS, "crouch_down", /* parms->blendFrames */ 0);
SRESULT_STAGE(STAGE_WAIT);
case STAGE_WAIT:
if (!IsLegsIdle(true) || AnimDone(ANIMCHANNEL_LEGS, 4)) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Crouch_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
return SRESULT_WAIT;
}
return SRESULT_ERROR;
}
/*
================
idPlayer::Legs_Uncrouch
================
*/
stateResult_t idPlayer::Legs_Uncrouch(stateParms_t* parms) {
enum {
STAGE_INIT,
STAGE_WAIT
};
switch (parms->stage) {
case STAGE_INIT:
Event_PlayAnim(ANIMCHANNEL_LEGS, "crouch_up", /* parms->blendFrames */ 0);
SRESULT_STAGE(STAGE_WAIT);
case STAGE_WAIT:
if (!IsLegsIdle(false) || AnimDone(ANIMCHANNEL_LEGS, 4)) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Idle", 4);
return SRESULT_DONE;
}
return SRESULT_WAIT;
}
return SRESULT_ERROR;
}
/*
================
idPlayer::Legs_Run_Forward
================
*/
stateResult_t idPlayer::Legs_Run_Forward(stateParms_t* parms) {
if (!AI_JUMP && AI_ONGROUND && !AI_CROUCH && !AI_BACKWARD && AI_FORWARD) {
if (usercmd.buttons & BUTTON_RUN) {
return SRESULT_WAIT;
}
else {
Event_PlayCycle(ANIMCHANNEL_LEGS, "walk", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Walk_Forward", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
}
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
/*
================
idPlayer::Legs_Run_Backward
================
*/
stateResult_t idPlayer::Legs_Run_Backward(stateParms_t* parms) {
if (!AI_JUMP && AI_ONGROUND && !AI_CROUCH && !AI_FORWARD && AI_BACKWARD) {
if (usercmd.buttons & BUTTON_RUN) {
return SRESULT_WAIT;
}
else {
Event_PlayCycle(ANIMCHANNEL_LEGS, "walk_backwards", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Walk_Backward", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
}
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
/*
================
idPlayer::Legs_Run_Left
================
*/
stateResult_t idPlayer::Legs_Run_Left(stateParms_t* parms) {
if (!AI_JUMP && AI_ONGROUND && !AI_CROUCH && (AI_FORWARD == AI_BACKWARD) && AI_STRAFE_LEFT && !AI_STRAFE_RIGHT) {
if (usercmd.buttons & BUTTON_RUN) {
return SRESULT_WAIT;
}
else {
Event_PlayCycle(ANIMCHANNEL_LEGS, "walk_left", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Walk_Left", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
}
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
/*
================
idPlayer::Legs_Run_Right
================
*/
stateResult_t idPlayer::Legs_Run_Right(stateParms_t* parms) {
if (!AI_JUMP && AI_ONGROUND && !AI_CROUCH && (AI_FORWARD == AI_BACKWARD) && AI_STRAFE_RIGHT && !AI_STRAFE_LEFT) {
if (usercmd.buttons & BUTTON_RUN) {
return SRESULT_WAIT;
}
else {
Event_PlayCycle(ANIMCHANNEL_LEGS, "walk_right", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Walk_Right", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
}
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
/*
================
idPlayer::Legs_Walk_Forward
================
*/
stateResult_t idPlayer::Legs_Walk_Forward(stateParms_t* parms) {
if (!AI_JUMP && AI_ONGROUND && !AI_CROUCH && !AI_BACKWARD && AI_FORWARD) {
if (!(usercmd.buttons & BUTTON_RUN)) {
return SRESULT_WAIT;
}
else {
Event_PlayCycle(ANIMCHANNEL_LEGS, "run_forward", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Run_Forward", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
}
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
/*
================
idPlayer::Legs_Walk_Backward
================
*/
stateResult_t idPlayer::Legs_Walk_Backward(stateParms_t* parms) {
if (!AI_JUMP && AI_ONGROUND && !AI_CROUCH && !AI_FORWARD && AI_BACKWARD) {
if (!(usercmd.buttons & BUTTON_RUN)) {
return SRESULT_WAIT;
}
else {
Event_PlayCycle(ANIMCHANNEL_LEGS, "run_backwards", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Run_Backward", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
}
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
/*
================
idPlayer::Legs_Walk_Left
================
*/
stateResult_t idPlayer::Legs_Walk_Left(stateParms_t* parms) {
if (!AI_JUMP && AI_ONGROUND && !AI_CROUCH && (AI_FORWARD == AI_BACKWARD) && AI_STRAFE_LEFT && !AI_STRAFE_RIGHT) {
if (!(usercmd.buttons & BUTTON_RUN)) {
return SRESULT_WAIT;
}
else {
Event_PlayCycle(ANIMCHANNEL_LEGS, "run_strafe_left", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Run_Left", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
}
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
/*
================
idPlayer::Legs_Walk_Right
================
*/
stateResult_t idPlayer::Legs_Walk_Right(stateParms_t* parms) {
if (!AI_JUMP && AI_ONGROUND && !AI_CROUCH && (AI_FORWARD == AI_BACKWARD) && AI_STRAFE_RIGHT && !AI_STRAFE_LEFT) {
if (!(usercmd.buttons & BUTTON_RUN)) {
return SRESULT_WAIT;
}
else {
Event_PlayCycle(ANIMCHANNEL_LEGS, "run_strafe_right", /* parms->blendFrames */ 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Run_Right", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
}
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
/*
================
idPlayer::Legs_Crouch_Forward
================
*/
stateResult_t idPlayer::Legs_Crouch_Forward(stateParms_t* parms) {
enum {
STAGE_INIT,
STAGE_WAIT
};
switch (parms->stage) {
case STAGE_INIT:
Event_PlayCycle(ANIMCHANNEL_LEGS, "crouch_walk", /* parms->blendFrames */ 0);
SRESULT_STAGE(STAGE_WAIT);
case STAGE_WAIT:
if (!AI_JUMP && AI_ONGROUND && AI_CROUCH && ((!AI_BACKWARD && AI_FORWARD) || (AI_STRAFE_LEFT != AI_STRAFE_RIGHT))) {
return SRESULT_WAIT;
}
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Crouch_Idle", 2);
return SRESULT_DONE;
}
return SRESULT_DONE;
}
/*
================
idPlayer::Legs_Crouch_Backward
================
*/
stateResult_t idPlayer::Legs_Crouch_Backward(stateParms_t* parms) {
enum {
STAGE_INIT,
STAGE_WAIT
};
switch (parms->stage) {
case STAGE_INIT:
Event_PlayCycle(ANIMCHANNEL_LEGS, "crouch_walk_backward", /* parms->blendFrames */ 0);
SRESULT_STAGE(STAGE_WAIT);
case STAGE_WAIT:
if (!AI_JUMP && AI_ONGROUND && AI_CROUCH && !AI_FORWARD && AI_BACKWARD) {
return SRESULT_WAIT;
}
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Crouch_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
return SRESULT_ERROR;
}
/*
================
idPlayer::Legs_Jump
================
*/
stateResult_t idPlayer::Legs_Jump(stateParms_t* parms) {
enum {
STAGE_INIT,
STAGE_WAIT
};
switch (parms->stage) {
case STAGE_INIT:
// prevent infinite recursion
AI_JUMP = false;
if (AI_RUN) {
Event_PlayAnim(ANIMCHANNEL_LEGS, "run_jump", /* parms->blendFrames */ 0);
}
else {
Event_PlayAnim(ANIMCHANNEL_LEGS, "jump", /* parms->blendFrames */ 0);
}
SRESULT_STAGE(STAGE_WAIT);
case STAGE_WAIT:
if (AI_ONGROUND) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Land", 4);
return SRESULT_DONE;
}
if (AnimDone(ANIMCHANNEL_LEGS, 4)) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Fall", 4);
return SRESULT_DONE;
}
return SRESULT_WAIT;
}
return SRESULT_ERROR;
}
/*
================
idPlayer::Legs_Fall
================
*/
stateResult_t idPlayer::Legs_Fall(stateParms_t* parms) {
enum {
STAGE_INIT,
STAGE_WAIT
};
switch (parms->stage) {
case STAGE_INIT:
if (AI_ONGROUND) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Land", 2);
return SRESULT_DONE;
}
Event_PlayCycle(ANIMCHANNEL_LEGS, "fall", /* parms->blendFrames */ 0);
SRESULT_STAGE(STAGE_WAIT);
case STAGE_WAIT:
if (AI_ONGROUND) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Land", 2);
return SRESULT_DONE;
}
return SRESULT_WAIT;
}
return SRESULT_DONE;
}
/*
================
idPlayer::Legs_Land
================
*/
stateResult_t idPlayer::Legs_Land(stateParms_t* parms) {
enum {
STAGE_INIT,
STAGE_WAIT
};
switch (parms->stage) {
case STAGE_INIT:
if (IsLegsIdle(false) && (AI_HARDLANDING || AI_SOFTLANDING)) {
if (AI_HARDLANDING) {
Event_PlayAnim(ANIMCHANNEL_LEGS, "hard_land", /* parms->blendFrames */ 0);
}
else {
Event_PlayAnim(ANIMCHANNEL_LEGS, "soft_land", /* parms->blendFrames */ 0);
}
SRESULT_STAGE(STAGE_WAIT);
}
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Idle", 4);
return SRESULT_DONE;
case STAGE_WAIT:
if (!IsLegsIdle(false) || AnimDone(ANIMCHANNEL_LEGS, /* parms->blendFrames */ 0)) {
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
return SRESULT_WAIT;
}
return SRESULT_ERROR;
}
/*
================
idPlayer::Legs_Dead
================
*/
stateResult_t idPlayer::Legs_Dead(stateParms_t* parms) {
PostAnimState(ANIMCHANNEL_LEGS, "Wait_Alive", 0);
PostAnimState(ANIMCHANNEL_LEGS, "Legs_Idle", 0);
return SRESULT_DONE;
}
/*
================
idPlayer::Wait_Alive
Waits until the player is alive again.
================
*/
stateResult_t idPlayer::Wait_Alive(stateParms_t* parms) {
if (AI_DEAD) {
return SRESULT_WAIT;
}
return SRESULT_DONE;
}
/*
================
idPlayer::Wait_ReloadAnim
================
*/
stateResult_t idPlayer::Wait_ReloadAnim(stateParms_t* parms) {
// The gun firing can cancel any of the relod animations
if (AI_WEAPON_FIRED) {
SetAnimState(ANIMCHANNEL_TORSO, "Torso_Idle", /* parms->blendFrames */ 0);
return SRESULT_DONE;
}
// wait for the animation to finish
if (AnimDone(ANIMCHANNEL_TORSO, /* parms->blendFrames */ 0)) {
return SRESULT_DONE;
}
return SRESULT_WAIT;
}