now bullets support warpzones too
authordiv0 <div0@f962a42d-fe04-0410-a3ab-8c8b0445ebaa>
Sun, 28 Feb 2010 19:43:31 +0000 (19:43 +0000)
committerdiv0 <div0@f962a42d-fe04-0410-a3ab-8c8b0445ebaa>
Sun, 28 Feb 2010 19:43:31 +0000 (19:43 +0000)
git-svn-id: svn://svn.icculus.org/nexuiz/trunk@8701 f962a42d-fe04-0410-a3ab-8c8b0445ebaa

data/qcsrc/server/w_common.qc
data/qcsrc/warpzonelib/common.qc
data/qcsrc/warpzonelib/common.qh

index bca4c8b..cfd04d9 100644 (file)
@@ -322,6 +322,14 @@ void endFireBallisticBullet()
        endzcurveparticles();
 }
 
+entity fireBallisticBullet_trace_callback_ent;
+float fireBallisticBullet_trace_callback_eff;
+void fireBallisticBullet_trace_callback()
+{
+       if(vlen(trace_endpos - fireBallisticBullet_trace_callback_ent.origin) > 16)
+               zcurveparticles_from_tracetoss(fireBallisticBullet_trace_callback_eff, fireBallisticBullet_trace_callback_ent.origin, trace_endpos, fireBallisticBullet_trace_callback_ent.velocity);
+}
+
 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;
@@ -404,12 +412,14 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
                        self.velocity = self.velocity * 0.125;
                        self.gravity *= 0.125 * 0.125;
                        trace_fraction = 0;
-                       tracetoss(self, oldself);
+                       fireBallisticBullet_trace_callback_ent = self;
+                       fireBallisticBullet_trace_callback_eff = eff;
+                       WarpZone_trace_callback = fireBallisticBullet_trace_callback;
+                       WarpZone_TraceToss(self, oldself);
+                       WarpZone_trace_callback = func_null;
                        self.velocity = v0;
                        self.gravity = g0;
 
-                       if(vlen(trace_endpos - self.origin) > 16)
-                               zcurveparticles_from_tracetoss(eff, self.origin, trace_endpos, self.velocity);
                        if(trace_fraction == 1)
                                break;
                                // won't hit anything anytime soon (DP's
@@ -417,9 +427,9 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
                                // 0.05*0.125s, that is, 1.25 seconds
 
                        other = trace_ent;
-                       dt = vlen(trace_endpos - self.origin) / vlen(self.velocity); // this is only approximate!
+                       dt = WarpZone_tracetoss_time * 0.125; // this is only approximate!
                        setorigin(self, trace_endpos);
-                       self.velocity_z -= sv_gravity * dt;
+                       self.velocity = WarpZone_tracetoss_velocity * (1 / 0.125);
 
                        if(!SUB_OwnerCheck())
                        {
index d0c3777..0efa19c 100644 (file)
@@ -97,6 +97,8 @@ void WarpZone_TraceBox(vector org, vector mi, vector ma, vector end, float nomon
        for(;;)
        {
                tracebox(org, mi, ma, end, nomonsters, forent);
+               if(WarpZone_trace_callback)
+                       WarpZone_trace_callback();
                if(sol < 0)
                        sol = trace_startsolid;
                if(trace_fraction >= 1)
@@ -109,6 +111,7 @@ void WarpZone_TraceBox(vector org, vector mi, vector ma, vector end, float nomon
                end = WarpZone_TransformOrigin(trace_ent, end);
        }
        WarpZone_MakeAllOther();
+       trace_startsolid = sol;
        WarpZone_trace_endpos = o0 + (e0 - o0) * trace_fraction;
        v_forward = vf;
        v_right = vr;
@@ -120,21 +123,58 @@ void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent)
        WarpZone_TraceBox(org, '0 0 0', '0 0 0', end, nomonsters, forent);
 }
 
+void WarpZone_TraceToss(entity e, entity forent)
+{
+       float g, dt;
+       vector vf, vr, vu, v0, o0;
+       vf = v_forward;
+       vr = v_right;
+       vu = v_up;
+       WarpZone_MakeAllSolid();
+       g = cvar("sv_gravity") * e.gravity;
+       WarpZone_tracetoss_time = 0;
+       v0 = e.velocity;
+       o0 = e.origin;
+       for(;;)
+       {
+               tracetoss(e, forent);
+               if(WarpZone_trace_callback)
+                       WarpZone_trace_callback();
+               e.origin = trace_endpos;
+               dt = vlen(e.origin - o0) / vlen(e.velocity);
+               WarpZone_tracetoss_time += dt;
+               e.velocity_z -= WarpZone_tracetoss_time * g;
+               if(trace_fraction >= 1)
+                       break;
+               if(trace_ent.classname != "trigger_warpzone")
+                       break;
+               // we hit a warpzone... so, let's perform the trace after the warp again
+               e.origin = WarpZone_TransformOrigin(trace_ent, e.origin);
+               e.velocity = WarpZone_TransformVelocity(trace_ent, e.velocity);
+       }
+       WarpZone_MakeAllOther();
+       v_forward = vf;
+       v_right = vr;
+       v_up = vu;
+       WarpZone_tracetoss_velocity = e.velocity;
+       e.velocity = v0;
+       e.origin = o0;
+       WarpZone_trace_endpos = e.origin + e.velocity * WarpZone_tracetoss_time;
+       WarpZone_trace_endpos_z -= 0.5 * g * WarpZone_tracetoss_time * WarpZone_tracetoss_time;
+}
+
 void WarpZone_TrailParticles(entity own, float eff, vector org, vector end)
 {
-       float frac, sol;
+       float frac;
        vector vf, vr, vu;
        vf = v_forward;
        vr = v_right;
        vu = v_up;
        WarpZone_MakeAllSolid();
-       sol = -1;
        frac = 0;
        for(;;)
        {
                traceline(org, end, MOVE_NOMONSTERS, world);
-               if(sol < 0)
-                       sol = trace_startsolid;
                //print(vtos(org), " to ", vtos(trace_endpos), "\n");
                trailparticles(own, eff, org, trace_endpos);
                if(trace_fraction >= 1)
index 29507ae..4017234 100644 (file)
@@ -6,9 +6,13 @@ entity WarpZone_Find(vector mi, vector ma);
 void WarpZone_MakeAllSolid();
 void WarpZone_MakeAllOther();
 
+var void(void) WarpZone_trace_callback; // called after every trace
 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)
 void WarpZone_TraceBox(vector org, vector min, vector max, vector end, float nomonsters, entity forent);
 void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent);
+void WarpZone_TraceToss(entity e, entity forent);
 void WarpZone_TrailParticles(entity own, float eff, vector org, vector end);
 
 vector WarpZone_TransformOrigin(entity wz, vector v);