]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/w_common.qc
Merge remote branch 'origin/master' into fruitiex/balance
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / w_common.qc
index ec307528a0984f4bfdf64ab47d7c05c3532407d3..320ffb7507e6173714af897ba43ab4ed917316bb 100644 (file)
@@ -1,3 +1,4 @@
+
 void W_GiveWeapon (entity e, float wep, string name)
 {
        entity oldself;
@@ -269,7 +270,7 @@ float W_BallisticBullet_LeaveSolid(entity e, vector vel, float constant)
 
        self.W_BallisticBullet_LeaveSolid_origin = trace_endpos;
 
-       dst = vlen(trace_endpos - self.origin);
+       dst = max(cvar("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)
@@ -301,14 +302,40 @@ float W_BallisticBullet_LeaveSolid(entity e, vector vel, float constant)
 
 void W_BallisticBullet_Touch (void)
 {
+       float density;
+
        if(self.think == W_BallisticBullet_LeaveSolid_think) // skip this!
                return;
 
        PROJECTILE_TOUCH;
        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)
+       {
+               remove(self);
+               return;
+       }
+
+       density = other.ballistics_density;
+       if(density == 0)
+               density = 1;
+
        // go through solid!
-       if(!W_BallisticBullet_LeaveSolid(self, self.velocity, self.dmg_radius))
+       if(!W_BallisticBullet_LeaveSolid(self, self.velocity, self.dmg_radius * density))
        {
                remove(self);
                return;
@@ -332,8 +359,11 @@ void fireBallisticBullet_trace_callback(vector start, vector hit, vector end)
 
 void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, float lifetime, float damage, float headshotbonus, float force, float dtype, float tracereffects, float gravityfactor, float bulletconstant)
 {
-       float lag, dt, savetime;
+       float lag, dt, savetime, density;
        entity pl, oldself;
+       float antilagging;
+
+       antilagging = (cvar("g_antilag_bullets") && (pSpeed >= cvar("g_antilag_bullets")));
 
        entity proj;
        proj = spawn();
@@ -349,7 +379,7 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
                proj.movetype = MOVETYPE_FLY;
        proj.think = SUB_Remove;
        proj.nextthink = time + lifetime; // min(pLifetime, vlen(world.maxs - world.mins) / pSpeed);
-       W_SetupProjectileVelocityEx(proj, dir, v_up, pSpeed, 0, 0, spread);
+       W_SetupProjectileVelocityEx(proj, dir, v_up, pSpeed, 0, 0, spread, antilagging);
        proj.angles = vectoangles(proj.velocity);
        proj.dmg_radius = cvar("g_ballistics_materialconstant") / bulletconstant;
        // so: bulletconstant = bullet mass / area of bullet circle
@@ -364,8 +394,9 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
 
        proj.oldvelocity = proj.velocity;
 
-       if(cvar("g_antilag_bullets"))
-       if(pSpeed >= cvar("g_antilag_bullets"))
+       other = proj; MUTATOR_CALLHOOK(EditProjectile);
+
+       if(antilagging)
        {
                float eff;
 
@@ -438,8 +469,12 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
                                W_BallisticBullet_Hit();
                        }
 
+                       density = other.ballistics_density;
+                       if(density == 0)
+                               density = 1;
+
                        // go through solid!
-                       if(!W_BallisticBullet_LeaveSolid(self, self.velocity, self.dmg_radius))
+                       if(!W_BallisticBullet_LeaveSolid(self, self.velocity, self.dmg_radius * density))
                                break;
 
                        W_BallisticBullet_LeaveSolid_think();
@@ -500,6 +535,7 @@ void W_PrepareExplosionByDamage(entity attacker, void() explode)
        self.takedamage = DAMAGE_NO;
        self.event_damage = SUB_Null;
        self.owner = attacker;
+       self.realowner = attacker;
 
        // do not explode NOW but in the NEXT FRAME!
        // because recursive calls to RadiusDamage are not allowed