]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/w_common.qc
Release loaded rockets when the player dies
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / w_common.qc
index 600f260f434c212c4b99e0bd830cf5653b68703b..2d9ecfd8b31085d0fb0ea2eb2d4294d56d3826a0 100644 (file)
@@ -23,6 +23,7 @@ void W_GiveWeapon (entity e, float wep, string name)
 }
 
 .float railgundistance;
+.vector railgunforce;
 void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, float deathtype)
 {
        local vector hitloc, force, endpoint, dir;
@@ -67,6 +68,7 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
                trace_ent.railgunhitloc = end;
                trace_ent.railgunhitsolidbackup = trace_ent.solid;
                trace_ent.railgundistance = vlen(WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos) - start);
+               trace_ent.railgunforce = WarpZone_TransformVelocity(WarpZone_trace_transform, force);
 
                // stop if this is a wall
                if (trace_ent.solid == SOLID_BSP)
@@ -130,7 +132,7 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
 
                // apply the damage
                if (ent.takedamage)
-                       Damage (ent, self, self, bdamage * f, deathtype, hitloc, force * ffs);
+                       Damage (ent, self, self, bdamage * f, deathtype, hitloc, ent.railgunforce * ffs);
 
                // create a small explosion to throw gibs around (if applicable)
                //setorigin (explosion, hitloc);
@@ -180,16 +182,15 @@ void W_BallisticBullet_Hit (void)
                Damage(other, self, self.owner, self.dmg * f, self.projectiledeathtype, self.origin, self.dmg_force * normalize(self.velocity) * f);
                damage_headshotbonus = 0;
 
-               if(self.dmg_edge != 0)
+               if(headshot)
+                       f *= q;
+               if(DEATH_WEAPONOF(self.projectiledeathtype) == WEP_SNIPERRIFLE)
                {
                        if(headshot)
-                       {       
-                               f *= q;
                                AnnounceTo(self.owner, "headshot");
-                       }
+                       if(yoda)
+                               AnnounceTo(self.owner, "awesome");
                }
-               if(yoda)
-                       AnnounceTo(self.owner, "awesome");
 
                // calculate hits for ballistic weapons
                if(g)
@@ -250,7 +251,7 @@ float W_BallisticBullet_LeaveSolid(entity e, vector vel, float constant)
        // maxdist = 0.5 * v0 * v0 / constant
        // dprint("max dist = ", ftos(maxdist), "\n");
 
-       if(maxdist <= cvar("g_ballistics_mindistance"))
+       if(maxdist <= autocvar_g_ballistics_mindistance)
                return 0;
 
        traceline_inverted (self.origin, self.origin + normalize(vel) * maxdist, MOVE_NORMAL, self);
@@ -260,7 +261,7 @@ float W_BallisticBullet_LeaveSolid(entity e, vector vel, float constant)
 
        self.W_BallisticBullet_LeaveSolid_origin = trace_endpos;
 
-       dst = max(cvar("g_ballistics_mindistance"), vlen(trace_endpos - self.origin));
+       dst = max(autocvar_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)
@@ -353,7 +354,7 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
        entity pl, oldself;
        float antilagging;
 
-       antilagging = (cvar("g_antilag_bullets") && (pSpeed >= cvar("g_antilag_bullets")));
+       antilagging = (autocvar_g_antilag_bullets && (pSpeed >= autocvar_g_antilag_bullets));
 
        entity proj;
        proj = spawn();
@@ -371,7 +372,7 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
        proj.nextthink = time + lifetime; // min(pLifetime, vlen(world.maxs - world.mins) / pSpeed);
        W_SetupProjectileVelocityEx(proj, dir, v_up, pSpeed, 0, 0, spread, antilagging);
        proj.angles = vectoangles(proj.velocity);
-       proj.dmg_radius = cvar("g_ballistics_materialconstant") / bulletconstant;
+       proj.dmg_radius = autocvar_g_ballistics_materialconstant / bulletconstant;
        // so: bulletconstant = bullet mass / area of bullet circle
        setorigin(proj, start);
        proj.flags = FL_PROJECTILE;
@@ -392,6 +393,8 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
 
                if(tracereffects & EF_RED)
                        eff = particleeffectnum("tr_rifle");
+               else if(tracereffects & EF_BLUE)
+                       eff = particleeffectnum("tr_rifle_weak");
                else
                        eff = particleeffectnum("tr_bullet");
 
@@ -401,7 +404,7 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
                        lag = 0;
                if(clienttype(self) != CLIENTTYPE_REAL)
                        lag = 0;
-               if(cvar("g_antilag") == 0 || self.cvar_cl_noantilag)
+               if(autocvar_g_antilag == 0 || self.cvar_cl_noantilag)
                        lag = 0; // only do hitscan, but no antilag
 
                if(lag)
@@ -452,6 +455,23 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
                                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)
+                               break;
+
                        density = other.ballistics_density;
                        if(density == 0)
                                density = 1;