r5294 - in trunk/data: . qcsrc/server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Wed Dec 24 08:57:07 EST 2008


Author: div0
Date: 2008-12-24 08:57:07 -0500 (Wed, 24 Dec 2008)
New Revision: 5294

Modified:
   trunk/data/defaultNexuiz.cfg
   trunk/data/qcsrc/server/constants.qh
   trunk/data/qcsrc/server/w_campingrifle.qc
   trunk/data/qcsrc/server/w_common.qc
   trunk/data/weapons.cfg
   trunk/data/weaponsPro.cfg
Log:
updated ballistics code and data, matches physics better now


Modified: trunk/data/defaultNexuiz.cfg
===================================================================
--- trunk/data/defaultNexuiz.cfg	2008-12-24 13:16:14 UTC (rev 5293)
+++ trunk/data/defaultNexuiz.cfg	2008-12-24 13:57:07 UTC (rev 5294)
@@ -16,7 +16,7 @@
 seta g_configversion 0
 
 // default.cfg versioning (update using update-cvarcount.sh; run that every time after adding a new cvar)
-set cvar_check_default b58c84e3a08bf79ae880a0d4b081efbb
+set cvar_check_default 3a4552d8adffd3ad69fec3f0c15c62d8
 
 // Nexuiz version (formatted for machines)
 // used to determine if a client version is compatible
@@ -1247,7 +1247,37 @@
 
 alias records "cmd records"
 
-set g_ballistics_solidspeedhalflife 0.001 // note: bullets can travel this*velocity*1.44 far inside solid
+// ballistics use physical units, but qu based
+//   Quake-Newton: 1 qN  = 1 qu * 1 g / 1 s^2
+//   Quake-Joule:  1 qJ  = 1 qN * 1 qu
+//   Quake-Pascal: 1 qPa = 1 qN / 1 qu^2
+
+set g_ballistics_materialconstant 600060006 // arbitrary: 2^22
+// unit: qJ / qu^3 (energy needed per volume unit of solid to push/burn away
+// parameter: bullet constant: mass / area in g/qu^2
+// = mass / (pi/4 * caliber^2)
+// with caliber in inches, mass in grams:
+// = 1.273239544735163 * mass / caliber^2
+// with caliber in inches, mass in grains:
+// = 0.082633246453312 * mass / caliber^2
+
+// bullet max travel distance inside solid:
+//   0.5 * v^2 * bulletconstant / g_ballistics_materialconstant
+
+// some bullet constants:
+//   http://hypertextbook.com/facts/2000/ShantayArmstrong.shtml
+//     second bullet: caliber .45, mass 16.2g, bullet constant 101.859163578813
+//     third bullet: caliber .338, mass 16.2g, bullet constant 180.5476053421592
+//     fourth bullet: caliber .25, mass 2.3g, bullet constant 46.85521524625399
+//   http://en.wikipedia.org/wiki/.50_BMG
+//     caliber .5, 360 grains, bullet constant 118.9918748927693
+//   AK-47:
+//     caliber .3, 62 grains, bullet constant 56.92512533450383
+//   .3 winchester magnum:
+//     caliber .3, 150 grains, bullet constant 137.7220774221867
+
 set g_ballistics_force 0 // 1: make all bullets use the ballistics code instead of hitscan
 set g_ballistics_force_uzi_speed 10000 // speed of uzi bullets if g_ballistics_force is 1
+set g_ballistics_force_uzi_bulletconstant 80 // 6.7 qu
 set g_ballistics_force_shotgun_speed 6000 // speed of shotgun bullets if g_ballistics_force is 1
+set g_ballistics_force_shotgun_bulletconstant 50 // 1.5 qu

Modified: trunk/data/qcsrc/server/constants.qh
===================================================================
--- trunk/data/qcsrc/server/constants.qh	2008-12-24 13:16:14 UTC (rev 5293)
+++ trunk/data/qcsrc/server/constants.qh	2008-12-24 13:57:07 UTC (rev 5294)
@@ -1,5 +1,5 @@
-string CVAR_CHECK_DEFAULT = "b58c84e3a08bf79ae880a0d4b081efbb";
-string CVAR_CHECK_WEAPONS = "5a724edde37f7db7608cf03f262a1f34";
+string CVAR_CHECK_DEFAULT = "3a4552d8adffd3ad69fec3f0c15c62d8";
+string CVAR_CHECK_WEAPONS = "7abbcf55140e618bfaa97b587fc7aef7";
 float	FALSE					= 0;
 float	TRUE					= 1;
 

Modified: trunk/data/qcsrc/server/w_campingrifle.qc
===================================================================
--- trunk/data/qcsrc/server/w_campingrifle.qc	2008-12-24 13:16:14 UTC (rev 5293)
+++ trunk/data/qcsrc/server/w_campingrifle.qc	2008-12-24 13:57:07 UTC (rev 5294)
@@ -20,7 +20,7 @@
 		W_Campingrifle_Reload();
 }
 
