From a8e1017ded352efb6f9189cfd735c5fdbdec671d Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Mon, 22 Nov 2010 14:26:27 +0100 Subject: [PATCH] way more fixes --- qcsrc/common/constants.qh | 3 +- qcsrc/server/accuracy.qc | 46 +++++++++++++++++++------ qcsrc/server/cl_client.qc | 35 ------------------- qcsrc/server/cl_weaponsystem.qc | 7 +--- qcsrc/server/clientcommands.qc | 1 - qcsrc/server/defs.qh | 10 ------ qcsrc/server/g_damage.qc | 12 ++----- qcsrc/server/g_world.qc | 54 +++-------------------------- qcsrc/server/miscfunctions.qc | 22 ------------ qcsrc/server/w_common.qc | 60 ++++++++++++--------------------- 10 files changed, 65 insertions(+), 185 deletions(-) diff --git a/qcsrc/common/constants.qh b/qcsrc/common/constants.qh index 87484cd8f..8cc24634c 100644 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@ -111,6 +111,7 @@ const float ENT_CLIENT_TRIGGER_MUSIC = 26; const float ENT_CLIENT_HOOK = 27; const float ENT_CLIENT_LGBEAM = 28; const float ENT_CLIENT_GAUNTLET = 29; +const float ENT_CLIENT_ACCURACY = 30; const float ENT_CLIENT_TURRET = 40; @@ -300,8 +301,6 @@ const float STAT_SWITCHWEAPON = 36; const float STAT_GAMESTARTTIME = 37; const float STAT_STRENGTH_FINISHED = 38; const float STAT_INVINCIBLE_FINISHED = 39; -const float STAT_DAMAGE_HITS = 40; // Used by the weapon stats code, represents the total amount of damage done to other players -const float STAT_DAMAGE_FIRED = 41;// Used by the weapon stats code, represents the total amount of potential damage fired const float STAT_PRESSED_KEYS = 42; const float STAT_ALLOW_OLDNEXBEAM = 43; // this stat could later contain some other bits of info, like, more server-side particle config const float STAT_FUEL = 44; diff --git a/qcsrc/server/accuracy.qc b/qcsrc/server/accuracy.qc index 4e86e7052..30f9e18d2 100644 --- a/qcsrc/server/accuracy.qc +++ b/qcsrc/server/accuracy.qc @@ -1,12 +1,21 @@ .entity accuracy; .float accuracy_hit[WEP_MAXCOUNT]; .float accuracy_fired[WEP_MAXCOUNT]; +FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(accuracy_hit); +FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(accuracy_fired); -void accuracy_send(entity to, float sf) +float accuracy_send(entity to, float sf) { float w, f; + entity a; WriteByte(MSG_ENTITY, ENT_CLIENT_ACCURACY); - if(to != self.owner) + + a = self.owner; + if(a.classname == "spectator") + a = a.enemy; + a = a.accuracy; + + if(to != a.owner) if not(self.owner.cvar_cl_accuracy_data_share && autocvar_sv_accuracy_data_share) sf = 0; // note: zero sendflags can never be sent... so we can use that to say that we send no accuracy! @@ -34,6 +43,7 @@ void accuracy_init(entity e) e.accuracy.owner = e; e.accuracy.classname = "accuracy"; e.accuracy.SendEntity = accuracy_send; + e.accuracy.drawonlytoclient = e; } void accuracy_free(entity e) @@ -50,18 +60,34 @@ void accuracy_resend(entity e) // update accuracy stats void accuracy_set(entity e, float w, float hit, float fired) { - e = e.accuracy; + entity a; + a = e.accuracy; + if(!a) + return; w -= WEP_FIRST; - e.(accuracy_hit[w]) = hit; - e.(accuracy_fired[w]) = fired; - e.SendFlags |= pow(2, w); + a.(accuracy_hit[w]) = hit; + a.(accuracy_fired[w]) = fired; + w = pow(2, w); + a.SendFlags |= w; + FOR_EACH_CLIENT(a) + if(a.classname == "spectator") + if(a.enemy == e) + a.SendFlags |= w; } void accuracy_add(entity e, float w, float hit, float fired) { - e = e.accuracy; + entity a; + a = e.accuracy; + if(!a) + return; w -= WEP_FIRST; - e.(accuracy_hit[w]) += hit; - e.(accuracy_fired[w]) += fired; - e.SendFlags |= pow(2, w); + a.(accuracy_hit[w]) += hit; + a.(accuracy_fired[w]) += fired; + w = pow(2, w); + a.SendFlags |= w; + FOR_EACH_CLIENT(a) + if(a.classname == "spectator") + if(a.enemy == e) + a.SendFlags |= w; } diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 87d567f29..b2127febe 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -2271,33 +2271,13 @@ void GetPressedKeys(void) { self.pressedkeys &~= KEY_CROUCH; } -void update_stats (float number, float hit, float fired) { -// self.stat_hit = number + ((number==0) ? 1 : 64) * hit * sv_accuracy_data_share; -// self.stat_fired = number + ((number==0) ? 1 : 64) * fired * sv_accuracy_data_share; - - if(number) { - self.stat_hit = number + 64 * hit * sv_accuracy_data_share; - self.stat_fired = number + 64 * fired * sv_accuracy_data_share; - } else { - self.stat_hit = hit * sv_accuracy_data_share; - self.stat_fired = fired * sv_accuracy_data_share; - } -} - /* ====================== spectate mode routines ====================== */ -.float weapon_count; void SpectateCopy(entity spectatee) { - if(spectatee.weapon_count < WEP_LAST) { - update_stats (spectatee.weapon_count, spectatee.cvar_cl_accuracy_data_share * floor(spectatee.stats_hit[spectatee.weapon_count - 1]), spectatee.cvar_cl_accuracy_data_share * floor(spectatee.stats_fired[spectatee.weapon_count - 1])); - spectatee.weapon_count ++; - } else - update_stats (0, spectatee.cvar_cl_accuracy_data_share * spectatee.stat_hit, spectatee.cvar_cl_accuracy_data_share * spectatee.stat_fired); - other = spectatee; MUTATOR_CALLHOOK(SpectateCopy); self.armortype = spectatee.armortype; @@ -2366,8 +2346,6 @@ float SpectateNext() { //stuffcmd(self, "set viewsize $tmpviewsize \n"); self.movetype = MOVETYPE_NONE; - self.enemy.weapon_count = 0; - if(!SpectateUpdate()) PutObserverInServer(); @@ -2415,8 +2393,6 @@ void LeaveSpectatorMode() if(cvar("g_campaign")) campaign_bots_may_start = 1; - self.stat_count = WEP_LAST; - PutClientInServer(); if(self.classname == "player") @@ -2520,14 +2496,12 @@ void SpectatorThink() self.classname = "spectator"; } else { self.classname = "observer"; - self.stat_count = WEP_LAST; PutClientInServer(); } } else if (self.BUTTON_ATCK2) { self.welcomemessage_time = 0; self.flags &~= FL_JUMPRELEASED; self.classname = "observer"; - self.stat_count = WEP_LAST; PutClientInServer(); } else { if(!SpectateUpdate()) @@ -2965,15 +2939,6 @@ void PlayerPostThink (void) stuffcmd(self, strcat("name ", self.netname, substring(ftos(random()), 2, -1), "\n")); } - // send the clients accuracy stats to the client - if(self.stat_count > 0) - if(frametime) - { - self.stat_hit = self.stat_count + 64 * floor(self.(stats_hit[self.stat_count - 1])); - self.stat_fired = self.stat_count + 64 * floor(self.(stats_fired[self.stat_count - 1])); - self.stat_count -= 1; - } - if(sv_maxidle && frametime) { // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero). diff --git a/qcsrc/server/cl_weaponsystem.qc b/qcsrc/server/cl_weaponsystem.qc index 04666c47f..14618cadf 100644 --- a/qcsrc/server/cl_weaponsystem.qc +++ b/qcsrc/server/cl_weaponsystem.qc @@ -160,12 +160,7 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector m // track max damage if not(inWarmupStage) { - entity w; - w = get_weaponinfo(ent.weapon); - if(w.spawnflags & WEP_TYPE_SPLASH) { // splash damage - ent.stats_fired[ent.weapon - 1] += maxdamage; - ent.stat_fired = ent.weapon + 64 * floor(ent.stats_fired[ent.weapon - 1]); - } + accuracy_add(ent, ent.weapon, maxdamage, 0); } W_HitPlotAnalysis(ent, v_forward, v_right, v_up); diff --git a/qcsrc/server/clientcommands.qc b/qcsrc/server/clientcommands.qc index 0cbe3017e..e221911d3 100644 --- a/qcsrc/server/clientcommands.qc +++ b/qcsrc/server/clientcommands.qc @@ -235,7 +235,6 @@ void SV_ParseClientCommand(string s) { self.caplayer = 1; PlayerScore_Clear(self); bprint ("^4", self.netname, "^4 is playing now\n"); - self.stat_count = WEP_LAST; PutClientInServer(); if(cvar("g_campaign")) campaign_bots_may_start = 1; diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index b99f27544..a0718d839 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -598,18 +598,8 @@ string matchid; .float hitplotfh; .string noise4; -.float stat_hit; -.float stat_fired; -.float stat_count; - -.float stats_hit[WEP_MAXCOUNT]; // for hitscan bullets hit -.float stats_fired[WEP_MAXCOUNT]; // for hitscan bullets fired - .float last_pickup; -FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(stats_hit); -FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(stats_fired); - .float stat_leadlimit; float radar_showennemies; diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index 460c608dc..673bf5688 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -851,10 +851,7 @@ void Damage_RecordDamage(entity attacker, float deathtype, float damage) if not(inWarmupStage) if (weaponid) - if ((clienttype(attacker) == CLIENTTYPE_REAL) | (clienttype(attacker) == CLIENTTYPE_BOT)) { - attacker.stats_hit[weaponid - 1] += damage; - attacker.stat_hit = weaponid + 64 * floor(attacker.stats_hit[weaponid - 1]); - } + accuracy_add(attacker, weaponid, 0, damage); } float RadiusDamage_running; @@ -875,7 +872,6 @@ float RadiusDamage (entity inflictor, entity attacker, float coredamage, float e float tfloorforce; float stat_damagedone; - float stat_maxdamage; if(RadiusDamage_running) { @@ -913,7 +909,6 @@ float RadiusDamage (entity inflictor, entity attacker, float coredamage, float e } stat_damagedone = 0; - stat_maxdamage = 0; targ = WarpZone_FindRadius (blastorigin, rad, FALSE); while (targ) @@ -1035,10 +1030,7 @@ float RadiusDamage (entity inflictor, entity attacker, float coredamage, float e if(targ.deadflag == DEAD_NO) if(targ != attacker) if(!teamplay || targ.team != attacker.team) - { stat_damagedone += finaldmg; - stat_maxdamage += coredamage; - } } if(targ == directhitentity || DEATH_ISSPECIAL(deathtype)) @@ -1054,7 +1046,7 @@ float RadiusDamage (entity inflictor, entity attacker, float coredamage, float e RadiusDamage_running = 0; - Damage_RecordDamage(attacker, deathtype, min(stat_maxdamage, stat_damagedone)); + Damage_RecordDamage(attacker, deathtype, min(coredamage, stat_damagedone)); return total_damage_to_creatures; } diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index ded4518d3..4628aef45 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -801,8 +801,6 @@ void spawnfunc_worldspawn (void) addstat(STAT_INVINCIBLE_FINISHED, AS_FLOAT, invincible_finished); addstat(STAT_PRESSED_KEYS, AS_FLOAT, pressedkeys); addstat(STAT_FUEL, AS_INT, ammo_fuel); - addstat(STAT_DAMAGE_HITS, AS_INT, stat_hit); - addstat(STAT_DAMAGE_FIRED, AS_INT, stat_fired); addstat(STAT_SHOTORG, AS_INT, stat_shotorg); addstat(STAT_LEADLIMIT, AS_FLOAT, stat_leadlimit); addstat(STAT_BULLETS_LOADED, AS_INT, campingrifle_bulletcounter); @@ -1544,8 +1542,6 @@ only called if a time or frag limit has expired */ void NextLevel() { - float i; - gameover = TRUE; intermission_running = 1; @@ -1574,52 +1570,10 @@ void NextLevel() GameLogClose(); -// TO DO - -// save the stats to a text file on the client -// stuffcmd(other, log_stats "stats/file_name"); -// bprint stats -// stuffcmd(other, log_stats ""); -// use a filename similar to the demo name - // string file_name; - // file_name = strcat("\nlog_file \"stats/", strftime(TRUE, "%Y-%m-%d_%H-%M"), "_", mapname, ".txt\""); // open the log file - -// write a stats parser for the menu - - if(cvar("sv_accuracy_data_send")) { - string stats_to_send; - - FOR_EACH_CLIENT(other) { // make the string to send - FixIntermissionClient(other); - - if(other.cvar_cl_accuracy_data_share) { - stats_to_send = strcat(stats_to_send, ":hits:", other.netname); - - for(i = WEP_FIRST; i <= WEP_LAST; ++i) - stats_to_send = strcat(stats_to_send, ":", ftos(other.stats_hit[i-1])); - - stats_to_send = strcat(stats_to_send, "\n:fired:", other.netname); - - for(i = WEP_FIRST; i <= WEP_LAST; ++i) - stats_to_send = strcat(stats_to_send, ":", ftos(other.stats_fired[i-1])); - - stats_to_send = strcat(stats_to_send, "\n"); - } - } - - FOR_EACH_REALCLIENT(other) { // only spam humans - Score_NicePrint(other); // print the score - - if(other.cvar_cl_accuracy_data_receive) // send the stats string to all the willing clients - bprint(stats_to_send); - } - } else { // ye olde message - FOR_EACH_PLAYER(other) { - FixIntermissionClient(other); - - if(other.winning) - bprint(other.netname, " ^7wins.\n"); - } + FOR_EACH_PLAYER(other) { + FixIntermissionClient(other); + if(other.winning) + bprint(other.netname, " ^7wins.\n"); } if(cvar("g_campaign")) diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 5b8ec7127..25222a38f 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -468,28 +468,6 @@ string formatmessage(string msg) replacement = ftos(vlen(self.velocity - self.velocity_z * '0 0 1')); else if (escape == "S") replacement = ftos(vlen(self.velocity)); - else if (escape == "v") { - float weapon_number; - local entity stats; - - if(self.classname == "spectator") - stats = self.enemy; - else - stats = self; - - weapon_number = stats.weapon; - - if (!weapon_number) - weapon_number = stats.switchweapon; - - if (!weapon_number) - weapon_number = stats.cnt; - - if(stats.cvar_cl_accuracy_data_share && stats.stats_fired[weapon_number - 1]) - replacement = ftos(bound(0, floor(100 * stats.stats_hit[weapon_number - 1] / stats.stats_fired[weapon_number - 1]), 100)); - else - replacement = "~"; // or something to indicate NULL, not available - } msg = strcat(substring(msg, 0, p), replacement, substring(msg, p+2, strlen(msg) - (p+2))); p = p + strlen(replacement); diff --git a/qcsrc/server/w_common.qc b/qcsrc/server/w_common.qc index 320ffb750..378cab4de 100644 --- a/qcsrc/server/w_common.qc +++ b/qcsrc/server/w_common.qc @@ -28,6 +28,7 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f local vector hitloc, force, endpoint, dir; local entity ent, endent; local float endq3surfaceflags; + float totaldmg; float length; vector beampos; @@ -35,8 +36,6 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f entity pseudoprojectile; float f, ffs; - float hit; - railgun_start = start; railgun_end = end; @@ -47,6 +46,8 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f // go a little bit into the wall because we need to hit this wall later end = end + dir; + totaldmg = 0; + // trace multiple times until we hit a wall, each obstacle will be made // non-solid so we can hit the next, while doing this we spawn effects and // note down which entities were hit so we can damage them later @@ -121,18 +122,14 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f // get the details we need to call the damage function hitloc = ent.railgunhitloc; - //for stats so that team hit will count as a miss - if(ent.flags & FL_CLIENT) - if(ent.deadflag == DEAD_NO) - hit = 1; - - if(teams_matter) - if(ent.team == self.team) - hit = 0; - f = ExponentialFalloff(mindist, maxdist, halflifedist, ent.railgundistance); ffs = ExponentialFalloff(mindist, maxdist, forcehalflifedist, ent.railgundistance); + if(ent.flags & FL_CLIENT) + if(ent.deadflag == DEAD_NO) + if(!teamplay || ent.team != self.team) + totaldmg += bdamage * f; + // apply the damage if (ent.takedamage) Damage (ent, self, self, bdamage * f, deathtype, hitloc, force * ffs); @@ -152,15 +149,7 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f // calculate hits and fired shots for hitscan if not(inWarmupStage) - { - self.stats_fired[self.weapon - 1] += 1; - self.stat_fired = self.weapon + 64 * floor(self.stats_fired[self.weapon - 1]); - - if(hit) { - self.stats_hit[self.weapon - 1] += 1; - self.stat_hit = self.weapon + 64 * floor(self.stats_hit[self.weapon - 1]); - } - } + accuracy_add(self, self.weapon, 0, min(bdamage, totaldmg)); trace_endpos = endpoint; trace_ent = endent; @@ -170,11 +159,13 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f .float dmg_edge; .float dmg_force; .float dmg_radius; +.float dmg_total; void W_BallisticBullet_Hit (void) { - float f; + float f, q; f = pow(bound(0, vlen(self.velocity) / vlen(self.oldvelocity), 1), 2); // energy multiplier + q = 1 + self.dmg_edge / self.dmg; if(other.solid == SOLID_BSP) Damage_DamageInfo(self.origin, self.dmg * f, 0, 0, max(1, self.dmg_force) * normalize(self.velocity) * f, self.projectiledeathtype, self); @@ -195,10 +186,13 @@ void W_BallisticBullet_Hit (void) if(self.dmg_edge != 0) { if(headshot) + { + f *= q; AnnounceTo(self.owner, "headshot"); - if(yoda) - AnnounceTo(self.owner, "awesome"); + } } + if(yoda) + AnnounceTo(self.owner, "awesome"); // calculate hits for ballistic weapons if (other.flags & FL_CLIENT) // is the player a client @@ -206,8 +200,10 @@ void W_BallisticBullet_Hit (void) if ((!(teamplay)) | (other.team != self.owner.team)) // not teamplay (ctf, kh, tdm etc) or the victim is in the same team if not(inWarmupStage) // not in warm up stage { - self.owner.stats_hit[self.owner.weapon - 1] += 1; - self.owner.stat_hit = self.owner.weapon + 64 * floor(self.owner.stats_hit[self.owner.weapon - 1]); + // do not exceed 100% + q = min(self.dmg * q, self.dmg_total + f * self.dmg) - self.dmg_total; + self.dmg_total += f * self.dmg; + accuracy_add(self.owner, self.owner.weapon, 0, q); } } @@ -424,13 +420,6 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f savetime = frametime; frametime = 0.05; - // update the accuracy stats - increase shots fired by 1 - if not(inWarmupStage) - { - oldself.stats_fired[oldself.weapon - 1] += 1; - oldself.stat_fired = oldself.weapon + 64 * floor(oldself.stats_fired[oldself.weapon - 1]); - } - for(;;) { // DP tracetoss is stupid and always traces in 0.05s @@ -491,13 +480,6 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f return; } - // update the accuracy stats - if not(inWarmupStage) - { - self.stats_fired[self.weapon - 1] += 1; - self.stat_fired = self.weapon + 64 * floor(self.stats_fired[self.weapon - 1]); - } - if(tracereffects & EF_RED) CSQCProjectile(proj, TRUE, PROJECTILE_BULLET_GLOWING_TRACER, TRUE); else if(tracereffects & EF_BLUE) -- 2.39.2