From: Rudolf Polzer <divverent@xonotic.org>
Date: Wed, 23 May 2012 10:58:00 +0000 (+0200)
Subject: special support for object density -1, which is always passed by ballistic bullets... 
X-Git-Tag: xonotic-v0.7.0~314^2~4^2~1
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=8c1b42346203085dec4e3f33e51348ac1976e860;p=xonotic%2Fxonotic-data.pk3dir.git

special support for object density -1, which is always passed by ballistic bullets (as example of how to mimic the nex beam's behaviour)
---

diff --git a/qcsrc/server/w_common.qc b/qcsrc/server/w_common.qc
index d2f172b4d..4a6de5b4b 100644
--- a/qcsrc/server/w_common.qc
+++ b/qcsrc/server/w_common.qc
@@ -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;