]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
special support for object density -1, which is always passed by ballistic bullets...
authorRudolf Polzer <divverent@xonotic.org>
Wed, 23 May 2012 10:58:00 +0000 (12:58 +0200)
committerRudolf Polzer <divverent@xonotic.org>
Wed, 23 May 2012 10:58:00 +0000 (12:58 +0200)
qcsrc/server/w_common.qc

index d2f172b4d08c8f6ed581cf93e98bc065ceec3025..4a6de5b4b8d036b8f72e270fb042dd261570652e 100644 (file)
@@ -247,25 +247,52 @@ float W_BallisticBullet_LeaveSolid(float eff)
 {
        // move the entity along its velocity until it's out of solid, then let it resume
        vector vel = self.velocity;
-       float constant = self.dmg_radius * (other.ballistics_density ? other.ballistics_density : 1);
        float dt, dst, velfactor, v0, vs;
        float maxdist;
        float E0_m, Es_m;
+       float constant = self.dmg_radius * (other.ballistics_density ? other.ballistics_density : 1);
 
        // outside the world? forget it
        if(self.origin_x > world.maxs_x || self.origin_y > world.maxs_y || self.origin_z > world.maxs_z || self.origin_x < world.mins_x || self.origin_y < world.mins_y || self.origin_z < world.mins_z)
                return 0;
 
+       // special case for zero density and zero bullet constant: 
+
+       if(self.dmg_radius == 0)
+       {
+               if(other.ballistics_density < 0)
+                       constant = 0; // infinite travel distance
+               else
+                       return 0; // no penetration
+       }
+       else
+       {
+               if(other.ballistics_density < 0)
+                       constant = 0; // infinite travel distance
+               else if(other.ballistics_density == 0)
+                       constant = self.dmg_radius;
+               else
+                       constant = self.dmg_radius * other.ballistics_density;
+       }
+
        // E(s) = E0 - constant * s, constant = area of bullet circle * material constant / mass
        v0 = vlen(vel);
 
        E0_m = 0.5 * v0 * v0;
-       maxdist = E0_m / constant;
-       // maxdist = 0.5 * v0 * v0 / constant
-       // dprint("max dist = ", ftos(maxdist), "\n");
 
-       if(maxdist <= autocvar_g_ballistics_mindistance)
-               return 0;
+       if(constant)
+       {
+               maxdist = E0_m / constant;
+               // maxdist = 0.5 * v0 * v0 / constant
+               // dprint("max dist = ", ftos(maxdist), "\n");
+
+               if(maxdist <= autocvar_g_ballistics_mindistance)
+                       return 0;
+       }
+       else
+       {
+               maxdist = vlen(other.maxs - other.mins) + 1; // any distance, as long as we leave the entity
+       }
 
        traceline_inverted (self.origin, self.origin + normalize(vel) * maxdist, MOVE_NORMAL, self, TRUE);
        if(trace_fraction == 1) // 1: we never got out of solid
@@ -389,7 +416,10 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
        proj.nextthink = time + lifetime; // min(pLifetime, vlen(world.maxs - world.mins) / pSpeed);
        W_SetupProjectileVelocityEx(proj, dir, v_up, pSpeed, 0, 0, spread, antilagging);
        proj.angles = vectoangles(proj.velocity);
-       proj.dmg_radius = autocvar_g_ballistics_materialconstant / bulletconstant;
+       if(bulletconstant)
+               proj.dmg_radius = autocvar_g_ballistics_materialconstant / bulletconstant;
+       else
+               proj.dmg_radius = 0;
        // so: bulletconstant = bullet mass / area of bullet circle
        setorigin(proj, start);
        proj.flags = FL_PROJECTILE;