[nexuiz-commits] r8291 - in trunk/data: . qcsrc/client qcsrc/server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Mon Nov 16 16:47:46 EST 2009


Author: fruitiex
Date: 2009-11-16 16:47:45 -0500 (Mon, 16 Nov 2009)
New Revision: 8291

Modified:
   trunk/data/defaultNexuiz.cfg
   trunk/data/qcsrc/client/Main.qc
   trunk/data/qcsrc/client/sbar.qc
   trunk/data/qcsrc/server/cl_client.qc
   trunk/data/qcsrc/server/cl_weaponsystem.qc
   trunk/data/qcsrc/server/clientcommands.qc
   trunk/data/qcsrc/server/defs.qh
   trunk/data/qcsrc/server/g_damage.qc
   trunk/data/qcsrc/server/g_world.qc
   trunk/data/qcsrc/server/miscfunctions.qc
   trunk/data/qcsrc/server/w_common.qc
   trunk/data/qcsrc/server/w_shotgun.qc
Log:
Patch by Spaceman: Allow viewing the accuracy stats of spectated players (client and serverside setting, default off)


Modified: trunk/data/defaultNexuiz.cfg
===================================================================
--- trunk/data/defaultNexuiz.cfg	2009-11-16 07:47:47 UTC (rev 8290)
+++ trunk/data/defaultNexuiz.cfg	2009-11-16 21:47:45 UTC (rev 8291)
@@ -1682,3 +1682,9 @@
 set sv_pitch_fixyaw 1 "workaround to fix the aiming direction on stupidly made player models, FIXME fix the models and set this to 0"
 
 set rescan_pending 0 "set to 1 to schedule a fs_rescan at the end of this match"
+
+// weapon accuracy stats
+set sv_accuracy_data_share 1 "1 send weapon accuracy data statistics to spectating clients, depends on cl_accuracy_data_share"
+set sv_accuracy_data_send 1 "1 send weapon accuracy data statistics and improved score info to all the clients at the end of the match, depends on cl_accuracy_data_receive, 0 send the current 'player has won' to all the clients"
+set cl_accuracy_data_share 0 "1 share my weapon accuracy data statistics with other players, 0 keep my weapon accuracy data statistics hidden"
+set cl_accuracy_data_receive 0 "1 receive weapon accuracy data statistics at the end of the match"

