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

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Mon May 4 05:38:33 EDT 2009


Author: div0
Date: 2009-05-04 05:38:27 -0400 (Mon, 04 May 2009)
New Revision: 6654

Modified:
   trunk/data/defaultNexuiz.cfg
   trunk/data/qcsrc/client/Main.qc
   trunk/data/qcsrc/client/View.qc
   trunk/data/qcsrc/common/constants.qh
   trunk/data/qcsrc/common/util.qc
   trunk/data/qcsrc/common/util.qh
   trunk/data/qcsrc/server/cl_weaponsystem.qc
   trunk/data/qcsrc/server/constants.qh
   trunk/data/qcsrc/server/defs.qh
   trunk/data/qcsrc/server/g_world.qc
Log:
crosshair_hittest feature: blur out the crosshair if the shot can't hit the crosshair because of obstruction


Modified: trunk/data/defaultNexuiz.cfg
===================================================================
--- trunk/data/defaultNexuiz.cfg	2009-05-04 07:46:32 UTC (rev 6653)
+++ trunk/data/defaultNexuiz.cfg	2009-05-04 09:38:27 UTC (rev 6654)
@@ -95,6 +95,7 @@
 crosshair 5
 seta crosshair_per_weapon 0	"when 1, each gun will display a different crosshair"
 seta crosshair_color_override 0	"when 1, crosshair_color_* overrides the per-weapon color"
+seta crosshair_hittest 1 "when 1, the crosshair is blurred if the shot wouldn't hit the crosshair because of obstructions"
 seta crosshair_laser ""	"crosshair to display when wielding the laser"
 seta crosshair_laser_color_red 1	"crosshair color red component to display when wielding the laser"
 seta crosshair_laser_color_green 0.35	"crosshair color green component to display when wielding the laser"

Modified: trunk/data/qcsrc/client/Main.qc
===================================================================
--- trunk/data/qcsrc/client/Main.qc	2009-05-04 07:46:32 UTC (rev 6653)
+++ trunk/data/qcsrc/client/Main.qc	2009-05-04 09:38:27 UTC (rev 6654)
@@ -268,6 +268,7 @@
 }
 
 void Porto_Init();
+void TrueAim_Init();
 void PostInit(void)
 {
 	print(strcat("PostInit\n    maxclients = ", ftos(maxclients), "\n"));
@@ -279,6 +280,7 @@
 	playerchecker.nextthink = time + 0.2;
 
 	Porto_Init();
+	TrueAim_Init();
 
 	postinit = true;
 }

Modified: trunk/data/qcsrc/client/View.qc
===================================================================
--- trunk/data/qcsrc/client/View.qc	2009-05-04 07:46:32 UTC (rev 6653)
+++ trunk/data/qcsrc/client/View.qc	2009-05-04 09:38:27 UTC (rev 6654)
@@ -4,6 +4,7 @@
 float Q3SURFACEFLAG_SLICK = 2; // low friction surface
 float DPCONTENTS_SOLID = 1; // blocks player movement
 float DPCONTENTS_BODY = 32; // blocks player movement
+float DPCONTENTS_CORPSE = 64; // blocks player movement
 float DPCONTENTS_PLAYERCLIP = 256; // blocks player movement
 void Porto_Draw()
 {
@@ -189,6 +190,65 @@
 	return '1 0 0' * fovx + '0 1 0' * fovy;
 }
 
