]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/cl_weaponsystem.qc
Merge branch 'master' into Mario/mutator_minstagib
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / cl_weaponsystem.qc
index 3b69e13eb0942f30b1e394a3a7b0813ae6e3cce7..07b9149cea10424892854674ede3c70ef6a1c003 100644 (file)
@@ -69,6 +69,7 @@ vector W_HitPlotNormalizedUntransform(vector org, entity targ, vector screenforw
 
        // x = 0..1 relative to hitbox; y = 0..1 relative to hitbox; z = distance
 
+       mi = ma = targ.origin + 0.5 * (targ.mins + targ.maxs);
        for(i = 0; i < 2; ++i) for(j = 0; j < 2; ++j) for(k = 0; k < 2; ++k)
        {
                thisv = targ.origin;
@@ -131,8 +132,10 @@ vector w_shotend;
 .float prevstrengthsoundattempt;
 void W_PlayStrengthSound(entity player) // void W_PlayStrengthSound
 {
-               if((!g_minstagib)
-                       && (player.items & IT_STRENGTH)
+       if(MUTATOR_CALLHOOK(PlayStrengthSound))
+               return;
+               
+               if((player.items & IT_STRENGTH)
                        && ((time > player.prevstrengthsound + autocvar_sv_strengthsound_antispam_time) // prevent insane sound spam
                        || (time > player.prevstrengthsoundattempt + autocvar_sv_strengthsound_antispam_refire_threshold)))
                {
@@ -557,7 +560,6 @@ void CL_Weaponentity_Think()
 
        self.angles = '0 0 0';
        float f;
-       f = 0;
        if (self.state == WS_RAISE && !intermission_running)
        {
                f = (self.owner.weapon_nextthink - time) * g_weaponratefactor / autocvar_g_balance_weaponswitchdelay;
@@ -727,7 +729,7 @@ void Send_WeaponComplain (entity e, float wpn, string wpnname, float type)
 
 float client_hasweapon(entity cl, float wpn, float andammo, float complain)
 {
-       float weaponbit, f;
+       float f;
        entity oldself;
 
        if(time < self.hasweapon_complain_spam)
@@ -741,8 +743,7 @@ float client_hasweapon(entity cl, float wpn, float andammo, float complain)
                        sprint(self, "Invalid weapon\n");
                return FALSE;
        }
-       weaponbit = W_WeaponBit(wpn);
-       if (cl.weapons & weaponbit)
+       if (WEPSET_CONTAINS_EW(cl, wpn))
        {
                if (andammo)
                {
@@ -783,7 +784,7 @@ float client_hasweapon(entity cl, float wpn, float andammo, float complain)
        {
                // DRESK - 3/16/07
                // Report Proper Weapon Status / Modified Weapon Ownership Message
-               if(weaponsInMap & weaponbit)
+               if (WEPSET_CONTAINS_AW(weaponsInMap, wpn))
                {
                        sprint(cl, strcat("You do not have the ^2", W_Name(wpn), "\n") );
                        Send_WeaponComplain (cl, wpn, W_Name(wpn), 1);
@@ -796,7 +797,7 @@ float client_hasweapon(entity cl, float wpn, float andammo, float complain)
                                e = get_weaponinfo(wpn);
                                s = e.model2;
 
-                               for(e = world; (e = findfloat(e, weapons, weaponbit)); )
+                               for(e = world; (e = findfloat(e, weapon, wpn)); )
                                {
                                        if(e.classname == "droppedweapon")
                                                continue;
@@ -853,7 +854,7 @@ void weapon_setup(float windex)
        entity e;
        e = get_weaponinfo(windex);
        self.items &~= IT_AMMO;
-       self.items = self.items | e.items;
+       self.items = self.items | (e.items & IT_AMMO);
 
        // the two weapon entities will notice this has changed and update their models
        self.weapon = windex;
@@ -867,10 +868,15 @@ void W_SwitchToOtherWeapon(entity pl)
 {
        // hack to ensure it switches to an OTHER weapon (in case the other fire mode still has ammo, we want that anyway)
        float w, ww;
-       w = W_WeaponBit(pl.weapon);
-       pl.weapons &~= w;
-       ww = w_getbestweapon(pl);
-       pl.weapons |= w;
+       w = pl.weapon;
+       if(WEPSET_CONTAINS_EW(pl, w))
+       {
+               WEPSET_ANDNOT_EW(pl, w);
+               ww = w_getbestweapon(pl);
+               WEPSET_OR_EW(pl, w);
+       }
+       else
+               ww = w_getbestweapon(pl);
        if(ww)
                W_SwitchWeapon_Force(pl, ww);
 }
@@ -1004,13 +1010,14 @@ void weapon_thinkf(float fr, float t, void() func)
        if (self.weaponentity)
        {
                self.weaponentity.wframe = fr;
+               a = '0 0 0';
                if (fr == WFRAME_IDLE)
                        a = self.weaponentity.anim_idle;
                else if (fr == WFRAME_FIRE1)
                        a = self.weaponentity.anim_fire1;
                else if (fr == WFRAME_FIRE2)
                        a = self.weaponentity.anim_fire2;
-               else if (fr == WFRAME_RELOAD)
+               else // if (fr == WFRAME_RELOAD)
                        a = self.weaponentity.anim_reload;
                a_z *= g_weaponratefactor;
                setanim(self.weaponentity, a, restartanim == FALSE, restartanim, restartanim);
@@ -1073,8 +1080,6 @@ vector W_CalculateProjectileVelocity(vector pvelocity, vector mvelocity, float f
 {
        vector mdirection;
        float mspeed;
-       float outspeed;
-       float nstyle;
        vector outvelocity;
 
        mvelocity = mvelocity * g_weaponspeedfactor;
@@ -1082,61 +1087,7 @@ vector W_CalculateProjectileVelocity(vector pvelocity, vector mvelocity, float f
        mdirection = normalize(mvelocity);
        mspeed = vlen(mvelocity);
 
-       nstyle = autocvar_g_projectiles_newton_style;
-       if(nstyle == 0 || forceAbsolute)
-       {
-               // absolute velocity
-               outvelocity = mvelocity;
-       }
-       else if(nstyle == 1)
-       {
-               // true Newtonian projectiles
-               outvelocity = pvelocity + mvelocity;
-       }
-       else if(nstyle == 2)
-       {
-               // true Newtonian projectiles with automatic aim adjustment
-               //
-               // solve: |outspeed * mdirection - pvelocity| = mspeed
-               // outspeed^2 - 2 * outspeed * (mdirection * pvelocity) + pvelocity^2 - mspeed^2 = 0
-               // outspeed = (mdirection * pvelocity) +- sqrt((mdirection * pvelocity)^2 - pvelocity^2 + mspeed^2)
-               // PLUS SIGN!
-               // not defined?
-               // then...
-               // pvelocity^2 - (mdirection * pvelocity)^2 > mspeed^2
-               // velocity without mdirection component > mspeed
-               // fire at smallest possible mspeed that works?
-               // |(mdirection * pvelocity) * pvelocity - pvelocity| = mspeed
-
-               vector solution;
-               solution = solve_quadratic(1, -2 * (mdirection * pvelocity), pvelocity * pvelocity - mspeed * mspeed);
-               if(solution_z)
-                       outspeed = solution_y; // the larger one
-               else
-               {
-                       //outspeed = 0; // slowest possible shot
-                       outspeed = solution_x; // the real part (that is, the average!)
-                       //dprint("impossible shot, adjusting\n");
-               }
-
-               outspeed = bound(mspeed * autocvar_g_projectiles_newton_style_2_minfactor, outspeed, mspeed * autocvar_g_projectiles_newton_style_2_maxfactor);
-               outvelocity = mdirection * outspeed;
-       }
-       else if(nstyle == 3)
-       {
-               // pseudo-Newtonian:
-               outspeed = mspeed + mdirection * pvelocity;
-               outspeed = bound(mspeed * 0.7, outspeed, mspeed * 5.0);
-               outvelocity = mdirection * outspeed;
-       }
-       else if(nstyle == 4)
-       {
-               // tZorkian:
-               outspeed = mspeed + vlen(pvelocity);
-               outvelocity = mdirection * outspeed;
-       }
-       else
-               error("g_projectiles_newton_style must be 0 (absolute), 1 (Newtonian), 2 (Newtonian + aimfix), 3 (pseudo Newtonian) or 4 (tZorkian)!");
+       outvelocity = get_shotvelocity(pvelocity, mdirection, mspeed, (forceAbsolute ? 0 : autocvar_g_projectiles_newton_style), autocvar_g_projectiles_newton_style_2_minfactor, autocvar_g_projectiles_newton_style_2_maxfactor);
 
        return outvelocity;
 }
@@ -1248,7 +1199,7 @@ vector findperpendicular(vector v)
 vector W_CalculateProjectileSpread(vector forward, float spread)
 {
        float sigma;
-       vector v1, v2;
+       vector v1 = '0 0 0', v2;
        float dx, dy, r;
        float sstyle;
        spread *= g_weaponspreadfactor;
@@ -1512,7 +1463,7 @@ void W_Reload(float sent_ammo_min, float sent_ammo_amount, float sent_time, stri
 
        // now begin the reloading process
 
-       sound (self, CH_WEAPON_B, self.reload_sound, VOL_BASE, ATTN_NORM);
+       sound (self, CH_WEAPON_SINGLE, self.reload_sound, VOL_BASE, ATTN_NORM);
 
        // do not set ATTACK_FINISHED in reload code any more. This causes annoying delays if eg: You start reloading a weapon,
        // then quickly switch to another weapon and back. Reloading is canceled, but the reload delay is still there,