]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/w_campingrifle.qc
rifle: "bullet hail" feature: empty whole magazine (not enabled)
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / w_campingrifle.qc
index f0ac7307bededa0d525fa31b0ff19ececbbe21fd..8f6a9104946ce3f6dc263191d5520853f1065e57 100644 (file)
@@ -31,24 +31,27 @@ void W_CampingRifle_ReloadedAndReady()
        w_ready();
 }
 
-void W_CampingRifle_Reload()
+float W_CampingRifle_Reload()
 {
        float t;
 
        W_CampingRifle_CheckMaxBullets(TRUE);
-       if (self.campingrifle_bulletcounter >= cvar("g_balance_campingrifle_magazinecapacity"))
-               return;
 
-       if(self.ammo_nails < min(cvar("g_balance_campingrifle_primary_ammo"), cvar("g_balance_campingrifle_secondary_ammo")))
+       if(self.ammo_nails < min(cvar("g_balance_campingrifle_primary_ammo"), cvar("g_balance_campingrifle_secondary_ammo"))) // when we get here, bulletcounter must be 0 or -1
        {
+               print("cannot reload... not enough bullets\n");
                self.campingrifle_bulletcounter = -1; // reload later
-               return;
+               W_SwitchToOtherWeapon(self);
+               return 0;
        }
        
+       if (self.campingrifle_bulletcounter >= cvar("g_balance_campingrifle_magazinecapacity"))
+               return 0;
+
        if (self.weaponentity)
        {
                if (self.weaponentity.wframe == WFRAME_RELOAD)
-                       return;
+                       return 0;
 
                // allow to switch away while reloading, but this will cause a new reload!
                self.weaponentity.state = WS_READY;
@@ -62,15 +65,16 @@ void W_CampingRifle_Reload()
        weapon_thinkf(WFRAME_RELOAD, cvar("g_balance_campingrifle_reloadtime"), W_CampingRifle_ReloadedAndReady);
 
        self.campingrifle_bulletcounter = -1;
+
+       return 1;
 }
 
 void W_CampingRifle_CheckReloadAndReady()
 {
        w_ready();
-       if (self.campingrifle_bulletcounter <= 0)
-               W_CampingRifle_Reload();
-       else
-               w_ready();
+       if(self.campingrifle_bulletcounter <= 0)
+               if(W_CampingRifle_Reload())
+                       return;
 }
 
 void W_CampingRifle_FireBullet(float pSpread, float pDamage, float pHeadshotAddedDamage, float pForce, float pSpeed, float pLifetime, float pAmmo, float deathtype, float pBulletConstant)
@@ -116,6 +120,57 @@ void spawnfunc_weapon_campingrifle (void)
        weapon_defaultspawnfunc(WEP_CAMPINGRIFLE);
 }
 
+.void(void) campingrifle_bullethail_attackfunc;
+.float campingrifle_bullethail_frame;
+.float campingrifle_bullethail_animtime;
+.float campingrifle_bullethail_refire;
+void W_CampingRifle_BulletHail_Continue()
+{
+       float r, sw, af;
+       W_CampingRifle_CheckReloadAndReady();
+       if(self.campingrifle_bulletcounter < 0)
+               return; // reloading, so we are done
+       sw = self.switchweapon; // make it not detect weapon changes as reason to abort firing
+       af = ATTACK_FINISHED(self);
+       self.switchweapon = self.weapon;
+       ATTACK_FINISHED(self) = time;
+       print(ftos(self.ammo_nails), "\n");
+       r = weapon_prepareattack(self.campingrifle_bullethail_frame == WFRAME_FIRE2, self.campingrifle_bullethail_refire);
+       if(self.switchweapon == self.weapon)
+               self.switchweapon = sw;
+       if(r)
+       {
+               self.campingrifle_bullethail_attackfunc();
+               weapon_thinkf(self.campingrifle_bullethail_frame, self.campingrifle_bullethail_animtime, W_CampingRifle_BulletHail_Continue);
+               print("thinkf set\n");
+       }
+       else
+       {
+               ATTACK_FINISHED(self) = af; // reset attack_finished if we didn't fire, so the last shot enforces the refire time
+               print("out of ammo... ", ftos(self.weaponentity.state), "\n");
+       }
+}
+
+void W_CampingRifle_BulletHail(float mode, void(void) AttackFunc, float fr, float animtime, float refire)
+{
+       // if we get here, we have at least one bullet to fire
+       AttackFunc();
+       if(mode)
+       {
+               // continue hail
+               self.campingrifle_bullethail_attackfunc = AttackFunc;
+               self.campingrifle_bullethail_frame = fr;
+               self.campingrifle_bullethail_animtime = animtime;
+               self.campingrifle_bullethail_refire = refire;
+               weapon_thinkf(fr, animtime, W_CampingRifle_BulletHail_Continue);
+       }
+       else
+       {
+               // just one shot
+               weapon_thinkf(fr, animtime, W_CampingRifle_CheckReloadAndReady);
+       }
+}
+
 .float bot_secondary_campingriflemooth;
 float w_campingrifle(float req)
 {
@@ -155,19 +210,19 @@ float w_campingrifle(float req)
                {
                        self.campingrifle_accumulator = bound(time - cvar("g_balance_campingrifle_bursttime"), self.campingrifle_accumulator, time);
                        if (self.BUTTON_ATCK)
+                       if (weapon_prepareattack_check(0, cvar("g_balance_campingrifle_primary_refire")))
                        if (time >= self.campingrifle_accumulator + cvar("g_balance_campingrifle_primary_burstcost"))
-                       if (weapon_prepareattack(0, cvar("g_balance_campingrifle_primary_refire")))
                        {
-                               W_CampingRifle_Attack();
-                               weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_campingrifle_primary_animtime"), W_CampingRifle_CheckReloadAndReady);
+                               weapon_prepareattack_do(0, cvar("g_balance_campingrifle_primary_refire"));
+                               W_CampingRifle_BulletHail(cvar("g_balance_campingrifle_primary_bullethail"), W_CampingRifle_Attack, WFRAME_FIRE1, cvar("g_balance_campingrifle_primary_animtime"), cvar("g_balance_campingrifle_primary_refire"));
                                self.campingrifle_accumulator += cvar("g_balance_campingrifle_primary_burstcost");
                        }
                        if (self.BUTTON_ATCK2)
+                       if (weapon_prepareattack_check(1, cvar("g_balance_campingrifle_secondary_refire")))
                        if (time >= self.campingrifle_accumulator + cvar("g_balance_campingrifle_secondary_burstcost"))
-                       if (weapon_prepareattack(1, cvar("g_balance_campingrifle_secondary_refire")))
                        {
-                               W_CampingRifle_Attack2();
-                               weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_campingrifle_secondary_animtime"), W_CampingRifle_CheckReloadAndReady);
+                               weapon_prepareattack_do(1, cvar("g_balance_campingrifle_secondary_refire"));
+                               W_CampingRifle_BulletHail(cvar("g_balance_campingrifle_secondary_bullethail"), W_CampingRifle_Attack2, WFRAME_FIRE2, cvar("g_balance_campingrifle_secondary_animtime"), cvar("g_balance_campingrifle_primary_refire"));
                                self.campingrifle_accumulator += cvar("g_balance_campingrifle_secondary_burstcost");
                        }
                }