]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/weapons/weapon/blaster.qc
Remove legacy Quake bbox expansion: projectiles
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / weapons / weapon / blaster.qc
index 2f24e9e254bcb495b4c53782f4434771ed1269b8..c4d6720c2d37c915457ed0a7453f31f5a7fb4a7c 100644 (file)
@@ -1,78 +1,29 @@
 #include "blaster.qh"
-#ifndef IMPLEMENTATION
-CLASS(Blaster, Weapon)
-/* ammotype  */ //ATTRIB(Blaster, ammo_field, .int, ammo_none);
-/* impulse   */ ATTRIB(Blaster, impulse, int, 1);
-/* flags     */ ATTRIB(Blaster, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
-/* rating    */ ATTRIB(Blaster, bot_pickupbasevalue, float, 0);
-/* color     */ ATTRIB(Blaster, wpcolor, vector, '1 0.5 0.5');
-/* modelname */ ATTRIB(Blaster, mdl, string, "laser");
-#ifdef GAMEQC
-/* model     */ ATTRIB(Blaster, m_model, Model, MDL_BLASTER_ITEM);
-#endif
-/* crosshair */ ATTRIB(Blaster, w_crosshair, string, "gfx/crosshairlaser");
-/* crosshair */ ATTRIB(Blaster, w_crosshair_size, float, 0.5);
-/* wepimg    */ ATTRIB(Blaster, model2, string, "weaponlaser");
-/* refname   */ ATTRIB(Blaster, netname, string, "blaster");
-/* wepname   */ ATTRIB(Blaster, m_name, string, _("Blaster"));
-
-#define X(BEGIN, P, END, class, prefix) \
-       BEGIN(class) \
-               P(class, prefix, animtime, float, BOTH) \
-               P(class, prefix, damage, float, BOTH) \
-               P(class, prefix, delay, float, BOTH) \
-               P(class, prefix, edgedamage, float, BOTH) \
-               P(class, prefix, force, float, BOTH) \
-               P(class, prefix, force_zscale, float, BOTH) \
-               P(class, prefix, lifetime, float, BOTH) \
-               P(class, prefix, radius, float, BOTH) \
-               P(class, prefix, refire, float, BOTH) \
-               P(class, prefix, secondary, float, NONE) \
-               P(class, prefix, shotangle, float, BOTH) \
-               P(class, prefix, speed, 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, 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, Blaster, blaster)
-#undef X
-
-ENDCLASS(Blaster)
-REGISTER_WEAPON(BLASTER, blaster, NEW(Blaster));
 
 #ifdef SVQC
-.float blaster_damage;
-.float blaster_edgedamage;
-.float blaster_radius;
-.float blaster_force;
-.float blaster_lifetime;
-#endif
-#endif
-#ifdef IMPLEMENTATION
-#ifdef SVQC
-spawnfunc(weapon_blaster) { weapon_defaultspawnfunc(this, WEP_BLASTER); }
-spawnfunc(weapon_laser) { spawnfunc_weapon_blaster(this); }
 
 void W_Blaster_Touch(entity this, entity toucher)
 {
        PROJECTILE_TOUCH(this, toucher);
 
        this.event_damage = func_null;
+       bool isprimary = !(this.projectiledeathtype & HITTYPE_SECONDARY);
 
-       RadiusDamage(
+       RadiusDamageForSource(
                this,
+               (this.origin + (this.mins + this.maxs) * 0.5),
+               this.velocity,
                this.realowner,
-               this.blaster_damage,
-               this.blaster_edgedamage,
-               this.blaster_radius,
+               WEP_CVAR_BOTH(blaster, isprimary, damage),
+               WEP_CVAR_BOTH(blaster, isprimary, edgedamage),
+               WEP_CVAR_BOTH(blaster, isprimary, radius),
                NULL,
                NULL,
-               this.blaster_force,
+               false,
+               WEP_CVAR_BOTH(blaster, isprimary, force),
+               WEP_CVAR_BOTH(blaster, isprimary, force_zscale),
                this.projectiledeathtype,
+               this.weaponentity_fld,
                toucher
        );
 
@@ -83,54 +34,37 @@ void W_Blaster_Think(entity this)
 {
        set_movetype(this, MOVETYPE_FLY);
        setthink(this, SUB_Remove);
-       this.nextthink = time + this.blaster_lifetime;
+       bool isprimary = !(this.projectiledeathtype & HITTYPE_SECONDARY);
+       this.nextthink = time + WEP_CVAR_BOTH(blaster, isprimary, lifetime);
        CSQCProjectile(this, true, PROJECTILE_BLASTER, true);
 }
 
 void W_Blaster_Attack(
        entity actor,
        .entity weaponentity,
-       float atk_deathtype,
-       float atk_shotangle,
-       float atk_damage,
-       float atk_edgedamage,
-       float atk_radius,
-       float atk_force,
-       float atk_speed,
-       float atk_spread,
-       float atk_delay,
-       float atk_lifetime)
+       float atk_deathtype)
 {
+       bool isprimary = !(atk_deathtype & HITTYPE_SECONDARY);
+       float atk_shotangle = WEP_CVAR_BOTH(blaster, isprimary, shotangle);
+       float atk_damage = WEP_CVAR_BOTH(blaster, isprimary, damage);
        vector s_forward = v_forward * cos(atk_shotangle * DEG2RAD) + v_up * sin(atk_shotangle * DEG2RAD);
 
-       W_SetupShot_Dir(actor, weaponentity, s_forward, false, 3, SND_LASERGUN_FIRE, CH_WEAPON_B, atk_damage);
-       Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
+       W_SetupShot_Dir(actor, weaponentity, s_forward, false, 3, SND_LASERGUN_FIRE, CH_WEAPON_B, atk_damage, atk_deathtype);
+       W_MuzzleFlash(WEP_BLASTER, actor, weaponentity, w_shotorg, w_shotdir);
 
        entity missile = new(blasterbolt);
        missile.owner = missile.realowner = actor;
        missile.bot_dodge = true;
        missile.bot_dodgerating = atk_damage;
        PROJECTILE_MAKETRIGGER(missile);
-
-       missile.blaster_damage = atk_damage;
-       missile.blaster_edgedamage = atk_edgedamage;
-       missile.blaster_radius = atk_radius;
-       missile.blaster_force = atk_force;
-       missile.blaster_lifetime = atk_lifetime;
+       missile.clipgroup = CLIPGROUP_UNHITTABLEPROJ;
 
        setorigin(missile, w_shotorg);
-       setsize(missile, '0 0 0', '0 0 0');
+       setsize(missile, UNHITTABLEPROJ_MINS, UNHITTABLEPROJ_MAXS);
 
-       W_SetupProjVelocity_Explicit(
-               missile,
-               w_shotdir,
-               v_up,
-               atk_speed,
-               0,
-               0,
-               atk_spread,
-               false
-       );
+       float atk_speed = WEP_CVAR_BOTH(blaster, isprimary, speed);
+       float atk_spread = WEP_CVAR_BOTH(blaster, isprimary, spread);
+       W_SetupProjVelocity_Explicit(missile, w_shotdir, v_up, atk_speed, 0, 0, atk_spread, false);
 
        missile.angles = vectoangles(missile.velocity);
 
@@ -140,10 +74,12 @@ void W_Blaster_Attack(
        settouch(missile, W_Blaster_Touch);
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
        missile.missile_flags = MIF_SPLASH;
        missile.projectiledeathtype = atk_deathtype;
+       missile.weaponentity_fld = weaponentity;
        setthink(missile, W_Blaster_Think);
-       missile.nextthink = time + atk_delay;
+       missile.nextthink = time + WEP_CVAR_BOTH(blaster, isprimary, delay);
 
        MUTATOR_CALLHOOK(EditProjectile, actor, missile);
 
@@ -153,17 +89,17 @@ void W_Blaster_Attack(
        }
 }
 
-METHOD(Blaster, wr_aim, void(entity thiswep, entity actor))
+METHOD(Blaster, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
 {
     if(WEP_CVAR(blaster, secondary))
     {
         if((random() * (WEP_CVAR_PRI(blaster, damage) + WEP_CVAR_SEC(blaster, damage))) > WEP_CVAR_PRI(blaster, damage))
-            { PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, WEP_CVAR_SEC(blaster, speed), 0, WEP_CVAR_SEC(blaster, lifetime), false); }
+            { PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_SEC(blaster, speed), 0, WEP_CVAR_SEC(blaster, lifetime), false, true); }
         else
-            { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
+            { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false, true); }
     }
     else
-        { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
+        { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false, true); }
 }
 
 METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponentity, int fire))
