]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/weapons/tracing.qc
Make map weapons glow the color of their waypoint instead of white
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / weapons / tracing.qc
index 1f7f5946757dac215ca0621bb682cb0f97aeca51..b37e1578e2878ed0011c4fe22d59cf42eee168ad 100644 (file)
@@ -10,6 +10,7 @@
 #include "../antilag.qh"
 
 #include <common/constants.qh>
+#include <common/net_linked.qh>
 #include <common/util.qh>
 
 #include <common/weapons/_all.qh>
@@ -56,7 +57,7 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect
                accuracy_add(ent, ent.(weaponentity).m_weapon.m_id, maxdamage, 0);
 
        if(IS_PLAYER(ent))
-               W_HitPlotAnalysis(ent, v_forward, v_right, v_up);
+               W_HitPlotAnalysis(ent, weaponentity, v_forward, v_right, v_up);
 
        vector md = ent.(weaponentity).movedir;
        if(md.x > 0)
@@ -198,33 +199,21 @@ void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float p
 
 void FireRailgunBullet (entity this, .entity weaponentity, 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;
-       float totaldmg;
-       entity o;
+       entity pseudoprojectile = NULL;
 
-       float length;
-       vector beampos;
-       string snd;
-       entity pseudoprojectile;
-       float f, ffs;
-
-       pseudoprojectile = NULL;
-
-       dir = normalize(end - start);
-       length = vlen(end - start);
-       force = dir * bforce;
+       vector dir = normalize(end - start);
+       float length = vlen(end - start);
+       vector force = dir * bforce;
 
        // go a little bit into the wall because we need to hit this wall later
        end = end + dir;
 
-       totaldmg = 0;
+       float totaldmg = 0;
 
        // 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 = this;
+       entity o = this;
        while (1)
        {
                if(CS(this).antilag_debug)
@@ -259,18 +248,15 @@ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector
                trace_ent.solid = SOLID_NOT;
        }
 
-       endpoint = trace_endpos;
-       endent = trace_ent;
-       endq3surfaceflags = trace_dphitq3surfaceflags;
+       vector endpoint = trace_endpos;
+       entity endent = trace_ent;
+       float endq3surfaceflags = trace_dphitq3surfaceflags;
 
        // find all the entities the railgun hit and restore their solid state
-       ent = findfloat(NULL, railgunhit, true);
-       while (ent)
+       FOREACH_ENTITY_FLOAT(railgunhit, true,
        {
-               // restore their solid type
-               ent.solid = ent.railgunhitsolidbackup;
-               ent = findfloat(ent, railgunhit, true);
-       }
+               it.solid = it.railgunhitsolidbackup;
+       });
 
        // spawn a temporary explosion entity for RadiusDamage calls
        //explosion = spawn();
@@ -284,17 +270,15 @@ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector
                        {
                                msg_entity = it;
                                // nearest point on the beam
-                               beampos = start + dir * bound(0, (msg_entity.origin - start) * dir, length);
+                               vector beampos = start + dir * bound(0, (msg_entity.origin - start) * dir, length);
 
-                               f = bound(0, 1 - vlen(beampos - msg_entity.origin) / 512, 1);
+                               float f = bound(0, 1 - vlen(beampos - msg_entity.origin) / 512, 1);
                                if(f <= 0)
                                        continue;
 
-                               snd = SND(NEXWHOOSH_RANDOM());
-
                                if(!pseudoprojectile)
                                        pseudoprojectile = spawn(); // we need this so the sound uses the "entchannel4" volume
-                               soundtoat(MSG_ONE, pseudoprojectile, beampos, CH_SHOTS, snd, VOL_BASE * f, ATTEN_NONE);
+                               soundtoat(MSG_ONE, pseudoprojectile, beampos, CH_SHOTS, SND(NEXWHOOSH_RANDOM()), VOL_BASE * f, ATTEN_NONE);
                        }
                ));
 
@@ -303,34 +287,30 @@ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector
        }
 
        // find all the entities the railgun hit and hurt them
-       ent = findfloat(NULL, railgunhit, true);
-       while (ent)
+       FOREACH_ENTITY_FLOAT(railgunhit, true,
        {
                // get the details we need to call the damage function
-               hitloc = ent.railgunhitloc;
+               vector hitloc = it.railgunhitloc;
 
-               f = ExponentialFalloff(mindist, maxdist, halflifedist, ent.railgundistance);
-               ffs = ExponentialFalloff(mindist, maxdist, forcehalflifedist, ent.railgundistance);
+               float foff = ExponentialFalloff(mindist, maxdist, halflifedist, it.railgundistance);
+               float ffs = ExponentialFalloff(mindist, maxdist, forcehalflifedist, it.railgundistance);
 
-               if(accuracy_isgooddamage(this, ent))
-                       totaldmg += bdamage * f;
+               if(accuracy_isgooddamage(this, it))
+                       totaldmg += bdamage * foff;
 
                // apply the damage
-               if (ent.takedamage)
-                       Damage (ent, this, this, bdamage * f, deathtype, hitloc, ent.railgunforce * ffs);
+               if (it.takedamage)
+                       Damage (it, this, this, bdamage * foff, deathtype, hitloc, it.railgunforce * ffs);
 
                // create a small explosion to throw gibs around (if applicable)
                //setorigin(explosion, hitloc);
                //RadiusDamage (explosion, this, 10, 0, 50, NULL, NULL, 300, deathtype);
 
-               ent.railgunhitloc = '0 0 0';
-               ent.railgunhitsolidbackup = SOLID_NOT;
-               ent.railgunhit = false;
-               ent.railgundistance = 0;
-
-               // advance to the next entity
-               ent = findfloat(ent, railgunhit, true);
-       }
+               it.railgunhitloc = '0 0 0';
+               it.railgunhitsolidbackup = SOLID_NOT;
+               it.railgunhit = false;
+               it.railgundistance = 0;
+       });
 
        // calculate hits and fired shots for hitscan
        accuracy_add(this, this.(weaponentity).m_weapon.m_id, 0, min(bdamage, totaldmg));
@@ -353,7 +333,7 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo
        vector  end;
 
        dir = normalize(dir + randomvec() * spread);
-       end = start + dir * MAX_SHOT_DISTANCE;
+       end = start + dir * max_shot_distance;
 
        fireBullet_last_hit = NULL;
        float solid_penetration_left = 1;
@@ -398,6 +378,10 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo
                start = trace_endpos;
                entity hit = trace_ent;
 
+               // traced up to max_shot_distance and didn't hit anything at all
+               if (trace_fraction == 1.0)
+                       break;
+
                // When hitting sky, stop.
                if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
                        break;
@@ -431,7 +415,7 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo
                {
                        fireBullet_last_hit = hit;
                        yoda = 0;
-                       MUTATOR_CALLHOOK(FireBullet_Hit, this, hit, start, end, damage);
+                       MUTATOR_CALLHOOK(FireBullet_Hit, this, hit, start, end, damage, this.(weaponentity));
                        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);