]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Attempt to make hook depend on weaponentity instead of the player
authorMario <mario@smbclan.net>
Thu, 29 Sep 2016 08:54:53 +0000 (18:54 +1000)
committerMario <mario@smbclan.net>
Thu, 29 Sep 2016 08:54:53 +0000 (18:54 +1000)
19 files changed:
qcsrc/common/mutators/mutator/breakablehook/sv_breakablehook.qc
qcsrc/common/mutators/mutator/nades/nades.qc
qcsrc/common/physics/player.qc
qcsrc/common/triggers/trigger/teleport.qc
qcsrc/common/vehicles/sv_vehicles.qc
qcsrc/common/vehicles/vehicle/bumblebee.qc
qcsrc/common/weapons/all.qc
qcsrc/common/weapons/all.qh
qcsrc/common/weapons/weapon/hook.qc
qcsrc/server/client.qc
qcsrc/server/g_damage.qc
qcsrc/server/g_hook.qc
qcsrc/server/g_hook.qh
qcsrc/server/miscfunctions.qc
qcsrc/server/player.qc
qcsrc/server/portals.qc
qcsrc/server/sv_main.qc
qcsrc/server/weapons/weaponsystem.qc
qcsrc/server/weapons/weaponsystem.qh

index fdb0dc38d1ee24161bfe30e83ca172c23d065f63..dfde6ed73b163be7c5bc3c30027d87b47f206793 100644 (file)
@@ -23,7 +23,7 @@ MUTATOR_HOOKFUNCTION(breakablehook, PlayerDamage_Calculate)
                if(DIFF_TEAM(frag_attacker, frag_target.realowner))
                {
                        Damage (frag_target.realowner, frag_attacker, frag_attacker, 5, WEP_HOOK.m_id | HITTYPE_SPLASH, frag_target.realowner.origin, '0 0 0');
                if(DIFF_TEAM(frag_attacker, frag_target.realowner))
                {
                        Damage (frag_target.realowner, frag_attacker, frag_attacker, 5, WEP_HOOK.m_id | HITTYPE_SPLASH, frag_target.realowner.origin, '0 0 0');
-                       RemoveGrapplingHook(frag_target.realowner);
+                       RemoveHook(frag_target);
                        return; // dead
                }
        }
                        return; // dead
                }
        }
index 02760045c3e89e68bd8f309ad80a3fba7fd7ca8c..d3487459828214576ca41f6c40b3532b3619c0a6 100644 (file)
@@ -736,7 +736,7 @@ void nade_boom(entity this)
 
        IL_EACH(g_projectiles, it.classname == "grapplinghook" && it.aiment == this,
        {
 
        IL_EACH(g_projectiles, it.classname == "grapplinghook" && it.aiment == this,
        {
-               RemoveGrapplingHook(it.realowner);
+               RemoveHook(it);
        });
 
        delete(this);
        });
 
        delete(this);
@@ -785,7 +785,7 @@ void nade_touch(entity this, entity toucher)
        {
                IL_EACH(g_projectiles, it.classname == "grapplinghook" && it.aiment == this,
                {
        {
                IL_EACH(g_projectiles, it.classname == "grapplinghook" && it.aiment == this,
                {
-                       RemoveGrapplingHook(it.realowner);
+                       RemoveHook(it);
                });
                delete(this);
                return;
                });
                delete(this);
                return;
index 4eb527d62adeddc73a870d334afab0c8ca42e9d2..5978fb6582fae6c7a5d6184f5eecfcaec8035645 100644 (file)
@@ -89,8 +89,15 @@ void PM_ClientMovement_UpdateStatus(entity this)
 
        // set crouched
        bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
 
        // set crouched
        bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
-       if(this.hook && !wasfreed(this.hook))
-               do_crouch = false;
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+       {
+               entity wep = viewmodels[slot];
+               if(wep.hook && !wasfreed(wep.hook))
+               {
+                       do_crouch = false;
+                       break; // don't bother checking the others
+               }
+       }
        if(this.waterlevel >= WATERLEVEL_SWIMMING)
                do_crouch = false;
        if(hud != HUD_NORMAL)
        if(this.waterlevel >= WATERLEVEL_SWIMMING)
                do_crouch = false;
        if(hud != HUD_NORMAL)
@@ -600,7 +607,12 @@ void PM_check_hitground(entity this)
     this.wasFlying = false;
     if (this.waterlevel >= WATERLEVEL_SWIMMING) return;
     if (time < this.ladder_time) return;
     this.wasFlying = false;
     if (this.waterlevel >= WATERLEVEL_SWIMMING) return;
     if (time < this.ladder_time) return;
-    if (this.hook) return;
+    for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+    {
+       .entity weaponentity = weaponentities[slot];
+       if(this.(weaponentity).hook)
+               return;
+    }
     this.nextstep = time + 0.3 + random() * 0.1;
     trace_dphitq3surfaceflags = 0;
     tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
     this.nextstep = time + 0.3 + random() * 0.1;
     trace_dphitq3surfaceflags = 0;
     tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
index c3de654609ff5e0db36ad1bf01e4b314b3283023..1fabc80a571514315c7c3469437741e8e03dbe6b 100644 (file)
@@ -43,7 +43,7 @@ void Teleport_Touch(entity this, entity toucher)
 
 #ifdef SVQC
        if(IS_PLAYER(toucher))
 
 #ifdef SVQC
        if(IS_PLAYER(toucher))
-               RemoveGrapplingHook(toucher);
+               RemoveGrapplingHooks(toucher);
 #endif
 
        entity e;
 #endif
 
        entity e;
index bcb06318692f476bd0a4e61b75c1a48d9c0e512c..75d2f4635889e0d78b04229fff77ad0a5794ccf3 100644 (file)
@@ -947,7 +947,7 @@ void vehicles_enter(entity pl, entity veh)
        }
        else return;
 
        }
        else return;
 