-void W_CampingRifle_FireBullet(float pSpread, float pDamage, float pHeadshotAddedDamage, float pForce, float pSpeed, float pLifetime, float pAmmo, float deathtype)
+void W_CampingRifle_FireBullet(float pSpread, float pDamage, float pHeadshotAddedDamage, float pForce, float pSpeed, float pLifetime, float pAmmo, float deathtype, float pBulletConstant)
 {
 	if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
 		self.ammo_nails -= pAmmo;
@@ -28,7 +28,7 @@
 	W_SetupShot (self, '25 8 -8', FALSE, 2, "weapons/campingrifle_fire.wav");
 	pointparticles(particleeffectnum("shotgun_muzzleflash"), w_shotorg, w_shotdir * 2000, 1);
 
-	fireBallisticBullet(w_shotorg, v_forward /* no TrueAim for this weapon */, pSpread, pSpeed, pLifetime, pDamage, pHeadshotAddedDamage / pDamage, pForce, deathtype, EF_RED, 1);
+	fireBallisticBullet(w_shotorg, v_forward /* no TrueAim, so shooting through solid is easier */, pSpread, pSpeed, pLifetime, pDamage, pHeadshotAddedDamage / pDamage, pForce, deathtype, EF_RED, 1, pBulletConstant);
 
 	if (cvar("g_casings") >= 2)
 		SpawnCasing (w_shotorg + v_forward * 10, ((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3);
@@ -39,12 +39,12 @@
 
 void W_Campingrifle_Attack()
 {
-	W_CampingRifle_FireBullet(cvar("g_balance_campingrifle_primary_spread"), cvar("g_balance_campingrifle_primary_damage"), cvar("g_balance_campingrifle_primary_headshotaddeddamage"), cvar("g_balance_campingrifle_primary_force"), cvar("g_balance_campingrifle_primary_speed"), cvar("g_balance_campingrifle_primary_lifetime"), cvar("g_balance_campingrifle_primary_ammo"), WEP_CAMPINGRIFLE);
+	W_CampingRifle_FireBullet(cvar("g_balance_campingrifle_primary_spread"), cvar("g_balance_campingrifle_primary_damage"), cvar("g_balance_campingrifle_primary_headshotaddeddamage"), cvar("g_balance_campingrifle_primary_force"), cvar("g_balance_campingrifle_primary_speed"), cvar("g_balance_campingrifle_primary_lifetime"), cvar("g_balance_campingrifle_primary_ammo"), WEP_CAMPINGRIFLE, cvar("g_balance_campingrifle_primary_bulletconstant"));
 }
 
 void W_Campingrifle_Attack2()
 {
-	W_CampingRifle_FireBullet(cvar("g_balance_campingrifle_secondary_spread"), cvar("g_balance_campingrifle_secondary_damage"), cvar("g_balance_campingrifle_secondary_headshotaddeddamage"), cvar("g_balance_campingrifle_secondary_force"), cvar("g_balance_campingrifle_secondary_speed"), cvar("g_balance_campingrifle_secondary_lifetime"), cvar("g_balance_campingrifle_secondary_ammo"), WEP_CAMPINGRIFLE | HITTYPE_SECONDARY);
+	W_CampingRifle_FireBullet(cvar("g_balance_campingrifle_secondary_spread"), cvar("g_balance_campingrifle_secondary_damage"), cvar("g_balance_campingrifle_secondary_headshotaddeddamage"), cvar("g_balance_campingrifle_secondary_force"), cvar("g_balance_campingrifle_secondary_speed"), cvar("g_balance_campingrifle_secondary_lifetime"), cvar("g_balance_campingrifle_secondary_ammo"), WEP_CAMPINGRIFLE | HITTYPE_SECONDARY, cvar("g_balance_campingrifle_secondary_bulletconstant"));
 }
 
 void spawnfunc_weapon_campingrifle (void)

Modified: trunk/data/qcsrc/server/w_common.qc
===================================================================
--- trunk/data/qcsrc/server/w_common.qc	2008-12-24 13:16:14 UTC (rev 5293)
+++ trunk/data/qcsrc/server/w_common.qc	2008-12-24 13:57:07 UTC (rev 5294)
@@ -119,7 +119,7 @@
 	vector org2;
 	float f;
 
-	org2 = self.origin - 6 * normalize(self.oldvelocity);
+	org2 = self.origin - 6 * normalize(self.velocity);
 	if (DEATH_ISWEAPON(self.projectiledeathtype, WEP_SHOTGUN))
 		pointparticles(particleeffectnum("shotgun_impact"), org2, normalize(self.velocity) * 1000, 1);
 	else
@@ -129,7 +129,7 @@
 	{
 		self.enemy = other; // don't hit the same player twice with the same bullet
 
-		f = vlen(self.velocity) / vlen(self.oldvelocity);
+		f = pow(bound(0, vlen(self.velocity) / vlen(self.oldvelocity), 1), 2); // energy multiplier
 
 		headshot = 0;
 		yoda = 0;
@@ -170,7 +170,7 @@
 	self.flags &~= FL_ONGROUND;
 	self.effects &~= EF_NODRAW;
 
-	org2 = self.origin - 6 * normalize(self.oldvelocity);
+	org2 = self.origin + 6 * normalize(self.velocity);
 	if (DEATH_ISWEAPON(self.projectiledeathtype, WEP_SHOTGUN))
 		pointparticles(particleeffectnum("shotgun_impact"), org2, normalize(self.velocity) * 1000, 1);
 	else
@@ -187,31 +187,23 @@
 	return 2 * log(sqrt(x));
 }
 
-float W_BallisticBullet_LeaveSolid(entity e, vector vel, float speedhalflife)
+float W_BallisticBullet_LeaveSolid(entity e, vector vel, float constant)
 {
 	// move the entity along its velocity until it's out of solid, then let it resume
 	
 	vector tracevel, org, skiporg, endorg, t;
-	float dt, dst, velfactor, v0;
+	float dt, dst, velfactor, v0, vs;
 	float maxdist;
+	float E0_m, Es_m;
 
-	speedhalflife *= 1.442695040888963; // distance for 1/eth of the speed
+	// E(s) = E0 - constant * s, constant = area of bullet circle * material constant / mass
 	v0 = vlen(vel);
 
-	// maxdist: max distance that CAN be travelled using current velocity and speed halflife
-	//
-	// v(t) = v(0) * e^(-t / speedhalflife)
-	// integrate
-	// V(t) = - v(0) * e^(-t / speedhalflife) * speedhalflife
-	// s(t) = V(t) - V(0)
-	// s(t) = (speedhalflife * v(0)) * (1 - e^(-t / speedhalflife))
-	// lim s = speedhalflife * v(0)
-	// t(s) = speedhalflife * log((speedhalflife * v(0)) / (speedhalflife * v(0) - s))
-	// v(s) = (speedhalflife * v(0) - s) / speedhalflife
+	E0_m = 0.5 * v0 * v0;
+	maxdist = E0_m / constant;
+	// maxdist = 0.5 * v0 * v0 / constant
+	dprint("max dist = ", ftos(maxdist), "\n");
 
-	maxdist = speedhalflife * v0;
-	//print("max dist = ", ftos(maxdist), "\n");
-
 	if(maxdist <= 0)
 		return 0;
 
@@ -259,14 +251,23 @@
 	}
 
 	dst = vlen(self.W_BallisticBullet_LeaveSolid_origin - org);
-	velfactor = (speedhalflife * v0 - dst) / (speedhalflife * v0);
+	// E(s) = E0 - constant * s, constant = area of bullet circle * material constant / mass
+	Es_m = E0_m - constant * dst;
+	if(Es_m < 0)
+	{
+		print("ballistics: error condition Es_m < 0\n");
+		print("dst = ", ftos(dst), "\n");
+		print("maxdist = ", ftos(maxdist), "\n");
+		Es_m = 0;
+		return 0;
+	}
+	vs = sqrt(2 * Es_m);
+	velfactor = vs / v0;
 
-	// t(s) = speedhalflife * log((speedhalflife * v(0)) / (speedhalflife * v(0) - s))
-	dt = speedhalflife * log((speedhalflife * v0) / (speedhalflife * v0 - dst));
+	dt = dst / (0.5 * (v0 + vs));
+	// this is not correct, but the differential equations have no analytic
+	// solution - and these times are very small anyway
 
-	//print("slowdown by ", ftos(dst), " units = ", ftos(velfactor), "\n");
-	//print("takes time ", ftos(dt), "\n");
-
 	self.W_BallisticBullet_LeaveSolid_think_save = self.think;
 	self.W_BallisticBullet_LeaveSolid_nextthink_save = self.nextthink;
 	self.think = W_BallisticBullet_LeaveSolid_think;
@@ -300,7 +301,7 @@
 	self.projectiledeathtype |= HITTYPE_BOUNCE;
 }
 
-void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, float lifetime, float damage, float headshotbonus, float force, float dtype, float tracereffects, float gravityfactor)
+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)
 {
 	entity proj;
 	proj = spawn();
@@ -318,7 +319,8 @@
 	proj.velocity = (dir + randomvec() * spread) * pSpeed;
 	W_SetupProjectileVelocity(proj);
 	proj.angles = vectoangles(proj.velocity);
-	proj.dmg_radius = cvar("g_ballistics_solidspeedhalflife");
+	proj.dmg_radius = cvar("g_ballistics_materialconstant") / bulletconstant;
+	// so: bulletconstant = bullet mass / area of bullet circle
 	setmodel(proj, "models/tracer.mdl");
 	setsize(proj, '0 0 0', '0 0 0');
 	setorigin(proj, start);
@@ -342,9 +344,9 @@
 	if(cvar("g_ballistics_force"))
 	{
 		if (DEATH_ISWEAPON(dtype, WEP_SHOTGUN))
-			fireBallisticBullet(start, dir, spread, cvar("g_ballistics_force_shotgun_speed"), 5, damage, 0, force, dtype, 0, 1);
+			fireBallisticBullet(start, dir, spread, cvar("g_ballistics_force_shotgun_speed"), 5, damage, 0, force, dtype, 0, 1, cvar("g_ballistics_force_shotgun_bulletconstant"));
 		else
-			fireBallisticBullet(start, dir, spread, cvar("g_ballistics_force_uzi_speed"), 5, damage, 0, force, dtype, 0, 1);
+			fireBallisticBullet(start, dir, spread, cvar("g_ballistics_force_uzi_speed"), 5, damage, 0, force, dtype, 0, 1, cvar("g_ballistics_force_shotgun_bulletconstant"));
 		return;
 	}
 

Modified: trunk/data/weapons.cfg
===================================================================
--- trunk/data/weapons.cfg	2008-12-24 13:16:14 UTC (rev 5293)
+++ trunk/data/weapons.cfg	2008-12-24 13:57:07 UTC (rev 5294)
@@ -3,7 +3,7 @@
 //
 // And... don't forget to edit weaponsPro.cfg too.
 
-set cvar_check_weapons 5a724edde37f7db7608cf03f262a1f34
+set cvar_check_weapons 7abbcf55140e618bfaa97b587fc7aef7
 
 set g_start_weapon_laser 1
 set g_start_weapon_shotgun 1
@@ -350,11 +350,12 @@
 set g_balance_campingrifle_primary_headshotaddeddamage 160
 set g_balance_campingrifle_primary_spread 0
 set g_balance_campingrifle_primary_force 2
-set g_balance_campingrifle_primary_speed 40000
+set g_balance_campingrifle_primary_speed 30000
 set g_balance_campingrifle_primary_lifetime 5
 set g_balance_campingrifle_primary_refire 0.7
 set g_balance_campingrifle_primary_animtime 0.3
 set g_balance_campingrifle_primary_ammo 10
+set g_balance_campingrifle_primary_bulletconstant 130 // 97.5 qu
 set g_balance_campingrifle_secondary_damage 60
 set g_balance_campingrifle_secondary_headshotaddeddamage 0
 set g_balance_campingrifle_secondary_spread 0.02
@@ -365,3 +366,4 @@
 set g_balance_campingrifle_secondary_animtime 0.06
 set g_balance_campingrifle_secondary_ammo 10
 set g_balance_campingrifle_secondary_health 5
+set g_balance_campingrifle_secondary_bulletconstant 130 // 6.9 qu

Modified: trunk/data/weaponsPro.cfg
===================================================================
--- trunk/data/weaponsPro.cfg	2008-12-24 13:16:14 UTC (rev 5293)
+++ trunk/data/weaponsPro.cfg	2008-12-24 13:57:07 UTC (rev 5294)
@@ -1,4 +1,4 @@
-set cvar_check_weapons 5a724edde37f7db7608cf03f262a1f34
+set cvar_check_weapons 7abbcf55140e618bfaa97b587fc7aef7
 
 set g_start_weapon_laser 1
 set g_start_weapon_shotgun 1
@@ -345,11 +345,12 @@
 set g_balance_campingrifle_primary_headshotaddeddamage 160
 set g_balance_campingrifle_primary_spread 0
 set g_balance_campingrifle_primary_force 2
-set g_balance_campingrifle_primary_speed 40000
+set g_balance_campingrifle_primary_speed 30000
 set g_balance_campingrifle_primary_lifetime 5
 set g_balance_campingrifle_primary_refire 0.7
 set g_balance_campingrifle_primary_animtime 0.3
 set g_balance_campingrifle_primary_ammo 10
+set g_balance_campingrifle_primary_bulletconstant 130 // 97.5 qu
 set g_balance_campingrifle_secondary_damage 60
 set g_balance_campingrifle_secondary_headshotaddeddamage 0
 set g_balance_campingrifle_secondary_spread 0.02
@@ -360,3 +361,4 @@
 set g_balance_campingrifle_secondary_animtime 0.06
 set g_balance_campingrifle_secondary_ammo 10
 set g_balance_campingrifle_secondary_health 5
+set g_balance_campingrifle_secondary_bulletconstant 130 // 6.9 qu




More information about the nexuiz-commits mailing list