X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_player.qc;h=60df5dd314a21d7008cd1232731a006dadffada3;hp=dcf1ab76842afdd5a8885d68d4aacc16811c4627;hb=d0db4b5db11800d291fbdba93a67e8487fa033e2;hpb=f879dea04474678d9a263cf5d8c127415e390ca5 diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index dcf1ab768..60df5dd31 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -26,7 +26,7 @@ void WeaponStats_ready(entity fh, entity pass, float status) url_fputs(fh, "#begin statsfile\n"); url_fputs(fh, strcat("#date ", strftime(TRUE, "%a %b %e %H:%M:%S %Z %Y"), "\n")); #ifdef WATERMARK - url_fputs(fh, strcat("#version ", WATERMARK(), "\n")); + url_fputs(fh, strcat("#version ", WATERMARK, "\n")); #endif url_fputs(fh, strcat("#config ", ftos(crc16(FALSE, cvar_purechanges)), "\n")); url_fputs(fh, strcat("#cvar_purechanges ", ftos(cvar_purechanges_count), "\n")); @@ -161,16 +161,20 @@ void CopyBody(float keepvelocity) 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; @@ -208,6 +212,8 @@ void CopyBody(float keepvelocity) 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; } @@ -225,132 +231,33 @@ float player_getspecies() 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) @@ -431,7 +338,6 @@ void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float } void ClientKill_Now_TeamChange(); -void freezetag_CheckWinner(); void PlayerDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) { @@ -440,9 +346,6 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht float valid_damage_for_weaponstats; float excess; - if((g_arena && numspawned < 2) || (g_ca && allowed_to_spawn) && !inWarmupStage) - return; - dh = max(self.health, 0); da = max(self.armorvalue, 0); @@ -560,15 +463,15 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht { 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); } } @@ -647,7 +550,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht 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) @@ -672,18 +575,9 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht } } - if(!g_freezetag) - { - // become fully visible - self.alpha = default_player_alpha; - // throw a weapon - SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon); - } - // print an obituary message Obituary (attacker, inflictor, self, deathtype); race_PreDie(); - DropAllRunes(self); // increment frag counter for used weapon type float w; @@ -692,18 +586,12 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht if(accuracy_isgooddamage(attacker, self)) attacker.accuracy.(accuracy_frags[w-1]) += 1; - if(deathtype == DEATH_HURTTRIGGER && g_freezetag) - { - PutClientInServer(); - count_alive_players(); // re-count players - freezetag_CheckWinner(); - return; - } - frag_attacker = attacker; frag_inflictor = inflictor; frag_target = self; + frag_deathtype = deathtype; MUTATOR_CALLHOOK(PlayerDies); + weapon_action(self.weapon, WR_PLAYERDEATH); RemoveGrapplingHook(self); @@ -712,7 +600,6 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht if(clienttype(self) == CLIENTTYPE_REAL) { - stuffcmd(self, "-zoom\n"); self.fixangle = TRUE; //msg_entity = self; //WriteByte (MSG_ONE, SVC_SETANGLE); @@ -721,19 +608,23 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht //WriteAngle (MSG_ONE, 80); } - if(defer_ClientKill_Now_TeamChange) // TODO does this work with FreezeTag? - ClientKill_Now_TeamChange(); - - if(g_arena) - Spawnqueue_Unmark(self); + if(defer_ClientKill_Now_TeamChange) + ClientKill_Now_TeamChange(); // can turn player into spectator - if(g_freezetag) + // 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") return; // when we get here, player actually dies - // clear waypoints (do this AFTER FreezeTag) + + // clear waypoints WaypointSprite_PlayerDead(); + // throw a weapon + SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon); + // become fully visible + self.alpha = default_player_alpha; // make the corpse upright (not tilted) self.angles_x = 0; self.angles_z = 0; @@ -772,11 +663,15 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht 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; @@ -789,7 +684,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht // 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); } @@ -1026,17 +921,18 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f 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) @@ -1050,7 +946,7 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f else if(teamsay < 0) // spectator message, only sent to spectators { sprint(source, sourcemsgstr); - //print(msgstr); // send to server console too + dedicated_print(msgstr); // send to server console too FOR_EACH_REALCLIENT(head) if(head.classname != "player") if(head != source) sprint(head, msgstr); @@ -1058,7 +954,7 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f 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); @@ -1240,7 +1136,7 @@ void FakeGlobalSound(string sample, float chan, float voicetype) break; if(!sv_taunt) break; - if(sv_gentle) + if(autocvar_sv_gentle) break; tauntrand = random(); msg_entity = self; @@ -1255,10 +1151,10 @@ void FakeGlobalSound(string sample, float chan, float voicetype) 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) + if(autocvar_sv_gentle) break; msg_entity = self; if (msg_entity.cvar_cl_voice_directional >= 1) @@ -1337,7 +1233,7 @@ void GlobalSound(string sample, float chan, float voicetype) break; if(!sv_taunt) break; - if(sv_gentle) + if(autocvar_sv_gentle) break; tauntrand = random(); FOR_EACH_REALCLIENT(msg_entity) @@ -1352,10 +1248,10 @@ void GlobalSound(string sample, float chan, float voicetype) 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) + if(autocvar_sv_gentle) break; FOR_EACH_REALCLIENT(msg_entity) { @@ -1403,14 +1299,8 @@ void VoiceMessage(string type, string msg) 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 @@ -1419,14 +1309,9 @@ void MoveToTeam(entity client, float team_colour, float type, float show_message 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")); }