@@ -172,20 +108,7 @@ METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponenti
     {
         if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(blaster, refire)))
         {
-            W_Blaster_Attack(
-                actor,
-                weaponentity,
-                WEP_BLASTER.m_id,
-                WEP_CVAR_PRI(blaster, shotangle),
-                WEP_CVAR_PRI(blaster, damage),
-                WEP_CVAR_PRI(blaster, edgedamage),
-                WEP_CVAR_PRI(blaster, radius),
-                WEP_CVAR_PRI(blaster, force),
-                WEP_CVAR_PRI(blaster, speed),
-                WEP_CVAR_PRI(blaster, spread),
-                WEP_CVAR_PRI(blaster, delay),
-                WEP_CVAR_PRI(blaster, lifetime)
-            );
+            W_Blaster_Attack(actor, weaponentity, WEP_BLASTER.m_id);
             weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(blaster, animtime), w_ready);
         }
     }
@@ -195,8 +118,8 @@ METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponenti
         {
             case 0: // switch to last used weapon
             {
-                if(PS(actor).m_switchweapon == WEP_BLASTER) // don't do this if already switching
-                    W_LastWeapon(actor);
+                if(actor.(weaponentity).m_switchweapon == WEP_BLASTER) // don't do this if already switching
+                    W_LastWeapon(actor, weaponentity);
                 break;
             }
 
@@ -204,20 +127,7 @@ METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponenti
             {
                 if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(blaster, refire)))
                 {
-                    W_Blaster_Attack(
-                        actor,
-                        weaponentity,
-                        WEP_BLASTER.m_id | HITTYPE_SECONDARY,
-                        WEP_CVAR_SEC(blaster, shotangle),
-                        WEP_CVAR_SEC(blaster, damage),
-                        WEP_CVAR_SEC(blaster, edgedamage),
-                        WEP_CVAR_SEC(blaster, radius),
-                        WEP_CVAR_SEC(blaster, force),
-                        WEP_CVAR_SEC(blaster, speed),
-                        WEP_CVAR_SEC(blaster, spread),
-                        WEP_CVAR_SEC(blaster, delay),
-                        WEP_CVAR_SEC(blaster, lifetime)
-                    );
+                    W_Blaster_Attack(actor, weaponentity, WEP_BLASTER.m_id | HITTYPE_SECONDARY);
                     weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(blaster, animtime), w_ready);
                 }
 
