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

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sat Sep 26 10:32:58 EDT 2009


Author: div0
Date: 2009-09-26 10:32:57 -0400 (Sat, 26 Sep 2009)
New Revision: 7924

Modified:
   trunk/data/defaultNexuiz.cfg
   trunk/data/qcsrc/server/cl_player.qc
   trunk/data/qcsrc/server/constants.qh
   trunk/data/qcsrc/server/g_world.qc
Log:
record weapon stats from QC code. See cvars at the end of defaultNexuiz.cfg.


Modified: trunk/data/defaultNexuiz.cfg
===================================================================
--- trunk/data/defaultNexuiz.cfg	2009-09-26 13:15:56 UTC (rev 7923)
+++ trunk/data/defaultNexuiz.cfg	2009-09-26 14:32:57 UTC (rev 7924)
@@ -26,7 +26,7 @@
 seta g_configversion 0	"Configuration file version (used to upgrade settings) 0: first run, or previous start was <2.4.1  Later, it's overridden by config.cfg, version ranges are defined in config_update.cfg"
 
 // default.cfg versioning (update using update-cvarcount.sh, run that every time after adding a new cvar)
-set cvar_check_default a806b2ec1a306ab62c20ebb3dd3fb5d2
+set cvar_check_default 3283aa7fbf7362ec962b4eec933fd55e
 
 // Nexuiz version (formatted for machines)
 // used to determine if a client version is compatible
@@ -1628,3 +1628,6 @@
 set g_triggerimpulse_radial_multiplier 1 "trigger_impulse radial field multiplier"
 
 set g_ghost_items 1 "enable ghosted items (when between 0 and 1, overrides the alpha value)"
+
+set g_weaponstats_damagefile "" "when set to a file name, per-weapon damage stats get written to that file"
+set g_weaponstats_killfile "" "when set to a file name, per-weapon kill stats get written to that file"

Modified: trunk/data/qcsrc/server/cl_player.qc
===================================================================
--- trunk/data/qcsrc/server/cl_player.qc	2009-09-26 13:15:56 UTC (rev 7923)
+++ trunk/data/qcsrc/server/cl_player.qc	2009-09-26 14:32:57 UTC (rev 7924)
@@ -1,4 +1,92 @@
+float weaponstats_buffer;
 
