X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_player.qc;h=17569147fb091d9e08f9ee4ea7e877287c69f34d;hp=0fe71f1448c7dd72fbfad0ab3e23066e1f9f166f;hb=dc25d591f448c6ed191fcf9452d65b87d7a26e90;hpb=d7ce456aa93a09db42b7c9db3c98049b382b791d;ds=sidebyside diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index 0fe71f144..17569147f 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -1,126 +1,3 @@ -.entity accuracy; -.float accuracy_frags[WEP_MAXCOUNT]; - -float weaponstats_buffer; - -void WeaponStats_Init() -{ - if(autocvar_sv_weaponstats_file != "") - weaponstats_buffer = buf_create(); - else - weaponstats_buffer = -1; -} - -#define WEAPONSTATS_GETINDEX(awep,abot,vwep,vbot) (((vwep) + (awep) * (WEP_LAST - WEP_FIRST + 1) - (WEP_FIRST + WEP_FIRST * (WEP_LAST - WEP_FIRST + 1))) * 4 + (abot) * 2 + (vbot)) - -void WeaponStats_ready(entity fh, entity pass, float status) -{ - float i, j, n, ibot, jbot, idx; - vector v; - string prefix, s; - switch(status) - { - case URL_READY_CANWRITE: - // we can write - prefix = strcat(autocvar_hostname, "\t", GetGametype(), "_", GetMapname(), "\t"); - 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")); -#endif - url_fputs(fh, strcat("#config ", ftos(crc16(FALSE, cvar_purechanges)), "\n")); - url_fputs(fh, strcat("#cvar_purechanges ", ftos(cvar_purechanges_count), "\n")); - n = tokenizebyseparator(cvar_purechanges, "\n"); - for(i = 0; i < n; ++i) - url_fputs(fh, strcat("#cvar_purechange ", argv(i), "\n")); - for(i = WEP_FIRST; i <= WEP_LAST; ++i) for(ibot = 0; ibot <= 1; ++ibot) - for(j = WEP_FIRST; j <= WEP_LAST; ++j) for(jbot = 0; jbot <= 1; ++jbot) - { - idx = WEAPONSTATS_GETINDEX(i, ibot, j, jbot); - v = stov(bufstr_get(weaponstats_buffer, idx)); - if(v != '0 0 0') - { - //vector is: kills hits damage - url_fputs(fh, sprintf("%s%d %d\t%d %d\t", prefix, i, ibot, j, jbot)); - url_fputs(fh, sprintf("%d %d %g\n", v_x, v_y, v_z)); - } - } - url_fputs(fh, "#end\n\n"); - url_fclose(fh); - break; - case URL_READY_CANREAD: - // url_fclose is processing, we got a response for writing the data - // this must come from HTTP - print("Got response from weapon stats server:\n"); - while((s = url_fgets(fh))) - print(" ", s, "\n"); - print("End of response.\n"); - url_fclose(fh); - break; - case URL_READY_CLOSED: - // url_fclose has finished - print("Weapon stats written\n"); - buf_del(weaponstats_buffer); - weaponstats_buffer = -1; - break; - case URL_READY_ERROR: - default: - print("Weapon stats writing failed: ", ftos(status), "\n"); - buf_del(weaponstats_buffer); - weaponstats_buffer = -1; - break; - } -} - -void WeaponStats_Shutdown() -{ - if(weaponstats_buffer < 0) - return; - if(autocvar_sv_weaponstats_file != "") - { - url_multi_fopen(autocvar_sv_weaponstats_file, FILE_APPEND, WeaponStats_ready, world); - } - else - { - buf_del(weaponstats_buffer); - weaponstats_buffer = -1; - } -} - -void WeaponStats_LogItem(float awep, float abot, float vwep, float vbot, vector item) -{ - float idx; - if(weaponstats_buffer < 0) - return; - if(awep < WEP_FIRST || vwep < WEP_FIRST) - return; - if(awep > WEP_LAST || vwep > WEP_LAST) - return; - idx = WEAPONSTATS_GETINDEX(awep,abot,vwep,vbot); - bufstr_set(weaponstats_buffer, idx, vtos(stov(bufstr_get(weaponstats_buffer, idx)) + item)); -} -void WeaponStats_LogDamage(float awep, float abot, float vwep, float vbot, float damage) -{ - if(damage < 0) - error("negative damage?"); - WeaponStats_LogItem(awep, abot, vwep, vbot, '0 0 1' * damage + '0 1 0'); -} -void WeaponStats_LogKill(float awep, float abot, float vwep, float vbot) -{ - WeaponStats_LogItem(awep, abot, vwep, vbot, '1 0 0'); -} - -// changes by LordHavoc on 03/29/04 and 03/30/04 at Vermeulen's request -// merged player_run and player_stand to player_anim -// added death animations to player_anim -// can now spawn thrown weapons from anywhere, not just from players -// thrown weapons now fade out after 20 seconds -// created PlayerGib function -// PlayerDie no longer uses hitloc or damage -// PlayerDie now supports dying animations as well as gibbing -// cleaned up PlayerDie a lot -// added CopyBody - .entity pusher; .float pushltime; .float istypefrag; @@ -240,13 +117,20 @@ void player_setupanimsformodel() void player_anim (void) { float deadbits = (self.anim_state & (ANIMSTATE_DEAD1 | ANIMSTATE_DEAD2)); - if(self.deadflag && !deadbits) - if(random() < 0.5) - deadbits = ANIMSTATE_DEAD1; - else - deadbits = ANIMSTATE_DEAD2; + if(self.deadflag) { + if (!deadbits) { + // Decide on which death animation to use. + if(random() < 0.5) + deadbits = ANIMSTATE_DEAD1; + else + deadbits = ANIMSTATE_DEAD2; + } + } else { + // Clear a previous death animation. + deadbits = 0; + } float animbits = deadbits; - if(self.freezetag_frozen) + if(self.frozen) animbits |= ANIMSTATE_FROZEN; if(self.crouch) animbits |= ANIMSTATE_DUCK; @@ -261,13 +145,6 @@ void player_anim (void) } } -void SpawnThrownWeapon (vector org, float w) -{ - if(self.weapons & WepSet_FromWeapon(self.weapon)) - if(W_IsWeaponThrowable(self.weapon)) - W_ThrowNewWeapon(self, self.weapon, FALSE, org, randomvec() * 125 + '0 0 200'); -} - void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) { float take, save; @@ -336,6 +213,9 @@ void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float void calculate_player_respawn_time() { + if(g_ca) + return; + float gametype_setting_tmp; float sdelay_max = GAMETYPE_DEFAULTED_SETTING(respawn_delay_max); float sdelay_small = GAMETYPE_DEFAULTED_SETTING(respawn_delay_small); @@ -414,7 +294,7 @@ void calculate_player_respawn_time() else self.respawn_countdown = -1; // do not count down - if(g_cts || autocvar_g_forced_respawn) + if(autocvar_g_forced_respawn) self.respawn_flags = self.respawn_flags | RESPAWN_FORCE; } @@ -535,7 +415,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht self.health = self.health - take; // pause regeneration for 5 seconds if(take) - self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_pause_health_regen); + self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_pause_health_regen); if (time > self.pain_finished) //Don't switch pain sequences like crazy { @@ -554,7 +434,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht } if(sound_allowed(MSG_BROADCAST, attacker)) - if(!DEATH_ISWEAPON(deathtype, WEP_LASER) || attacker != self || self.health < 2 * autocvar_g_balance_laser_primary_damage * autocvar_g_balance_selfdamagepercent + 1) + if((self.health < 2 * WEP_CVAR_PRI(blaster, damage) * autocvar_g_balance_selfdamagepercent + 1) || !((get_weaponinfo(DEATH_WEAPONOF(deathtype))).spawnflags & WEP_FLAG_CANCLIMB) || attacker != self) // WEAPONTODO: create separate limit for pain notification with laser if(self.health > 1) // exclude pain sounds for laserjumps as long as you aren't REALLY low on health and would die of the next two { @@ -570,12 +450,16 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht PlayerSound(playersound_pain25, CH_PAIN, VOICETYPE_PLAYERSOUND); } } + } - // throw off bot aim temporarily - float shake; + // throw off bot aim temporarily + float shake; + if(IS_BOT_CLIENT(self) && self.health >= 1) + { shake = damage * 5 / (bound(0,skill,100) + 1); self.v_angle_x = self.v_angle_x + (random() * 2 - 1) * shake; self.v_angle_y = self.v_angle_y + (random() * 2 - 1) * shake; + self.v_angle_x = bound(-90, self.v_angle_x, 90); } } else @@ -618,7 +502,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht if(self.alivetime) { - PlayerStats_Event(self, PLAYERSTATS_ALIVETIME, time - self.alivetime); + PS_GR_P_ADDVAL(self, PLAYERSTATS_ALIVETIME, time - self.alivetime); self.alivetime = 0; } @@ -652,7 +536,6 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht // print an obituary message Obituary (attacker, inflictor, self, deathtype); - race_PreDie(); // increment frag counter for used weapon type float w; @@ -667,7 +550,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht frag_deathtype = deathtype; MUTATOR_CALLHOOK(PlayerDies); - weapon_action(self.weapon, WR_PLAYERDEATH); + WEP_ACTION(self.weapon, WR_PLAYERDEATH); RemoveGrapplingHook(self); @@ -685,6 +568,9 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht // when we get here, player actually dies + Unfreeze(self); // remove any icy remains + self.health = 0; // Unfreeze resets health, so we need to set it back + // clear waypoints WaypointSprite_PlayerDead(); // throw a weapon @@ -708,6 +594,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht self.flags &= ~FL_ONGROUND; // dying animation self.deadflag = DEAD_DYING; + // when to allow respawn calculate_player_respawn_time(); @@ -736,7 +623,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht // reset fields the weapons may use just in case for (j = WEP_FIRST; j <= WEP_LAST; ++j) { - weapon_action(j, WR_RESETPLAYER); + WEP_ACTION(j, WR_RESETPLAYER); ATTACK_FINISHED_FOR(self, j) = 0; } } @@ -1342,10 +1229,10 @@ void VoiceMessage(string type, string msg) flood = Say(self, ownteam, world, msg, 1); - if (flood > 0) - GlobalSound(self.sample, CH_VOICE, voicetype); - else if (flood < 0) + if(IS_SPEC(self) || IS_OBSERVER(self) || flood < 0) FakeGlobalSound(self.sample, CH_VOICE, voicetype); + else if (flood > 0) + GlobalSound(self.sample, CH_VOICE, voicetype); } void MoveToTeam(entity client, float team_colour, float type)