self.effects = oldself.effects;
self.glowmod = oldself.glowmod;
self.event_damage = oldself.event_damage;
- self.animstate_startframe = oldself.animstate_startframe;
- self.animstate_numframes = oldself.animstate_numframes;
- self.animstate_framerate = oldself.animstate_framerate;
- self.animstate_starttime = oldself.animstate_starttime;
- self.animstate_endtime = oldself.animstate_endtime;
- self.animstate_override = oldself.animstate_override;
- self.animstate_looping = oldself.animstate_looping;
+ self.anim_state = oldself.anim_state;
+ self.anim_time = oldself.anim_time;
+ self.anim_lower_action = oldself.anim_lower_action;
+ self.anim_lower_time = oldself.anim_lower_time;
+ self.anim_upper_action = oldself.anim_upper_action;
+ self.anim_upper_time = oldself.anim_upper_time;
+ self.anim_implicit_state = oldself.anim_implicit_state;
+ self.anim_implicit_time = oldself.anim_implicit_time;
+ self.anim_lower_implicit_action = oldself.anim_lower_implicit_action;
+ self.anim_lower_implicit_time = oldself.anim_lower_implicit_time;
+ self.anim_upper_implicit_action = oldself.anim_upper_implicit_action;
+ self.anim_upper_implicit_time = oldself.anim_upper_implicit_time;
self.dphitcontentsmask = oldself.dphitcontentsmask;
self.death_time = oldself.death_time;
- self.frame = oldself.frame;
self.pain_finished = oldself.pain_finished;
self.health = oldself.health;
self.armorvalue = oldself.armorvalue;
self.CopyBody_think = oldself.think;
self.nextthink = time;
self.think = CopyBody_Think;
+ // "bake" the current animation frame for clones (they don't get clientside animation)
+ animdecide_setframes(self, FALSE, frame, frame1time, frame2, frame2time);
self = oldself;
}
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)
- {
- 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.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
- {
- 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)
- {
- 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);
- }
+ float deadbits = (self.anim_state & (ANIMSTATE_DEAD1 | ANIMSTATE_DEAD2));
+ if(self.deadflag && !deadbits)
+ if(random() < 0.5)
+ deadbits = ANIMSTATE_DEAD1;
else
- setanim(self, self.anim_idle, TRUE, FALSE, FALSE);
- }
+ deadbits = ANIMSTATE_DEAD2;
+ float animbits = deadbits;
+ if(self.freezetag_frozen)
+ animbits |= ANIMSTATE_FROZEN;
+ if(self.crouch)
+ animbits |= ANIMSTATE_DUCK;
+ animdecide_setstate(self, animbits, FALSE);
+ animdecide_setimplicitstate(self, (self.flags & FL_ONGROUND));
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(g_minstagib)
- if(self.ammo_cells <= 0)
- return;
-
if(g_pinata)
{
float j;
}
else
{
- if(W_IsWeaponThrowable(self.weapon))
- W_ThrowNewWeapon(self, self.weapon, FALSE, org, randomvec() * 125 + '0 0 200');
+ if(WEPSET_CONTAINS_EW(self, self.weapon))
+ if(W_IsWeaponThrowable(self.weapon))
+ W_ThrowNewWeapon(self, self.weapon, FALSE, org, randomvec() * 125 + '0 0 200');
}
}
else
Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, self, attacker);
- if (!g_minstagib)
- {
- v = healtharmor_applydamage(self.armorvalue, autocvar_g_balance_armor_blockpercent, damage);
- take = v_x;
- save = v_y;
- }
- else
- {
- save = 0;
- take = damage;
- }
+
+ v = healtharmor_applydamage(self.armorvalue, autocvar_g_balance_armor_blockpercent, damage);
+ take = v_x;
+ save = v_y;
if(attacker == self)
{
//self.pushltime = 0;
self.istypefrag = 0;
}
- else if(attacker.classname == "player")
+ else if(IS_PLAYER(attacker))
{
self.pusher = attacker;
self.pushltime = time + autocvar_g_maxpushtime;
frag_inflictor = inflictor;
frag_attacker = attacker;
frag_target = self;
+ frag_damage = damage;
damage_take = take;
damage_save = save;
damage_force = force;
{
self.pain_finished = time + 0.5; //Supajoe
- if(sv_gentle < 1) {
+ if(autocvar_sv_gentle < 1) {
if(self.classname != "body") // pain anim is BORKED on our ZYMs, FIXME remove this once we have good models
{
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.dmg_take = self.dmg_take + take;//max(take - 10, 0);
self.dmg_inflictor = inflictor;
- if(g_ca && self != attacker && attacker.classname == "player")
- PlayerScore_Add(attacker, SP_SCORE, (damage - excess) * autocvar_g_ca_damage2score_multiplier);
+ if(g_ca && self != attacker && IS_PLAYER(attacker))
+ PlayerTeamScore_Add(attacker, SP_SCORE, ST_SCORE, (damage - excess) * autocvar_g_ca_damage2score_multiplier);
float abot, vbot, awep;
- abot = (clienttype(attacker) == CLIENTTYPE_BOT);
- vbot = (clienttype(self) == CLIENTTYPE_BOT);
+ abot = (IS_BOT_CLIENT(attacker));
+ vbot = (IS_BOT_CLIENT(self));
valid_damage_for_weaponstats = 0;
awep = 0;
- if(vbot || clienttype(self) == CLIENTTYPE_REAL)
- if(abot || clienttype(attacker) == CLIENTTYPE_REAL)
+ if(vbot || IS_REAL_CLIENT(self))
+ if(abot || IS_REAL_CLIENT(attacker))
if(attacker && self != attacker)
if(IsDifferentTeam(self, attacker))
{
if(valid_damage_for_weaponstats)
WeaponStats_LogKill(awep, abot, self.weapon, vbot);
- if(sv_gentle < 1) // TODO make a "gentle" version?
+ if(autocvar_sv_gentle < 1) // TODO make a "gentle" version?
if(sound_allowed(MSG_BROADCAST, attacker))
{
if(deathtype == DEATH_DROWN)
// print an obituary message
Obituary (attacker, inflictor, self, deathtype);
race_PreDie();
- DropAllRunes(self);
// increment frag counter for used weapon type
float w;
Portal_ClearAllLater(self);
- if(clienttype(self) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(self))
{
- stuffcmd(self, "-zoom\n");
self.fixangle = TRUE;
//msg_entity = self;
//WriteByte (MSG_ONE, SVC_SETANGLE);
// player could have been miraculously resuscitated ;)
// e.g. players in freezetag get frozen, they don't really die
- if(self.health >= 1 || self.classname != "player")
+ if(self.health >= 1 || !IS_PLAYER(self))
return;
// when we get here, player actually dies
self.respawn_countdown = 10; // first number to count down from is 10
else
self.respawn_countdown = -1; // do not count down
+
+ if(g_cts || autocvar_g_forced_respawn)
+ self.respawn_flags = self.respawn_flags | RESPAWN_FORCE;
+
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;
// set up to fade out later
SUB_SetFade (self, time + 6 + random (), 1);
- if(sv_gentle > 0 || autocvar_ekg) {
+ if(autocvar_sv_gentle > 0 || autocvar_ekg) {
// remove corpse
PlayerCorpseDamage (inflictor, attacker, autocvar_sv_gibhealth+1.0, deathtype, hitloc, force);
}
msgin = formatmessage(msgin);
- if(source.classname != "player")
+ if not(IS_PLAYER(source))
colorstr = "^0"; // black for spectators
else if(teamplay)
colorstr = Team_ColorCode(source.team);
}
if(!privatesay)
- if(source.classname != "player")
+ if not(IS_PLAYER(source))
{
if not(intermission_running)
if(teamsay || (autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !(inWarmupStage || gameover)))
if(sourcecmsgstr != "" && !privatesay)
centerprint(source, sourcecmsgstr);
}
- else if(privatesay) // private message, between 2 people only, not sent to server console
+ else if(privatesay) // private message, between 2 people only
{
sprint(source, sourcemsgstr);
sprint(privatesay, msgstr);
+ if not(autocvar_g_chat_tellprivacy) { dedicated_print(msgstr); } // send to server console too if "tellprivacy" is disabled
if(cmsgstr != "")
centerprint(privatesay, cmsgstr);
}
else if(teamsay > 0) // team message, only sent to team mates
{
sprint(source, sourcemsgstr);
- //print(msgstr); // send to server console too
+ dedicated_print(msgstr); // send to server console too
if(sourcecmsgstr != "")
centerprint(source, sourcecmsgstr);
FOR_EACH_REALPLAYER(head) if(head.team == source.team)
else if(teamsay < 0) // spectator message, only sent to spectators
{
sprint(source, sourcemsgstr);
- //print(msgstr); // send to server console too
- FOR_EACH_REALCLIENT(head) if(head.classname != "player")
+ dedicated_print(msgstr); // send to server console too
+ FOR_EACH_REALCLIENT(head) if not(IS_PLAYER(head))
if(head != source)
sprint(head, msgstr);
}
else if(sourcemsgstr != msgstr) // trimmed/server fixed message, sent to all players
{
sprint(source, sourcemsgstr);
- //print(msgstr); // send to server console too
+ dedicated_print(msgstr); // send to server console too
FOR_EACH_REALCLIENT(head)
if(head != source)
sprint(head, msgstr);
if(self.pusher)
{
msg_entity = self;
- if(clienttype(msg_entity) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(msg_entity))
soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTN_NONE);
}
break;
break;
if(!sv_taunt)
break;
- if(sv_gentle)
+ if(autocvar_sv_gentle)
break;
tauntrand = random();
msg_entity = self;
}
break;
case VOICETYPE_TAUNT:
- if(self.classname == "player")
+ if(IS_PLAYER(self))
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)
+ if(autocvar_sv_gentle)
break;
msg_entity = self;
if (msg_entity.cvar_cl_voice_directional >= 1)
if(self.pusher)
{
msg_entity = self.pusher;
- if(clienttype(msg_entity) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(msg_entity))
{
if(msg_entity.cvar_cl_voice_directional == 1)
soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_MIN);
if(self.pusher)
{
msg_entity = self.pusher;
- if(clienttype(msg_entity) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(msg_entity))
{
if(msg_entity.cvar_cl_voice_directional == 1)
soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_MIN);
soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE);
}
msg_entity = self;
- if(clienttype(msg_entity) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(msg_entity))
soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTN_NONE);
}
break;
break;
if(!sv_taunt)
break;
- if(sv_gentle)
+ if(autocvar_sv_gentle)
break;
tauntrand = random();
FOR_EACH_REALCLIENT(msg_entity)
}
break;
case VOICETYPE_TAUNT:
- if(self.classname == "player")
+ if(IS_PLAYER(self))
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)
+ if(autocvar_sv_gentle)
break;
FOR_EACH_REALCLIENT(msg_entity)
{
FakeGlobalSound(self.sample, CH_VOICE, voicetype);
}
-void MoveToTeam(entity client, float team_colour, float type, float show_message)
+void MoveToTeam(entity client, float team_colour, float type)
{
-// show_message
-// 0 (00) automove centerprint, admin message
-// 1 (01) automove centerprint, no admin message
-// 2 (10) no centerprint, admin message
-// 3 (11) no centerprint, no admin message
-
float lockteams_backup;
lockteams_backup = lockteams; // backup any team lock
TeamchangeFrags(client); // move the players frags
SetPlayerColors(client, team_colour - 1); // set the players colour
- Damage(client, client, client, 100000, ((show_message & 2) ? DEATH_QUIET : DEATH_AUTOTEAMCHANGE), client.origin, '0 0 0'); // kill the player
+ Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE, client.origin, '0 0 0'); // kill the player
lockteams = lockteams_backup; // restore the team lock
LogTeamchange(client.playerid, client.team, type);
-
- if not(show_message & 1) // admin message
- sprint(client, strcat("\{1}\{13}^3", admin_name(), "^7: You have been moved to the ", Team_ColorNameLowerCase(team_colour), " team\n")); // send a chat message
-
- bprint(strcat(client.netname, " joined the ", ColoredTeamName(client.team), "\n"));
}