Modified: trunk/data/qcsrc/client/Main.qc
===================================================================
--- trunk/data/qcsrc/client/Main.qc	2009-11-16 07:47:47 UTC (rev 8290)
+++ trunk/data/qcsrc/client/Main.qc	2009-11-16 21:47:45 UTC (rev 8291)
@@ -720,6 +720,13 @@
 
 	if(newspectatee_status != spectatee_status)
 	{
+		float i;
+		// clear the weapon accuracy stats
+		for(i = WEP_FIRST; i <= WEP_LAST; ++i) {
+			weapon_hits[i] = 0;
+			weapon_fired[i] = 0;
+		}
+
 		// clear race stuff
 		race_laptime = 0;
 		race_checkpointtime = 0;

Modified: trunk/data/qcsrc/client/sbar.qc
===================================================================
--- trunk/data/qcsrc/client/sbar.qc	2009-11-16 07:47:47 UTC (rev 8290)
+++ trunk/data/qcsrc/client/sbar.qc	2009-11-16 21:47:45 UTC (rev 8291)
@@ -132,7 +132,8 @@
 	if(sbar_accuracy_hud)
  	{
 		if(weapon_damage)
- 			weapon_stats = rint(100*weapon_hit/weapon_damage);
+ 			weapon_stats = floor(100 * weapon_hit / weapon_damage);
+
 		fill_colour = Sbar_AccuracyColor(weapon_stats);
 		if(weapon_damage)
 			drawpic(pos - '2 0 0' + '0 1 0' * (w_height - accuracybar_height), "gfx/hud/sb_accuracy_bar.tga", '1 0 0' * w_width + '0 1 0' * accuracybar_height, fill_colour, sbar_alpha_fg, DRAWFLAG_NORMAL);
@@ -1190,7 +1191,7 @@
 		weapon_hit = weapon_hits[i];
 		weapon_damage = weapon_fired[i];
 		if(weapon_damage)
-			weapon_stats = bound(0, rint(100 * weapon_hit / weapon_damage), 100);
+			weapon_stats = bound(0, floor(100 * weapon_hit / weapon_damage), 100);
 		self = get_weaponinfo(i);
 		float weapon_alpha;
 
@@ -2227,6 +2228,7 @@
 	float left_border;  // position where the weapons start, the description is in the border
 	vector fill_colour, fill_size;
 	vector pos;
+	vector border_colour;
 
 	float col_margin = 20;  // pixels between the columns
 	float row_margin = 20;  // pixels between the rows
@@ -2264,11 +2266,11 @@
 		weapon_hit = weapon_hits[i];
 		weapon_damage = weapon_fired[i];
 		self = get_weaponinfo(i);
+		border_colour = (i == activeweapon) ? '1 1 1' : '0 0 0';  // white or black border
 
-		//if ((weapon_number != 42))  // print them all :)
 		if (weapon_damage) {
 			if (self.weapon_type == WEP_TYPE_SPLASH) {
-				weapon_stats = bound(0, rint(100 * weapon_hit / weapon_damage), 100);
+				weapon_stats = bound(0, floor(100 * weapon_hit / weapon_damage), 100);
 
 				fill_colour_x = 1 - 0.015 * weapon_stats;
 				fill_colour_y = 1 - 0.015 * (100 - weapon_stats);
@@ -2299,7 +2301,7 @@
 
 				// background
 				drawpic(pos, "gfx/hud/sb_accuracy", fill_size , fill_colour, sbar_alpha_bg, DRAWFLAG_NORMAL);
-				drawborderlines(sbar_border_thickness, pos, fill_size, '0 0 0', sbar_alpha_bg, DRAWFLAG_NORMAL);
+				drawborderlines(sbar_border_thickness, pos, fill_size, border_colour, sbar_alpha_bg, DRAWFLAG_NORMAL);
 
 				// the weapon
 				drawpic(pos, strcat("gfx/hud/inv_weapon", ftos(i-1)), '1 0.5 0' * fill_size_x , '1 1 1', sbar_alpha_fg, DRAWFLAG_NORMAL);
@@ -2317,8 +2319,8 @@
 				drawstringright(pos + '4.5 0 0' * sbar_fontsize_x + '0 9 0' * sbar_fontsize_y, ftos(max(0, weapon_damage - weapon_hit)), sbar_fontsize, '1 1 1', sbar_alpha_fg, DRAWFLAG_NORMAL);
 
 				++count_splash;
-			} else if ((self.weapon_type == WEP_TYPE_HITSCAN) && (weapon_damage)) {
-				weapon_stats = bound(0, rint(100 * weapon_hit / weapon_damage), 100);
+			} else if (self.weapon_type == WEP_TYPE_HITSCAN) {
+				weapon_stats = bound(0, floor(100 * weapon_hit / weapon_damage), 100);
 
 				fill_colour_x = 1 - 0.015 * weapon_stats;
 				fill_colour_y = 1 - 0.015 * (100 - weapon_stats);
@@ -2349,7 +2351,7 @@
 
 				// background
 				drawpic(pos, "gfx/hud/sb_accuracy", fill_size , fill_colour, sbar_alpha_bg, DRAWFLAG_NORMAL);
-				drawborderlines(sbar_border_thickness, pos, fill_size, '0 0 0', sbar_alpha_bg, DRAWFLAG_NORMAL);
+				drawborderlines(sbar_border_thickness, pos, fill_size, border_colour, sbar_alpha_bg, DRAWFLAG_NORMAL);
 
 				// the weapon
 				drawpic(pos, strcat("gfx/hud/inv_weapon", ftos(i-1)), '1 0.5 0' * fill_size_x , '1 1 1', sbar_alpha_fg, DRAWFLAG_NORMAL);
@@ -2467,12 +2469,12 @@
 	float stat_items, stat_weapons;
 
 	weapon_stats = getstati(STAT_DAMAGE_HITS);
- 	weapon_number = weapon_stats & 63;
- 	weapon_hits[weapon_number] = rint(weapon_stats / 64);
+	weapon_number = weapon_stats & 63;
+	weapon_hits[weapon_number] = floor(weapon_stats / 64);
 
- 	weapon_stats = getstati(STAT_DAMAGE_FIRED);
- 	weapon_number = weapon_stats & 63;
- 	weapon_fired[weapon_number] = rint(weapon_stats / 64);
+	weapon_stats = getstati(STAT_DAMAGE_FIRED);
+	weapon_number = weapon_stats & 63;
+	weapon_fired[weapon_number] = floor(weapon_stats / 64);
 
 	vector o; o = '1 0 0' * vid_conwidth;
 	o_y = 28; // move spectator text slightly down to prevent overlapping the timer

Modified: trunk/data/qcsrc/server/cl_client.qc
===================================================================
--- trunk/data/qcsrc/server/cl_client.qc	2009-11-16 07:47:47 UTC (rev 8290)
+++ trunk/data/qcsrc/server/cl_client.qc	2009-11-16 21:47:45 UTC (rev 8291)
@@ -2037,12 +2037,33 @@
 		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);
+
 	self.kh_state = spectatee.kh_state;
 	self.armortype = spectatee.armortype;
 	self.armorvalue = spectatee.armorvalue;
@@ -2093,20 +2114,25 @@
 
 float SpectateNext() {
 	other = find(self.enemy, classname, "player");
-	if (!other) {
+
+	if (!other)
 		other = find(other, classname, "player");
-	}
-	if (other) {
+
+	if (other)
 		self.enemy = other;
-	}
+
 	if(self.enemy.classname == "player") {
 		msg_entity = self;
 		WriteByte(MSG_ONE, SVC_SETVIEW);
 		WriteEntity(MSG_ONE, self.enemy);
 	 	//stuffcmd(self, "set viewsize $tmpviewsize \n");
 		self.movetype = MOVETYPE_NONE;
+
+		self.enemy.weapon_count = 0;
+
 		if(!SpectateUpdate())
 			PutObserverInServer();
+
 		return 1;
 	} else {
 		return 0;
@@ -2144,15 +2170,23 @@
 	if(isJoinAllowed()) {
 		if(!teams_matter || cvar("g_campaign") || cvar("g_balance_teams") || (self.wasplayer && cvar("g_changeteam_banned"))) {
 			self.classname = "player";
+
 			if(cvar("g_campaign") || cvar("g_balance_teams") || cvar("g_balance_teams_force"))
 				JoinBestTeam(self, FALSE, TRUE);
+
 			if(cvar("g_campaign"))
 				campaign_bots_may_start = 1;
+
+			self.stat_count = WEP_LAST;
+
 			PutClientInServer();
+
 			if(self.classname == "player")
 				bprint ("^4", self.netname, "^4 is playing now\n");
+
 			if(!cvar("g_campaign"))
 				centerprint(self,""); // clear MOTD
+
 			return;
 		} else {
 			if (g_ca && self.caplayer) {
@@ -2289,12 +2323,14 @@
 				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())
@@ -2311,6 +2347,7 @@
 			}
 		}
 	}
+
 	PrintWelcomeMessage(self);
 	self.flags |= FL_CLIENT | FL_NOTARGET;
 }
@@ -2839,6 +2876,15 @@
 		stuffcmd(self, "seta _cl_name Player\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).

Modified: trunk/data/qcsrc/server/cl_weaponsystem.qc
===================================================================
--- trunk/data/qcsrc/server/cl_weaponsystem.qc	2009-11-16 07:47:47 UTC (rev 8290)
+++ trunk/data/qcsrc/server/cl_weaponsystem.qc	2009-11-16 21:47:45 UTC (rev 8291)
@@ -147,11 +147,14 @@
 	ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
 	trueaimpoint = trace_endpos;
 
-	// Track max damage and set the stat to be sent later in g_world.qc
-	if not(inWarmupStage)
-	{
-		ent.max_damage[ent.weapon] += maxdamage;
-		ent.maxdamage_fired = ent.weapon + 64 * rint(ent.max_damage[ent.weapon]);
+	// track max damage
+	if not(inWarmupStage) {
+		entity w;
+		w = get_weaponinfo(ent.weapon);
+		if(w.weapon_type == 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]);
+		}
 	}
 
 	W_HitPlotAnalysis(ent, v_forward, v_right, v_up);

Modified: trunk/data/qcsrc/server/clientcommands.qc
===================================================================
--- trunk/data/qcsrc/server/clientcommands.qc	2009-11-16 07:47:47 UTC (rev 8290)
+++ trunk/data/qcsrc/server/clientcommands.qc	2009-11-16 21:47:45 UTC (rev 8291)
@@ -275,6 +275,7 @@
 					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;

Modified: trunk/data/qcsrc/server/defs.qh
===================================================================
--- trunk/data/qcsrc/server/defs.qh	2009-11-16 07:47:47 UTC (rev 8290)
+++ trunk/data/qcsrc/server/defs.qh	2009-11-16 21:47:45 UTC (rev 8291)
@@ -389,7 +389,7 @@
 
 float bot_waypoints_for_items;
 
-.float	attack_finished_for[WEP_COUNT];
+.float attack_finished_for[WEP_COUNT];
 .float attack_finished_single;
 #ifdef INDEPENDENT_ATTACK_FINISHED
 #define ATTACK_FINISHED_FOR(ent,w) ((ent).(attack_finished_for[(w) - WEP_FIRST]))
@@ -598,7 +598,16 @@
 .float hitplotfh;
 .string noise4;
 
-.float damage_hits, maxdamage_fired;
+.float stat_hit;
+.float stat_fired;
+.float stat_count;
+
+.float stats_hit[WEP_LAST - WEP_FIRST + 1];  // for hitscan bullets hit
+.float stats_fired[WEP_LAST - WEP_FIRST + 1];  // for hitscan bullets fired
+
+FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(stats_hit);
+FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(stats_fired);
+
 .float maycheat;
 .float stat_leadlimit;
 
@@ -624,3 +633,8 @@
 .entity personal;
 
 string deathmessage;
+
+
+
+.float cvar_cl_accuracy_data_share;
+.float cvar_cl_accuracy_data_receive;
\ No newline at end of file

Modified: trunk/data/qcsrc/server/g_damage.qc
===================================================================
--- trunk/data/qcsrc/server/g_damage.qc	2009-11-16 07:47:47 UTC (rev 8290)
+++ trunk/data/qcsrc/server/g_damage.qc	2009-11-16 21:47:45 UTC (rev 8291)
@@ -1009,23 +1009,16 @@
 	return nearest;
 }
 
-.float actual_damage[WEP_COUNT]; //amount of damage done
-.float max_damage[WEP_COUNT]; //the maximum damage of the weapon
-
-FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(actual_damage);
-FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(max_damage);
-
 void Damage_RecordDamage(entity attacker, float deathtype, float damage)
 {
 	float weaponid;
 	weaponid = DEATH_WEAPONOF(deathtype);
+
 	if not(inWarmupStage)
-	if(weaponid)
-	if(clienttype(attacker) == CLIENTTYPE_REAL)
-	{
-		// Track damage done and update the stat to be sent later in g_world.qc
-		attacker.actual_damage[weaponid] += damage;
-		attacker.damage_hits = weaponid + 64 * rint(attacker.actual_damage[weaponid]);
+	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]);
 	}
 }
 

