]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/weapons/weapon/hook.qc
Give W_SetupShot a deathtype parameter, fixes some ugly hacks
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / weapons / weapon / hook.qc
index ff815d4619115869dff624b175e2f066a2c6b2fe..e04376b2f4fee279a289c1bb7bb8fcb4de320e36 100644 (file)
@@ -1,96 +1,18 @@
 #include "hook.qh"
-#ifndef IMPLEMENTATION
-CLASS(Hook, Weapon)
-/* ammotype  */ ATTRIB(Hook, ammo_field, .int, ammo_fuel);
-/* impulse   */ ATTRIB(Hook, impulse, int, 0);
-/* flags     */ ATTRIB(Hook, spawnflags, int, WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
-/* rating    */ ATTRIB(Hook, bot_pickupbasevalue, float, 0);
-/* color     */ ATTRIB(Hook, wpcolor, vector, '0 0.5 0');
-/* modelname */ ATTRIB(Hook, mdl, string, "hookgun");
-#ifdef GAMEQC
-/* model     */ ATTRIB(Hook, m_model, Model, MDL_HOOK_ITEM);
-#endif
-/* crosshair */ ATTRIB(Hook, w_crosshair, string, "gfx/crosshairhook");
-/* crosshair */ ATTRIB(Hook, w_crosshair_size, float, 0.5);
-/* wepimg    */ ATTRIB(Hook, model2, string, "weaponhook");
-/* refname   */ ATTRIB(Hook, netname, string, "hook");
-/* wepname   */ ATTRIB(Hook, m_name, string, _("Grappling Hook"));
-       ATTRIB(Hook, ammo_factor, float, 1);
-
-#define X(BEGIN, P, END, class, prefix) \
-       BEGIN(class) \
-               P(class, prefix, ammo, float, PRI) \
-               P(class, prefix, animtime, float, BOTH) \
-               P(class, prefix, damageforcescale, float, SEC) \
-               P(class, prefix, damage, float, SEC) \
-               P(class, prefix, duration, float, SEC) \
-               P(class, prefix, edgedamage, float, SEC) \
-               P(class, prefix, force, float, SEC) \
-               P(class, prefix, gravity, float, SEC) \
-               P(class, prefix, health, float, SEC) \
-               P(class, prefix, hooked_ammo, float, PRI) \
-               P(class, prefix, hooked_time_free, float, PRI) \
-               P(class, prefix, hooked_time_max, float, PRI) \
-               P(class, prefix, lifetime, float, SEC) \
-               P(class, prefix, power, float, SEC) \
-               P(class, prefix, radius, float, SEC) \
-               P(class, prefix, refire, float, BOTH) \
-               P(class, prefix, speed, float, SEC) \
-        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, Hook, hook)
-#undef X
-
-ENDCLASS(Hook)
-REGISTER_WEAPON(HOOK, hook, NEW(Hook));
-
-CLASS(OffhandHook, OffhandWeapon)
-#ifdef SVQC
-    METHOD(OffhandHook, offhand_think, void(OffhandHook this, entity actor, bool key_pressed))
-    {
-       Weapon wep = WEP_HOOK;
-       .entity weaponentity = weaponentities[1];
-       wep.wr_think(wep, actor, weaponentity, key_pressed ? 1 : 0);
-    }
-#endif
-ENDCLASS(OffhandHook)
-OffhandHook OFFHAND_HOOK; STATIC_INIT(OFFHAND_HOOK) { OFFHAND_HOOK = NEW(OffhandHook); }
-
-#ifdef SVQC
 
-.float dmg;
-.float dmg_edge;
-.float dmg_radius;
-.float dmg_force;
-.float dmg_power;
-.float dmg_duration;
-.float dmg_last;
-.float hook_refire;
-.float hook_time_hooked;
-.float hook_time_fueldecrease;
-#endif
-#endif
-#ifdef IMPLEMENTATION
 #ifdef SVQC
 
