]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/weapons/tracing.qc
Merge branch 'master' into Mario/wepent_experimental
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / weapons / tracing.qc
index 85551aa2b36dd1168ab19c5fe93ff238284b418f..1417717e834e33270ed355d891a450bb73767938 100644 (file)
 #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>
 // make sure you call makevectors first (FIXME?)
 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;
        oldsolid = ent.dphitcontentsmask;
-       if (IS_PLAYER(ent) && PS(ent).m_weapon == WEP_RIFLE)
+       if (IS_PLAYER(ent) && ent.(weaponentity).m_weapon == WEP_RIFLE)
                ent.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_CORPSE;
        else
                ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
@@ -53,10 +54,10 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect
 
        // track max damage
        if (IS_PLAYER(ent) && accuracy_canbegooddamage(ent))
-               accuracy_add(ent, PS(ent).m_weapon.m_id, maxdamage, 0);
+               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)
@@ -196,7 +197,7 @@ void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float p
 //  Ballistics Tracing
 // ====================
 
-void FireRailgunBullet (entity this, vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype)
+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;
@@ -333,7 +334,7 @@ void FireRailgunBullet (entity this, vector start, vector end, float bdamage, fl
        }
 
        // calculate hits and fired shots for hitscan
-       accuracy_add(this, PS(this).m_weapon.m_id, 0, min(bdamage, totaldmg));
+       accuracy_add(this, this.(weaponentity).m_weapon.m_id, 0, min(bdamage, totaldmg));
 
        trace_endpos = endpoint;
        trace_ent = endent;
@@ -348,7 +349,7 @@ void fireBullet_trace_callback(vector start, vector hit, vector end)
        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)
+void fireBullet(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, int tracereffects)
 {
        vector  end;
 
@@ -399,7 +400,7 @@ void fireBullet(entity this, vector start, vector dir, float spread, float max_s
                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
@@ -441,11 +442,11 @@ void fireBullet(entity this, vector start, vector dir, float spread, float max_s
                                // do not exceed 100%
                                float added_damage = min(damage - total_damage, damage * solid_penetration_left);
                                total_damage += damage * solid_penetration_left;
-                               accuracy_add(this, PS(this).m_weapon.m_id, 0, added_damage);
+                               accuracy_add(this, this.(weaponentity).m_weapon.m_id, 0, added_damage);
                        }
                }
 
-               if (is_weapclip)
+               if (is_weapclip && !autocvar_g_ballistics_penetrate_clips)
                        break;
 
                // go through solid!
@@ -475,7 +476,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))