Modified: trunk/data/qcsrc/server/g_world.qc
===================================================================
--- trunk/data/qcsrc/server/g_world.qc	2009-11-16 07:47:47 UTC (rev 8290)
+++ trunk/data/qcsrc/server/g_world.qc	2009-11-16 21:47:45 UTC (rev 8291)
@@ -601,8 +601,8 @@
 	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, damage_hits);
- 	addstat(STAT_DAMAGE_FIRED, AS_INT, maxdamage_fired);
+	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);
@@ -1297,10 +1297,7 @@
 */
 void NextLevel()
 {
-	float minTotalFrags;
-	float maxTotalFrags;
-	float score;
-	float f;
+	float i;
 
 	gameover = TRUE;
 
@@ -1330,42 +1327,60 @@
 
 	GameLogClose();
 
-	FOR_EACH_CLIENT(other)
-	{
-		FixIntermissionClient(other);
+// TO DO
 
-		if(other.winning)
-			bprint(other.netname, " ^7wins.\n");
-	}
+// 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
 
-	minTotalFrags = 0;
-	maxTotalFrags = 0;
-	FOR_EACH_PLAYER(other)
-	{
-		if(maxTotalFrags < other.totalfrags)
-			maxTotalFrags = other.totalfrags;
-		if(minTotalFrags > other.totalfrags)
-			minTotalFrags = other.totalfrags;
-	}
+// write a stats parser for the menu
 
-	if(!currentbots)
-	{
-		FOR_EACH_PLAYER(other)
-		{
-			score = (other.totalfrags - minTotalFrags) / max(maxTotalFrags - minTotalFrags, 1);
-			f = bound(0, other.play_time / max(time, 1), 1);
-			// store some statistics?
+	if(cvar("sv_accuracy_data_send")) {
+		string stats_to_send;
+
+		FOR_EACH_PLAYER(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_PLAYER(other) {  // send the stats string to all the willing clients
+			Score_NicePrint(other);  // print the score
+
+			if(other.cvar_cl_accuracy_data_receive)
+				bprint(stats_to_send);
+		}
+	} else { // ye olde message
+		FOR_EACH_PLAYER(other) {
+			FixIntermissionClient(other);
+
+			if(other.winning)
+				bprint(other.netname, " ^7wins.\n");
+		}
 	}
 
 	if(cvar("g_campaign"))
 		CampaignPreIntermission();
 
 	localcmd("\nsv_hook_gameend;");
+}
 
-	// WriteByte (MSG_ALL, SVC_INTERMISSION);
-};
-
 /*
 ============
 CheckRules_Player

Modified: trunk/data/qcsrc/server/miscfunctions.qc
===================================================================
--- trunk/data/qcsrc/server/miscfunctions.qc	2009-11-16 07:47:47 UTC (rev 8290)
+++ trunk/data/qcsrc/server/miscfunctions.qc	2009-11-16 21:47:45 UTC (rev 8291)
@@ -495,12 +495,17 @@
 		replacement = ftos(vlen(self.velocity - self.velocity_z * '0 0 1'));
 	else if (escape == "S")
 		replacement = ftos(vlen(self.velocity));
-        msg = strcat(substring(msg, 0, p), replacement, substring(msg, p+2, strlen(msg) - (p+2)));
-        p = p + strlen(replacement);
-    }
-    return msg;
+	msg = strcat(substring(msg, 0, p), replacement, substring(msg, p+2, strlen(msg) - (p+2)));
+	p = p + strlen(replacement);
+	}
+
+	return msg;
 }
 
+float boolean(float value) { // if value is 0 return FALSE (0), otherwise return TRUE (1)
+	return (value == 0) ? FALSE : TRUE;
+}
+
 /*
 =============
 GetCvars
@@ -610,13 +615,18 @@
 	GetCvars_handleFloat(s, f, cvar_cl_voice_directional, "cl_voice_directional");
 	GetCvars_handleFloat(s, f, cvar_cl_voice_directional_taunt_attenuation, "cl_voice_directional_taunt_attenuation");
 	GetCvars_handleFloat(s, f, cvar_cl_hitsound, "cl_hitsound");
+	GetCvars_handleFloat(s, f, cvar_cl_accuracy_data_share, "cl_accuracy_data_share");
+	GetCvars_handleFloat(s, f, cvar_cl_accuracy_data_receive, "cl_accuracy_data_receive");
+
+	self.cvar_cl_accuracy_data_share = boolean(self.cvar_cl_accuracy_data_share);
+	self.cvar_cl_accuracy_data_receive = boolean(self.cvar_cl_accuracy_data_receive);
+
 #ifdef ALLOW_FORCEMODELS
 	GetCvars_handleFloat(s, f, cvar_cl_forceplayermodels, "cl_forceplayermodels");
 	GetCvars_handleFloat(s, f, cvar_cl_forceplayermodelsfromnexuiz, "cl_forceplayermodelsfromnexuiz");
 #endif
 	GetCvars_handleFloatOnce(s, f, cvar_cl_gunalign, "cl_gunalign");
 
-
 	// fixup of switchweapon (needed for LMS or when spectating is disabled, as PutClientInServer comes too early)
 	if (f > 0)
 	{
@@ -1103,6 +1113,8 @@
 float sv_pitch_max;
 float sv_pitch_fixyaw;
 
+float sv_accuracy_data_share;
+
 void readlevelcvars(void)
 {
     g_bugrigs = cvar("g_bugrigs");
@@ -1128,112 +1140,119 @@
     g_touchexplode_force = cvar("g_touchexplode_force");
 
 #ifdef ALLOW_FORCEMODELS
-    sv_clforceplayermodels = cvar("sv_clforceplayermodels");
+	sv_clforceplayermodels = cvar("sv_clforceplayermodels");
 #endif
-    sv_loddistance1 = cvar("sv_loddistance1");
-    sv_loddistance2 = cvar("sv_loddistance2");
+	sv_loddistance1 = cvar("sv_loddistance1");
+	sv_loddistance2 = cvar("sv_loddistance2");
+
 	if(sv_loddistance2 <= sv_loddistance1)
 		sv_loddistance2 = 1073741824; // enough to turn off LOD 2 reliably
-    sv_clones = cvar("sv_clones");
-    sv_cheats = cvar("sv_cheats");
-    sv_gentle = cvar("sv_gentle");
-    sv_foginterval = cvar("sv_foginterval");
-    g_cloaked = cvar("g_cloaked");
-    g_jump_grunt = cvar("g_jump_grunt");
-    g_footsteps = cvar("g_footsteps");
-    g_grappling_hook = cvar("g_grappling_hook");
-    g_jetpack = cvar("g_jetpack");
-    g_laserguided_missile = cvar("g_laserguided_missile");
-    g_midair = cvar("g_midair");
-    g_minstagib = cvar("g_minstagib");
-    g_nixnex = cvar("g_nixnex");
-    g_nixnex_with_laser = cvar("g_nixnex_with_laser");
-    g_norecoil = cvar("g_norecoil");
-    g_vampire = cvar("g_vampire");
-    g_bloodloss = cvar("g_bloodloss");
-    sv_maxidle = cvar("sv_maxidle");
-    sv_maxidle_spectatorsareidle = cvar("sv_maxidle_spectatorsareidle");
-    sv_pogostick = cvar("sv_pogostick");
-    sv_doublejump = cvar("sv_doublejump");
-    g_ctf_reverse = cvar("g_ctf_reverse");
+
+	sv_clones = cvar("sv_clones");
+	sv_cheats = cvar("sv_cheats");
+	sv_gentle = cvar("sv_gentle");
+	sv_foginterval = cvar("sv_foginterval");
+	g_cloaked = cvar("g_cloaked");
+	g_jump_grunt = cvar("g_jump_grunt");
+	g_footsteps = cvar("g_footsteps");
+	g_grappling_hook = cvar("g_grappling_hook");
+	g_jetpack = cvar("g_jetpack");
+	g_laserguided_missile = cvar("g_laserguided_missile");
+	g_midair = cvar("g_midair");
+	g_minstagib = cvar("g_minstagib");
+	g_nixnex = cvar("g_nixnex");
+	g_nixnex_with_laser = cvar("g_nixnex_with_laser");
+	g_norecoil = cvar("g_norecoil");
+	g_vampire = cvar("g_vampire");
+	g_bloodloss = cvar("g_bloodloss");
+	sv_maxidle = cvar("sv_maxidle");
+	sv_maxidle_spectatorsareidle = cvar("sv_maxidle_spectatorsareidle");
+	sv_pogostick = cvar("sv_pogostick");
+	sv_doublejump = cvar("sv_doublejump");
+	g_ctf_reverse = cvar("g_ctf_reverse");
 	sv_autotaunt = cvar("sv_autotaunt");
 	sv_taunt = cvar("sv_taunt");
 
-    inWarmupStage = cvar("g_warmup");
-    g_warmup_limit = cvar("g_warmup_limit");
-    g_warmup_allguns = cvar("g_warmup_allguns");
-    g_warmup_allow_timeout = cvar("g_warmup_allow_timeout");
+	inWarmupStage = cvar("g_warmup");
+	g_warmup_limit = cvar("g_warmup_limit");
+	g_warmup_allguns = cvar("g_warmup_allguns");
+	g_warmup_allow_timeout = cvar("g_warmup_allow_timeout");
 
-    if ((g_race && g_race_qualifying == 2) || g_runematch || g_arena || g_assault || cvar("g_campaign"))
-        inWarmupStage = 0; // these modes cannot work together, sorry
+	if ((g_race && g_race_qualifying == 2) || g_runematch || g_arena || g_assault || cvar("g_campaign"))
+		inWarmupStage = 0; // these modes cannot work together, sorry
 
-    g_pickup_respawntime_weapon = cvar("g_pickup_respawntime_weapon");
-    g_pickup_respawntime_ammo = cvar("g_pickup_respawntime_ammo");
-    g_pickup_respawntime_short = cvar("g_pickup_respawntime_short");
-    g_pickup_respawntime_medium = cvar("g_pickup_respawntime_medium");
-    g_pickup_respawntime_long = cvar("g_pickup_respawntime_long");
-    g_pickup_respawntime_powerup = cvar("g_pickup_respawntime_powerup");
-    g_pickup_respawntimejitter_weapon = cvar("g_pickup_respawntimejitter_weapon");
-    g_pickup_respawntimejitter_ammo = cvar("g_pickup_respawntimejitter_ammo");
-    g_pickup_respawntimejitter_short = cvar("g_pickup_respawntimejitter_short");
-    g_pickup_respawntimejitter_medium = cvar("g_pickup_respawntimejitter_medium");
-    g_pickup_respawntimejitter_long = cvar("g_pickup_respawntimejitter_long");
-    g_pickup_respawntimejitter_powerup = cvar("g_pickup_respawntimejitter_powerup");
+	g_pickup_respawntime_weapon = cvar("g_pickup_respawntime_weapon");
+	g_pickup_respawntime_ammo = cvar("g_pickup_respawntime_ammo");
+	g_pickup_respawntime_short = cvar("g_pickup_respawntime_short");
+	g_pickup_respawntime_medium = cvar("g_pickup_respawntime_medium");
+	g_pickup_respawntime_long = cvar("g_pickup_respawntime_long");
+	g_pickup_respawntime_powerup = cvar("g_pickup_respawntime_powerup");
+	g_pickup_respawntimejitter_weapon = cvar("g_pickup_respawntimejitter_weapon");
+	g_pickup_respawntimejitter_ammo = cvar("g_pickup_respawntimejitter_ammo");
+	g_pickup_respawntimejitter_short = cvar("g_pickup_respawntimejitter_short");
+	g_pickup_respawntimejitter_medium = cvar("g_pickup_respawntimejitter_medium");
+	g_pickup_respawntimejitter_long = cvar("g_pickup_respawntimejitter_long");
+	g_pickup_respawntimejitter_powerup = cvar("g_pickup_respawntimejitter_powerup");
 
-    if (g_minstagib) g_nixnex = g_weaponarena = 0;
-    if (g_nixnex) g_weaponarena = 0;
-    g_weaponarena = 0;
+	if (g_minstagib) g_nixnex = g_weaponarena = 0;
+	if (g_nixnex) g_weaponarena = 0;
+		g_weaponarena = 0;
 
-    g_weaponspeedfactor = cvar("g_weaponspeedfactor");
-    g_weaponratefactor = cvar("g_weaponratefactor");
-    g_weapondamagefactor = cvar("g_weapondamagefactor");
-    g_weaponforcefactor = cvar("g_weaponforcefactor");
+	g_weaponspeedfactor = cvar("g_weaponspeedfactor");
+	g_weaponratefactor = cvar("g_weaponratefactor");
+	g_weapondamagefactor = cvar("g_weapondamagefactor");
+	g_weaponforcefactor = cvar("g_weaponforcefactor");
 
-    g_pickup_shells                    = cvar("g_pickup_shells");
-    g_pickup_shells_max                = cvar("g_pickup_shells_max");
-    g_pickup_nails                     = cvar("g_pickup_nails");
-    g_pickup_nails_max                 = cvar("g_pickup_nails_max");
-    g_pickup_rockets                   = cvar("g_pickup_rockets");
-    g_pickup_rockets_max               = cvar("g_pickup_rockets_max");
-    g_pickup_cells                     = cvar("g_pickup_cells");
-    g_pickup_cells_max                 = cvar("g_pickup_cells_max");
-    g_pickup_fuel                     = cvar("g_pickup_fuel");
-    g_pickup_fuel_jetpack             = cvar("g_pickup_fuel_jetpack");
-    g_pickup_fuel_max                 = cvar("g_pickup_fuel_max");
-    g_pickup_armorsmall                = cvar("g_pickup_armorsmall");
-    g_pickup_armorsmall_max            = cvar("g_pickup_armorsmall_max");
-    g_pickup_armormedium               = cvar("g_pickup_armormedium");
-    g_pickup_armormedium_max           = cvar("g_pickup_armormedium_max");
-    g_pickup_armorbig                  = cvar("g_pickup_armorbig");
-    g_pickup_armorbig_max              = cvar("g_pickup_armorbig_max");
-    g_pickup_armorlarge                = cvar("g_pickup_armorlarge");
-    g_pickup_armorlarge_max            = cvar("g_pickup_armorlarge_max");
-    g_pickup_healthsmall               = cvar("g_pickup_healthsmall");
-    g_pickup_healthsmall_max           = cvar("g_pickup_healthsmall_max");
-    g_pickup_healthmedium              = cvar("g_pickup_healthmedium");
-    g_pickup_healthmedium_max          = cvar("g_pickup_healthmedium_max");
-    g_pickup_healthlarge               = cvar("g_pickup_healthlarge");
-    g_pickup_healthlarge_max           = cvar("g_pickup_healthlarge_max");
-    g_pickup_healthmega                = cvar("g_pickup_healthmega");
-    g_pickup_healthmega_max            = cvar("g_pickup_healthmega_max");
+	g_pickup_shells = cvar("g_pickup_shells");
+	g_pickup_shells_max = cvar("g_pickup_shells_max");
+	g_pickup_nails = cvar("g_pickup_nails");
+	g_pickup_nails_max = cvar("g_pickup_nails_max");
+	g_pickup_rockets = cvar("g_pickup_rockets");
+	g_pickup_rockets_max = cvar("g_pickup_rockets_max");
+	g_pickup_cells = cvar("g_pickup_cells");
+	g_pickup_cells_max = cvar("g_pickup_cells_max");
+	g_pickup_fuel = cvar("g_pickup_fuel");
+	g_pickup_fuel_jetpack = cvar("g_pickup_fuel_jetpack");
+	g_pickup_fuel_max = cvar("g_pickup_fuel_max");
+	g_pickup_armorsmall = cvar("g_pickup_armorsmall");
+	g_pickup_armorsmall_max = cvar("g_pickup_armorsmall_max");
+	g_pickup_armormedium = cvar("g_pickup_armormedium");
+	g_pickup_armormedium_max = cvar("g_pickup_armormedium_max");
+	g_pickup_armorbig = cvar("g_pickup_armorbig");
+	g_pickup_armorbig_max = cvar("g_pickup_armorbig_max");
+	g_pickup_armorlarge = cvar("g_pickup_armorlarge");
+	g_pickup_armorlarge_max = cvar("g_pickup_armorlarge_max");
+	g_pickup_healthsmall = cvar("g_pickup_healthsmall");
+	g_pickup_healthsmall_max = cvar("g_pickup_healthsmall_max");
+	g_pickup_healthmedium = cvar("g_pickup_healthmedium");
+	g_pickup_healthmedium_max = cvar("g_pickup_healthmedium_max");
+	g_pickup_healthlarge = cvar("g_pickup_healthlarge");
+	g_pickup_healthlarge_max = cvar("g_pickup_healthlarge_max");
+	g_pickup_healthmega = cvar("g_pickup_healthmega");
+	g_pickup_healthmega_max = cvar("g_pickup_healthmega_max");
 
-    g_pinata = cvar("g_pinata");
+	g_pinata = cvar("g_pinata");
 
-    g_weapon_stay = cvar("g_weapon_stay");
-    if (!g_weapon_stay && (cvar("deathmatch") == 2))
-        g_weapon_stay = 1;
+	g_weapon_stay = cvar("g_weapon_stay");
+
+	if (!g_weapon_stay && (cvar("deathmatch") == 2))
+		g_weapon_stay = 1;
+
 	g_ghost_items = cvar("g_ghost_items");
+
 	if(g_ghost_items >= 1)
 		g_ghost_items = 0.13; // default alpha value
 
-    if not(inWarmupStage)
-        game_starttime                 = cvar("g_start_delay");
+	if not(inWarmupStage)
+		game_starttime = cvar("g_start_delay");
 
 	sv_pitch_min = cvar("sv_pitch_min");
 	sv_pitch_max = cvar("sv_pitch_max");
 	sv_pitch_fixyaw = cvar("sv_pitch_fixyaw");
 
-    readplayerstartcvars();
+	sv_accuracy_data_share = boolean(cvar("sv_accuracy_data_share"));
+
+	readplayerstartcvars();
 }
 
 /*

Modified: trunk/data/qcsrc/server/w_common.qc
===================================================================
--- trunk/data/qcsrc/server/w_common.qc	2009-11-16 07:47:47 UTC (rev 8290)
+++ trunk/data/qcsrc/server/w_common.qc	2009-11-16 21:47:45 UTC (rev 8291)
@@ -1,9 +1,3 @@
-.float bullets_hit[WEP_COUNT]; 		//for hitscan bullets hit
-.float bullets_fired[WEP_COUNT];	//for hitscan bullets fired
-
-FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(bullets_hit);
-FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(bullets_fired);
-
 void W_GiveWeapon (entity e, float wep, string name)
 {
 	entity oldself;
@@ -32,15 +26,14 @@
 	local vector hitloc, force, endpoint, dir;
 	local entity ent, endent;
 	local float endq3surfaceflags;
-	//local entity explosion;
-	float did_hit;
+
 	float length;
 	vector beampos;
 	string snd;
 	entity pseudoprojectile;
 	float f, ffs;
 
-	did_hit = 0;
+	float hit;
 
 	railgun_start = start;
 	railgun_end = end;
@@ -131,11 +124,11 @@
 		//for stats so that team hit will count as a miss
 		if(ent.flags & FL_CLIENT)
 		if(ent.deadflag == DEAD_NO)
-			did_hit = 1;
+			hit = 1;
 
 		if(teams_matter)
 		if(ent.team == self.team)
-			did_hit = 0;
+			hit = 0;
 
 		f = ExponentialFalloff(mindist, maxdist, halflifedist, (ent.origin - start) * dir);
 		ffs = ExponentialFalloff(mindist, maxdist, forcehalflifedist, (ent.origin - start) * dir);
@@ -152,23 +145,18 @@
 		ent = findfloat(ent, railgunhit, TRUE);
 	}
 
-	//calculate hits and fired shots for hitscan
+	// calculate hits and fired shots for hitscan
 	if not(inWarmupStage)
-	if not(self.isbot)
 	{
-		self.bullets_fired[self.weapon] += 1;
+		self.stats_fired[self.weapon - 1] += 1;
+		self.stat_fired = self.weapon + 64 * floor(self.stats_fired[self.weapon - 1]);
 
-		if(did_hit)
-			self.bullets_hit[self.weapon] += 1;
-
-		// update the client and store in addstat() in g_world
-		self.damage_hits = self.weapon + 64 * rint(self.bullets_hit[self.weapon]);
-		self.maxdamage_fired = self.weapon + 64 * rint(self.bullets_fired[self.weapon]);
+		if(hit) {
+			self.stats_hit[self.weapon - 1] += 1;
+			self.stat_hit = self.weapon + 64 * floor(self.stats_hit[self.weapon - 1]);
+		}
 	}
 
-	// we're done with the explosion entity, remove it
-	//remove(explosion);
-
 	trace_endpos = endpoint;
 	trace_ent = endent;
 	trace_dphitq3surfaceflags = endq3surfaceflags;
@@ -181,9 +169,6 @@
 {
 	float f;
 
-	float hit;
-	hit = 0;
-
 	f = pow(bound(0, vlen(self.velocity) / vlen(self.oldvelocity), 1), 2); // energy multiplier
 
 	if(other.solid == SOLID_BSP)
@@ -199,14 +184,6 @@
 		railgun_start = self.origin - 2 * frametime * self.velocity;
 		railgun_end = self.origin + 2 * frametime * self.velocity;
 
-		if(other.flags & FL_CLIENT)
-		if(other.deadflag == DEAD_NO)
-			hit = 1;
-
-		if(teamplay)
-		if(other.team == self.owner.team)
-			hit = 0;
-
 		Damage(other, self, self.owner, self.dmg * f, self.projectiledeathtype, self.origin, self.dmg_force * normalize(self.velocity) * f);
 		damage_headshotbonus = 0;
 
@@ -218,17 +195,15 @@
 				announce(self.owner, "announcer/male/awesome.wav");
 		}
 
-		//calculate hits for ballistic weapons
-		if not(inWarmupStage)
-		if not(self.owner.isbot)
+		// calculate hits for ballistic weapons
+		if (other.flags & FL_CLIENT)  // is the player a client
+		if (other.deadflag == DEAD_NO)  // is the victim a corpse
+		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
 		{
-			if(hit)
-				self.owner.bullets_hit[self.owner.weapon] += 1;
-			// update the client
-			self.owner.damage_hits = self.owner.weapon + 64 * rint(self.owner.bullets_hit[self.owner.weapon]);
+			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]);
 		}
-
-		//sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
 	}
 
 	self.enemy = other; // don't hit the same player twice with the same bullet
@@ -342,6 +317,7 @@
 {
 	endzcurveparticles();
 }
+
 void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, float lifetime, float damage, float headshotbonus, float force, float dtype, float tracereffects, float gravityfactor, float bulletconstant)
 {
 	float lag, dt, savetime;
@@ -376,14 +352,6 @@
 
 	proj.oldvelocity = proj.velocity;
 
-	//calculate fired bullets for ballistics
-	if not(inWarmupStage)
-	if not(self.isbot)
-	{
-		self.bullets_fired[self.weapon] += 1;
-		self.maxdamage_fired = self.weapon + 64 * rint(self.bullets_fired[self.weapon]);
-	}
-
 	if(cvar("g_antilag_bullets"))
 	if(pSpeed >= cvar("g_antilag_bullets"))
 	{
@@ -413,6 +381,13 @@
 		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
@@ -429,13 +404,6 @@
 			self.velocity = v0;
 			self.gravity = g0;
 
-			if not(inWarmupStage)
-			if not(self.isbot)
-			{
-				self.bullets_fired[self.weapon] += 1;
-				self.maxdamage_fired = self.weapon + 64 * rint(self.bullets_fired[self.weapon]);
-			}
-
 			if(vlen(trace_endpos - self.origin) > 16)
 				zcurveparticles_from_tracetoss(eff, self.origin, trace_endpos, self.velocity);
 			if(trace_fraction == 1)
@@ -455,7 +423,7 @@
 					break;
 
 				// hit the player
-				W_BallisticBullet_Hit ();
+				W_BallisticBullet_Hit();
 			}
 
 			// go through solid!
@@ -476,6 +444,13 @@
 		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)
@@ -484,11 +459,9 @@
 		CSQCProjectile(proj, TRUE, PROJECTILE_BULLET, TRUE);
 }
 
-
 void fireBullet (vector start, vector dir, float spread, float damage, float force, float dtype, float tracer)
 {
 	vector  end;
-	//local entity e;
 
 	dir = normalize(dir + randomvec() * spread);
 	end = start + dir * MAX_SHOT_DISTANCE;
@@ -497,7 +470,7 @@
 	else
 		traceline_antilag (self, start, end, FALSE, self, ANTILAG_LATENCY(self));
 
-    end = trace_endpos;
+	end = trace_endpos;
 
 	if ((trace_fraction != 1.0) && (pointcontents (trace_endpos) != CONTENT_SKY))
 	{
@@ -510,7 +483,6 @@
 	trace_endpos = end;
 }
 
-
 void W_PrepareExplosionByDamage(entity attacker, void() explode)
 {
 	self.takedamage = DAMAGE_NO;

Modified: trunk/data/qcsrc/server/w_shotgun.qc
===================================================================
--- trunk/data/qcsrc/server/w_shotgun.qc	2009-11-16 07:47:47 UTC (rev 8290)
+++ trunk/data/qcsrc/server/w_shotgun.qc	2009-11-16 21:47:45 UTC (rev 8291)
@@ -1,4 +1,3 @@
-
 void W_Shotgun_Attack (void)
 {
 	float	sc;



More information about the nexuiz-commits mailing list