-spawnfunc(weapon_hook) { weapon_defaultspawnfunc(this, WEP_HOOK); }
-
 void W_Hook_ExplodeThink(entity this)
 {
        float dt, dmg_remaining_next, f;
 
        dt = time - this.teleport_time;
-       dmg_remaining_next = pow(bound(0, 1 - dt / this.dmg_duration, 1), this.dmg_power);
+       dmg_remaining_next = (bound(0, 1 - dt / this.dmg_duration, 1) ** this.dmg_power);
 
        f = this.dmg_last - dmg_remaining_next;
        this.dmg_last = dmg_remaining_next;
 
-       RadiusDamage(this, this.realowner, this.dmg * f, this.dmg_edge * f, this.dmg_radius, this.realowner, NULL, this.dmg_force * f, this.projectiledeathtype, NULL);
+       RadiusDamage(this, this.realowner, this.dmg * f, this.dmg_edge * f, this.dmg_radius, this.realowner, NULL, this.dmg_force * f, this.projectiledeathtype, this.weaponentity_fld, NULL);
        this.projectiledeathtype |= HITTYPE_BOUNCE;
        //RadiusDamage(this, NULL, this.dmg * f, this.dmg_edge * f, this.dmg_radius, NULL, NULL, this.dmg_force * f, this.projectiledeathtype, NULL);
 
@@ -124,7 +46,7 @@ void W_Hook_Explode2_use(entity this, entity actor, entity trigger)
        W_Hook_Explode2(this);
 }
 
-void W_Hook_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+void W_Hook_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
 {
        if(this.health <= 0)
                return;
@@ -147,7 +69,7 @@ void W_Hook_Touch2(entity this, entity toucher)
 void W_Hook_Attack2(Weapon thiswep, entity actor, .entity weaponentity)
 {
        //W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hook, ammo)); // WEAPONTODO: Figure out how to handle ammo with hook secondary (gravitybomb)
-       W_SetupShot(actor, weaponentity, false, 4, SND_HOOKBOMB_FIRE, CH_WEAPON_A, WEP_CVAR_SEC(hook, damage));
+       W_SetupShot(actor, weaponentity, false, 4, SND_HOOKBOMB_FIRE, CH_WEAPON_A, WEP_CVAR_SEC(hook, damage), WEP_HOOK.m_id | HITTYPE_SECONDARY);
 
        entity gren = new(hookbomb);
        gren.owner = gren.realowner = actor;
@@ -156,6 +78,7 @@ void W_Hook_Attack2(Weapon thiswep, entity actor, .entity weaponentity)
        set_movetype(gren, MOVETYPE_TOSS);
        PROJECTILE_MAKETRIGGER(gren);
        gren.projectiledeathtype = WEP_HOOK.m_id | HITTYPE_SECONDARY;
+       gren.weaponentity_fld = weaponentity;
        setorigin(gren, w_shotorg);
        setsize(gren, '0 0 0', '0 0 0');
 
@@ -252,7 +175,8 @@ METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity,
                     {
                         actor.ammo_fuel = 0;
                         actor.(weaponentity).hook_state |= HOOK_REMOVING;
-                        W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
+                        if(actor.(weaponentity).m_weapon != WEP_Null) // offhand
+                               W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
                     }
                 }
             }
@@ -395,8 +319,8 @@ void Draw_GrapplingHook(entity this)
                {
                        default:
                        case NET_ENT_CLIENT_HOOK:
-                               if(autocvar_chase_active > 0)
-                                       a = csqcplayer.origin;
+                               if(autocvar_chase_active)
+                                       a = csqcplayer.origin + csqcplayer.view_ofs;
                                else
                                        a = view_origin + view_forward * vs.x + view_right * -vs.y + view_up * vs.z;
                                b = this.origin;
@@ -501,8 +425,12 @@ void Remove_GrapplingHook(entity this)
 {
        sound (this, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM);
 
-       if(csqcplayer && csqcplayer.hook == this)
-               csqcplayer.hook = NULL;
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+       {
+               entity wep = viewmodels[slot];
+               if(wep.hook == this)
+                       wep.hook = NULL;
+       }
 }
 
 NET_HANDLE(ENT_CLIENT_HOOK, bool bIsNew)
@@ -578,5 +506,3 @@ NET_HANDLE(ENT_CLIENT_HOOK, bool bIsNew)
 
 // TODO: hook: temporarily transform this.origin for drawing the model along warpzones!
 #endif
-
-#endif