]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/weapons/weapon/rifle.qc
Merge branch 'master' into TimePath/notifications
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / weapons / weapon / rifle.qc
index 8aad95ef6240dc40f66d077b16e38c0acfc88090..c0734d77dd87b235902d94a1d15901f029873390 100644 (file)
@@ -13,57 +13,60 @@ CLASS(Rifle, Weapon)
 /* crosshair */ ATTRIB(Rifle, w_crosshair_size, float, 0.6);
 /* wepimg    */ ATTRIB(Rifle, model2, string, "weaponrifle");
 /* refname   */ ATTRIB(Rifle, netname, string, "rifle");
-/* wepname   */ ATTRIB(Rifle, message, string, _("Rifle"));
+/* wepname   */ ATTRIB(Rifle, m_name, string, _("Rifle"));
+
+#define X(BEGIN, P, END, class, prefix) \
+       BEGIN(class) \
+               P(class, prefix, ammo, float, BOTH) \
+               P(class, prefix, animtime, float, BOTH) \
+               P(class, prefix, bullethail, float, BOTH) \
+               P(class, prefix, burstcost, float, BOTH) \
+               P(class, prefix, bursttime, float, NONE) \
+               P(class, prefix, damage, float, BOTH) \
+               P(class, prefix, force, float, BOTH) \
+               P(class, prefix, refire, float, BOTH) \
+               P(class, prefix, reload, float, SEC) \
+               P(class, prefix, reload_ammo, float, NONE) \
+       P(class, prefix, reload_time, float, NONE) \
+               P(class, prefix, secondary, float, NONE) \
+               P(class, prefix, shots, float, BOTH) \
+               P(class, prefix, solidpenetration, float, BOTH) \
+               P(class, prefix, spread, float, BOTH) \
+       P(class, prefix, switchdelay_drop, float, NONE) \
+       P(class, prefix, switchdelay_raise, float, NONE) \
+               P(class, prefix, tracer, float, BOTH) \
+       P(class, prefix, weaponreplace, string, NONE) \
+       P(class, prefix, weaponstartoverride, float, NONE) \
+       P(class, prefix, weaponstart, float, NONE) \
+       P(class, prefix, weaponthrowable, float, NONE) \
+       END()
+    W_PROPS(X, Rifle, rifle)
+#undef X
 ENDCLASS(Rifle)
-REGISTER_WEAPON(RIFLE, NEW(Rifle));
+REGISTER_WEAPON(RIFLE, rifle, NEW(Rifle));
 
-#define RIFLE_SETTINGS(w_cvar,w_prop) RIFLE_SETTINGS_LIST(w_cvar, w_prop, RIFLE, rifle)
-#define RIFLE_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
-       w_cvar(id, sn, BOTH, ammo) \
-       w_cvar(id, sn, BOTH, animtime) \
-       w_cvar(id, sn, BOTH, bullethail) \
-       w_cvar(id, sn, BOTH, burstcost) \
-       w_cvar(id, sn, BOTH, damage) \
-       w_cvar(id, sn, BOTH, force) \
-       w_cvar(id, sn, BOTH, refire) \
-       w_cvar(id, sn, BOTH, shots) \
-       w_cvar(id, sn, BOTH, solidpenetration) \
-       w_cvar(id, sn, BOTH, spread) \
-       w_cvar(id, sn, BOTH, tracer) \
-       w_cvar(id, sn, NONE, bursttime) \
-       w_cvar(id, sn, NONE, secondary) \
-       w_cvar(id, sn, SEC,  reload) \
-       w_prop(id, sn, float,  reloading_ammo, reload_ammo) \
-       w_prop(id, sn, float,  reloading_time, reload_time) \
-       w_prop(id, sn, float,  switchdelay_raise, switchdelay_raise) \
-       w_prop(id, sn, float,  switchdelay_drop, switchdelay_drop) \
-       w_prop(id, sn, string, weaponreplace, weaponreplace) \
-       w_prop(id, sn, float,  weaponstart, weaponstart) \
-       w_prop(id, sn, float,  weaponstartoverride, weaponstartoverride) \
-       w_prop(id, sn, float,  weaponthrowable, weaponthrowable)
 
 #ifdef SVQC
-RIFLE_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
 .float rifle_accumulator;
 #endif
 #endif
 #ifdef IMPLEMENTATION
 #ifdef SVQC
