#include "../antilag.qh"
#include <common/constants.qh>
+#include <common/net_linked.qh>
#include <common/util.qh>
-#include <common/weapons/all.qh>
+#include <common/weapons/_all.qh>
#include <common/state.qh>
#include <lib/warpzone/common.qh>
// this function calculates w_shotorg and w_shotdir based on the weapon model
// offset, trueaim and antilag, and won't put w_shotorg inside a wall.
// make sure you call makevectors first (FIXME?)
-void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector mi, vector ma, float antilag, float recoil, Sound snd, float chan, float maxdamage, float range)
+void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vector s_forward, vector mi, vector ma, float antilag, float recoil, Sound snd, float chan, float maxdamage, float range)
{
- TC(Sound, snd);
+ TC(Sound, snd);
float nudge = 1; // added to traceline target and subtracted from result TOOD(divVerent): do we still need this? Doesn't the engine do this now for us?
float oldsolid;
vector vecs, dv;
else
ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
if(antilag)
- WarpZone_traceline_antilag(world, ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * range, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
- // passing world, because we do NOT want it to touch dphitcontentsmask
+ WarpZone_traceline_antilag(NULL, ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * range, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
+ // passing NULL, because we do NOT want it to touch dphitcontentsmask
else
WarpZone_TraceLine(ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * range, MOVE_NOMONSTERS, ent);
ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
if(IS_PLAYER(ent))
W_HitPlotAnalysis(ent, v_forward, v_right, v_up);
- .entity weaponentity = weaponentities[0]; // TODO: unhardcode
vector md = ent.(weaponentity).movedir;
if(md.x > 0)
vecs = md;
//if(w_shotdir != prevdir) { printf("SERVER: shotDIR differs: %s - %s\n", vtos(w_shotdir), vtos(prevdir)); }
}
-vector W_CalculateProjectileVelocity(vector pvelocity, vector mvelocity, float forceAbsolute)
+vector W_CalculateProjectileVelocity(entity actor, vector pvelocity, vector mvelocity, float forceAbsolute)
{
vector mdirection;
float mspeed;
vector outvelocity;
- mvelocity = mvelocity * W_WeaponSpeedFactor();
+ mvelocity = mvelocity * W_WeaponSpeedFactor(actor);
mdirection = normalize(mvelocity);
mspeed = vlen(mvelocity);
void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float pSpeed, float pUpSpeed, float pZSpeed, float spread, float forceAbsolute)
{
- if(proj.owner == world)
+ if(proj.owner == NULL)
error("Unowned missile");
dir = dir + upDir * (pUpSpeed / pSpeed);
LOG_INFO("avg: ", ftos(mspercallcount / mspercallsum), " per sec\n");
#endif
- proj.velocity = W_CalculateProjectileVelocity(proj.owner.velocity, pSpeed * dir, forceAbsolute);
+ proj.velocity = W_CalculateProjectileVelocity(proj.owner, proj.owner.velocity, pSpeed * dir, forceAbsolute);
}
entity pseudoprojectile;
float f, ffs;
- pseudoprojectile = world;
+ pseudoprojectile = NULL;
dir = normalize(end - start);
length = vlen(end - start);
WarpZone_traceline_antilag (this, start, end, false, o, ANTILAG_LATENCY(this));
if(o && WarpZone_trace_firstzone)
{
- o = world;
+ o = NULL;
continue;
}
if(trace_ent.solid == SOLID_BSP || trace_ent.solid == SOLID_SLIDEBOX)
Damage_DamageInfo(trace_endpos, bdamage, 0, 0, force, deathtype, trace_ent.species, this);
- // if it is world we can't hurt it so stop now
- if (trace_ent == world || trace_fraction == 1)
+ // if it is NULL we can't hurt it so stop now
+ if (trace_ent == NULL || trace_fraction == 1)
break;
// make the entity non-solid so we can hit the next one
endq3surfaceflags = trace_dphitq3surfaceflags;
// find all the entities the railgun hit and restore their solid state
- ent = findfloat(world, railgunhit, true);
+ ent = findfloat(NULL, railgunhit, true);
while (ent)
{
// restore their solid type
));
if(pseudoprojectile)
- remove(pseudoprojectile);
+ delete(pseudoprojectile);
}
// find all the entities the railgun hit and hurt them
- ent = findfloat(world, railgunhit, true);
+ ent = findfloat(NULL, railgunhit, true);
while (ent)
{
// get the details we need to call the damage function
Damage (ent, this, this, bdamage * f, deathtype, hitloc, ent.railgunforce * ffs);
// create a small explosion to throw gibs around (if applicable)
- //setorigin (explosion, hitloc);
- //RadiusDamage (explosion, this, 10, 0, 50, world, world, 300, deathtype);
+ //setorigin(explosion, hitloc);
+ //RadiusDamage (explosion, this, 10, 0, 50, NULL, NULL, 300, deathtype);
ent.railgunhitloc = '0 0 0';
ent.railgunhitsolidbackup = SOLID_NOT;
void fireBullet_trace_callback(vector start, vector hit, vector end)
{
if(vdist(hit - start, >, 16))
- trailparticles(world, fireBullet_trace_callback_eff, start, hit);
- WarpZone_trace_forent = world;
- fireBullet_last_hit = world;
+ trailparticles(NULL, fireBullet_trace_callback_eff, start, hit);
+ WarpZone_trace_forent = NULL;
+ fireBullet_last_hit = NULL;
}
void fireBullet(entity this, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, int tracereffects)
dir = normalize(dir + randomvec() * spread);
end = start + dir * MAX_SHOT_DISTANCE;
- fireBullet_last_hit = world;
+ fireBullet_last_hit = NULL;
float solid_penetration_left = 1;
float total_damage = 0;
if(lag)
{
FOREACH_CLIENT(IS_PLAYER(it) && it != this, antilag_takeback(it, CS(it), time - lag));
- FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, {
- if (it != this)
- antilag_takeback(it, it, time - lag);
+ IL_EACH(g_monsters, it != this,
+ {
+ antilag_takeback(it, it, time - lag);
});
}
for (;;)
{
// TODO also show effect while tracing
- WarpZone_TraceBox_ThroughZone(start, '0 0 0', '0 0 0', end, false, WarpZone_trace_forent, world, fireBullet_trace_callback);
+ WarpZone_TraceBox_ThroughZone(start, '0 0 0', '0 0 0', end, false, WarpZone_trace_forent, NULL, fireBullet_trace_callback);
dir = WarpZone_TransformVelocity(WarpZone_trace_transform, dir);
end = WarpZone_TransformOrigin(WarpZone_trace_transform, end);
start = trace_endpos;
entity hit = trace_ent;
// When hitting sky, stop.
- if (pointcontents(start) == CONTENT_SKY)
+ if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
break;
// can't use noimpact, as we need to pass through walls
fireBullet_last_hit = hit;
yoda = 0;
MUTATOR_CALLHOOK(FireBullet_Hit, this, hit, start, end, damage);
- damage = frag_damage;
+ damage = M_ARGV(4, float);
float g = accuracy_isgooddamage(this, hit);
Damage(hit, this, this, damage * solid_penetration_left, dtype, start, force * dir * solid_penetration_left);
// calculate hits for ballistic weapons
}
}
- if (is_weapclip)
+ if (is_weapclip && !autocvar_g_ballistics_penetrate_clips)
break;
// go through solid!
break;
float dist_taken = max(autocvar_g_ballistics_mindistance, vlen(trace_endpos - start));
- solid_penetration_left *= (dist_taken / maxdist);
+ // fraction_used_of_what_is_left = dist_taken / maxdist
+ // solid_penetration_left = solid_penetration_left - solid_penetration_left * fraction_used_of_what_is_left
+ solid_penetration_left *= 1 - dist_taken / maxdist;
+ solid_penetration_left = max(solid_penetration_left, 0);
// Only show effect when going through a player (invisible otherwise)
if (hit && (hit.solid != SOLID_BSP))
if(lag)
{
FOREACH_CLIENT(IS_PLAYER(it) && it != this, antilag_restore(it, CS(it)));
- FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, {
- if (it != this)
- antilag_restore(it, it);
+ IL_EACH(g_monsters, it != this,
+ {
+ antilag_restore(it, it);
});
}