-       RemoveGrapplingHook(pl);
+       RemoveGrapplingHooks(pl);
 
        veh.vehicle_ammo1 = 0;
        veh.vehicle_ammo2 = 0;
 
        veh.vehicle_ammo1 = 0;
        veh.vehicle_ammo2 = 0;
@@ -1109,7 +1109,15 @@ void vehicles_spawn(entity this)
        if(this.vehicle_controller)
                this.team = this.vehicle_controller.team;
 
        if(this.vehicle_controller)
                this.team = this.vehicle_controller.team;
 
-       FOREACH_CLIENT(IS_PLAYER(it) && it.hook.aiment == this, RemoveGrapplingHook(it));
+       FOREACH_CLIENT(IS_PLAYER(it),
+       {
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+           {
+               .entity weaponentity = weaponentities[slot];
+               if(it.(weaponentity).hook.aiment == this)
+                       RemoveHook(it.(weaponentity).hook);
+           }
+       });
 
        vehicles_reset_colors(this);
 
 
        vehicles_reset_colors(this);
 
index 4f74c86369f7b48cd667caf48801923cbb0bcf16..7bc10b4ecd2b31bb0a1bcae4e75c905fa309688d 100644 (file)
@@ -309,7 +309,7 @@ bool bumblebee_gunner_enter(entity this, entity player)
        player.vehicle_energy   = vehic.vehicle_energy;
        UNSET_ONGROUND(player);
 
        player.vehicle_energy   = vehic.vehicle_energy;
        UNSET_ONGROUND(player);
 
-       RemoveGrapplingHook(player);
+       RemoveGrapplingHooks(player);
 
        for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
        {
 
        for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
        {
index 99b232730a26104acd4be494bc33f7cb4fde93ad..d2acab1a040752da72e5237ce14c11b0aea77645 100644 (file)
@@ -523,7 +523,9 @@ void CL_WeaponEntity_SetModel(entity this, string name, bool _anim)
 
        if (this.movedir.x >= 0)
        {
 
        if (this.movedir.x >= 0)
        {
-               int algn = STAT(GUNALIGN, this.owner);
+               //int algn = STAT(GUNALIGN, this.owner);
+               int algn = W_GunAlign(this, STAT(GUNALIGN, this.owner));
+               this.m_gunalign = algn;
                vector v = this.movedir;
                this.movedir = shotorg_adjust(v, false, false, algn);
                this.view_ofs = shotorg_adjust(v, false, true, algn) - v;
                vector v = this.movedir;
                this.movedir = shotorg_adjust(v, false, false, algn);
                this.view_ofs = shotorg_adjust(v, false, true, algn) - v;
index 90cbe28db5c6e801f2317e3b5c69ccff823232af..12e26ac4e2bcf328490a1fc36094cf9a5f72983e 100644 (file)
@@ -339,6 +339,8 @@ vector weaponentity_glowmod(Weapon wep, entity actor, int c)
 entity gunaligns[5];
 #endif
 
 entity gunaligns[5];
 #endif
 
+.int m_gunalign;
+
 //.int weapon; // current weapon
 .string weaponname; // name of .weapon
 
 //.int weapon; // current weapon
 .string weaponname; // name of .weapon
 
index 2b322f76031f931dd5128e35f03d2191ae7d204e..c24db6583e6a25c06a8a63c18610155db08079a3 100644 (file)
@@ -191,19 +191,19 @@ void W_Hook_Attack2(Weapon thiswep, entity actor, .entity weaponentity)
 METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
 {
     if (fire & 1) {
 METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
 {
     if (fire & 1) {
-        if(!actor.hook)
-        if(!(actor.hook_state & HOOK_WAITING_FOR_RELEASE))
-        if(time > actor.hook_refire)
+        if(!actor.(weaponentity).hook)
+        if(!(actor.(weaponentity).hook_state & HOOK_WAITING_FOR_RELEASE))
+        if(time > actor.(weaponentity).hook_refire)
         if(weapon_prepareattack(thiswep, actor, weaponentity, false, -1))
         {
             W_DecreaseAmmo(thiswep, actor, thiswep.ammo_factor * WEP_CVAR_PRI(hook, ammo), weaponentity);
         if(weapon_prepareattack(thiswep, actor, weaponentity, false, -1))
         {
             W_DecreaseAmmo(thiswep, actor, thiswep.ammo_factor * WEP_CVAR_PRI(hook, ammo), weaponentity);
-            actor.hook_state |= HOOK_FIRING;
-            actor.hook_state |= HOOK_WAITING_FOR_RELEASE;
+            actor.(weaponentity).hook_state |= HOOK_FIRING;
+            actor.(weaponentity).hook_state |= HOOK_WAITING_FOR_RELEASE;
             weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hook, animtime), w_ready);
         }
     } else {
             weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hook, animtime), w_ready);
         }
     } else {
-        actor.hook_state |= HOOK_REMOVING;
-        actor.hook_state &= ~HOOK_WAITING_FOR_RELEASE;
+        actor.(weaponentity).hook_state |= HOOK_REMOVING;
+        actor.(weaponentity).hook_state &= ~HOOK_WAITING_FOR_RELEASE;
     }
 
     if(fire & 2)
     }
 
     if(fire & 2)
@@ -215,42 +215,42 @@ METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity,
         }
     }
 
         }
     }
 