-void spawnfunc_weapon_rifle(void) { weapon_defaultspawnfunc(WEP_RIFLE.m_id); }
-void spawnfunc_weapon_campingrifle(void) { spawnfunc_weapon_rifle(); }
-void spawnfunc_weapon_sniperrifle(void) { spawnfunc_weapon_rifle(); }
+spawnfunc(weapon_rifle) { weapon_defaultspawnfunc(this, WEP_RIFLE); }
+spawnfunc(weapon_campingrifle) { spawnfunc_weapon_rifle(this); }
+spawnfunc(weapon_sniperrifle) { spawnfunc_weapon_rifle(this); }
 
 void W_Rifle_FireBullet(Weapon thiswep, float pSpread, float pDamage, float pForce, float pSolidPenetration, float pAmmo, int deathtype, float pTracer, float pShots, string pSound)
 {SELFPARAM();
        float i;
 
-       W_DecreaseAmmo(thiswep, pAmmo);
+       W_DecreaseAmmo(thiswep, self, pAmmo);
 
        W_SetupShot(self, true, 2, pSound, CH_WEAPON_A, pDamage * pShots);
 
        Send_Effect(EFFECT_RIFLE_MUZZLEFLASH, w_shotorg, w_shotdir * 2000, 1);
 
-       if(self.BUTTON_ZOOM | self.BUTTON_ZOOMSCRIPT) // if zoomed, shoot from the eye
+       if(PHYS_INPUT_BUTTON_ZOOM(self) | PHYS_INPUT_BUTTON_ZOOMSCRIPT(self)) // if zoomed, shoot from the eye
        {
                w_shotdir = v_forward;
                w_shotorg = self.origin + self.view_ofs + ((w_shotorg - self.origin - self.view_ofs) * v_forward) * v_forward;
@@ -76,46 +79,44 @@ void W_Rifle_FireBullet(Weapon thiswep, float pSpread, float pDamage, float pFor
                SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, self);
 }
 
-void W_Rifle_Attack(void)
+void W_Rifle_Attack()
 {
        W_Rifle_FireBullet(WEP_RIFLE, WEP_CVAR_PRI(rifle, spread), WEP_CVAR_PRI(rifle, damage), WEP_CVAR_PRI(rifle, force), WEP_CVAR_PRI(rifle, solidpenetration), WEP_CVAR_PRI(rifle, ammo), WEP_RIFLE.m_id, WEP_CVAR_PRI(rifle, tracer), WEP_CVAR_PRI(rifle, shots), SND(CAMPINGRIFLE_FIRE));
 }
 
-void W_Rifle_Attack2(void)
+void W_Rifle_Attack2()
 {
        W_Rifle_FireBullet(WEP_RIFLE, WEP_CVAR_SEC(rifle, spread), WEP_CVAR_SEC(rifle, damage), WEP_CVAR_SEC(rifle, force), WEP_CVAR_SEC(rifle, solidpenetration), WEP_CVAR_SEC(rifle, ammo), WEP_RIFLE.m_id | HITTYPE_SECONDARY, WEP_CVAR_SEC(rifle, tracer), WEP_CVAR_SEC(rifle, shots), SND(CAMPINGRIFLE_FIRE2));
 }
 
-.void(void) rifle_bullethail_attackfunc;
-.float rifle_bullethail_frame;
+.void() rifle_bullethail_attackfunc;
+.WFRAME rifle_bullethail_frame;
 .float rifle_bullethail_animtime;
 .float rifle_bullethail_refire;
-void W_Rifle_BulletHail_Continue(void)
-{SELFPARAM();
-       float r, sw, af;
+void W_Rifle_BulletHail_Continue(Weapon thiswep, entity actor, .entity weaponentity, int fire)
+{
+       float r, af;
 
-       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;
-       LOG_INFO(ftos(self.WEP_AMMO(RIFLE)), "\n");
-       r = weapon_prepareattack(self.rifle_bullethail_frame == WFRAME_FIRE2, self.rifle_bullethail_refire);
-       if(self.switchweapon == self.weapon)
-               self.switchweapon = sw;
+       Weapon sw = PS(actor).m_switchweapon; // make it not detect weapon changes as reason to abort firing
+       int slot = weaponslot(weaponentity);
+       af = ATTACK_FINISHED(actor, slot);
+       PS(actor).m_switchweapon = PS(actor).m_weapon;
+       ATTACK_FINISHED(actor, slot) = time;
+       r = weapon_prepareattack(thiswep, actor, weaponentity, actor.rifle_bullethail_frame == WFRAME_FIRE2, actor.rifle_bullethail_refire);
+       if(PS(actor).m_switchweapon == PS(actor).m_weapon)
+               PS(actor).m_switchweapon = sw;
        if(r)
        {
-               self.rifle_bullethail_attackfunc();
-               weapon_thinkf(self.rifle_bullethail_frame, self.rifle_bullethail_animtime, W_Rifle_BulletHail_Continue);
-               LOG_INFO("thinkf set\n");
+               actor.rifle_bullethail_attackfunc();
+               weapon_thinkf(actor, weaponentity, actor.rifle_bullethail_frame, actor.rifle_bullethail_animtime, W_Rifle_BulletHail_Continue);
        }
        else
        {
-               ATTACK_FINISHED(self) = af; // reset attack_finished if we didn't fire, so the last shot enforces the refire time
-               LOG_INFO("out of ammo... ", ftos(self.weaponentity.state), "\n");
+               ATTACK_FINISHED(actor, slot) = af; // reset attack_finished if we didn't fire, so the last shot enforces the refire time
        }
 }
 
-void W_Rifle_BulletHail(float mode, void(void) AttackFunc, float fr, float animtime, float refire)
+void W_Rifle_BulletHail(.entity weaponentity, float mode, void() AttackFunc, WFRAME fr, float animtime, float refire)
 {SELFPARAM();
        // if we get here, we have at least one bullet to fire
        AttackFunc();
@@ -126,174 +127,150 @@ void W_Rifle_BulletHail(float mode, void(void) AttackFunc, float fr, float animt
                self.rifle_bullethail_frame = fr;
                self.rifle_bullethail_animtime = animtime;
                self.rifle_bullethail_refire = refire;
-               weapon_thinkf(fr, animtime, W_Rifle_BulletHail_Continue);
+               weapon_thinkf(self, weaponentity, fr, animtime, W_Rifle_BulletHail_Continue);
        }
        else
        {
                // just one shot
-               weapon_thinkf(fr, animtime, w_ready);
+               weapon_thinkf(self, weaponentity, fr, animtime, w_ready);
        }
 }
 
 .float bot_secondary_riflemooth;
 
-               METHOD(Rifle, wr_aim, bool(entity thiswep))
-               {
-                       self.BUTTON_ATCK=false;
-                       self.BUTTON_ATCK2=false;
-                       if(vlen(self.origin-self.enemy.origin) > 1000)
-                               self.bot_secondary_riflemooth = 0;
-                       if(self.bot_secondary_riflemooth == 0)
-                       {
-                               if(bot_aim(1000000, 0, 0.001, false))
-                               {
-                                       self.BUTTON_ATCK = true;
-                                       if(random() < 0.01) self.bot_secondary_riflemooth = 1;
-                               }
-                       }
-                       else
-                       {
-                               if(bot_aim(1000000, 0, 0.001, false))
-                               {
-                                       self.BUTTON_ATCK2 = true;
-                                       if(random() < 0.03) self.bot_secondary_riflemooth = 0;
-                               }
-                       }
-
-                       return true;
-               }
-               METHOD(Rifle, wr_think, bool(entity thiswep, bool fire1, bool fire2))
-               {
-                       if(autocvar_g_balance_rifle_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo))) // forced reload
-                               _WEP_ACTION(self.weapon, WR_RELOAD);
-                       else
-                       {
-                               self.rifle_accumulator = bound(time - WEP_CVAR(rifle, bursttime), self.rifle_accumulator, time);
-                               if(fire1)
-                               if(weapon_prepareattack_check(0, WEP_CVAR_PRI(rifle, refire)))
-                               if(time >= self.rifle_accumulator + WEP_CVAR_PRI(rifle, burstcost))
-                               {
-                                       weapon_prepareattack_do(0, WEP_CVAR_PRI(rifle, refire));
-                                       W_Rifle_BulletHail(WEP_CVAR_PRI(rifle, bullethail), W_Rifle_Attack, WFRAME_FIRE1, WEP_CVAR_PRI(rifle, animtime), WEP_CVAR_PRI(rifle, refire));
-                                       self.rifle_accumulator += WEP_CVAR_PRI(rifle, burstcost);
-                               }
-                               if(fire2)
-                               {
-                                       if(WEP_CVAR(rifle, secondary))
-                                       {
-                                               if(WEP_CVAR_SEC(rifle, reload))
-                                                       _WEP_ACTION(self.weapon, WR_RELOAD);
-                                               else
-                                               {
-                                                       if(weapon_prepareattack_check(1, WEP_CVAR_SEC(rifle, refire)))
-                                                       if(time >= self.rifle_accumulator + WEP_CVAR_SEC(rifle, burstcost))
-                                                       {
-                                                               weapon_prepareattack_do(1, WEP_CVAR_SEC(rifle, refire));
-                                                               W_Rifle_BulletHail(WEP_CVAR_SEC(rifle, bullethail), W_Rifle_Attack2, WFRAME_FIRE2, WEP_CVAR_SEC(rifle, animtime), WEP_CVAR_PRI(rifle, refire));
-                                                               self.rifle_accumulator += WEP_CVAR_SEC(rifle, burstcost);
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-
-                       return true;
-               }
-               METHOD(Rifle, wr_init, bool(entity thiswep))
-               {
-                       RIFLE_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
-                       return true;
-               }
-               METHOD(Rifle, wr_checkammo1, bool(entity thiswep))
-               {
-                       float ammo_amount = self.WEP_AMMO(RIFLE) >= WEP_CVAR_PRI(rifle, ammo);
-                       ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_PRI(rifle, ammo);
-                       return ammo_amount;
-               }
-               METHOD(Rifle, wr_checkammo2, bool(entity thiswep))
-               {
-                       float ammo_amount = self.WEP_AMMO(RIFLE) >= WEP_CVAR_SEC(rifle, ammo);
-                       ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_SEC(rifle, ammo);
-                       return ammo_amount;
-               }
-               METHOD(Rifle, wr_config, bool(entity thiswep))
-               {
-                       RIFLE_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS);
-                       return true;
-               }
-               METHOD(Rifle, wr_resetplayer, bool(entity thiswep))
-               {
-                       self.rifle_accumulator = time - WEP_CVAR(rifle, bursttime);
-                       return true;
-               }
-               METHOD(Rifle, wr_reload, bool(entity thiswep))
-               {
-                       W_Reload(min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo)), SND(RELOAD));
-                       return true;
-               }
-               METHOD(Rifle, wr_suicidemessage, bool(entity thiswep))
-               {
-                       return WEAPON_THINKING_WITH_PORTALS;
-               }
-               METHOD(Rifle, wr_killmessage, bool(entity thiswep))
-               {
-                       if(w_deathtype & HITTYPE_SECONDARY)
-                       {
-                               if(w_deathtype & HITTYPE_BOUNCE)
-                                       return WEAPON_RIFLE_MURDER_HAIL_PIERCING;
-                               else
-                                       return WEAPON_RIFLE_MURDER_HAIL;
-                       }
-                       else
-                       {
-                               if(w_deathtype & HITTYPE_BOUNCE)
-                                       return WEAPON_RIFLE_MURDER_PIERCING;
-                               else
-                                       return WEAPON_RIFLE_MURDER;
-                       }
-               }
+METHOD(Rifle, wr_aim, void(entity thiswep))
+{
+    PHYS_INPUT_BUTTON_ATCK(self) = false;
+    PHYS_INPUT_BUTTON_ATCK2(self) = false;
+    if(vdist(self.origin - self.enemy.origin, >, 1000))
+        self.bot_secondary_riflemooth = 0;
+    if(self.bot_secondary_riflemooth == 0)
+    {
+        if(bot_aim(1000000, 0, 0.001, false))
+        {
+            PHYS_INPUT_BUTTON_ATCK(self) = true;
+            if(random() < 0.01) self.bot_secondary_riflemooth = 1;
+        }
+    }
+    else
+    {
+        if(bot_aim(1000000, 0, 0.001, false))
+        {
+            PHYS_INPUT_BUTTON_ATCK2(self) = true;
+            if(random() < 0.03) self.bot_secondary_riflemooth = 0;
+        }
+    }
+}
+METHOD(Rifle, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+{
+    if(autocvar_g_balance_rifle_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo))) { // forced reload
+        thiswep.wr_reload(thiswep, actor, weaponentity);
+    } else
+    {
+        actor.rifle_accumulator = bound(time - WEP_CVAR(rifle, bursttime), actor.rifle_accumulator, time);
+        if(fire & 1)
+        if(weapon_prepareattack_check(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire)))
+        if(time >= actor.rifle_accumulator + WEP_CVAR_PRI(rifle, burstcost))
+        {
+            weapon_prepareattack_do(actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire));
+            W_Rifle_BulletHail(weaponentity, WEP_CVAR_PRI(rifle, bullethail), W_Rifle_Attack, WFRAME_FIRE1, WEP_CVAR_PRI(rifle, animtime), WEP_CVAR_PRI(rifle, refire));
+            actor.rifle_accumulator += WEP_CVAR_PRI(rifle, burstcost);
+        }
+        if(fire & 2)
+        {
+            if(WEP_CVAR(rifle, secondary))
+            {
+                if(WEP_CVAR_SEC(rifle, reload)) {
+                    thiswep.wr_reload(thiswep, actor, weaponentity);
+                } else
+                {
+                    if(weapon_prepareattack_check(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire)))
+                    if(time >= actor.rifle_accumulator + WEP_CVAR_SEC(rifle, burstcost))
+                    {
+                        weapon_prepareattack_do(actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire));
+                        W_Rifle_BulletHail(weaponentity, WEP_CVAR_SEC(rifle, bullethail), W_Rifle_Attack2, WFRAME_FIRE2, WEP_CVAR_SEC(rifle, animtime), WEP_CVAR_PRI(rifle, refire));
+                        actor.rifle_accumulator += WEP_CVAR_SEC(rifle, burstcost);
+                    }
+                }
+            }
+        }
+    }
+}
+METHOD(Rifle, wr_checkammo1, bool(entity thiswep))
+{
+    float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(rifle, ammo);
+    ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_PRI(rifle, ammo);
+    return ammo_amount;
+}
+METHOD(Rifle, wr_checkammo2, bool(entity thiswep))
+{
+    float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(rifle, ammo);
+    ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_SEC(rifle, ammo);
+    return ammo_amount;
+}
+METHOD(Rifle, wr_resetplayer, void(entity thiswep))
+{
+    self.rifle_accumulator = time - WEP_CVAR(rifle, bursttime);
+}
+METHOD(Rifle, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+{
+    W_Reload(self, min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo)), SND(RELOAD));
+}
+METHOD(Rifle, wr_suicidemessage, Notification(entity thiswep))
+{
+    return WEAPON_THINKING_WITH_PORTALS;
+}
+METHOD(Rifle, wr_killmessage, Notification(entity thiswep))
+{
+    if(w_deathtype & HITTYPE_SECONDARY)
+    {
+        if(w_deathtype & HITTYPE_BOUNCE)
+            return WEAPON_RIFLE_MURDER_HAIL_PIERCING;
+        else
+            return WEAPON_RIFLE_MURDER_HAIL;
+    }
+    else
+    {
+        if(w_deathtype & HITTYPE_BOUNCE)
+            return WEAPON_RIFLE_MURDER_PIERCING;
+        else
+            return WEAPON_RIFLE_MURDER;
+    }
+}
 
 #endif
 #ifdef CSQC
 