+void WeaponStats_Init()
+{
+	if(cvar_string("g_weaponstats_killfile") != "" || cvar_string("g_weaponstats_damagefile") != "")
+		weaponstats_buffer = buf_create();
+	else
+		weaponstats_buffer = -1;
+}
+
+#define WEAPONSTATS_GETINDEX(awep,vwep) ((vwep) + (awep) * (WEP_LAST - WEP_FIRST + 1) - (WEP_FIRST + WEP_FIRST * (WEP_LAST - WEP_FIRST + 1)))
+
+void WeaponStats_Shutdown()
+{
+	float i, j, idx, f;
+	float fh;
+	string prefix;
+	if(weaponstats_buffer < 0)
+		return;
+	prefix = strcat(cvar_string("hostname"), "\t", GetGametype(), "_", GetMapname(), "\t");
+	if(cvar_string("g_weaponstats_killfile") != "")
+	{
+		fh = fopen(cvar_string("g_weaponstats_killfile"), FILE_APPEND);
+		if(fh >= 0)
+		{
+			fputs(fh, "#begin killfile\n");
+			fputs(fh, strcat("#date ", strftime(TRUE, "%a %b %e %H:%M:%S %Z %Y"), "\n"));
+			fputs(fh, strcat("#config ", ftos(crc16(FALSE, cvar_changes)), "\n"));
+			for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+				for(j = WEP_FIRST; j <= WEP_LAST; ++j)
+				{
+					idx = WEAPONSTATS_GETINDEX(i, j);
+					f = stov(bufstr_get(weaponstats_buffer, idx)) * '0 1 0';
+					if(f != 0)
+						fputs(fh, strcat(prefix, "\t", ftos(i), "\t", ftos(j), "\t", ftos(f), "\n"));
+				}
+			fputs(fh, "#end\n\n");
+			fclose(fh);
+			print("Weapon kill stats written\n");
+		}
+	}
+	if(cvar_string("g_weaponstats_damagefile") != "")
+	{
+		fh = fopen(cvar_string("g_weaponstats_damagefile"), FILE_APPEND);
+		if(fh >= 0)
+		{
+			fputs(fh, "#begin damagefile\n");
+			fputs(fh, strcat("#date ", strftime(TRUE, "%a %b %e %H:%M:%S %Z %Y"), "\n"));
+			fputs(fh, strcat("#config ", ftos(crc16(FALSE, cvar_changes)), "\n"));
+			for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+				for(j = WEP_FIRST; j <= WEP_LAST; ++j)
+				{
+					idx = WEAPONSTATS_GETINDEX(i, j);
+					f = stov(bufstr_get(weaponstats_buffer, idx)) * '1 0 0';
+					if(f != 0)
+						fputs(fh, strcat(prefix, "\t", ftos(i), "\t", ftos(j), "\t", ftos(f), "\n"));
+				}
+			fputs(fh, "#end\n\n");
+			fclose(fh);
+			print("Weapon damage stats written\n");
+		}
+	}
+	buf_del(weaponstats_buffer);
+	weaponstats_buffer = -1;
+}
+
+void WeaponStats_LogItem(float awep, float vwep, 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,vwep);
+	bufstr_set(weaponstats_buffer, 2*idx, vtos(stov(bufstr_get(weaponstats_buffer, 2*idx)) + item));
+}
+void WeaponStats_LogDamage(float awep, float vwep, float damage)
+{
+	if(damage < 0)
+		error("negative damage?");
+	WeaponStats_LogItem(awep, vwep, '1 0 0' * damage);
+}
+void WeaponStats_LogKill(float awep, float vwep)
+{
+	WeaponStats_LogItem(awep, vwep, '0 1 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
@@ -342,9 +430,13 @@
 
 void PlayerDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 {
-	local float take, save, waves, sdelay;
+	local float take, save, waves, sdelay, dh, da;
 	vector v;
+	float valid_damage_for_weaponstats;
 
+	dh = max(self.health, 0);
+	da = max(self.armorvalue, 0);
+
 	if(!DEATH_ISSPECIAL(deathtype))
 	{
 		damage *= sqrt(bound(1.0, self.cvar_cl_handicap, 100.0));
@@ -484,11 +576,29 @@
 	else
 		self.pushltime = 0;
 
+	valid_damage_for_weaponstats = 0;
+	if(clienttype(self) == CLIENTTYPE_REAL)
+	if(clienttype(attacker) == CLIENTTYPE_REAL)
+	if(self != attacker)
+	if(!DEATH_ISSPECIAL(deathtype))
+	if(IsDifferentTeam(self, attacker))
+		valid_damage_for_weaponstats = 1;
+	
+	if(valid_damage_for_weaponstats)
+	{
+		dh = dh - max(self.health, 0);
+		da = da - max(self.armorvalue, 0);
+		WeaponStats_LogDamage(DEATH_WEAPONOF(deathtype), self.weapon, dh + da);
+	}
+
 	if (self.health < 1)
 	{
 		float defer_ClientKill_Now_TeamChange;
 		defer_ClientKill_Now_TeamChange = FALSE;
 
+		if(valid_damage_for_weaponstats)
+			WeaponStats_LogKill(DEATH_WEAPONOF(deathtype), self.weapon);
+
 		if(sv_gentle < 1) // TODO make a "gentle" version?
 		if(sound_allowed(MSG_BROADCAST, attacker))
 		{

Modified: trunk/data/qcsrc/server/constants.qh
===================================================================
--- trunk/data/qcsrc/server/constants.qh	2009-09-26 13:15:56 UTC (rev 7923)
+++ trunk/data/qcsrc/server/constants.qh	2009-09-26 14:32:57 UTC (rev 7924)
@@ -1,4 +1,4 @@
-string CVAR_CHECK_DEFAULT = "a806b2ec1a306ab62c20ebb3dd3fb5d2";
+string CVAR_CHECK_DEFAULT = "3283aa7fbf7362ec962b4eec933fd55e";
 string CVAR_CHECK_BALANCE = "59ee376a58dfcc2e2ee440c6a9508e11";
 
 float	FALSE					= 0;

Modified: trunk/data/qcsrc/server/g_world.qc
===================================================================
--- trunk/data/qcsrc/server/g_world.qc	2009-09-26 13:15:56 UTC (rev 7923)
+++ trunk/data/qcsrc/server/g_world.qc	2009-09-26 14:32:57 UTC (rev 7924)
@@ -375,6 +375,8 @@
 void RegisterWeapons();
 void Nagger_Init();
 void ClientInit_Spawn();
+void WeaponStats_Init();
+void WeaponStats_Shutdown();
 void spawnfunc_worldspawn (void)
 {
 	float fd, l, i, j, n;
@@ -586,6 +588,8 @@
 		}
 	}
 
+	WeaponStats_Init();
+
 	addstat(STAT_WEAPONS, AS_INT, weapons);
 	addstat(STAT_SWITCHWEAPON, AS_INT, switchweapon);
 	addstat(STAT_GAMESTARTTIME, AS_FLOAT, stat_game_starttime);
@@ -2585,6 +2589,7 @@
 	MapInfo_Shutdown();
 	MapInfo_Enumerate();
 	MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1);
+	WeaponStats_Init();
 }
 
 void SV_Shutdown()
@@ -2609,6 +2614,7 @@
 		// tell the bot system the game is ending now
 		bot_endgame();
 
+		WeaponStats_Shutdown();
 		MapInfo_Shutdown();
 	}
 	else if(world_initialized == 0)



More information about the nexuiz-commits mailing list