}
.float railgundistance;
+.vector railgunforce;
void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, float deathtype)
{
local vector hitloc, force, endpoint, dir;
trace_ent.railgunhitloc = end;
trace_ent.railgunhitsolidbackup = trace_ent.solid;
trace_ent.railgundistance = vlen(WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos) - start);
+ trace_ent.railgunforce = WarpZone_TransformVelocity(WarpZone_trace_transform, force);
// stop if this is a wall
if (trace_ent.solid == SOLID_BSP)
// apply the damage
if (ent.takedamage)
- Damage (ent, self, self, bdamage * f, deathtype, hitloc, force * ffs);
+ Damage (ent, self, self, bdamage * f, deathtype, hitloc, ent.railgunforce * ffs);
// create a small explosion to throw gibs around (if applicable)
//setorigin (explosion, hitloc);
.float dmg_total;
void W_BallisticBullet_Hit (void)
{
- float f, q;
+ float f, q, g;
f = pow(bound(0, vlen(self.velocity) / vlen(self.oldvelocity), 1), 2); // energy multiplier
q = 1 + self.dmg_edge / self.dmg;
headshot = 0;
yoda = 0;
- damage_headshotbonus = self.dmg_edge;
+ damage_headshotbonus = self.dmg_edge * f;
railgun_start = self.origin - 2 * frametime * self.velocity;
railgun_end = self.origin + 2 * frametime * self.velocity;
-
+ g = accuracy_isgooddamage(self.owner, other);
Damage(other, self, self.owner, self.dmg * f, self.projectiledeathtype, self.origin, self.dmg_force * normalize(self.velocity) * f);
damage_headshotbonus = 0;
- if(self.dmg_edge != 0)
+ if(headshot)
+ f *= q;
+ if(DEATH_WEAPONOF(self.projectiledeathtype) == WEP_SNIPERRIFLE)
{
if(headshot)
- {
- f *= q;
AnnounceTo(self.owner, "headshot");
- }
+ if(yoda)
+ AnnounceTo(self.owner, "awesome");
}
- if(yoda)
- AnnounceTo(self.owner, "awesome");
// calculate hits for ballistic weapons
- if(accuracy_isgooddamage(self.owner, other))
+ if(g)
{
// do not exceed 100%
q = min(self.dmg * q, self.dmg_total + f * self.dmg) - self.dmg_total;
// maxdist = 0.5 * v0 * v0 / constant
// dprint("max dist = ", ftos(maxdist), "\n");
- if(maxdist <= cvar("g_ballistics_mindistance"))
+ if(maxdist <= autocvar_g_ballistics_mindistance)
return 0;
traceline_inverted (self.origin, self.origin + normalize(vel) * maxdist, MOVE_NORMAL, self);
self.W_BallisticBullet_LeaveSolid_origin = trace_endpos;
- dst = max(cvar("g_ballistics_mindistance"), vlen(trace_endpos - self.origin));
+ dst = max(autocvar_g_ballistics_mindistance, vlen(trace_endpos - self.origin));
// E(s) = E0 - constant * s, constant = area of bullet circle * material constant / mass
Es_m = E0_m - constant * dst;
if(Es_m <= 0)
entity pl, oldself;
float antilagging;
- antilagging = (cvar("g_antilag_bullets") && (pSpeed >= cvar("g_antilag_bullets")));
+ antilagging = (autocvar_g_antilag_bullets && (pSpeed >= autocvar_g_antilag_bullets));
entity proj;
proj = spawn();
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 = cvar("g_ballistics_materialconstant") / bulletconstant;
+ proj.dmg_radius = autocvar_g_ballistics_materialconstant / bulletconstant;
// so: bulletconstant = bullet mass / area of bullet circle
setorigin(proj, start);
proj.flags = FL_PROJECTILE;
if(tracereffects & EF_RED)
eff = particleeffectnum("tr_rifle");
+ else if(tracereffects & EF_BLUE)
+ eff = particleeffectnum("tr_rifle_weak");
else
eff = particleeffectnum("tr_bullet");
lag = 0;
if(clienttype(self) != CLIENTTYPE_REAL)
lag = 0;
- if(cvar("g_antilag") == 0 || self.cvar_cl_noantilag)
+ if(autocvar_g_antilag == 0 || self.cvar_cl_noantilag)
lag = 0; // only do hitscan, but no antilag
if(lag)
W_BallisticBullet_Hit();
}
+ // if we hit "weapclip", bail out
+ //
+ // rationale of this check:
+ //
+ // any shader that is solid, nodraw AND trans is meant to clip weapon
+ // shots and players, but has no other effect!
+ //
+ // if it is not trans, it is caulk and should not have this side effect
+ //
+ // matching shaders:
+ // common/weapclip (intended)
+ // common/noimpact (is supposed to eat projectiles, but is erased farther above)
+ if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NODRAW)
+ if not(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NONSOLID)
+ if not(trace_dphitcontents & DPCONTENTS_OPAQUE)
+ break;
+
density = other.ballistics_density;
if(density == 0)
density = 1;