+// this function must match W_SetupShot!
+float zoomscript_caught;
+entity trueaim;
+void TrueAim_Init()
+{
+	trueaim = spawn();
+	trueaim.classname = "trueaim";
+	trueaim.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
+}
+
+float TrueAimCheck()
+{
+	float nudge = 1; // added to traceline target and subtracted from result
+	vector vecs, trueaimpoint, w_shotorg;
+	vector mi, ma;
+
+	mi = ma = '0 0 0';
+
+	switch(activeweapon)
+	{
+		case WEP_PORTO: // shoots from eye
+		case WEP_HOOK: // no trueaim
+		case WEP_GRENADE_LAUNCHER: // toss curve
+			return 1; 
+		case WEP_CAMPINGRIFLE:
+			if(zoomscript_caught)
+				return 1; // shoots from eye when zoomed
+		case WEP_ROCKET_LAUNCHER: // projectile has a size!
+			mi = '-3 -3 -3';
+			ma = '3 3 3';
+			break;
+		case WEP_SEEKER: // projectile has a size!
+			mi = '-2 -2 -2';
+			ma = '2 2 2';
+			break;
+	}
+
+	vecs = decompressShotOrigin(getstati(STAT_SHOTORG));
+
+	traceline(view_origin, view_origin + v_forward * MAX_SHOT_DISTANCE, MOVE_NOMONSTERS, trueaim);
+	trueaimpoint = trace_endpos;
+
+	if(vecs_x > 0)
+		vecs_y = -vecs_y;
+	else
+		vecs = '0 0 0';
+	
+	w_shotorg = view_origin + view_right * vecs_y + view_up * vecs_z;
+
+	// now move the vecs forward as much as requested if possible
+	traceline(w_shotorg, w_shotorg + view_forward * (vecs_x + nudge), MOVE_NORMAL, trueaim); // FIXME this MOVE_NORMAL part will misbehave a little in csqc
+	w_shotorg = trace_endpos - view_forward * nudge;
+
+	// now test whether we will actually hit the trueaimpoint...
+	tracebox(w_shotorg, mi, ma, trueaimpoint, MOVE_NOMONSTERS, trueaim);
+	return vlen(trace_endpos - trueaimpoint) <= vlen(ma - mi) + 1;
+		// yes, this is an ugly hack... but it seems good enough to find out whether the test hits the same place as the initial trace
+}
+
 void CSQC_common_hud(void);
 
 void CSQC_kh_hud(void);
@@ -196,7 +256,6 @@
 void PostInit(void);
 void CSQC_Demo_Camera();
 float Sbar_WouldDrawScoreboard ();
-float zoomscript_caught;
 float view_set;
 float camera_mode;
 string NextFrameCommand;
