oldself = self;
self = e;
- if not(g_minstagib)
if (other.classname == "player")
{
sprint (other, "You got the ^2");
self.think = self.W_BallisticBullet_LeaveSolid_think_save;
self.nextthink = max(time, self.W_BallisticBullet_LeaveSolid_nextthink_save);
- self.W_BallisticBullet_LeaveSolid_think_save = SUB_Null;
+ self.W_BallisticBullet_LeaveSolid_think_save = func_null;
self.flags &~= FL_ONGROUND;
{
// 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
void W_BallisticBullet_Touch (void)
{
- float density;
+ //float density;
if(self.think == W_BallisticBullet_LeaveSolid_think) // skip this!
return;
PROJECTILE_TOUCH;
W_BallisticBullet_Hit ();
+ if(self.dmg_radius < 0) // these NEVER penetrate solid
+ {
+ remove(self);
+ return;
+ }
+
// if we hit "weapclip", bail out
//
// rationale of this check:
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, density;
+ float lag, dt, savetime; //, density;
entity pl, oldself;
float antilagging;
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 > 0)
+ proj.dmg_radius = autocvar_g_ballistics_materialconstant / bulletconstant;
+ else if(bulletconstant == 0)
+ proj.dmg_radius = 0;
+ else
+ proj.dmg_radius = -1;
// so: bulletconstant = bullet mass / area of bullet circle
setorigin(proj, start);
proj.flags = FL_PROJECTILE;
W_BallisticBullet_Hit();
}
+ if(proj.dmg_radius < 0) // these NEVER penetrate solid
+ break;
+
// if we hit "weapclip", bail out
//
// rationale of this check:
void W_PrepareExplosionByDamage(entity attacker, void() explode)
{
self.takedamage = DAMAGE_NO;
- self.event_damage = SUB_Null;
+ self.event_damage = func_null;
if((attacker.flags & FL_CLIENT) && !autocvar_g_projectiles_keep_owner)
{