[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