]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/weapons/tracing.qc
Merge branch 'master' into TimePath/modules
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / weapons / tracing.qc
index 311edd0883586944d3bd5b28e6e61c2afe5d7d8a..176b69e6b6c9e5f720f2dfc09fb9af13367c1ff8 100644 (file)
@@ -12,7 +12,7 @@
 #include <common/constants.qh>
 #include <common/util.qh>
 
-#include <common/weapons/all.qh>
+#include <common/weapons/_all.qh>
 #include <common/state.qh>
 
 #include <lib/warpzone/common.qh>
@@ -20,9 +20,9 @@
 // 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;
@@ -32,8 +32,8 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector m
        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;
@@ -58,7 +58,6 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector m
        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;
@@ -146,13 +145,13 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector m
        //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);
@@ -164,7 +163,7 @@ vector W_CalculateProjectileVelocity(vector pvelocity, vector mvelocity, float f
 
 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);
@@ -189,7 +188,7 @@ void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float p
        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);
 }
 
 
@@ -197,8 +196,8 @@ void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float p
 //  Ballistics Tracing
 // ====================
 
-void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype)
-{SELFPARAM();
+void FireRailgunBullet (entity this, vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype)
+{
        vector hitloc, force, endpoint, dir;
        entity ent, endent;
        float endq3surfaceflags;
@@ -211,7 +210,7 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
        entity pseudoprojectile;
        float f, ffs;
 
-       pseudoprojectile = world;
+       pseudoprojectile = NULL;
 
        dir = normalize(end - start);
        length = vlen(end - start);
@@ -225,24 +224,24 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
        // trace multiple times until we hit a wall, each obstacle will be made
        // non-solid so we can hit the next, while doing this we spawn effects and
        // note down which entities were hit so we can damage them later
-       o = self;
+       o = this;
        while (1)
        {
-               if(CS(self).antilag_debug)
-                       WarpZone_traceline_antilag (self, start, end, false, o, CS(self).antilag_debug);
+               if(CS(this).antilag_debug)
+                       WarpZone_traceline_antilag (this, start, end, false, o, CS(this).antilag_debug);
                else
-                       WarpZone_traceline_antilag (self, start, end, false, o, ANTILAG_LATENCY(self));
+                       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, self);
+                       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
@@ -265,7 +264,7 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
        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
@@ -279,9 +278,9 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
        // Find all non-hit players the beam passed close by
        if(deathtype == WEP_VAPORIZER.m_id || deathtype == WEP_VORTEX.m_id)
        {
-               FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != self, LAMBDA(
+               FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != this, LAMBDA(
                        if(!it.railgunhit)
-                       if(!(IS_SPEC(it) && it.enemy == self))
+                       if(!(IS_SPEC(it) && it.enemy == this))
                        {
                                msg_entity = it;
                                // nearest point on the beam
@@ -300,11 +299,11 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
                ));
 
                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
@@ -313,16 +312,16 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
                f = ExponentialFalloff(mindist, maxdist, halflifedist, ent.railgundistance);
                ffs = ExponentialFalloff(mindist, maxdist, forcehalflifedist, ent.railgundistance);
 
-               if(accuracy_isgooddamage(self, ent))
+               if(accuracy_isgooddamage(this, ent))
                        totaldmg += bdamage * f;
 
                // apply the damage
                if (ent.takedamage)
-                       Damage (ent, self, self, bdamage * f, deathtype, hitloc, ent.railgunforce * ffs);
+                       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, self, 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;
@@ -334,7 +333,7 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
        }
 
        // calculate hits and fired shots for hitscan
-       accuracy_add(self, PS(self).m_weapon.m_id, 0, min(bdamage, totaldmg));
+       accuracy_add(this, PS(this).m_weapon.m_id, 0, min(bdamage, totaldmg));
 
        trace_endpos = endpoint;
        trace_ent = endent;
@@ -344,9 +343,9 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
 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)
@@ -356,7 +355,7 @@ void fireBullet(entity this, vector start, vector dir, float spread, float max_s
        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;
 
@@ -377,9 +376,9 @@ void fireBullet(entity this, vector start, vector dir, float spread, float max_s
        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);
                });
        }
 
@@ -393,7 +392,7 @@ void fireBullet(entity this, vector start, vector dir, float spread, float max_s
        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;
@@ -433,7 +432,7 @@ void fireBullet(entity this, vector start, vector dir, float spread, float max_s
                        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
@@ -476,7 +475,10 @@ void fireBullet(entity this, vector start, vector dir, float spread, float max_s
                        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))
@@ -492,9 +494,9 @@ void fireBullet(entity this, vector start, vector dir, float spread, float max_s
        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);
                });
        }