-               METHOD(Rifle, wr_impacteffect, bool(entity thiswep))
-               {
-                       vector org2;
-                       org2 = w_org + w_backoff * 2;
-                       pointparticles(particleeffectnum(EFFECT_RIFLE_IMPACT), org2, w_backoff * 1000, 1);
-                       if(!w_issilent)
-                       {
-                               if(w_random < 0.2)
-                                       sound(self, CH_SHOTS, SND_RIC1, VOL_BASE, ATTN_NORM);
-                               else if(w_random < 0.4)
-                                       sound(self, CH_SHOTS, SND_RIC2, VOL_BASE, ATTN_NORM);
-                               else if(w_random < 0.5)
-                                       sound(self, CH_SHOTS, SND_RIC3, VOL_BASE, ATTN_NORM);
-                       }
-
-                       return true;
-               }
-               METHOD(Rifle, wr_init, bool(entity thiswep))
-               {
-                       if(autocvar_cl_reticle && autocvar_cl_reticle_weapon)
-                       {
-                               precache_pic("gfx/reticle_nex");
-                       }
-                       return true;
-               }
-               METHOD(Rifle, wr_zoomreticle, bool(entity thiswep))
-               {
-                       if(button_zoom || zoomscript_caught)
-                       {
-                               reticle_image = "gfx/reticle_nex";
-                               return true;
-                       }
-                       else
-                       {
-                               // no weapon specific image for this weapon
-                               return false;
-                       }
-               }
+METHOD(Rifle, wr_impacteffect, void(entity thiswep))
+{
+    vector org2;
+    org2 = w_org + w_backoff * 2;
+    pointparticles(EFFECT_RIFLE_IMPACT, org2, w_backoff * 1000, 1);
+    if(!w_issilent)
+    {
+        sound(self, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTN_NORM);
+    }
+}
+METHOD(Rifle, wr_init, void(entity thiswep))
+{
+    if(autocvar_cl_reticle && autocvar_cl_reticle_weapon)
+    {
+        precache_pic("gfx/reticle_nex");
+    }
+}
+METHOD(Rifle, wr_zoomreticle, bool(entity thiswep))
+{
+    if(button_zoom || zoomscript_caught)
+    {
+        reticle_image = "gfx/reticle_nex";
+        return true;
+    }
+    else
+    {
+        // no weapon specific image for this weapon
+        return false;
+    }
+}
 
 #endif
 #endif