#include "../common/vehicles/all.qh"
#include "../common/constants.qh"
#include "../common/util.qh"
+#include <common/net_linked.qh>
#include <common/weapons/_all.qh>
#include "../lib/warpzone/common.qh"
#include "../lib/warpzone/server.qh"
.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);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(!pl.(weaponentity))
+ continue; // continue incase other slots exist?
+ if(pl.(weaponentity).hook)
+ delete(pl.(weaponentity).hook);
+ pl.(weaponentity).hook = NULL;
+ }
+
//pl.disableclientprediction = false;
}
+void RemoveHook(entity this)
+{
+ entity player = this.realowner;
+ .entity weaponentity = this.weaponentity_fld;
+
+ if(player.(weaponentity).hook == this)
+ player.(weaponentity).hook = NULL;
+
+ if(player.move_movetype == MOVETYPE_FLY)
+ set_movetype(player, MOVETYPE_WALK);
+ delete(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);
if(sf & 1)
{
WriteByte(MSG_ENTITY, etof(this.realowner));
+ WriteByte(MSG_ENTITY, weaponslot(this.weaponentity_fld));
}
if(sf & 2)
{
{
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"))
+ if(LostMovetypeFollow(this) || game_stopped || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || ((this.aiment.flags & FL_PROJECTILE) && this.aiment.classname != "nade"))
{
- RemoveGrapplingHook(this.realowner);
+ RemoveHook(this);
return;
}
if(this.aiment)
this.nextthink = time;
- int s = W_GetGunAlignment(this.realowner);
+ int s = W_GunAlign(this.realowner.(weaponentity), STAT(GUNALIGN, this.realowner)) - 1;
vs = hook_shotorigin[s];
makevectors(this.realowner.v_angle);
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);
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;
if(frozen_pulling && autocvar_g_balance_grapplehook_pull_frozen == 2 && !STAT(FROZEN, this.aiment))
{
- RemoveGrapplingHook(this.realowner);
+ RemoveHook(this);
return;
}
}
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;
- vector vs;
-
if(forbidWeaponUse(actor)) return;
if(actor.vehicle) return;
makevectors(actor.v_angle);
- int s = W_GetGunAlignment(actor);
- vs = hook_shotorigin[s];
+ int s = W_GunAlign(actor.(weaponentity), STAT(GUNALIGN, actor)) - 1;
+ vector vs = hook_shotorigin[s];
// UGLY WORKAROUND: play this on CH_WEAPON_B so it can't cut off fire sounds
sound (actor, CH_WEAPON_B, SND_HOOK_FIRE, VOL_BASE, ATTEN_NORM);
- org = actor.origin + actor.view_ofs + v_forward * vs.x + v_right * -vs.y + v_up * vs.z;
+ vector org = actor.origin + actor.view_ofs + v_forward * vs.x + v_right * -vs.y + v_up * vs.z;
tracebox(actor.origin + actor.view_ofs, '-3 -3 -3', '3 3 3', org, MOVE_NORMAL, actor);
org = trace_endpos;
Send_Effect(EFFECT_HOOK_MUZZLEFLASH, org, '0 0 0', 1);
- missile = WarpZone_RefSys_SpawnSameRefSys(actor);
+ entity 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.takedamage = DAMAGE_AIM;
missile.damageforcescale = 0;
missile.damagedbycontents = (autocvar_g_balance_grapplehook_damagedbycontents);
+ if(missile.damagedbycontents)
+ IL_PUSH(g_damagedbycontents, missile);
missile.hook_start = missile.hook_end = missile.origin;