--- /dev/null
+// implicit anim state
+.float anim_implicit_state;
+.float anim_implicit_time;
+
+// actions
+.float anim_lower_action;
+.float anim_lower_time;
+.float anim_upper_action;
+.float anim_upper_time;
+
+// player animation data for this model
+// each vector is as follows:
+// _x = startframe
+// _y = numframes
+// _z = framerate
+.vector anim_die1; // player dies
+.vector anim_die2; // player dies differently
+.vector anim_draw; // player pulls out a weapon
+.vector anim_duckwalk; // player walking while crouching
+.vector anim_duckjump; // player jumping from a crouch
+.vector anim_duckidle; // player idling while crouching
+.vector anim_idle; // player standing
+.vector anim_jump; // player jump
+.vector anim_pain1; // player flinches from pain
+.vector anim_pain2; // player flinches from pain, differently
+.vector anim_shoot; // player shoots
+.vector anim_taunt; // player taunts others (FIXME: no code references this)
+.vector anim_run; // player running forward
+.vector anim_runbackwards; // player running backward
+.vector anim_strafeleft; // player shuffling left quickly
+.vector anim_straferight; // player shuffling right quickly
+.vector anim_forwardright; // player running forward and right
+.vector anim_forwardleft; // player running forward and left
+.vector anim_backright; // player running backward and right
+.vector anim_backleft; // player running back and left
+.vector anim_melee; // player doing the melee action
+.vector anim_duck; // player doing the melee action
+.vector anim_duckwalkbackwards;
+.vector anim_duckwalkstrafeleft;
+.vector anim_duckwalkstraferight;
+.vector anim_duckwalkforwardright;
+.vector anim_duckwalkforwardleft;
+.vector anim_duckwalkbackright;
+.vector anim_duckwalkbackleft;
+
+void animdecide_init(entity e)
+{
+ self.anim_die1 = animfixfps(self, '0 1 0.5'); // 2 seconds
+ self.anim_die2 = animfixfps(self, '1 1 0.5'); // 2 seconds
+ self.anim_draw = animfixfps(self, '2 1 3');
+ self.anim_duckwalk = animfixfps(self, '4 1 1');
+ self.anim_duckjump = '5 1 100'; // NOTE: zym anims keep playing until changed, so this only has to start the anim, landing will end it
+ self.anim_duckidle = animfixfps(self, '6 1 1');
+ self.anim_idle = animfixfps(self, '7 1 1');
+ self.anim_jump = '8 1 100'; // NOTE: zym anims keep playing until changed, so this only has to start the anim, landing will end it
+ self.anim_pain1 = animfixfps(self, '9 1 2'); // 0.5 seconds
+ self.anim_pain2 = animfixfps(self, '10 1 2'); // 0.5 seconds
+ self.anim_shoot = animfixfps(self, '11 1 5'); // analyze models and set framerate
+ self.anim_taunt = animfixfps(self, '12 1 0.33');
+ self.anim_run = animfixfps(self, '13 1 1');
+ self.anim_runbackwards = animfixfps(self, '14 1 1');
+ self.anim_strafeleft = animfixfps(self, '15 1 1');
+ self.anim_straferight = animfixfps(self, '16 1 1');
+ self.anim_forwardright = animfixfps(self, '19 1 1');
+ self.anim_forwardleft = animfixfps(self, '20 1 1');
+ self.anim_backright = animfixfps(self, '21 1 1');
+ self.anim_backleft = animfixfps(self, '22 1 1');
+ self.anim_melee = animfixfps(self, '23 1 1');
+ self.anim_duckwalkbackwards = animfixfps(self, '24 1 1');
+ self.anim_duckwalkstrafeleft = animfixfps(self, '25 1 1');
+ self.anim_duckwalkstraferight = animfixfps(self, '26 1 1');
+ self.anim_duckwalkforwardright = animfixfps(self, '27 1 1');
+ self.anim_duckwalkforwardleft = animfixfps(self, '28 1 1');
+ self.anim_duckwalkbackright = animfixfps(self, '29 1 1');
+ self.anim_duckwalkbackleft = animfixfps(self, '30 1 1');
+}
+
+#define ANIMPRIO_IDLE 0
+#define ANIMPRIO_STATIC 1
+#define ANIMPRIO_ACTIVE 2
+#define ANIMPRIO_DEAD 3
+
+vector animdecide_getupperanim(entity e)
+{
+ // is there an action?
+ vector outframe = '-1 0 0';
+ switch(e.anim_upper_action)
+ {
+ case ANIMACTION_DRAW: outframe = e.anim_draw; break;
+ case ANIMACTION_PAIN1: outframe = e.anim_pain1; break;
+ case ANIMACTION_PAIN2: outframe = e.anim_pain2; break;
+ case ANIMACTION_SHOOT: outframe = e.anim_shoot; break;
+ case ANIMACTION_TAUNT: outframe = e.anim_taunt; break;
+ case ANIMACTION_MELEE: outframe = e.anim_melee; break;
+ }
+ if(outframe_x >= 0)
+ {
+ if(time <= e.anim_upper_time + outframe_y / outframe_z)
+ {
+ // animation is running!
+ return vec3(outframe_x, e.anim_upper_time, ANIMPRIO_ACTIVE);
+ }
+ }
+ float t = max(e.anim_time, e.anim_implicit_time);
+ // or, decide the anim by state
+ // but all states are for lower body!
+ return vec3(e.anim_idle_x, t, ANIMPRIO_IDLE);
+}
+
+vector animdecide_getloweranim(entity e)
+{
+ // death etc.
+ if(e.anim_state & ANIMSTATE_FROZEN)
+ return vec3(e.anim_idle_x, e.anim_time, ANIMPRIO_DEAD);
+ if(e.anim_state & ANIMSTATE_DEAD1)
+ return vec3(e.anim_die1_x, e.anim_time, ANIMPRIO_DEAD);
+ if(e.anim_state & ANIMSTATE_DEAD2)
+ return vec3(e.anim_die2_x, e.anim_time, ANIMPRIO_DEAD);
+
+ // is there an action?
+ vector outframe = '-1 0 0';
+ switch(e.anim_lower_action)
+ {
+ case ANIMACTION_JUMP: if(e.anim_state & ANIMSTATE_DUCK) outframe = e.anim_duckjump; else outframe = e.anim_jump; break;
+ }
+ if(outframe_x >= 0)
+ {
+ if(time <= e.anim_lower_time + outframe_y / outframe_z)
+ {
+ // animation is running!
+ return vec3(outframe_x, e.anim_lower_time, ANIMPRIO_ACTIVE);
+ }
+ }
+ float t = max(e.anim_time, e.anim_implicit_time);
+ // or, decide the anim by state
+ if(e.anim_state & ANIMSTATE_DUCK)
+ {
+ switch(self.anim_implicit_state & (ANIMIMPLICITSTATE_FORWARD | ANIMIMPLICITSTATE_BACKWARDS | ANIMIMPLICITSTATE_LEFT | ANIMIMPLICITSTATE_RIGHT))
+ {
+ case ANIMIMPLICITSTATE_FORWARD:
+ return vec3(e.anim_duckwalk_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_BACKWARDS:
+ return vec3(e.anim_duckwalkbackwards_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_RIGHT:
+ return vec3(e.anim_duckwalkstraferight_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_LEFT:
+ return vec3(e.anim_duckwalkstrafeleft_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_FORWARD | ANIMIMPLICITSTATE_RIGHT:
+ return vec3(e.anim_duckwalkforwardright_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_FORWARD | ANIMIMPLICITSTATE_LEFT:
+ return vec3(e.anim_duckwalkforwardleft_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_BACKWARDS | ANIMIMPLICITSTATE_RIGHT:
+ return vec3(e.anim_duckwalkbackright_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_BACKWARDS | ANIMIMPLICITSTATE_LEFT:
+ return vec3(e.anim_duckwalkbackleft_x, t, ANIMPRIO_ACTIVE);
+ default:
+ return vec3(e.anim_duckidle_x, t, ANIMPRIO_STATIC);
+ }
+ }
+ else if(e.anim_implicit_state & ANIMIMPLICITSTATE_RUN)
+ {
+ switch(self.anim_implicit_state & (ANIMIMPLICITSTATE_FORWARD | ANIMIMPLICITSTATE_BACKWARDS | ANIMIMPLICITSTATE_LEFT | ANIMIMPLICITSTATE_RIGHT))
+ {
+ case ANIMIMPLICITSTATE_FORWARD:
+ return vec3(e.anim_run_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_BACKWARDS:
+ return vec3(e.anim_runbackwards_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_RIGHT:
+ return vec3(e.anim_straferight_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_LEFT:
+ return vec3(e.anim_strafeleft_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_FORWARD | ANIMIMPLICITSTATE_RIGHT:
+ return vec3(e.anim_forwardright_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_FORWARD | ANIMIMPLICITSTATE_LEFT:
+ return vec3(e.anim_forwardleft_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_BACKWARDS | ANIMIMPLICITSTATE_RIGHT:
+ return vec3(e.anim_backright_x, t, ANIMPRIO_ACTIVE);
+ case ANIMIMPLICITSTATE_BACKWARDS | ANIMIMPLICITSTATE_LEFT:
+ return vec3(e.anim_backleft_x, t, ANIMPRIO_ACTIVE);
+ default:
+ return vec3(e.anim_run_x, t, ANIMPRIO_STATIC);
+ }
+ }
+ return vec3(e.anim_idle_x, t, ANIMPRIO_IDLE);
+}
+
+void animdecide_setimplicitstate(entity e)
+{
+ float s;
+ s = 0;
+
+ makevectors(self.angles);
+ if(self.velocity * v_forward > 0)
+ s |= ANIMIMPLICITSTATE_FORWARD;
+ if(self.velocity * v_forward < 0)
+ s |= ANIMIMPLICITSTATE_BACKWARDS;
+ if(self.velocity * v_right > 0)
+ s |= ANIMIMPLICITSTATE_RIGHT;
+ if(self.velocity * v_right < 0)
+ s |= ANIMIMPLICITSTATE_LEFT;
+ if(vlen(self.velocity) > 100)
+ s |= ANIMIMPLICITSTATE_RUN;
+
+ // TODO infer jumping too!
+}
+void animdecide_setframes(entity e, float support_blending)
+{
+ animdecide_setimplicitstate(e);
+ // _x: frame
+ // _y: priority
+ // _z: start time
+ vector upper = animdecide_getupperanim(e);
+ vector lower = animdecide_getloweranim(e);
+ if(upper_y > lower_y)
+ lower = upper;
+ else if(lower_y > upper_y)
+ upper = lower;
+ if(support_blending)
+ {
+ self.frame = upper_x;
+ self.frame1time = upper_z;
+ self.frame2 = lower_x;
+ self.frame2time = lower_z;
+ }
+ else
+ {
+ self.frame = upper_x;
+ self.frame1time = upper_z;
+ }
+}
+
+void animdecide_setstate(entity e, float newstate, float restart)
+{
+ if(!restart)
+ if(newstate == e.anim_state)
+ return;
+ e.anim_state = newstate;
+ e.anim_time = time;
+}
+void animdecide_setaction(entity e, float action, float restart)
+{
+ if(action < 0)
+ {
+ if(!restart)
+ if(action == e.anim_lower_action)
+ return;
+ e.anim_lower_action = action;
+ e.anim_lower_time = time;
+ }
+ else
+ {
+ if(!restart)
+ if(action == e.anim_upper_action)
+ return;
+ e.anim_upper_action = action;
+ e.anim_upper_time = time;
+ }
+}
--- /dev/null
+// client side frame inferring
+void animdecide_init(entity e);
+void animdecide_setframes(entity e, float support_blending);
+
+// please network this one
+.float anim_state;
+.float anim_time;
+#define ReadAnimState() do { self.anim_state = ReadByte(); self.anim_time = ReadApproxPastTime(); } while(0)
+#define WriteAnimState(dest) do { WriteByte(dest, self.anim_state); WriteApproxPastTime(dest, self.anim_time); } while(0)
+
+// explicit anim states (networked)
+void animdecide_setstate(entity e, float newstate, float restart);
+#define ANIMSTATE_DEAD1 1 // base frames: die1
+#define ANIMSTATE_DEAD2 2 // base frames: die2
+#define ANIMSTATE_DUCK 4 // turns walk into duckwalk, jump into duckjump, etc.
+#define ANIMSTATE_FROZEN 8 // force idle
+
+// implicit anim states (inferred from velocity, etc.)
+#define ANIMIMPLICITSTATE_RUN 1
+#define ANIMIMPLICITSTATE_FORWARD 2
+#define ANIMIMPLICITSTATE_BACKWARDS 4
+#define ANIMIMPLICITSTATE_LEFT 8
+#define ANIMIMPLICITSTATE_RIGHT 16
+
+// explicit actions (networked); negative values are for lower body
+void animdecide_setaction(entity e, float action, float restart);
+#define ANIMACTION_JUMP -1 // jump
+#define ANIMACTION_DRAW 1 // draw
+#define ANIMACTION_PAIN1 2 // pain
+#define ANIMACTION_PAIN2 3 // pain
+#define ANIMACTION_SHOOT 4 // shoot
+#define ANIMACTION_TAUNT 5 // taunt
+#define ANIMACTION_MELEE 6 // melee
for(queue_start = e; queue_start; queue_start = queue_start.fld)
queue_start.FindConnectedComponent_processing = 0;
}
+
+vector vec3(float x, float y, float z)
+{
+ vector v;
+ v_x = x;
+ v_y = y;
+ v_z = z;
+ return v;
+}
typedef entity(entity cur, entity near, entity pass) findNextEntityNearFunction_t;
typedef float(entity a, entity b, entity pass) isConnectedFunction_t;
void FindConnectedComponent(entity e, .entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass);
+
+vector vec3(float x, float y, float z);
self.prevorigin = self.origin;
if (!self.vehicle)
- if (((self.BUTTON_CROUCH && !self.hook.state) || self.health <= g_bloodloss) && self.animstate_startframe != self.anim_melee_x && !self.freezetag_frozen) // prevent crouching if using melee attack
+ if (((self.BUTTON_CROUCH && !self.hook.state) || self.health <= g_bloodloss) && !self.freezetag_frozen) // FIXME-CSAD: prevent crouching if using melee attack
{
if (!self.crouch)
{
self.flags &~= FL_ONGROUND;
self.flags &~= FL_JUMPRELEASED;
- if (self.crouch)
- setanim(self, self.anim_duckjump, FALSE, TRUE, TRUE);
- else if (self.animstate_startframe != self.anim_melee_x || (self.animstate_startframe == self.anim_melee_x && time - self.animstate_starttime >= 21/20)) // jump animation shouldn't override melee until we have animation blending (or until the anim finished, 21/20 = numframes/fps)
- setanim(self, self.anim_jump, FALSE, TRUE, TRUE);
+ animdecide_setaction(self, ANIMACTION_JUMP, TRUE);
if(g_jump_grunt)
PlayerSound(playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
void player_setupanimsformodel()
{
- // defaults for legacy .zym models without animinfo files
- self.anim_die1 = animfixfps(self, '0 1 0.5'); // 2 seconds
- self.anim_die2 = animfixfps(self, '1 1 0.5'); // 2 seconds
- self.anim_draw = animfixfps(self, '2 1 3');
- // self.anim_duck = '3 1 100'; // This anim is broken, use slot 3 as a new free slot in the future ;)
- self.anim_duckwalk = animfixfps(self, '4 1 1');
- self.anim_duckjump = '5 1 100'; // NOTE: zym anims keep playing until changed, so this only has to start the anim, landing will end it
- self.anim_duckidle = animfixfps(self, '6 1 1');
- self.anim_idle = animfixfps(self, '7 1 1');
- self.anim_jump = '8 1 100'; // NOTE: zym anims keep playing until changed, so this only has to start the anim, landing will end it
- self.anim_pain1 = animfixfps(self, '9 1 2'); // 0.5 seconds
- self.anim_pain2 = animfixfps(self, '10 1 2'); // 0.5 seconds
- self.anim_shoot = animfixfps(self, '11 1 5'); // analyze models and set framerate
- self.anim_taunt = animfixfps(self, '12 1 0.33');
- self.anim_run = animfixfps(self, '13 1 1');
- self.anim_runbackwards = animfixfps(self, '14 1 1');
- self.anim_strafeleft = animfixfps(self, '15 1 1');
- self.anim_straferight = animfixfps(self, '16 1 1');
- //self.anim_dead1 = animfixfps(self, '17 1 1');
- //self.anim_dead2 = animfixfps(self, '18 1 1');
- self.anim_forwardright = animfixfps(self, '19 1 1');
- self.anim_forwardleft = animfixfps(self, '20 1 1');
- self.anim_backright = animfixfps(self, '21 1 1');
- self.anim_backleft = animfixfps(self, '22 1 1');
- self.anim_melee = animfixfps(self, '23 1 1');
- self.anim_duckwalkbackwards = animfixfps(self, '24 1 1');
- self.anim_duckwalkstrafeleft = animfixfps(self, '25 1 1');
- self.anim_duckwalkstraferight = animfixfps(self, '26 1 1');
- self.anim_duckwalkforwardright = animfixfps(self, '27 1 1');
- self.anim_duckwalkforwardleft = animfixfps(self, '28 1 1');
- self.anim_duckwalkbackright = animfixfps(self, '29 1 1');
- self.anim_duckwalkbackleft = animfixfps(self, '30 1 1');
- // TODO introspect models for finding right "fps" value (1/duration)
- // reset animstate now
- setanim(self, self.anim_idle, TRUE, FALSE, TRUE);
+ // load animation info
+ animdecide_init(self);
+ animdecide_setstate(self, 0, FALSE);
}
void player_anim (void)
{
- updateanim(self);
- if (self.weaponentity)
- updateanim(self.weaponentity);
-
- if (self.deadflag != DEAD_NO)
- return;
-
- if (!self.animstate_override)
+ float deadbits = (self.anim_state & (ANIMSTATE_DEAD1 | ANIMSTATE_DEAD2));
+ if(self.deadflag && !deadbits)
+ if(random() < 0.5)
+ deadbits = ANIMSTATE_DEAD1;
+ else
+ deadbits = ANIMSTATE_DEAD2;
+ float animbits = deadbits;
+ if(self.freezetag_frozen)
+ animbits |= ANIMSTATE_FROZEN;
+ if(self.crouch)
+ animbits |= ANIMSTATE_DUCK;
+ animdecide_setstate(self, animbits, FALSE);
+
+ /* FIXME-CSAD port this to animdecide.qc
+ if (!(self.flags & FL_ONGROUND) || self.BUTTON_JUMP)
{
- if (self.freezetag_frozen)
- setanim(self, self.anim_idle, TRUE, FALSE, FALSE);
- else if (!(self.flags & FL_ONGROUND) || self.BUTTON_JUMP)
+ if (self.crouch)
{
- if (self.crouch)
+ if (self.animstate_startframe != self.anim_duckjump_x) // don't perform another trace if already playing the crouch jump anim
{
- if (self.animstate_startframe != self.anim_duckjump_x) // don't perform another trace if already playing the crouch jump anim
+ traceline(self.origin + '0 0 1' * PL_CROUCH_MIN_z, self.origin + '0 0 1' * (PL_CROUCH_MIN_z - autocvar_sv_player_jumpanim_minfall), TRUE, self);
+ if(!trace_startsolid && trace_fraction == 1 || !(self.animstate_startframe == self.anim_duckwalk_x || self.animstate_startframe == self.anim_duckidle_x)) // don't get stuck on non-crouch anims
{
- traceline(self.origin + '0 0 1' * PL_CROUCH_MIN_z, self.origin + '0 0 1' * (PL_CROUCH_MIN_z - autocvar_sv_player_jumpanim_minfall), TRUE, self);
- if(!trace_startsolid && trace_fraction == 1 || !(self.animstate_startframe == self.anim_duckwalk_x || self.animstate_startframe == self.anim_duckidle_x)) // don't get stuck on non-crouch anims
- {
- setanim(self, self.anim_duckjump, FALSE, TRUE, self.restart_jump);
- self.restart_jump = FALSE;
- }
+ setanim(self, self.anim_duckjump, FALSE, TRUE, self.restart_jump);
+ self.restart_jump = FALSE;
}
}
- else
- {
- if (self.animstate_startframe != self.anim_jump_x) // don't perform another trace if already playing the jump anim
- {
- traceline(self.origin + '0 0 1' * PL_MIN_z, self.origin + '0 0 1' * (PL_MIN_z - autocvar_sv_player_jumpanim_minfall), TRUE, self);
- if(!trace_startsolid && trace_fraction == 1 || self.animstate_startframe == self.anim_idle_x || (self.animstate_startframe == self.anim_melee_x && time - self.animstate_starttime >= 21/20)) // don't get stuck on idle animation in midair, nor melee after it finished
- {
- setanim(self, self.anim_jump, FALSE, TRUE, self.restart_jump);
- self.restart_jump = FALSE;
- }
- }
- }
- }
- else if (self.crouch)
- {
- if (self.movement_x > 0 && self.movement_y == 0)
- setanim(self, self.anim_duckwalk, TRUE, FALSE, FALSE);
- else if (self.movement_x < 0 && self.movement_y == 0)
- setanim(self, self.anim_duckwalkbackwards, TRUE, FALSE, FALSE);
- else if (self.movement_x == 0 && self.movement_y > 0)
- setanim(self, self.anim_duckwalkstraferight, TRUE, FALSE, FALSE);
- else if (self.movement_x == 0 && self.movement_y < 0)
- setanim(self, self.anim_duckwalkstrafeleft, TRUE, FALSE, FALSE);
- else if (self.movement_x > 0 && self.movement_y > 0)
- setanim(self, self.anim_duckwalkforwardright, TRUE, FALSE, FALSE);
- else if (self.movement_x > 0 && self.movement_y < 0)
- setanim(self, self.anim_duckwalkforwardleft, TRUE, FALSE, FALSE);
- else if (self.movement_x < 0 && self.movement_y > 0)
- setanim(self, self.anim_duckwalkbackright, TRUE, FALSE, FALSE);
- else if (self.movement_x < 0 && self.movement_y < 0)
- setanim(self, self.anim_duckwalkbackleft, TRUE, FALSE, FALSE);
- else
- setanim(self, self.anim_duckidle, TRUE, FALSE, FALSE);
}
- else if ((self.movement_x * self.movement_x + self.movement_y * self.movement_y) > 20)
+ else
{
- if (self.movement_x > 0 && self.movement_y == 0)
- setanim(self, self.anim_run, TRUE, FALSE, FALSE);
- else if (self.movement_x < 0 && self.movement_y == 0)
- setanim(self, self.anim_runbackwards, TRUE, FALSE, FALSE);
- else if (self.movement_x == 0 && self.movement_y > 0)
- setanim(self, self.anim_straferight, TRUE, FALSE, FALSE);
- else if (self.movement_x == 0 && self.movement_y < 0)
- setanim(self, self.anim_strafeleft, TRUE, FALSE, FALSE);
- else if (self.movement_x > 0 && self.movement_y > 0)
- setanim(self, self.anim_forwardright, TRUE, FALSE, FALSE);
- else if (self.movement_x > 0 && self.movement_y < 0)
- setanim(self, self.anim_forwardleft, TRUE, FALSE, FALSE);
- else if (self.movement_x < 0 && self.movement_y > 0)
- setanim(self, self.anim_backright, TRUE, FALSE, FALSE);
- else if (self.movement_x < 0 && self.movement_y < 0)
- setanim(self, self.anim_backleft, TRUE, FALSE, FALSE);
- else
- setanim(self, self.anim_run, TRUE, FALSE, FALSE);
+ if (self.animstate_startframe != self.anim_jump_x) // don't perform another trace if already playing the jump anim
+ {
+ traceline(self.origin + '0 0 1' * PL_MIN_z, self.origin + '0 0 1' * (PL_MIN_z - autocvar_sv_player_jumpanim_minfall), TRUE, self);
+ if(!trace_startsolid && trace_fraction == 1 || self.animstate_startframe == self.anim_idle_x || (self.animstate_startframe == self.anim_melee_x && time - self.animstate_starttime >= 21/20)) // don't get stuck on idle animation in midair, nor melee after it finished
+ {
+ setanim(self, self.anim_jump, FALSE, TRUE, self.restart_jump);
+ self.restart_jump = FALSE;
+ }
+ }
}
- else
- setanim(self, self.anim_idle, TRUE, FALSE, FALSE);
}
+ */
+
+ animdecide_setframes(self, FALSE);
if (self.weaponentity)
- if (!self.weaponentity.animstate_override)
- setanim(self.weaponentity, self.weaponentity.anim_idle, TRUE, FALSE, FALSE);
+ {
+ updateanim(self.weaponentity);
+ if (!self.weaponentity.animstate_override)
+ setanim(self.weaponentity, self.weaponentity.anim_idle, TRUE, FALSE, FALSE);
+ }
}
void SpawnThrownWeapon (vector org, float w)
if (!self.animstate_override)
{
if (random() > 0.5)
- setanim(self, self.anim_pain1, FALSE, TRUE, TRUE);
+ animdecide_setaction(self, ANIMACTION_PAIN1, TRUE);
else
- setanim(self, self.anim_pain2, FALSE, TRUE, TRUE);
+ animdecide_setaction(self, ANIMACTION_PAIN2, TRUE);
}
}
self.respawn_countdown = -1; // do not count down
self.death_time = time;
if (random() < 0.5)
- setanim(self, self.anim_die1, FALSE, TRUE, TRUE);
+ animdecide_setstate(self, self.anim_state | ANIMSTATE_DEAD1, TRUE);
else
- setanim(self, self.anim_die2, FALSE, TRUE, TRUE);
+ animdecide_setstate(self, self.anim_state | ANIMSTATE_DEAD2, TRUE);
if (self.maxs_z > 5)
{
self.maxs_z = 5;
case VOICETYPE_TAUNT:
if(self.classname == "player")
if(self.deadflag == DEAD_NO)
- setanim(self, self.anim_taunt, FALSE, TRUE, TRUE);
+ animdecide_setaction(self, ANIMACTION_TAUNT, TRUE);
if(!sv_taunt)
break;
if(sv_gentle)
case VOICETYPE_TAUNT:
if(self.classname == "player")
if(self.deadflag == DEAD_NO)
- setanim(self, self.anim_taunt, FALSE, TRUE, TRUE);
+ animdecide_setaction(self, ANIMACTION_TAUNT, TRUE);
if(!sv_taunt)
break;
if(sv_gentle)
// The shoot animation looks TERRIBLE without animation blending! Yay for moonwalking while shooting!
//anim = self.anim_shoot;
- if (restartanim)
if (t)
if (!self.crouch) // shoot anim stands up, this looks bad
{
- vector anim;
if(self.weapon == WEP_SHOTGUN && self.BUTTON_ATCK2)
- {
- anim = self.anim_melee;
- anim_z = anim_y / (t + sys_frametime);
- setanim(self, anim, FALSE, TRUE, TRUE);
- }
- else if (self.animstate_startframe == self.anim_idle_x) // only allow shoot anim to override idle animation until we have animation blending
- {
- anim = self.anim_shoot;
- anim_z = anim_y / (t + sys_frametime);
- setanim(self, anim, FALSE, TRUE, TRUE);
- }
+ animdecide_setaction(self, ANIMACTION_MELEE, restartanim);
+ else
+ animdecide_setaction(self, ANIMACTION_SHOOT, restartanim);
}
}
.float animstate_override;
.float animstate_looping;
-// player animation data for this model
-// each vector is as follows:
-// _x = startframe
-// _y = numframes
-// _z = framerate
-.vector anim_die1; // player dies
-.vector anim_die2; // player dies differently
-.vector anim_draw; // player pulls out a weapon
-// .vector anim_duck; // player crouches (from idle to duckidle)
-.vector anim_duckwalk; // player walking while crouching
-.vector anim_duckjump; // player jumping from a crouch
-.vector anim_duckidle; // player idling while crouching
-.vector anim_idle; // player standing
-.vector anim_jump; // player jump
-.vector anim_pain1; // player flinches from pain
-.vector anim_pain2; // player flinches from pain, differently
-.vector anim_shoot; // player shoots
-.vector anim_taunt; // player taunts others (FIXME: no code references this)
-.vector anim_run; // player running forward
-.vector anim_runbackwards; // player running backward
-.vector anim_strafeleft; // player shuffling left quickly
-.vector anim_straferight; // player shuffling right quickly
-//.vector anim_dead1; // player dead (must be identical to last frame of die1)
-//.vector anim_dead2; // player dead (must be identical to last frame of die2)
-.vector anim_forwardright; // player running forward and right
-.vector anim_forwardleft; // player running forward and left
-.vector anim_backright; // player running backward and right
-.vector anim_backleft; // player running back and left
-.vector anim_melee; // player doing the melee action
-.vector anim_duck; // player doing the melee action
-.vector anim_duckwalkbackwards;
-.vector anim_duckwalkstrafeleft;
-.vector anim_duckwalkstraferight;
-.vector anim_duckwalkforwardright;
-.vector anim_duckwalkforwardleft;
-.vector anim_duckwalkbackright;
-.vector anim_duckwalkbackleft;
-
// weapon animation vectors:
.vector anim_fire1;
.vector anim_fire2;
if (autocvar_sv_dodging_sound == 1)
PlayerSound(playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
- setanim(self, self.anim_jump, TRUE, FALSE, TRUE);
+ animdecide_setaction(self, ANIMACTION_JUMP, TRUE);
self.dodging_single_action = 0;
}
../common/command/generic.qh
../common/command/shared_defs.qh
../common/net_notice.qh
+../common/animdecide.qh
autocvars.qh
constants.qh
../warpzonelib/util_server.qc
../warpzonelib/server.qc
+../common/animdecide.qc
../common/util.qc
../common/if-this-file-errors-scroll-up-and-fix-the-warnings.fteqccfail
else
other.lastteleporttime = time;
- if (!other.animstate_override)
if (other.deadflag == DEAD_NO)
- {
- if (other.crouch)
- setanim(other, other.anim_duckjump, FALSE, TRUE, TRUE);
- else
- setanim(other, other.anim_jump, FALSE, TRUE, TRUE);
- }
+ animdecide_setaction(other, ANIMACTION_JUMP, TRUE);
}
else
other.jumppadcount = TRUE;
{
if(autocvar_g_balance_electro_lightning)
if(self.BUTTON_ATCK_prev)
- {
- // prolong the animtime while the gun is being fired
- if(self.animstate_startframe == self.anim_shoot_x && self.animstate_numframes == self.anim_shoot_y)
- weapon_thinkf(WFRAME_DONTCHANGE, autocvar_g_balance_electro_primary_animtime, w_ready);
- else
- weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_electro_primary_animtime, w_ready);
- }
+ weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_electro_primary_animtime, w_ready);
+
if (weapon_prepareattack(0, (autocvar_g_balance_electro_lightning ? 0 : autocvar_g_balance_electro_primary_refire)))
{
if(autocvar_g_balance_electro_lightning)