@@ -227,17 +137,12 @@ METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponenti
     }
 }
 
-METHOD(Blaster, wr_setup, void(entity thiswep, entity actor))
-{
-    actor.ammo_field = ammo_none;
-}
-
-METHOD(Blaster, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Blaster, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
 {
     return true; // infinite ammo
 }
 
-METHOD(Blaster, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Blaster, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
 {
     return true; // blaster has infinite ammo
 }
@@ -252,16 +157,26 @@ METHOD(Blaster, wr_killmessage, Notification(entity thiswep))
     return WEAPON_BLASTER_MURDER;
 }
 
+METHOD(OffhandBlaster, offhand_think, void(OffhandBlaster this, entity actor, bool key_pressed))
+{
+       if (!key_pressed || (time < actor.jump_interval))
+       {
+               return;
+       }
+       actor.jump_interval = time + WEP_CVAR_SEC(blaster, refire) * W_WeaponRateFactor(actor);
+       .entity weaponentity = weaponentities[1];
+       makevectors(actor.v_angle);
+       W_Blaster_Attack(actor, weaponentity, WEP_BLASTER.m_id | HITTYPE_SECONDARY);
+}
+
 #endif
 #ifdef CSQC
 
 METHOD(Blaster, wr_impacteffect, void(entity thiswep, entity actor))
 {
-    vector org2;
-    org2 = w_org + w_backoff * 6;
+    vector org2 = w_org + w_backoff * 2;
     pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1);
     if(!w_issilent) { sound(actor, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); }
 }
 
 #endif
-#endif