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

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sun Feb 28 14:43:45 EST 2010


Author: div0
Date: 2010-02-28 14:43:45 -0500 (Sun, 28 Feb 2010)
New Revision: 8704

Modified:
   trunk/data/Makefile
   trunk/data/qcsrc/client/csqc_builtins.qc
   trunk/data/qcsrc/server/miscfunctions.qc
   trunk/data/qcsrc/server/sv_main.qc
   trunk/data/qcsrc/server/t_teleporters.qc
   trunk/data/qcsrc/warpzonelib/client.qc
   trunk/data/qcsrc/warpzonelib/common.qc
   trunk/data/qcsrc/warpzonelib/common.qh
   trunk/data/qcsrc/warpzonelib/server.qc
   trunk/data/qcsrc/warpzonelib/server.qh
Log:
properly transport projectiles

Modified: trunk/data/Makefile
===================================================================
--- trunk/data/Makefile	2010-02-28 19:43:40 UTC (rev 8703)
+++ trunk/data/Makefile	2010-02-28 19:43:45 UTC (rev 8704)
@@ -56,10 +56,10 @@
 clean:
 	rm -f progs.dat menu.dat csprogs.dat
 
-csprogs.dat: qcsrc/client/*.* qcsrc/common/*.*
+csprogs.dat: qcsrc/client/*.* qcsrc/common/*.* qcsrc/warpzonelib/*.*
 	cd qcsrc/client && $(FTEQCC) $(FTEQCCFLAGS) $(FTEQCCFLAGS_CSPROGS)
 
-progs.dat: qcsrc/server/*.* qcsrc/common/*.* qcsrc/server/*/*.* qcsrc/server/*/*/*.*
+progs.dat: qcsrc/server/*.* qcsrc/common/*.* qcsrc/server/*/*.* qcsrc/server/*/*/*.* qcsrc/warpzonelib/*.*
 	cd qcsrc/server && $(FTEQCC) $(FTEQCCFLAGS) $(FTEQCCFLAGS_PROGS)
 
 menu.dat: qcsrc/menu/*.* qcsrc/menu/*/*.* qcsrc/common/*.*

Modified: trunk/data/qcsrc/client/csqc_builtins.qc
===================================================================
--- trunk/data/qcsrc/client/csqc_builtins.qc	2010-02-28 19:43:40 UTC (rev 8703)
+++ trunk/data/qcsrc/client/csqc_builtins.qc	2010-02-28 19:43:45 UTC (rev 8704)
@@ -306,3 +306,5 @@
 float RAD2DEG = 57.2957795130823208767981548141051703324054724665643215491602438612;
 float PI      = 3.1415926535897932384626433832795028841971693993751058209749445923;
 float log(float f) = #532;
+
+void(entity e, entity ignore) tracetoss = #64;

Modified: trunk/data/qcsrc/server/miscfunctions.qc
===================================================================
--- trunk/data/qcsrc/server/miscfunctions.qc	2010-02-28 19:43:40 UTC (rev 8703)
+++ trunk/data/qcsrc/server/miscfunctions.qc	2010-02-28 19:43:45 UTC (rev 8704)
@@ -1996,7 +1996,20 @@
 
 #define SUB_OwnerCheck() (other && (other == self.owner))
 
-#define PROJECTILE_TOUCH do { if(SUB_OwnerCheck()) return; if(SUB_NoImpactCheck()) { remove(self); return; } if(trace_ent && trace_ent.solid > SOLID_TRIGGER) UpdateCSQCProjectileNextFrame(self); } while(0)
+float WarpZone_Projectile_Touch_ImpactFilter_Callback()
+{
+	if(SUB_OwnerCheck())
+		return TRUE;
+	if(SUB_NoImpactCheck())
+	{
+		remove(self);
+		return TRUE;
+	}
+	if(trace_ent && trace_ent.solid > SOLID_TRIGGER)
+		UpdateCSQCProjectileNextFrame(self);
+	return FALSE;
+}
+#define PROJECTILE_TOUCH if(WarpZone_Projectile_Touch()) return
 
 float MAX_IPBAN_URIS = 16;
 

Modified: trunk/data/qcsrc/server/sv_main.qc
===================================================================
--- trunk/data/qcsrc/server/sv_main.qc	2010-02-28 19:43:40 UTC (rev 8703)
+++ trunk/data/qcsrc/server/sv_main.qc	2010-02-28 19:43:45 UTC (rev 8704)
@@ -176,6 +176,8 @@
 	UncustomizeEntitiesRun();
 	InitializeEntitiesRun();
 
+	WarpZone_StartFrame();
+
 	sv_gravity = cvar("sv_gravity");
 	sv_maxairspeed = cvar("sv_maxairspeed");
 	sv_maxspeed = cvar ("sv_maxspeed");

Modified: trunk/data/qcsrc/server/t_teleporters.qc
===================================================================
--- trunk/data/qcsrc/server/t_teleporters.qc	2010-02-28 19:43:40 UTC (rev 8703)
+++ trunk/data/qcsrc/server/t_teleporters.qc	2010-02-28 19:43:45 UTC (rev 8704)
@@ -298,7 +298,7 @@
 	}
 }
 
-void WarpZone_PostTeleportPlayer(entity pl)
+void WarpZone_PostTeleportPlayer_Callback(entity pl)
 {
 	UpdateCSQCProjectileAfterTeleport(pl);
 	if(pl.classname == "player")

Modified: trunk/data/qcsrc/warpzonelib/client.qc
===================================================================
--- trunk/data/qcsrc/warpzonelib/client.qc	2010-02-28 19:43:40 UTC (rev 8703)
+++ trunk/data/qcsrc/warpzonelib/client.qc	2010-02-28 19:43:45 UTC (rev 8704)
@@ -29,13 +29,12 @@
 	self.avelocity_y = ReadCoord();
 	self.avelocity_z = ReadCoord();
 
+	// common stuff
+	WarpZone_SetUp(self, self.enemy.oldorigin, self.enemy.avelocity, self.oldorigin, self.avelocity);
+
+	// engine currently wants this
 	self.avelocity = AnglesTransform_TurnDirectionFR(self.avelocity);
 
-	// for common code
-	self.warpzone_origin = self.enemy.oldorigin;
-	self.enemy.warpzone_origin = self.oldorigin;
-	self.warpzone_transform = AnglesTransform_Divide(self.avelocity, self.enemy.avelocity);
-
 	self.flags = FL_CAMERA;
 	self.drawmask = MASK_NORMAL;
 
@@ -69,13 +68,11 @@
 	e = WarpZone_Find(warpzone_fixview_origin - '1 1 1' * nearclip, warpzone_fixview_origin + '1 1 1' * nearclip);
 	if(e)
 	{
-		fixedmakevectors(e.enemy.avelocity);
-		pd = (warpzone_fixview_origin - e.enemy.oldorigin) * v_forward;
+		pd = WarpZone_PlaneDist(e, warpzone_fixview_origin);
 		if(pd >= 0 && pd < nearclip)
 		{
 			warpzone_saved = 1;
-			warpzone_fixview_origin = warpzone_fixview_origin + v_forward * (nearclip - pd);
-			pd = (warpzone_fixview_origin - e.enemy.oldorigin) * v_forward;
+			warpzone_fixview_origin = warpzone_fixview_origin + e.warpzone_forward * (nearclip - pd);
 		}
 	}
 

Modified: trunk/data/qcsrc/warpzonelib/common.qc
===================================================================
--- trunk/data/qcsrc/warpzonelib/common.qc	2010-02-28 19:43:40 UTC (rev 8703)
+++ trunk/data/qcsrc/warpzonelib/common.qc	2010-02-28 19:43:45 UTC (rev 8704)
@@ -1,5 +1,14 @@
-.vector warpzone_origin;
-.vector warpzone_transform;
+void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, vector other_ang)
+{
+	e.warpzone_transform = AnglesTransform_Divide(other_ang, AnglesTransform_TurnDirectionFR(my_ang));
+	e.warpzone_origin = my_org;
+	e.warpzone_targetorigin = other_org;
+	e.warpzone_angles = my_ang;
+	e.warpzone_targetangles = other_ang;
+	fixedmakevectors(my_ang); e.warpzone_forward = v_forward;
+	fixedmakevectors(other_ang); e.warpzone_targetforward = v_forward;
+}
+
 .entity enemy;
 
 vector WarpZoneLib_BoxTouchesBrush_mins;
@@ -109,6 +118,9 @@
 		// we hit a warpzone... so, let's perform the trace after the warp again
 		org = WarpZone_TransformOrigin(trace_ent, trace_endpos);
 		end = WarpZone_TransformOrigin(trace_ent, end);
+		WarpZone_trace_velocity = WarpZone_TransformVelocity(trace_ent, WarpZone_trace_velocity);
+		WarpZone_trace_angles = WarpZone_TransformAngles(trace_ent, WarpZone_trace_angles);
+		WarpZone_trace_v_angle = WarpZone_TransformVAngles(trace_ent, WarpZone_trace_v_angle);
 	}
 	WarpZone_MakeAllOther();
 	trace_startsolid = sol;
@@ -191,6 +203,16 @@
 	v_up = vu;
 }
 
+float WarpZone_PlaneDist(entity wz, vector v)
+{
+	return (v - wz.warpzone_origin) * wz.warpzone_forward;
+}
+
+float WarpZone_TargetPlaneDist(entity wz, vector v)
+{
+	return (v - wz.warpzone_targetorigin) * wz.warpzone_targetforward;
+}
+
 vector WarpZone_TransformOrigin(entity wz, vector v)
 {
 	return wz.enemy.warpzone_origin + AnglesTransform_Apply(wz.warpzone_transform, v - wz.warpzone_origin);

Modified: trunk/data/qcsrc/warpzonelib/common.qh
===================================================================
--- trunk/data/qcsrc/warpzonelib/common.qh	2010-02-28 19:43:40 UTC (rev 8703)
+++ trunk/data/qcsrc/warpzonelib/common.qh	2010-02-28 19:43:45 UTC (rev 8704)
@@ -1,3 +1,12 @@
+.vector warpzone_origin;
+.vector warpzone_angles;
+.vector warpzone_forward;
+.vector warpzone_targetorigin;
+.vector warpzone_targetangles;
+.vector warpzone_targetforward;
+.vector warpzone_transform;
+void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, vector other_ang);
+
 float FL_CAMERA = 8192;
 
 float WarpZoneLib_BoxTouchesBrush(vector mi, vector ma, entity e, entity ig);
@@ -7,6 +16,9 @@
 void WarpZone_MakeAllOther();
 
 var void(void) WarpZone_trace_callback; // called after every trace
+vector WarpZone_trace_angles; // total angles accumulator
+vector WarpZone_trace_v_angle; // total v_angle accumulator
+vector WarpZone_trace_velocity; // total velocity
 vector WarpZone_trace_endpos; // UNtransformed endpos
 vector WarpZone_tracetoss_velocity; // ending velocity of a tracetoss (post-transform)
 float WarpZone_tracetoss_time; // duration of toss (approximate)
@@ -15,6 +27,8 @@
 void WarpZone_TraceToss(entity e, entity forent);
 void WarpZone_TrailParticles(entity own, float eff, vector org, vector end);
 
+float WarpZone_PlaneDist(entity wz, vector v);
+float WarpZone_TargetPlaneDist(entity wz, vector v);
 vector WarpZone_TransformOrigin(entity wz, vector v);
 vector WarpZone_TransformVelocity(entity wz, vector v);
 vector WarpZone_TransformAngles(entity wz, vector v);

Modified: trunk/data/qcsrc/warpzonelib/server.qc
===================================================================
--- trunk/data/qcsrc/warpzonelib/server.qc	2010-02-28 19:43:40 UTC (rev 8703)
+++ trunk/data/qcsrc/warpzonelib/server.qc	2010-02-28 19:43:45 UTC (rev 8704)
@@ -1,5 +1,15 @@
-void WarpZone_TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity, vector telefragmin, vector telefragmax, float tflags)
+.vector warpzone_oldorigin, warpzone_oldvelocity, warpzone_oldangles;
+.float warpzone_teleport_time;
+
+void WarpZone_StoreProjectileData(entity e)
 {
+	e.warpzone_oldorigin = e.origin;
+	e.warpzone_oldvelocity = e.velocity;
+	e.warpzone_oldangles = e.angles;
+}
+
+void WarpZone_TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity)
+{
 	vector from;
 
 	makevectors (to_angles);
@@ -19,13 +29,9 @@
 	if(player.classname == "player")
 		player.flags &~= FL_ONGROUND;
 
-	WarpZone_PostTeleportPlayer(player);
+	WarpZone_PostTeleportPlayer_Callback(player);
 }
 
-// the transform
-.vector warpzone_angles;
-.vector warpzone_forward;
-
 float WarpZone_Teleport(entity player)
 {
 	vector o0, a0, v0, o1, a1, v1;
@@ -34,7 +40,7 @@
 	v0 = player.velocity;
 	a0 = player.angles;
 
-	if((o0 - self.warpzone_origin) * self.warpzone_forward >= 0) // wrong side of the portal
+	if(WarpZone_PlaneDist(self, o0) >= 0) // wrong side of the portal
 		return 2;
 	// no failure, we simply don't want to teleport yet; TODO in
 	// this situation we may want to create a temporary clone
@@ -71,7 +77,7 @@
 		}
 	}
 
-	if((o1 - self.enemy.warpzone_origin) * self.enemy.warpzone_forward <= 0) // wrong side of the portal post-teleport
+	if(WarpZone_TargetPlaneDist(self, o1) <= 0)
 	{
 		print("inconsistent warp zones or evil roundoff error\n");
 		return 0;
@@ -80,7 +86,9 @@
 	//print(sprintf("warpzone: %f %f %f -> %f %f %f\n", o0_x, o0_y, o0_z, o1_x, o1_y, o1_z));
 
 	//o1 = trace_endpos;
-	TeleportPlayer(self, other, o1 - player.view_ofs, a1, v1, '0 0 0', '0 0 0', TELEPORT_FLAGS_WARPZONE);
+	WarpZone_TeleportPlayer(self, other, o1 - player.view_ofs, a1, v1);
+	WarpZone_StoreProjectileData(player);
+	player.warpzone_teleport_time = time;
 
 	return 1;
 }
@@ -89,6 +97,9 @@
 {
 	entity oldself, e;
 
+	if(other.classname == "trigger_warpzone")
+		return;
+
 	// FIXME needs a better check to know what is safe to teleport and what not
 	if(other.movetype == MOVETYPE_NONE)
 		return;
@@ -138,12 +149,12 @@
 	WriteCoord(MSG_ENTITY, self.warpzone_angles_x);
 	WriteCoord(MSG_ENTITY, self.warpzone_angles_y);
 	WriteCoord(MSG_ENTITY, self.warpzone_angles_z);
-	WriteCoord(MSG_ENTITY, self.enemy.warpzone_origin_x);
-	WriteCoord(MSG_ENTITY, self.enemy.warpzone_origin_y);
-	WriteCoord(MSG_ENTITY, self.enemy.warpzone_origin_z);
-	WriteCoord(MSG_ENTITY, self.enemy.warpzone_angles_x);
-	WriteCoord(MSG_ENTITY, self.enemy.warpzone_angles_y);
-	WriteCoord(MSG_ENTITY, self.enemy.warpzone_angles_z);
+	WriteCoord(MSG_ENTITY, self.warpzone_targetorigin_x);
+	WriteCoord(MSG_ENTITY, self.warpzone_targetorigin_y);
+	WriteCoord(MSG_ENTITY, self.warpzone_targetorigin_z);
+	WriteCoord(MSG_ENTITY, self.warpzone_targetangles_x);
+	WriteCoord(MSG_ENTITY, self.warpzone_targetangles_y);
+	WriteCoord(MSG_ENTITY, self.warpzone_targetangles_z);
 
 	return TRUE;
 }
@@ -203,24 +214,81 @@
 		return;
 	}
 
-	// 1. update this, and the enemy, warp zone
-	self.warpzone_origin = self.aiment.origin;
-	self.warpzone_angles = self.aiment.angles;
-	self.enemy.warpzone_origin = self.enemy.aiment.origin;
-	self.enemy.warpzone_angles = self.enemy.aiment.angles;
+	WarpZone_SetUp(self, self.aiment.origin, self.aiment.angles, self.enemy.aiment.origin, self.enemy.aiment.angles);
 
-	// 2. combine the angle transforms
-	//    current forward must be turned into previous backward
-	self.warpzone_transform = AnglesTransform_Divide(AnglesTransform_TurnDirectionFR(self.enemy.warpzone_angles), self.warpzone_angles);
-
-	// 3. store off a saved forward vector for plane hit decisions
-	fixedmakevectors(self.warpzone_angles);
-	self.warpzone_forward = v_forward;
-
 	// now enable touch
 	self.touch = WarpZone_Touch;
 
 	// our mins/maxs are set to the warpzone... so all we need:
 	self.flags |= FL_CAMERA;
-	self.view_ofs = self.enemy.warpzone_origin;
+	self.view_ofs = self.warpzone_targetorigin;
 }
+
+float WarpZone_CheckProjectileImpact()
+{
+	// if self hit a warpzone, abort
+	vector o0, v0, a0;
+	float mpd, pd, dpd;
+	entity wz;
+	wz = WarpZone_Find(self.origin + self.mins, self.origin + self.maxs);
+	if(!wz)
+		return FALSE;
+	o0 = self.origin;
+	v0 = self.velocity;
+	a0 = self.angles;
+
+	// this approach transports the projectile at its full speed, but does
+	// not properly retain the projectile trail (but we can't retain it
+	// easily anyway without delaying the projectile by two frames, so who
+	// cares)
+	WarpZone_trace_angles = self.angles;
+	WarpZone_trace_velocity = self.velocity;
+	WarpZone_TraceBox(self.warpzone_oldorigin, self.mins, self.maxs, self.warpzone_oldorigin + self.warpzone_oldvelocity * frametime, MOVE_NORMAL, self); // this will get us through the warpzone
+	setorigin(self, trace_endpos);
+	self.angles = WarpZone_trace_angles;
+	self.velocity = WarpZone_trace_velocity;
+	
+	// in case we are in our warp zone post-teleport, shift the projectile forward a bit
+	mpd = max(vlen(self.mins), vlen(self.maxs));
+	pd = WarpZone_TargetPlaneDist(wz, self.origin);
+	if(pd < mpd)
+	{
+		dpd = normalize(self.velocity) * self.warpzone_targetforward;
+		setorigin(self, self.origin + normalize(self.velocity) * ((mpd - pd) / dpd));
+		if(!WarpZoneLib_MoveOutOfSolid(self))
+		{
+			setorigin(self, o0);
+			self.angles = a0;
+			self.velocity = v0;
+			return FALSE;
+		}
+	}
+	WarpZone_StoreProjectileData(self);
+	self.warpzone_teleport_time = time;
+
+	return TRUE;
+}
+void WarpZone_StartFrame()
+{
+	entity e;
+	for(e = world; (e = nextent(e)); )
+		WarpZone_StoreProjectileData(e);
+}
+float WarpZone_Projectile_Touch()
+{
+	if(other.classname == "trigger_warpzone")
+		return TRUE;
+	if(WarpZone_Projectile_Touch_ImpactFilter_Callback())
+		return TRUE;
+	if(WarpZone_CheckProjectileImpact())
+		return TRUE;
+	if(self.warpzone_teleport_time == time) // already got teleported this frame? no collision then please
+	{
+		setorigin(self, self.warpzone_oldorigin);
+		self.velocity = self.warpzone_oldvelocity;
+		self.angles = self.warpzone_oldangles;
+		return TRUE;
+	}
+
+	return FALSE;
+}

Modified: trunk/data/qcsrc/warpzonelib/server.qh
===================================================================
--- trunk/data/qcsrc/warpzonelib/server.qh	2010-02-28 19:43:40 UTC (rev 8703)
+++ trunk/data/qcsrc/warpzonelib/server.qh	2010-02-28 19:43:45 UTC (rev 8704)
@@ -2,9 +2,13 @@
 void WarpZone_InitStep_FindTarget();
 void WarpZone_InitStep_UpdateTransform();
 
+void WarpZone_StartFrame();
+float WarpZone_Projectile_Touch();
+
 // THESE must be defined by calling QC code:
 void spawnfunc_trigger_warpzone(); // must call the init steps in order, first all spawnfunc init steps, then all findtarget init steps, then all updatetransform init steps
-void WarpZone_PostTeleportPlayer(entity pl);
+void WarpZone_PostTeleportPlayer_Callback(entity pl);
+float WarpZone_Projectile_Touch_ImpactFilter_Callback();
 
 // server must also define a float called ENT_CLIENT_WARPZONE for the initial byte of WarpZone entities
 const float ENT_CLIENT_WARPZONE;



More information about the nexuiz-commits mailing list