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