-    if(actor.hook)
+    if(actor.(weaponentity).hook)
     {
         // if hooked, no bombs, and increase the timer
     {
         // if hooked, no bombs, and increase the timer
-        actor.hook_refire = max(actor.hook_refire, time + WEP_CVAR_PRI(hook, refire) * W_WeaponRateFactor(actor));
+        actor.(weaponentity).hook_refire = max(actor.(weaponentity).hook_refire, time + WEP_CVAR_PRI(hook, refire) * W_WeaponRateFactor(actor));
 
         // hook also inhibits health regeneration, but only for 1 second
         if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
             actor.pauseregen_finished = max(actor.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen);
     }
 
 
         // hook also inhibits health regeneration, but only for 1 second
         if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
             actor.pauseregen_finished = max(actor.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen);
     }
 
-    if(actor.hook && actor.hook.state == 1)
+    if(actor.(weaponentity).hook && actor.(weaponentity).hook.state == 1)
     {
         float hooked_time_max = WEP_CVAR_PRI(hook, hooked_time_max);
         if(hooked_time_max > 0)
         {
     {
         float hooked_time_max = WEP_CVAR_PRI(hook, hooked_time_max);
         if(hooked_time_max > 0)
         {
-            if( time > actor.hook_time_hooked + hooked_time_max )
-                actor.hook_state |= HOOK_REMOVING;
+            if( time > actor.(weaponentity).hook_time_hooked + hooked_time_max )
+                actor.(weaponentity).hook_state |= HOOK_REMOVING;
         }
 
         float hooked_fuel = thiswep.ammo_factor * WEP_CVAR_PRI(hook, hooked_ammo);
         if(hooked_fuel > 0)
         {
         }
 
         float hooked_fuel = thiswep.ammo_factor * WEP_CVAR_PRI(hook, hooked_ammo);
         if(hooked_fuel > 0)
         {
-            if( time > actor.hook_time_fueldecrease )
+            if( time > actor.(weaponentity).hook_time_fueldecrease )
             {
                 if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
                 {
             {
                 if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
                 {
-                    if( actor.ammo_fuel >= (time - actor.hook_time_fueldecrease) * hooked_fuel )
+                    if( actor.ammo_fuel >= (time - actor.(weaponentity).hook_time_fueldecrease) * hooked_fuel )
                     {
                     {
-                        W_DecreaseAmmo(thiswep, actor, (time - actor.hook_time_fueldecrease) * hooked_fuel, weaponentity);
-                        actor.hook_time_fueldecrease = time;
+                        W_DecreaseAmmo(thiswep, actor, (time - actor.(weaponentity).hook_time_fueldecrease) * hooked_fuel, weaponentity);
+                        actor.(weaponentity).hook_time_fueldecrease = time;
                         // decrease next frame again
                     }
                     else
                     {
                         actor.ammo_fuel = 0;
                         // decrease next frame again
                     }
                     else
                     {
                         actor.ammo_fuel = 0;
-                        actor.hook_state |= HOOK_REMOVING;
+                        actor.(weaponentity).hook_state |= HOOK_REMOVING;
                         W_SwitchWeapon_Force(actor, w_getbestweapon(actor), weaponentity);
                     }
                 }
                         W_SwitchWeapon_Force(actor, w_getbestweapon(actor), weaponentity);
                     }
                 }
@@ -259,38 +259,46 @@ METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity,
     }
     else
     {
     }
     else
     {
-        actor.hook_time_hooked = time;
-        actor.hook_time_fueldecrease = time + WEP_CVAR_PRI(hook, hooked_time_free);
+        actor.(weaponentity).hook_time_hooked = time;
+        actor.(weaponentity).hook_time_fueldecrease = time + WEP_CVAR_PRI(hook, hooked_time_free);
     }
 
     }
 
-    actor.hook_state = BITSET(actor.hook_state, HOOK_PULLING, (!PHYS_INPUT_BUTTON_CROUCH(actor) || !autocvar_g_balance_grapplehook_crouchslide));
+    actor.(weaponentity).hook_state = BITSET(actor.(weaponentity).hook_state, HOOK_PULLING, (!PHYS_INPUT_BUTTON_CROUCH(actor) || !autocvar_g_balance_grapplehook_crouchslide));
 
 
-    if (actor.hook_state & HOOK_FIRING)
+    if (actor.(weaponentity).hook_state & HOOK_FIRING)
     {
     {
-        if (actor.hook)
-            RemoveGrapplingHook(actor);
-        FireGrapplingHook(actor);
-        actor.hook_state &= ~HOOK_FIRING;
-        actor.hook_refire = max(actor.hook_refire, time + autocvar_g_balance_grapplehook_refire * W_WeaponRateFactor(actor));
+        if (actor.(weaponentity).hook)
+            RemoveHook(actor.(weaponentity).hook);
+        FireGrapplingHook(actor, weaponentity);
+        actor.(weaponentity).hook_state &= ~HOOK_FIRING;
+        actor.(weaponentity).hook_refire = max(actor.(weaponentity).hook_refire, time + autocvar_g_balance_grapplehook_refire * W_WeaponRateFactor(actor));
     }
     }
-    else if (actor.hook_state & HOOK_REMOVING)
+    else if (actor.(weaponentity).hook_state & HOOK_REMOVING)
     {
     {
-        if (actor.hook)
-            RemoveGrapplingHook(actor);
-        actor.hook_state &= ~HOOK_REMOVING;
+        if (actor.(weaponentity).hook)
+            RemoveHook(actor.(weaponentity).hook);
+        actor.(weaponentity).hook_state &= ~HOOK_REMOVING;
     }
 }
 METHOD(Hook, wr_setup, void(entity thiswep, entity actor))
 {
     }
 }
 METHOD(Hook, wr_setup, void(entity thiswep, entity actor))
 {
-    actor.hook_state &= ~HOOK_WAITING_FOR_RELEASE;
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+    {
+       .entity weaponentity = weaponentities[slot];
+       actor.(weaponentity).hook_state &= ~HOOK_WAITING_FOR_RELEASE;
+    }
 }
 METHOD(Hook, wr_checkammo1, bool(Hook thiswep, entity actor))
 {
     if (!thiswep.ammo_factor) return true;
 }
 METHOD(Hook, wr_checkammo1, bool(Hook thiswep, entity actor))
 {
     if (!thiswep.ammo_factor) return true;
-    if(actor.hook)
-        return actor.ammo_fuel > 0;
-    else
-        return actor.ammo_fuel >= WEP_CVAR_PRI(hook, ammo);
+    for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+    {
+       .entity weaponentity = weaponentities[slot];
+       if(actor.(weaponentity).hook)
+               return actor.ammo_fuel > 0;
+    }
+
+    return actor.ammo_fuel >= WEP_CVAR_PRI(hook, ammo);
 }
 METHOD(Hook, wr_checkammo2, bool(Hook thiswep, entity actor))
 {
 }
 METHOD(Hook, wr_checkammo2, bool(Hook thiswep, entity actor))
 {
@@ -299,9 +307,13 @@ METHOD(Hook, wr_checkammo2, bool(Hook thiswep, entity actor))
 }
 METHOD(Hook, wr_resetplayer, void(entity thiswep, entity actor))
 {
 }
 METHOD(Hook, wr_resetplayer, void(entity thiswep, entity actor))
 {
-    RemoveGrapplingHook(actor);
-    actor.hook_time = 0;
-    actor.hook_refire = time;
+    RemoveGrapplingHooks(actor);
+    for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+    {
+       .entity weaponentity = weaponentities[slot];
+       actor.(weaponentity).hook_time = 0;
+       actor.(weaponentity).hook_refire = time;
+    }
 }
 METHOD(Hook, wr_killmessage, Notification(entity thiswep))
 {
 }
 METHOD(Hook, wr_killmessage, Notification(entity thiswep))
 {
@@ -510,10 +522,12 @@ NET_HANDLE(ENT_CLIENT_HOOK, bool bIsNew)
        if(sf & 1)
        {
                int myowner = ReadByte();
        if(sf & 1)
        {
                int myowner = ReadByte();
+               int slot = ReadByte();
                this.owner = playerslots[myowner - 1];
                this.sv_entnum = myowner;
                this.owner = playerslots[myowner - 1];
                this.sv_entnum = myowner;
-               if(csqcplayer && myowner == player_localentnum)
-                       csqcplayer.hook = this;
+               if(myowner == player_localentnum)
+                       viewmodels[slot].hook = this;
+               this.cnt = slot;
                switch(this.HookType)
                {
                        default:
                switch(this.HookType)
                {
                        default:
index ddb23f0b13d859962e48ad6b3997f6f49e20ee7a..d6805263ce9c3d9ffdd955dc50185bcde9cc44ba 100644 (file)
@@ -257,7 +257,7 @@ void PutObserverInServer(entity this)
         this.view_ofs = '0 0 0';
     }
 
         this.view_ofs = '0 0 0';
     }
 
-    RemoveGrapplingHook(this);
+    RemoveGrapplingHooks(this);
        Portal_ClearAll(this);
        Unfreeze(this);
        SetSpectatee(this, NULL);
        Portal_ClearAll(this);
        Unfreeze(this);
        SetSpectatee(this, NULL);
@@ -334,7 +334,6 @@ void PutObserverInServer(entity this)
        this.istypefrag = 0;
        setthink(this, func_null);
        this.nextthink = 0;
        this.istypefrag = 0;
        setthink(this, func_null);
        this.nextthink = 0;
-       this.hook_time = 0;
        this.deadflag = DEAD_NO;
        this.crouch = false;
        this.revival_time = 0;
        this.deadflag = DEAD_NO;
        this.crouch = false;
        this.revival_time = 0;
@@ -346,6 +345,7 @@ void PutObserverInServer(entity this)
        this.weaponmodel = "";
        for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
        {
        this.weaponmodel = "";
        for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
        {
+               this.weaponentities[slot].hook_time = 0;
                this.weaponentities[slot].weaponname = "";
                this.weaponentities[slot] = NULL;
        }
                this.weaponentities[slot].weaponname = "";
                this.weaponentities[slot] = NULL;
        }
@@ -695,10 +695,10 @@ void PutClientInServer(entity this)
                for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
                {
                        .entity weaponentity = weaponentities[slot];
                for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
                {
                        .entity weaponentity = weaponentities[slot];
-                       //if(slot == 0)
+                       if(slot == 0)
                                this.(weaponentity).m_switchweapon = w_getbestweapon(this);
                                this.(weaponentity).m_switchweapon = w_getbestweapon(this);
-                       //else
-                               //this.(weaponentity).m_switchweapon = WEP_Null;
+                       else
+                               this.(weaponentity).m_switchweapon = WEP_Null;
                        this.(weaponentity).weaponname = "";
                        this.(weaponentity).m_switchingweapon = WEP_Null;
                        this.cnt = -1;
                        this.(weaponentity).weaponname = "";
                        this.(weaponentity).m_switchingweapon = WEP_Null;
                        this.cnt = -1;
@@ -1254,7 +1254,7 @@ void ClientDisconnect(entity this)
 
        Unfreeze(this);
 
 
        Unfreeze(this);
 
-       RemoveGrapplingHook(this);
+       RemoveGrapplingHooks(this);
 
        // Here, everything has been done that requires this player to be a client.
 
 
        // Here, everything has been done that requires this player to be a client.
 
index 6851f7cdfe3bb78af48a2a31dfe467aee8729528..fd8e89c9f71bff9cf035ecbe13960e56a64fe100 100644 (file)
@@ -561,9 +561,17 @@ void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypo
 
        Ice_Think(ice);
 
 
        Ice_Think(ice);
 
-       RemoveGrapplingHook(targ);
+       RemoveGrapplingHooks(targ);
 
 
-       FOREACH_CLIENT(IS_PLAYER(it) && it.hook.aiment == targ, LAMBDA(RemoveGrapplingHook(it)));
+       FOREACH_CLIENT(IS_PLAYER(it),
+       {
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+           {
+               .entity weaponentity = weaponentities[slot];
+               if(it.(weaponentity).hook.aiment == targ)
+                       RemoveHook(it.(weaponentity).hook);
+           }
+       });
 
        // add waypoint
        if(show_waypoint)
 
        // add waypoint
        if(show_waypoint)
@@ -590,7 +598,15 @@ void Unfreeze (entity targ)
 
        WaypointSprite_Kill(targ.waypointsprite_attached);
 
 
        WaypointSprite_Kill(targ.waypointsprite_attached);
 
-       FOREACH_CLIENT(IS_PLAYER(it) && it.hook.aiment == targ, LAMBDA(RemoveGrapplingHook(it)));
+       FOREACH_CLIENT(IS_PLAYER(it),
+       {
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+           {
+               .entity weaponentity = weaponentities[slot];
+               if(it.(weaponentity).hook.aiment == targ)
+                       RemoveHook(it.(weaponentity).hook);
+           }
+       });
 
        // remove the ice block
        if(targ.iceblock)
 
        // remove the ice block
        if(targ.iceblock)
@@ -616,10 +632,14 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
        attacker_save = attacker;
 
        if(IS_PLAYER(targ))
        attacker_save = attacker;
 
        if(IS_PLAYER(targ))
-               if(targ.hook)
-                       if(targ.hook.aiment)
-                               if(targ.hook.aiment == attacker)
-                                       RemoveGrapplingHook(targ); // STOP THAT, you parasite!
+       {
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+           {
+               .entity weaponentity = weaponentities[slot];
+               if(targ.(weaponentity).hook && targ.(weaponentity).hook.aiment == attacker)
+                       RemoveHook(targ.(weaponentity).hook);
+           }
+       }
 
        // special rule: gravity bomb does not hit team mates (other than for disconnecting the hook)
        if(DEATH_ISWEAPON(deathtype, WEP_HOOK) || DEATH_ISWEAPON(deathtype, WEP_TUBA))
 
        // special rule: gravity bomb does not hit team mates (other than for disconnecting the hook)
        if(DEATH_ISWEAPON(deathtype, WEP_HOOK) || DEATH_ISWEAPON(deathtype, WEP_TUBA))
index 92d6ccac4140b2a34fb707b82ae2533f55e0dab9..636e8c6aae99670ab355a0c24354c4a4c79291f3 100644 (file)
@@ -70,24 +70,41 @@ And you should be done!
 
 .float hook_length;
 
 
 .float hook_length;
 
-void RemoveGrapplingHook(entity pl)
+void RemoveGrapplingHooks(entity pl)
 {
 {
-       if(pl.hook == NULL)
-               return;
-       delete(pl.hook);
-       pl.hook = NULL;
        if(pl.move_movetype == MOVETYPE_FLY)
                set_movetype(pl, MOVETYPE_WALK);
 
        if(pl.move_movetype == MOVETYPE_FLY)
                set_movetype(pl, MOVETYPE_WALK);
 
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+    {
+       .entity weaponentity = weaponentities[slot];
+       if(pl.(weaponentity).hook)
+       {
+               delete(pl.(weaponentity).hook);
+               pl.(weaponentity).hook = NULL;
+       }
+    }
+
        //pl.disableclientprediction = false;
 }
 
        //pl.disableclientprediction = false;
 }
 
+void RemoveHook(entity this)
+{
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+    {
+       .entity weaponentity = weaponentities[slot];
+       if(this.realowner.(weaponentity).hook == this)
+               this.realowner.(weaponentity).hook = NULL;
+    }
+
+    if(this.realowner.move_movetype == MOVETYPE_FLY)
+       set_movetype(this.realowner, MOVETYPE_WALK);
+    delete(this);
+}
+
 void GrapplingHookReset(entity this)
 {
 void GrapplingHookReset(entity this)
 {
-       if(this.realowner.hook == this)
-               RemoveGrapplingHook(this.owner);
-       else // in any case:
-               delete(this);
+       RemoveHook(this);
 }
 
 void GrapplingHookThink(entity this);
 }
 
 void GrapplingHookThink(entity this);
@@ -116,6 +133,7 @@ bool GrapplingHookSend(entity this, entity to, int sf)
        if(sf & 1)
        {
                WriteByte(MSG_ENTITY, etof(this.realowner));
        if(sf & 1)
        {
                WriteByte(MSG_ENTITY, etof(this.realowner));
+               WriteByte(MSG_ENTITY, weaponslot(this.weaponentity_fld));
        }
        if(sf & 2)
        {
        }
        if(sf & 2)
        {
@@ -138,14 +156,15 @@ void GrapplingHookThink(entity this)
 {
        float spd, dist, minlength, pullspeed, ropestretch, ropeairfriction, rubberforce, newlength, rubberforce_overstretch;
        vector dir, org, end, v0, dv, v, myorg, vs;
 {
        float spd, dist, minlength, pullspeed, ropestretch, ropeairfriction, rubberforce, newlength, rubberforce_overstretch;
        vector dir, org, end, v0, dv, v, myorg, vs;
-       if(this.realowner.hook != this) // how did that happen?
+       .entity weaponentity = this.weaponentity_fld;
+       if(this.realowner.(weaponentity).hook != this)  // how did that happen?
        {
                error("Owner lost the hook!\n");
                return;
        }
        if(LostMovetypeFollow(this) || intermission_running || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || ((this.aiment.flags & FL_PROJECTILE) && this.aiment.classname != "nade"))
        {
        {
                error("Owner lost the hook!\n");
                return;
        }
        if(LostMovetypeFollow(this) || intermission_running || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || ((this.aiment.flags & FL_PROJECTILE) && this.aiment.classname != "nade"))
        {
-               RemoveGrapplingHook(this.realowner);
+               RemoveHook(this);
                return;
        }
        if(this.aiment)
                return;
        }
        if(this.aiment)
@@ -153,7 +172,7 @@ void GrapplingHookThink(entity this)
 
        this.nextthink = time;
 
 
        this.nextthink = time;
 
-       int s = W_GunAlign(this.realowner, STAT(GUNALIGN, this.realowner));
+       int s = W_GunAlign(this.realowner.(weaponentity), STAT(GUNALIGN, this.realowner));
        vs = hook_shotorigin[s];
 
        makevectors(this.realowner.v_angle);
        vs = hook_shotorigin[s];
 
        makevectors(this.realowner.v_angle);
@@ -205,7 +224,7 @@ void GrapplingHookThink(entity this)
                        v = v0 = WarpZone_RefSys_TransformVelocity(pull_entity, this, pull_entity.velocity);
 
                        // first pull the rope...
                        v = v0 = WarpZone_RefSys_TransformVelocity(pull_entity, this, pull_entity.velocity);
 
                        // first pull the rope...
-                       if(this.realowner.hook_state & HOOK_PULLING)
+                       if(this.realowner.(weaponentity).hook_state & HOOK_PULLING)
                        {
                                newlength = this.hook_length;
                                newlength = max(newlength - pullspeed * frametime, minlength);
                        {
                                newlength = this.hook_length;
                                newlength = max(newlength - pullspeed * frametime, minlength);
@@ -223,7 +242,7 @@ void GrapplingHookThink(entity this)
                        if(pull_entity.move_movetype == MOVETYPE_FLY)
                                set_movetype(pull_entity, MOVETYPE_WALK);
 
                        if(pull_entity.move_movetype == MOVETYPE_FLY)
                                set_movetype(pull_entity, MOVETYPE_WALK);
 
-                       if(this.realowner.hook_state & HOOK_RELEASING)
+                       if(this.realowner.(weaponentity).hook_state & HOOK_RELEASING)
                        {
                                newlength = dist;
                                this.hook_length = newlength;
                        {
                                newlength = dist;
                                this.hook_length = newlength;
@@ -265,7 +284,7 @@ void GrapplingHookThink(entity this)
 
                        if(frozen_pulling && autocvar_g_balance_grapplehook_pull_frozen == 2 && !STAT(FROZEN, this.aiment))
                        {
 
                        if(frozen_pulling && autocvar_g_balance_grapplehook_pull_frozen == 2 && !STAT(FROZEN, this.aiment))
                        {
-                               RemoveGrapplingHook(this.realowner);
+                               RemoveHook(this);
                                return;
                        }
                }
                                return;
                        }
                }
@@ -337,11 +356,11 @@ void GrapplingHook_Damage(entity this, entity inflictor, entity attacker, float
                        this.realowner.pushltime = time + autocvar_g_maxpushtime;
                        this.realowner.istypefrag = PHYS_INPUT_BUTTON_CHAT(this.realowner);
                }
                        this.realowner.pushltime = time + autocvar_g_maxpushtime;
                        this.realowner.istypefrag = PHYS_INPUT_BUTTON_CHAT(this.realowner);
                }
-               RemoveGrapplingHook(this.realowner);
+               RemoveHook(this);
        }
 }
 
        }
 }
 
-void FireGrapplingHook(entity actor)
+void FireGrapplingHook(entity actor, .entity weaponentity)
 {
        entity missile;
        vector org;
 {
        entity missile;
        vector org;
@@ -352,7 +371,7 @@ void FireGrapplingHook(entity actor)
 
        makevectors(actor.v_angle);
 
 
        makevectors(actor.v_angle);
 
-       int s = W_GunAlign(actor, STAT(GUNALIGN, actor));
+       int s = W_GunAlign(actor.(weaponentity), STAT(GUNALIGN, actor));
        vs = hook_shotorigin[s];
 
        // UGLY WORKAROUND: play this on CH_WEAPON_B so it can't cut off fire sounds
        vs = hook_shotorigin[s];
 
        // UGLY WORKAROUND: play this on CH_WEAPON_B so it can't cut off fire sounds
@@ -366,7 +385,8 @@ void FireGrapplingHook(entity actor)
 
        missile = WarpZone_RefSys_SpawnSameRefSys(actor);
        missile.owner = missile.realowner = actor;
 
        missile = WarpZone_RefSys_SpawnSameRefSys(actor);
        missile.owner = missile.realowner = actor;
-       actor.hook = missile;
+       actor.(weaponentity).hook = missile;
+       missile.weaponentity_fld = weaponentity;
        missile.reset = GrapplingHookReset;
        missile.classname = "grapplinghook";
        missile.flags = FL_PROJECTILE;
        missile.reset = GrapplingHookReset;
        missile.classname = "grapplinghook";
        missile.flags = FL_PROJECTILE;
index 900c23d36abac3eb9ce8dfb5edf0c1a8681c6bf3..719bf5b605bdbfc1832761610f0f0ac8a3c88670 100644 (file)
@@ -2,7 +2,8 @@
 
 // Wazat's grappling hook
 .entity                hook;
 
 // Wazat's grappling hook
 .entity                hook;
-void RemoveGrapplingHook(entity pl);
+void RemoveGrapplingHooks(entity pl);
+void RemoveHook(entity this);
 // (note: you can change the hook impulse #'s to whatever you please)
 .float hook_time;
 
 // (note: you can change the hook impulse #'s to whatever you please)
 .float hook_time;
 
index d38eedaf3412010935be0cdbb5a09528ed28d081..2914ca2deee09cb6430f8222f51344afa9b4e2db 100644 (file)
@@ -1076,7 +1076,7 @@ bool WarpZone_Projectile_Touch_ImpactFilter_Callback(entity this, entity toucher
                if(this.classname == "nade")
                        return false; // no checks here
                else if(this.classname == "grapplinghook")
                if(this.classname == "nade")
                        return false; // no checks here
                else if(this.classname == "grapplinghook")
-                       RemoveGrapplingHook(this.realowner);
+                       RemoveHook(this);
                else if(this.classname == "spike")
                {
                        W_Crylink_Dequeue(this);
                else if(this.classname == "spike")
                {
                        W_Crylink_Dequeue(this);
index 6bfee14b2ca9ded3f884c3f3763a0f2097d9dcc2..8b44e39cacfb39f994f8984fc078aa04f3b192f1 100644 (file)
@@ -563,14 +563,13 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                excess = M_ARGV(4, float);
 
                Weapon wep = this.(weaponentity).m_weapon;
                excess = M_ARGV(4, float);
 
                Weapon wep = this.(weaponentity).m_weapon;
-               /*for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
                {
                        .entity weaponentity = weaponentities[slot];
                        wep.wr_playerdeath(wep, this, weaponentity);
                {
                        .entity weaponentity = weaponentities[slot];
                        wep.wr_playerdeath(wep, this, weaponentity);
-               }*/
-               wep.wr_playerdeath(wep, this, weaponentity);
+               }
 
 
-               RemoveGrapplingHook(this);
+               RemoveGrapplingHooks(this);
 
                Portal_ClearAllLater(this);
 
 
                Portal_ClearAllLater(this);
 
index 12083e423cb573b940c3c82c9453450447f6c096..b41c53bbcce4eed3dcd541f25fd738ebfb750fae 100644 (file)
@@ -481,8 +481,12 @@ void Portal_Think(entity this)
                if(it != o || time >= this.portal_activatetime)
                        Portal_Think_TryTeleportPlayer(this, it, g);
 
                if(it != o || time >= this.portal_activatetime)
                        Portal_Think_TryTeleportPlayer(this, it, g);
 
-               if(it.hook)
-                       Portal_Think_TryTeleportPlayer(this, it.hook, g);
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+           {
+               .entity weaponentity = weaponentities[slot];
+               if(it.(weaponentity).hook)
+                       Portal_Think_TryTeleportPlayer(this, it.(weaponentity).hook, g);
+           }
        ));
        this.solid = SOLID_TRIGGER;
        this.aiment = o;
        ));
        this.solid = SOLID_TRIGGER;
        this.aiment = o;
index ea11ea36a613f25ffb8c3f9915c8fa3dbf9c58f0..ccc309be64703b6e32047297ec678a480edbdf68 100644 (file)
@@ -99,7 +99,17 @@ void CreatureFrame_FallDamage(entity this)
        {
                // check for falling damage
                float velocity_len = vlen(this.velocity);
        {
                // check for falling damage
                float velocity_len = vlen(this.velocity);
-               if(!this.hook.state)
+               bool have_hook = false;
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+           {
+               .entity weaponentity = weaponentities[slot];
+               if(this.(weaponentity).hook && this.(weaponentity).hook.state)
+               {
+                       have_hook = true;
+                       break;
+               }
+           }
+               if(!have_hook)
                {
                        float dm = vlen(this.oldvelocity) - velocity_len; // dm is now the velocity DECREASE. Velocity INCREASE should never cause a sound or any damage.
                        if (IS_DEAD(this))
                {
                        float dm = vlen(this.oldvelocity) - velocity_len; // dm is now the velocity DECREASE. Velocity INCREASE should never cause a sound or any damage.
                        if (IS_DEAD(this))
index 45838350018d2fc87d774dca1131a0696845e2e1..0dffe0289439079d6a3fb0c7d977625e2cb60eb0 100644 (file)
@@ -60,7 +60,6 @@ vector CL_Weapon_GetShotOrg(int wpn)
        return ret;
 }
 
        return ret;
 }
 
-..entity weaponentity_fld;
 .float m_alpha;
 .string w_weaponname;
 .int w_dmg;
 .float m_alpha;
 .string w_weaponname;
 .int w_dmg;
@@ -317,7 +316,7 @@ void weapon_prepareattack_do(entity actor, .entity weaponentity, bool secondary,
                }
                ATTACK_FINISHED(actor, slot) = ATTACK_FINISHED(actor, slot) + attacktime * W_WeaponRateFactor(actor);
        }
                }
                ATTACK_FINISHED(actor, slot) = ATTACK_FINISHED(actor, slot) + attacktime * W_WeaponRateFactor(actor);
        }
-       actor.(weaponentity).bulletcounter += 1;
+       this.bulletcounter += 1;
        // dprint("attack finished ", ftos(ATTACK_FINISHED(actor, slot)), "\n");
 }
 
        // dprint("attack finished ", ftos(ATTACK_FINISHED(actor, slot)), "\n");
 }
 
index bdc261d8e601578b885a9ee9023f4ddf98c55b75..389a52bcc4e91e0f313271a3a8f03f6b317e1592 100644 (file)
@@ -4,6 +4,8 @@ float internalteam;
 float weaponswapping;
 entity weapon_dropevent_item;
 
 float weaponswapping;
 entity weapon_dropevent_item;
 
+..entity weaponentity_fld;
+
 void CL_SpawnWeaponentity(entity e, .entity weaponentity);
 
 vector CL_Weapon_GetShotOrg(float wpn);
 void CL_SpawnWeaponentity(entity e, .entity weaponentity);
 
 vector CL_Weapon_GetShotOrg(float wpn);