/* * @brief Sets the animation sequences for the specified entity. This is called * towards the end of each frame, after our ground entity and water level have * been resolved. */ static void G_ClientAnimation(g_entity_t *ent) { if (ent->s.model1 != MODEL_CLIENT) return; // corpses animate to their final resting place if (ent->solid == SOLID_DEAD) { if (g_level.time >= ent->client->locals.respawn_time) { switch (ent->s.animation1) { case ANIM_BOTH_DEATH1: case ANIM_BOTH_DEATH2: case ANIM_BOTH_DEATH3: G_SetAnimation(ent, ent->s.animation1 + 1, false); break; default: break; } } return; } // no-clippers do not animate if (ent->locals.move_type == MOVE_TYPE_NO_CLIP) { G_SetAnimation(ent, ANIM_TORSO_STAND1, false); G_SetAnimation(ent, ANIM_LEGS_JUMP1, false); return; } // check for falling g_client_locals_t *cl = &ent->client->locals; if (!ent->locals.ground_entity) { // not on the ground if (g_level.time - cl->jump_time > 400) { if (ent->locals.water_level == 3 && cl->speed > 10.0) { // swimming G_SetAnimation(ent, ANIM_LEGS_SWIM, false); return; } if (ent->client->ps.pm_state.flags & PMF_DUCKED) { // ducking G_SetAnimation(ent, ANIM_LEGS_IDLECR, false); return; } } _Bool jumping = G_IsAnimation(ent, ANIM_LEGS_JUMP1); jumping |= G_IsAnimation(ent, ANIM_LEGS_JUMP2); if (!jumping) G_SetAnimation(ent, ANIM_LEGS_JUMP1, false); return; } // duck, walk or run after landing if (g_level.time - 400 > cl->land_time && g_level.time - 50 > cl->ground_time) { if (ent->client->ps.pm_state.flags & PMF_DUCKED) { // ducked if (cl->speed < 1.0) G_SetAnimation(ent, ANIM_LEGS_IDLECR, false); else G_SetAnimation(ent, ANIM_LEGS_WALKCR, false); return; } if (cl->speed < 1.0 && !cl->cmd.forward && !cl->cmd.right && !cl->cmd.up) { G_SetAnimation(ent, ANIM_LEGS_IDLE, false); return; } vec3_t angles, forward; VectorSet(angles, 0.0, ent->s.angles[YAW], 0.0); AngleVectors(angles, forward, NULL, NULL); if (DotProduct(ent->locals.velocity, forward) < -0.1) G_SetAnimation(ent, ANIM_LEGS_BACK, false); else if (cl->speed < 200.0) G_SetAnimation(ent, ANIM_LEGS_WALK, false); else G_SetAnimation(ent, ANIM_LEGS_RUN, false); return; } }
/* * @brief Sets the animation sequences for the specified entity. This is called * towards the end of each frame, after our ground entity and water level have * been resolved. */ static void G_ClientAnimation(g_edict_t *ent) { if (ent->sv_flags & SVF_NO_CLIENT) return; // no-clippers do not animate if (ent->locals.move_type == MOVE_TYPE_NO_CLIP) { G_SetAnimation(ent, ANIM_TORSO_STAND1, false); G_SetAnimation(ent, ANIM_LEGS_JUMP1, false); return; } // check for falling g_client_locals_t *cl = &ent->client->locals; if (!ent->locals.ground_entity) { // not on the ground if (g_level.time - cl->jump_time > 400) { if (ent->locals.water_level == 3 && cl->speed > 10.0) { // swimming G_SetAnimation(ent, ANIM_LEGS_SWIM, false); return; } if (ent->client->ps.pm_state.flags & PMF_DUCKED) { // ducking G_SetAnimation(ent, ANIM_LEGS_IDLECR, false); return; } } _Bool jumping = G_IsAnimation(ent, ANIM_LEGS_JUMP1); jumping |= G_IsAnimation(ent, ANIM_LEGS_JUMP2); if (!jumping) G_SetAnimation(ent, ANIM_LEGS_JUMP1, false); return; } // duck, walk or run after landing if (g_level.time - 400 > cl->land_time && g_level.time - 50 > cl->ground_time) { if (ent->client->ps.pm_state.flags & PMF_DUCKED) { // ducked if (cl->speed < 1.0) G_SetAnimation(ent, ANIM_LEGS_IDLECR, false); else G_SetAnimation(ent, ANIM_LEGS_WALKCR, false); return; } if (cl->speed < 1.0 && !cl->cmd.forward && !cl->cmd.right && !cl->cmd.up) { G_SetAnimation(ent, ANIM_LEGS_IDLE, false); return; } vec3_t angles, forward; VectorSet(angles, 0.0, ent->s.angles[YAW], 0.0); AngleVectors(angles, forward, NULL, NULL); if (DotProduct(ent->locals.velocity, forward) < -0.1) G_SetAnimation(ent, ANIM_LEGS_BACK, false); else if (cl->speed < 200.0) G_SetAnimation(ent, ANIM_LEGS_WALK, false); else G_SetAnimation(ent, ANIM_LEGS_RUN, false); return; } }