@@ -204,7 +263,7 @@
 {
 	entity e;
 	float fov;
-	float f;
+	float f, i, j;
 
 	dprint_load();
 	WaypointSprite_Load();
@@ -421,6 +480,11 @@
 
 	// crosshair goes VERY LAST
 	if(!scoreboard_active && !ons_showmap && !camera_active) {
+		// TrueAim check
+		float goodshot;
+
+		goodshot = TrueAimCheck();
+
 		string wcross_style;
 		wcross_style = cvar_string("crosshair");
 
@@ -461,7 +525,17 @@
 			wcross_size_x *= wcross_sizefloat;
 			wcross_size_y *= wcross_sizefloat;
 
-			drawpic('0.5 0 0' * (vid_conwidth - wcross_size_x) + '0 0.5 0' * (vid_conheight - wcross_size_y), wcross_name, wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
+			if(goodshot || !cvar("crosshair_hittest"))
+			{
+				drawpic('0.5 0 0' * (vid_conwidth - wcross_size_x) + '0 0.5 0' * (vid_conheight - wcross_size_y), wcross_name, wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
+			}
+			else
+			{
+				wcross_alpha *= 0.04 * 0.75;
+				for(i = -2; i <= 2; ++i)
+					for(j = -2; j <= 2; ++j)
+						drawpic('0.5 0 0' * (vid_conwidth - wcross_size_x + i) + '0 0.5 0' * (vid_conheight - wcross_size_y + j), wcross_name, wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
+			}
 		}
 	}
 

Modified: trunk/data/qcsrc/common/constants.qh
===================================================================
--- trunk/data/qcsrc/common/constants.qh	2009-05-04 07:46:32 UTC (rev 6653)
+++ trunk/data/qcsrc/common/constants.qh	2009-05-04 09:38:27 UTC (rev 6654)
@@ -250,6 +250,7 @@
 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;
 const float STAT_NB_METERSTART = 45;
+const float STAT_SHOTORG = 46; // compressShotOrigin
 const float CTF_STATE_ATTACK = 1;
 const float CTF_STATE_DEFEND = 2;
 const float CTF_STATE_COMMANDER = 3;
@@ -430,3 +431,5 @@
 float WATERLEVEL_WETFEET = 1;
 float WATERLEVEL_SWIMMING = 2;
 float WATERLEVEL_SUBMERGED = 3;
+
+float MAX_SHOT_DISTANCE = 32768;

Modified: trunk/data/qcsrc/common/util.qc
===================================================================
--- trunk/data/qcsrc/common/util.qc	2009-05-04 07:46:32 UTC (rev 6653)
+++ trunk/data/qcsrc/common/util.qc	2009-05-04 09:38:27 UTC (rev 6654)
@@ -1457,3 +1457,26 @@
 	if(strcat(argv(0), substring("foo bar", 4, 7 - argv_start_index(1))) == "barbar")
 		error("fteqcc bug introduced with revision 3178 detected. Please upgrade fteqcc to a later revision, downgrade fteqcc to revision 3177, or pester Spike until he fixes it. You can set _allow_unacceptable_compiler_bugs 1 to skip this check, but expect stuff to be horribly broken then.");
 }
+
+float compressShotOrigin(vector v)
+{
+	float x, y, z;
+	x = rint(v_x * 2);
+	y = rint(v_y * 4) + 128;
+	z = rint(v_z * 4) + 128;
+	if(x > 255 || x < 0)
+		error("shot origin x out of bounds");
+	if(y > 255 || y < 0)
+		error("shot origin y out of bounds");
+	if(z > 255 || z < 0)
+		error("shot origin z out of bounds");
+	return x * 0x10000 + y * 0x100 + z;
+}
+vector decompressShotOrigin(float f)
+{
+	vector v;
+	v_x = ((f & 0xFF0000) / 0x10000) / 2;
+	v_y = ((f & 0xFF00) / 0x100 - 128) / 4;
+	v_z = ((f & 0xFF) - 128) / 4;
+	return v;
+}

Modified: trunk/data/qcsrc/common/util.qh
===================================================================
--- trunk/data/qcsrc/common/util.qh	2009-05-04 07:46:32 UTC (rev 6653)
+++ trunk/data/qcsrc/common/util.qh	2009-05-04 09:38:27 UTC (rev 6654)
@@ -155,3 +155,6 @@
 // if no real solution exists, x contains the real part and y the imaginary part of the complex solutions x+iy and x-iy
 
 void check_unacceptable_compiler_bugs();
+
+float compressShotOrigin(vector v);
+vector decompressShotOrigin(float f);

Modified: trunk/data/qcsrc/server/cl_weaponsystem.qc
===================================================================
--- trunk/data/qcsrc/server/cl_weaponsystem.qc	2009-05-04 07:46:32 UTC (rev 6653)
+++ trunk/data/qcsrc/server/cl_weaponsystem.qc	2009-05-04 09:38:27 UTC (rev 6654)
@@ -37,9 +37,9 @@
 	local vector trueaimpoint;
 	local float oldsolid;
 	vector vecs;
-	oldsolid = self.dphitcontentsmask;
-	self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
-	traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * MAX_SHOT_DISTANCE, MOVE_NOMONSTERS, self);
+	oldsolid = ent.dphitcontentsmask;
+	ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
+	traceline(ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + v_forward * MAX_SHOT_DISTANCE, MOVE_NOMONSTERS, ent);
 	trueaimpoint = trace_endpos;
 
 	if(ent.weaponentity.movedir_x > 0)
@@ -56,7 +56,7 @@
 	w_shotorg = ent.origin + ent.view_ofs + v_right * vecs_y + v_up * vecs_z;
 
 	// now move the shotorg forward as much as requested if possible
-	traceline(w_shotorg, w_shotorg + v_forward * (vecs_x + nudge), MOVE_NORMAL, self);
+	traceline(w_shotorg, w_shotorg + v_forward * (vecs_x + nudge), MOVE_NORMAL, ent);
 	w_shotorg = trace_endpos - v_forward * nudge;
 	// calculate the shotdir from the chosen shotorg
 	w_shotdir = normalize(trueaimpoint - w_shotorg);
@@ -72,51 +72,51 @@
 	// ghost corresponding to this player's ping time, and if so it would do
 	// damage to the real player
 	if (antilag)
-	if (self.cursor_trace_ent)                 // client was aiming at someone
-	if (self.cursor_trace_ent != self)         // just to make sure
-	if (self.cursor_trace_ent.takedamage)      // and that person is killable
-	if (self.cursor_trace_ent.classname == "player") // and actually a player
+	if (ent.cursor_trace_ent)                 // client was aiming at someone
+	if (ent.cursor_trace_ent != ent)         // just to make sure
+	if (ent.cursor_trace_ent.takedamage)      // and that person is killable
+	if (ent.cursor_trace_ent.classname == "player") // and actually a player
 	if (cvar("g_antilag") == 1)
 	{
 		// verify that the shot would miss without antilag
 		// (avoids an issue where guns would always shoot at their origin)
-		traceline(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, self);
+		traceline(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, ent);
 		if (!trace_ent.takedamage)
 		{
 			// verify that the shot would hit if altered
-			traceline(w_shotorg, self.cursor_trace_ent.origin, MOVE_NORMAL, self);
-			if (trace_ent == self.cursor_trace_ent)
+			traceline(w_shotorg, ent.cursor_trace_ent.origin, MOVE_NORMAL, ent);
+			if (trace_ent == ent.cursor_trace_ent)
 			{
 				// verify that the shot would hit in the past
-				if(self.antilag_debug)
-					antilag_takeback(self.cursor_trace_ent, time - self.antilag_debug);
+				if(ent.antilag_debug)
+					antilag_takeback(ent.cursor_trace_ent, time - ent.antilag_debug);
 				else
-					antilag_takeback(self.cursor_trace_ent, time - ANTILAG_LATENCY(self));
+					antilag_takeback(ent.cursor_trace_ent, time - ANTILAG_LATENCY(ent));
 
-				traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, self);
-				antilag_restore(self.cursor_trace_ent);
+				traceline(ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, ent);
+				antilag_restore(ent.cursor_trace_ent);
 
-				if(trace_ent == self.cursor_trace_ent)
+				if(trace_ent == ent.cursor_trace_ent)
 				{
 					// HIT!
-					w_shotdir = normalize(self.cursor_trace_ent.origin - w_shotorg);
-					dprint("ANTILAG HIT for ", self.netname, "\n");
+					w_shotdir = normalize(ent.cursor_trace_ent.origin - w_shotorg);
+					dprint("ANTILAG HIT for ", ent.netname, "\n");
 				}
 				else
 				{
 					// prydon cursor aimbot or odd network conditions
-					dprint("WARNING: antilag ghost trace for ", self.netname, " failed!\n");
+					dprint("WARNING: antilag ghost trace for ", ent.netname, " failed!\n");
 				}
 
 				if(cvar("developer") >= 2)
 				{
 					vector v, vplus, vel;
 					float X;
-					v     = antilag_takebackorigin(self.cursor_trace_ent, time - (ANTILAG_LATENCY(self)       ));
-					vplus = antilag_takebackorigin(self.cursor_trace_ent, time - (ANTILAG_LATENCY(self) + 0.01));
+					v     = antilag_takebackorigin(ent.cursor_trace_ent, time - (ANTILAG_LATENCY(ent)       ));
+					vplus = antilag_takebackorigin(ent.cursor_trace_ent, time - (ANTILAG_LATENCY(ent) + 0.01));
 					vel = (vplus - v) * (1 / 0.01);
-					// solve: v + X * vel = closest to self.origin + self.view_ofs, v_forward axis
-					v     -= (self.origin + self.view_ofs);
+					// solve: v + X * vel = closest to ent.origin + ent.view_ofs, v_forward axis
+					v     -= (ent.origin + ent.view_ofs);
 					// solve: v + X * vel = closest to v_forward axis
 					// project into 2D by subtracting v_forward components:
 					v   -= (v   * v_forward) * v_forward;
@@ -125,7 +125,7 @@
 					// (v + X * vel)^2 closest to 0
 					// v^2 + 2 * X * (v * vel) + X^2 * vel^2 closest to 0
 					X = -(v * vel) / (vel * vel);
-					dprint("dead center needs adjustment of ", ftos(X), " (that is, ", ftos(ANTILAG_LATENCY(self) + X), " instead of ", ftos(ANTILAG_LATENCY(self)), "\n");
+					dprint("dead center needs adjustment of ", ftos(X), " (that is, ", ftos(ANTILAG_LATENCY(ent) + X), " instead of ", ftos(ANTILAG_LATENCY(ent)), "\n");
 				}
 			}
 		}
@@ -135,15 +135,15 @@
 	{
 		if (cvar("g_antilag") == 1) // switch to "ghost" if not hitting original
 		{
-			traceline(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, self);
+			traceline(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, ent);
 			if (!trace_ent.takedamage)
 			{
-				traceline_antilag_force (self, w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, self, ANTILAG_LATENCY(self));
+				traceline_antilag_force (ent, w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
 				if (trace_ent.takedamage && trace_ent.classname == "player")
 				{
 					entity e;
 					e = trace_ent;
-					traceline(w_shotorg, e.origin, MOVE_NORMAL, self);
+					traceline(w_shotorg, e.origin, MOVE_NORMAL, ent);
 					if(trace_ent == e)
 						w_shotdir = normalize(trace_ent.origin - w_shotorg);
 				}
@@ -151,20 +151,20 @@
 		}
 		else if(cvar("g_antilag") == 3) // client side hitscan
 		{
-			if (self.cursor_trace_ent)                 // client was aiming at someone
-			if (self.cursor_trace_ent != self)         // just to make sure
-			if (self.cursor_trace_ent.takedamage)      // and that person is killable
-			if (self.cursor_trace_ent.classname == "player") // and actually a player
+			if (ent.cursor_trace_ent)                 // client was aiming at someone
+			if (ent.cursor_trace_ent != ent)         // just to make sure
+			if (ent.cursor_trace_ent.takedamage)      // and that person is killable
+			if (ent.cursor_trace_ent.classname == "player") // and actually a player
 			{
 				// verify that the shot would miss without antilag
 				// (avoids an issue where guns would always shoot at their origin)
-				traceline(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, self);
+				traceline(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, ent);
 				if (!trace_ent.takedamage)
 				{
 					// verify that the shot would hit if altered
-					traceline(w_shotorg, self.cursor_trace_ent.origin, MOVE_NORMAL, self);
-					if (trace_ent == self.cursor_trace_ent)
-						w_shotdir = normalize(self.cursor_trace_ent.origin - w_shotorg);
+					traceline(w_shotorg, ent.cursor_trace_ent.origin, MOVE_NORMAL, ent);
+					if (trace_ent == ent.cursor_trace_ent)
+						w_shotdir = normalize(ent.cursor_trace_ent.origin - w_shotorg);
 					else
 						print("antilag fail\n");
 				}
@@ -173,19 +173,19 @@
 	}
 #endif
 
-	self.dphitcontentsmask = oldsolid; // restore solid type (generally SOLID_SLIDEBOX)
+	ent.dphitcontentsmask = oldsolid; // restore solid type (generally SOLID_SLIDEBOX)
 
 	if (!g_norecoil)
-		self.punchangle_x = recoil * -1;
+		ent.punchangle_x = recoil * -1;
 
 	if (snd != "")
 	{
-		sound (self, CHAN_WEAPON, snd, VOL_BASE, ATTN_NORM);
+		sound (ent, CHAN_WEAPON, snd, VOL_BASE, ATTN_NORM);
 	}
 
-	if (self.items & IT_STRENGTH)
+	if (ent.items & IT_STRENGTH)
 	if (!g_minstagib)
-		sound (self, CHAN_AUTO, "weapons/strength_fire.wav", VOL_BASE, ATTN_NORM);
+		sound (ent, CHAN_AUTO, "weapons/strength_fire.wav", VOL_BASE, ATTN_NORM);
 };
 
 void LaserTarget_Think()
@@ -470,6 +470,8 @@
 			self.movedir = shotorg_adjust(v0, FALSE, FALSE);
 			self.view_ofs = shotorg_adjust(v0, FALSE, TRUE) - v0;
 		}
+		self.owner.stat_shotorg = compressShotOrigin(self.movedir);
+		self.movedir = decompressShotOrigin(self.owner.stat_shotorg); // make them match perfectly
 
 		self.spawnorigin += self.view_ofs; // offset the casings origin by the same amount
 

Modified: trunk/data/qcsrc/server/constants.qh
===================================================================
--- trunk/data/qcsrc/server/constants.qh	2009-05-04 07:46:32 UTC (rev 6653)
+++ trunk/data/qcsrc/server/constants.qh	2009-05-04 09:38:27 UTC (rev 6654)
@@ -159,8 +159,6 @@
 float FLAG_CARRY = 2;
 float FLAG_DROPPED = 3;
 
-float MAX_SHOT_DISTANCE = 32768;
-
 float COLOR_TEAM1	= 5;  // red
 float COLOR_TEAM2	= 14; // blue
 float COLOR_TEAM3	= 13; // yellow

Modified: trunk/data/qcsrc/server/defs.qh
===================================================================
--- trunk/data/qcsrc/server/defs.qh	2009-05-04 07:46:32 UTC (rev 6653)
+++ trunk/data/qcsrc/server/defs.qh	2009-05-04 09:38:27 UTC (rev 6654)
@@ -571,3 +571,5 @@
 
 .float nickspamtime; // time of last nick change
 .float nickspamcount;
+
+.float stat_shotorg; // networked stat for trueaim HUD

Modified: trunk/data/qcsrc/server/g_world.qc
===================================================================
--- trunk/data/qcsrc/server/g_world.qc	2009-05-04 07:46:32 UTC (rev 6653)
+++ trunk/data/qcsrc/server/g_world.qc	2009-05-04 09:38:27 UTC (rev 6654)
@@ -592,6 +592,7 @@
 	addstat(STAT_INVINCIBLE_FINISHED, AS_FLOAT, invincible_finished);
 	addstat(STAT_PRESSED_KEYS, AS_FLOAT, pressedkeys);
 	addstat(STAT_FUEL, AS_INT, ammo_fuel);
+	addstat(STAT_SHOTORG, AS_INT, stat_shotorg);
 
 	next_pingtime = time + 5;
 	InitializeEntity(self, cvar_changes_init, INITPRIO_CVARS);



More information about the nexuiz-commits mailing list