From 6bd8012ca8b6f81cb0c1cb558d130bc9e1c44682 Mon Sep 17 00:00:00 2001 From: TimePath Date: Tue, 29 Sep 2015 10:22:26 +1000 Subject: [PATCH] Weapons: Introduce concept of offhand weapons --- qcsrc/common/monsters/monster/mage.qc | 4 +- qcsrc/common/turrets/turret/plasma_dual.qc | 4 +- qcsrc/common/vehicles/vehicle/racer.qc | 4 +- qcsrc/common/weapons/all.qh | 13 +++- qcsrc/common/weapons/weapon/arc.qc | 10 +-- qcsrc/common/weapons/weapon/blaster.qc | 6 +- qcsrc/common/weapons/weapon/crylink.qc | 8 +- qcsrc/common/weapons/weapon/devastator.qc | 6 +- qcsrc/common/weapons/weapon/electro.qc | 6 +- qcsrc/common/weapons/weapon/fireball.qc | 6 +- qcsrc/common/weapons/weapon/hagar.qc | 6 +- qcsrc/common/weapons/weapon/hlac.qc | 6 +- qcsrc/common/weapons/weapon/hmg.qc | 4 +- qcsrc/common/weapons/weapon/hook.qc | 21 +++-- qcsrc/common/weapons/weapon/machinegun.qc | 10 +-- qcsrc/common/weapons/weapon/minelayer.qc | 6 +- qcsrc/common/weapons/weapon/mortar.qc | 6 +- qcsrc/common/weapons/weapon/porto.qc | 12 +-- qcsrc/common/weapons/weapon/rifle.qc | 6 +- qcsrc/common/weapons/weapon/rpc.qc | 6 +- qcsrc/common/weapons/weapon/seeker.qc | 6 +- qcsrc/common/weapons/weapon/shockwave.qc | 6 +- qcsrc/common/weapons/weapon/shotgun.qc | 8 +- qcsrc/common/weapons/weapon/tuba.qc | 8 +- qcsrc/common/weapons/weapon/vaporizer.qc | 6 +- qcsrc/common/weapons/weapon/vortex.qc | 8 +- qcsrc/server/g_hook.qc | 7 +- qcsrc/server/g_hook.qh | 1 + qcsrc/server/mutators/gamemode_nexball.qc | 37 +++++---- qcsrc/server/mutators/mutator_hook.qc | 7 ++ qcsrc/server/mutators/mutator_nades.qc | 90 +++++++++++----------- qcsrc/server/mutators/mutators_include.qc | 1 + qcsrc/server/weapons/weaponsystem.qc | 19 ++++- 33 files changed, 201 insertions(+), 153 deletions(-) create mode 100644 qcsrc/server/mutators/mutator_hook.qc diff --git a/qcsrc/common/monsters/monster/mage.qc b/qcsrc/common/monsters/monster/mage.qc index c034f992b..0030a4fa8 100644 --- a/qcsrc/common/monsters/monster/mage.qc +++ b/qcsrc/common/monsters/monster/mage.qc @@ -39,9 +39,9 @@ REGISTER_WEAPON(MAGE_SPIKE, NEW(MageSpike)); #ifdef SVQC void M_Mage_Attack_Spike(vector dir); -METHOD(MageSpike, wr_think, bool(entity thiswep)) { +METHOD(MageSpike, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { SELFPARAM(); - if (self.BUTTON_ATCK) + if (fire1) if (weapon_prepareattack(0, WEP_CVAR_PRI(electro, refire))) { if (!self.target_range) self.target_range = autocvar_g_monsters_target_range; self.enemy = Monster_FindTarget(self); diff --git a/qcsrc/common/turrets/turret/plasma_dual.qc b/qcsrc/common/turrets/turret/plasma_dual.qc index bde6ebf74..3041410ec 100644 --- a/qcsrc/common/turrets/turret/plasma_dual.qc +++ b/qcsrc/common/turrets/turret/plasma_dual.qc @@ -30,9 +30,9 @@ REGISTER_WEAPON(PLASMA_DUAL, NEW(PlasmaDualAttack)); #ifdef SVQC -METHOD(PlasmaDualAttack, wr_think, bool(entity thiswep)) { +METHOD(PlasmaDualAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { SELFPARAM(); - if (self.BUTTON_ATCK) + if (fire1) if (weapon_prepareattack(0, WEP_CVAR_PRI(electro, refire))) { W_SetupShot_Dir(self, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); self.tur_shotdir_updated = w_shotdir; diff --git a/qcsrc/common/vehicles/vehicle/racer.qc b/qcsrc/common/vehicles/vehicle/racer.qc index 9dabe77c0..c797e7538 100644 --- a/qcsrc/common/vehicles/vehicle/racer.qc +++ b/qcsrc/common/vehicles/vehicle/racer.qc @@ -37,9 +37,9 @@ REGISTER_WEAPON(RACER, NEW(RacerAttack)); #include "../../triggers/trigger/impulse.qh" void racer_fire_cannon(string tagname); -METHOD(RacerAttack, wr_think, bool(entity thiswep)) { +METHOD(RacerAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { SELFPARAM(); - if (self.BUTTON_ATCK) + if (fire1) if (weapon_prepareattack(0, 0)) { W_SetupShot_Dir(self, v_forward, false, 0, W_Sound("lasergun_fire"), CH_WEAPON_B, 0); racer_fire_cannon("tag_fire1"); diff --git a/qcsrc/common/weapons/all.qh b/qcsrc/common/weapons/all.qh index cb13d1e22..7f7e34dda 100644 --- a/qcsrc/common/weapons/all.qh +++ b/qcsrc/common/weapons/all.qh @@ -34,8 +34,8 @@ const int WEP_FLAG_MUTATORBLOCKED = 0x200; // hides from impulse 99 etc. (mutato // weapon requests const int WR_SETUP = 1; // (SERVER) setup weapon data .bool(entity this) wr_setup; -const int WR_THINK = 2; // (SERVER) logic to run every frame -.bool(entity this) wr_think; +/** (SERVER) logic to run every frame */ +.bool(entity this, bool fire1, bool fire2) wr_think; const int WR_CHECKAMMO1 = 3; // (SERVER) checks ammo for weapon primary .bool(entity this) wr_checkammo1; const int WR_CHECKAMMO2 = 4; // (SERVER) checks ammo for weapon second @@ -69,7 +69,6 @@ const int WR_PICKUP = 17; // (SERVER) a weapon is picked up bool w_new(entity this, int req) { if (req == WR_SETUP) return this.wr_setup ? this.wr_setup(this) : false; - if (req == WR_THINK) return this.wr_think ? this.wr_think(this) : false; if (req == WR_CHECKAMMO1) return this.wr_checkammo1 ? this.wr_checkammo1(this) : false; if (req == WR_CHECKAMMO2) return this.wr_checkammo2 ? this.wr_checkammo2(this) : false; if (req == WR_AIM) return this.wr_aim ? this.wr_aim(this) : false; @@ -270,6 +269,14 @@ CLASS(Weapon, Object) } ENDCLASS(Weapon) +CLASS(OffhandWeapon, Object) + METHOD(OffhandWeapon, offhand_think, void(OffhandWeapon this, entity player, bool key_pressed)) {} +ENDCLASS(OffhandWeapon) + +#ifdef SVQC +.OffhandWeapon offhand; +#endif + void RegisterWeapons(); REGISTER_REGISTRY(RegisterWeapons) entity weapon_info[WEP_MAXCOUNT], weapon_info_first, weapon_info_last; diff --git a/qcsrc/common/weapons/weapon/arc.qc b/qcsrc/common/weapons/weapon/arc.qc index 515a21eff..2853d857d 100644 --- a/qcsrc/common/weapons/weapon/arc.qc +++ b/qcsrc/common/weapons/weapon/arc.qc @@ -656,14 +656,14 @@ void Arc_Smoke() } return true; } - METHOD(Arc, wr_think, bool(entity thiswep)) + METHOD(Arc, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { SELFPARAM(); Arc_Player_SetHeat(self); Arc_Smoke(); if ( self.arc_overheat <= time ) - if(self.BUTTON_ATCK || self.BUTTON_ATCK2 || self.arc_beam.beam_bursting ) + if(fire1 || fire2 || self.arc_beam.beam_bursting ) { if(self.arc_BUTTON_ATCK_prev) @@ -678,9 +678,9 @@ void Arc_Smoke() if((!self.arc_beam) || wasfreed(self.arc_beam)) { - if(weapon_prepareattack(!!self.BUTTON_ATCK2, 0)) + if(weapon_prepareattack(!!fire2, 0)) { - W_Arc_Beam(!!self.BUTTON_ATCK2); + W_Arc_Beam(!!fire2); if(!self.arc_BUTTON_ATCK_prev) { @@ -702,7 +702,7 @@ void Arc_Smoke() self.arc_BUTTON_ATCK_prev = 0; #if 0 - if(self.BUTTON_ATCK2) + if(fire2) if(weapon_prepareattack(1, autocvar_g_balance_arc_secondary_refire)) { W_Arc_Attack2(); diff --git a/qcsrc/common/weapons/weapon/blaster.qc b/qcsrc/common/weapons/weapon/blaster.qc index bba933887..706c07a04 100644 --- a/qcsrc/common/weapons/weapon/blaster.qc +++ b/qcsrc/common/weapons/weapon/blaster.qc @@ -162,9 +162,9 @@ void W_Blaster_Attack( return true; } - METHOD(Blaster, wr_think, bool(entity thiswep)) + METHOD(Blaster, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { - if(self.BUTTON_ATCK) + if(fire1) { if(weapon_prepareattack(0, WEP_CVAR_PRI(blaster, refire))) { @@ -183,7 +183,7 @@ void W_Blaster_Attack( weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(blaster, animtime), w_ready); } } - else if(self.BUTTON_ATCK2) + else if(fire2) { switch(WEP_CVAR(blaster, secondary)) { diff --git a/qcsrc/common/weapons/weapon/crylink.qc b/qcsrc/common/weapons/weapon/crylink.qc index 4d3b7dfa6..902bcab49 100644 --- a/qcsrc/common/weapons/weapon/crylink.qc +++ b/qcsrc/common/weapons/weapon/crylink.qc @@ -576,13 +576,13 @@ void W_Crylink_Attack2(void) return true; } - METHOD(Crylink, wr_think, bool(entity thiswep)) + METHOD(Crylink, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { SELFPARAM(); if(autocvar_g_balance_crylink_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo))) // forced reload _WEP_ACTION(self.weapon, WR_RELOAD); - if(self.BUTTON_ATCK) + if(fire1) { if(self.crylink_waitrelease != 1) if(weapon_prepareattack(0, WEP_CVAR_PRI(crylink, refire))) @@ -592,7 +592,7 @@ void W_Crylink_Attack2(void) } } - if(self.BUTTON_ATCK2 && autocvar_g_balance_crylink_secondary) + if(fire2 && autocvar_g_balance_crylink_secondary) { if(self.crylink_waitrelease != 2) if(weapon_prepareattack(1, WEP_CVAR_SEC(crylink, refire))) @@ -602,7 +602,7 @@ void W_Crylink_Attack2(void) } } - if((self.crylink_waitrelease == 1 && !self.BUTTON_ATCK) || (self.crylink_waitrelease == 2 && !self.BUTTON_ATCK2)) + if((self.crylink_waitrelease == 1 && !fire1) || (self.crylink_waitrelease == 2 && !fire2)) { if(!self.crylink_lastgroup || time > self.crylink_lastgroup.teleport_time) { diff --git a/qcsrc/common/weapons/weapon/devastator.qc b/qcsrc/common/weapons/weapon/devastator.qc index 76ebd8e99..c52693a65 100644 --- a/qcsrc/common/weapons/weapon/devastator.qc +++ b/qcsrc/common/weapons/weapon/devastator.qc @@ -522,13 +522,13 @@ void W_Devastator_Attack(void) return true; } #endif - METHOD(Devastator, wr_think, bool(entity thiswep)) + METHOD(Devastator, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { if(WEP_CVAR(devastator, reload_ammo) && self.clip_load < WEP_CVAR(devastator, ammo)) // forced reload _WEP_ACTION(self.weapon, WR_RELOAD); else { - if(self.BUTTON_ATCK) + if(fire1) { if(self.rl_release || WEP_CVAR(devastator, guidestop)) if(weapon_prepareattack(0, WEP_CVAR(devastator, refire))) @@ -541,7 +541,7 @@ void W_Devastator_Attack(void) else self.rl_release = 1; - if(self.BUTTON_ATCK2) + if(fire2) if(self.switchweapon == WEP_DEVASTATOR.m_id) { entity rock; diff --git a/qcsrc/common/weapons/weapon/electro.qc b/qcsrc/common/weapons/weapon/electro.qc index 073a4e0f5..5a23f8849 100644 --- a/qcsrc/common/weapons/weapon/electro.qc +++ b/qcsrc/common/weapons/weapon/electro.qc @@ -453,7 +453,7 @@ void W_Electro_CheckAttack(void) return true; } - METHOD(Electro, wr_think, bool(entity thiswep)) + METHOD(Electro, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { if(autocvar_g_balance_electro_reload_ammo) // forced reload // WEAPONTODO { @@ -472,7 +472,7 @@ void W_Electro_CheckAttack(void) return true; } - if(self.BUTTON_ATCK) + if(fire1) { if(weapon_prepareattack(0, WEP_CVAR_PRI(electro, refire))) { @@ -480,7 +480,7 @@ void W_Electro_CheckAttack(void) weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); } } - else if(self.BUTTON_ATCK2) + else if(fire2) { if(time >= self.electro_secondarytime) if(weapon_prepareattack(1, WEP_CVAR_SEC(electro, refire))) diff --git a/qcsrc/common/weapons/weapon/fireball.qc b/qcsrc/common/weapons/weapon/fireball.qc index 1ff37df00..13d5ed3e4 100644 --- a/qcsrc/common/weapons/weapon/fireball.qc +++ b/qcsrc/common/weapons/weapon/fireball.qc @@ -373,9 +373,9 @@ void W_Fireball_Attack2(void) return true; } - METHOD(Fireball, wr_think, bool(entity thiswep)) + METHOD(Fireball, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { - if(self.BUTTON_ATCK) + if(fire1) { if(time >= self.fireball_primarytime) if(weapon_prepareattack(0, WEP_CVAR_PRI(fireball, refire))) @@ -384,7 +384,7 @@ void W_Fireball_Attack2(void) self.fireball_primarytime = time + WEP_CVAR_PRI(fireball, refire2) * W_WeaponRateFactor(); } } - else if(self.BUTTON_ATCK2) + else if(fire2) { if(weapon_prepareattack(1, WEP_CVAR_SEC(fireball, refire))) { diff --git a/qcsrc/common/weapons/weapon/hagar.qc b/qcsrc/common/weapons/weapon/hagar.qc index 2c827cb22..9ca028450 100644 --- a/qcsrc/common/weapons/weapon/hagar.qc +++ b/qcsrc/common/weapons/weapon/hagar.qc @@ -408,7 +408,7 @@ void W_Hagar_Attack2_Load(void) return true; } - METHOD(Hagar, wr_think, bool(entity thiswep)) + METHOD(Hagar, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { float loadable_secondary; loadable_secondary = (WEP_CVAR_SEC(hagar, load) && WEP_CVAR(hagar, secondary)); @@ -417,7 +417,7 @@ void W_Hagar_Attack2_Load(void) W_Hagar_Attack2_Load(); // must always run each frame if(autocvar_g_balance_hagar_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo))) // forced reload _WEP_ACTION(self.weapon, WR_RELOAD); - else if(self.BUTTON_ATCK && !self.hagar_load && !self.hagar_loadblock) // not while secondary is loaded or awaiting reset + else if(fire1 && !self.hagar_load && !self.hagar_loadblock) // not while secondary is loaded or awaiting reset { if(weapon_prepareattack(0, WEP_CVAR_PRI(hagar, refire))) { @@ -425,7 +425,7 @@ void W_Hagar_Attack2_Load(void) weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(hagar, refire), w_ready); } } - else if(self.BUTTON_ATCK2 && !loadable_secondary && WEP_CVAR(hagar, secondary)) + else if(fire2 && !loadable_secondary && WEP_CVAR(hagar, secondary)) { if(weapon_prepareattack(1, WEP_CVAR_SEC(hagar, refire))) { diff --git a/qcsrc/common/weapons/weapon/hlac.qc b/qcsrc/common/weapons/weapon/hlac.qc index 7e4477604..1c4b3a018 100644 --- a/qcsrc/common/weapons/weapon/hlac.qc +++ b/qcsrc/common/weapons/weapon/hlac.qc @@ -211,11 +211,11 @@ void W_HLAC_Attack2_Frame(void) self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(hlac, speed), 0, WEP_CVAR_PRI(hlac, lifetime), false); return true; } - METHOD(HLAC, wr_think, bool(entity thiswep)) + METHOD(HLAC, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { if(autocvar_g_balance_hlac_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo))) // forced reload _WEP_ACTION(self.weapon, WR_RELOAD); - else if(self.BUTTON_ATCK) + else if(fire1) { if(weapon_prepareattack(0, WEP_CVAR_PRI(hlac, refire))) { @@ -225,7 +225,7 @@ void W_HLAC_Attack2_Frame(void) } } - else if(self.BUTTON_ATCK2 && WEP_CVAR(hlac, secondary)) + else if(fire2 && WEP_CVAR(hlac, secondary)) { if(weapon_prepareattack(1, WEP_CVAR_SEC(hlac, refire))) { diff --git a/qcsrc/common/weapons/weapon/hmg.qc b/qcsrc/common/weapons/weapon/hmg.qc index 8e5398745..bba7f127f 100644 --- a/qcsrc/common/weapons/weapon/hmg.qc +++ b/qcsrc/common/weapons/weapon/hmg.qc @@ -97,13 +97,13 @@ void W_HeavyMachineGun_Attack_Auto() return true; } - METHOD(HeavyMachineGun, wr_think, bool(entity thiswep)) + METHOD(HeavyMachineGun, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { if(WEP_CVAR(hmg, reload_ammo) && self.clip_load < WEP_CVAR(hmg, ammo)) // forced reload _WEP_ACTION(self.weapon, WR_RELOAD); else { - if (self.BUTTON_ATCK) + if (fire1) if (weapon_prepareattack(0, 0)) { self.misc_bulletcounter = 0; diff --git a/qcsrc/common/weapons/weapon/hook.qc b/qcsrc/common/weapons/weapon/hook.qc index b0b8b8b3f..1478d96ed 100644 --- a/qcsrc/common/weapons/weapon/hook.qc +++ b/qcsrc/common/weapons/weapon/hook.qc @@ -17,6 +17,15 @@ CLASS(Hook, Weapon) ENDCLASS(Hook) REGISTER_WEAPON(HOOK, NEW(Hook)); +CLASS(OffhandHook, OffhandWeapon) + METHOD(OffhandHook, offhand_think, void(OffhandHook this, entity player, bool key_pressed)) + { + Weapon wep = WEP_HOOK; + WITH(entity, self, player, wep.wr_think(wep, key_pressed, false)); + } +ENDCLASS(OffhandHook) +OffhandHook OFFHAND_HOOK; STATIC_INIT(OFFHAND_HOOK) { OFFHAND_HOOK = NEW(OffhandHook); } + #define HOOK_SETTINGS(w_cvar,w_prop) HOOK_SETTINGS_LIST(w_cvar, w_prop, HOOK, hook) #define HOOK_SETTINGS_LIST(w_cvar,w_prop,id,sn) \ w_cvar(id, sn, BOTH, animtime) \ @@ -181,9 +190,9 @@ void W_Hook_Attack2(void) // no bot AI for hook (yet?) return true; } - METHOD(Hook, wr_think, bool(entity thiswep)) + METHOD(Hook, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { - if(self.BUTTON_ATCK || self.BUTTON_HOOK) + if(fire1 || self.BUTTON_HOOK) { if(!self.hook) if(!(self.hook_state & HOOK_WAITING_FOR_RELEASE)) @@ -197,7 +206,7 @@ void W_Hook_Attack2(void) } } - if(self.BUTTON_ATCK2) + if(fire2) { if(weapon_prepareattack(1, WEP_CVAR_SEC(hook, refire))) { @@ -257,7 +266,7 @@ void W_Hook_Attack2(void) if(self.BUTTON_CROUCH) { self.hook_state &= ~HOOK_PULLING; - if(self.BUTTON_ATCK || self.BUTTON_HOOK) + if(fire1 || self.BUTTON_HOOK) self.hook_state &= ~HOOK_RELEASING; else self.hook_state |= HOOK_RELEASING; @@ -267,7 +276,7 @@ void W_Hook_Attack2(void) self.hook_state |= HOOK_PULLING; self.hook_state &= ~HOOK_RELEASING; - if(self.BUTTON_ATCK || self.BUTTON_HOOK) + if(fire1 || self.BUTTON_HOOK) { // already fired if(self.hook) @@ -280,6 +289,8 @@ void W_Hook_Attack2(void) } } + _GrapplingHookFrame(); + return true; } METHOD(Hook, wr_init, bool(entity thiswep)) diff --git a/qcsrc/common/weapons/weapon/machinegun.qc b/qcsrc/common/weapons/weapon/machinegun.qc index ddbc0fdb6..784b9a435 100644 --- a/qcsrc/common/weapons/weapon/machinegun.qc +++ b/qcsrc/common/weapons/weapon/machinegun.qc @@ -247,20 +247,20 @@ void W_MachineGun_Attack_Burst(void) return true; } - METHOD(MachineGun, wr_think, bool(entity thiswep)) + METHOD(MachineGun, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { if(WEP_CVAR(machinegun, reload_ammo) && self.clip_load < min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo))) // forced reload _WEP_ACTION(self.weapon, WR_RELOAD); else if(WEP_CVAR(machinegun, mode) == 1) { - if(self.BUTTON_ATCK) + if(fire1) if(weapon_prepareattack(0, 0)) { self.misc_bulletcounter = 0; W_MachineGun_Attack_Auto(); } - if(self.BUTTON_ATCK2) + if(fire2) if(weapon_prepareattack(1, 0)) { if(!_WEP_ACTION(self.weapon, WR_CHECKAMMO2)) @@ -280,7 +280,7 @@ void W_MachineGun_Attack_Burst(void) else { - if(self.BUTTON_ATCK) + if(fire1) if(weapon_prepareattack(0, 0)) { self.misc_bulletcounter = 1; @@ -288,7 +288,7 @@ void W_MachineGun_Attack_Burst(void) weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame); } - if(self.BUTTON_ATCK2 && WEP_CVAR(machinegun, first)) + if(fire2 && WEP_CVAR(machinegun, first)) if(weapon_prepareattack(1, 0)) { self.misc_bulletcounter = 1; diff --git a/qcsrc/common/weapons/weapon/minelayer.qc b/qcsrc/common/weapons/weapon/minelayer.qc index 7c8c63bd3..b6aa26343 100644 --- a/qcsrc/common/weapons/weapon/minelayer.qc +++ b/qcsrc/common/weapons/weapon/minelayer.qc @@ -499,7 +499,7 @@ float W_MineLayer_PlacedMines(float detonate) return true; } - METHOD(MineLayer, wr_think, bool(entity thiswep)) + METHOD(MineLayer, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { if(autocvar_g_balance_minelayer_reload_ammo && self.clip_load < WEP_CVAR(minelayer, ammo)) // forced reload { @@ -507,7 +507,7 @@ float W_MineLayer_PlacedMines(float detonate) if(!(W_MineLayer_PlacedMines(false) && self.WEP_AMMO(MINE_LAYER) < WEP_CVAR(minelayer, ammo))) _WEP_ACTION(self.weapon, WR_RELOAD); } - else if(self.BUTTON_ATCK) + else if(fire1) { if(weapon_prepareattack(0, WEP_CVAR(minelayer, refire))) { @@ -516,7 +516,7 @@ float W_MineLayer_PlacedMines(float detonate) } } - if(self.BUTTON_ATCK2) + if(fire2) { if(W_MineLayer_PlacedMines(true)) sound(self, CH_WEAPON_B, SND_MINE_DET, VOL_BASE, ATTN_NORM); diff --git a/qcsrc/common/weapons/weapon/mortar.qc b/qcsrc/common/weapons/weapon/mortar.qc index 0f01fcf47..559c50310 100644 --- a/qcsrc/common/weapons/weapon/mortar.qc +++ b/qcsrc/common/weapons/weapon/mortar.qc @@ -336,11 +336,11 @@ void W_Mortar_Attack2(void) wepinfo_sec_dps = (WEP_CVAR_SEC(mortar, damage) * (1 / max3(sys_frametime, WEP_CVAR_SEC(mortar, refire), WEP_CVAR_SEC(mortar, animtime)))); wepinfo_ter_dps = 0; */ - METHOD(Mortar, wr_think, bool(entity thiswep)) + METHOD(Mortar, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { if(autocvar_g_balance_mortar_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo))) // forced reload _WEP_ACTION(self.weapon, WR_RELOAD); - else if(self.BUTTON_ATCK) + else if(fire1) { if(weapon_prepareattack(0, WEP_CVAR_PRI(mortar, refire))) { @@ -348,7 +348,7 @@ void W_Mortar_Attack2(void) weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(mortar, animtime), w_ready); } } - else if(self.BUTTON_ATCK2) + else if(fire2) { if(WEP_CVAR_SEC(mortar, remote_detonateprimary)) { diff --git a/qcsrc/common/weapons/weapon/porto.qc b/qcsrc/common/weapons/weapon/porto.qc index a8ad17602..97a0203f4 100644 --- a/qcsrc/common/weapons/weapon/porto.qc +++ b/qcsrc/common/weapons/weapon/porto.qc @@ -301,12 +301,12 @@ void W_Porto_Attack(float type) PORTO_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS); return true; } - METHOD(PortoLaunch, wr_think, bool(entity thiswep)) + METHOD(PortoLaunch, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { SELFPARAM(); if(WEP_CVAR(porto, secondary)) { - if(self.BUTTON_ATCK) + if(fire1) if(!self.porto_current) if(!self.porto_forbidden) if(weapon_prepareattack(0, WEP_CVAR_PRI(porto, refire))) @@ -315,7 +315,7 @@ void W_Porto_Attack(float type) weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(porto, animtime), w_ready); } - if(self.BUTTON_ATCK2) + if(fire2) if(!self.porto_current) if(!self.porto_forbidden) if(weapon_prepareattack(1, WEP_CVAR_SEC(porto, refire))) @@ -328,7 +328,7 @@ void W_Porto_Attack(float type) { if(self.porto_v_angle_held) { - if(!self.BUTTON_ATCK2) + if(!fire2) { self.porto_v_angle_held = 0; @@ -337,7 +337,7 @@ void W_Porto_Attack(float type) } else { - if(self.BUTTON_ATCK2) + if(fire2) { self.porto_v_angle = self.v_angle; self.porto_v_angle_held = 1; @@ -348,7 +348,7 @@ void W_Porto_Attack(float type) if(self.porto_v_angle_held) makevectors(self.porto_v_angle); // override the previously set angles - if(self.BUTTON_ATCK) + if(fire1) if(!self.porto_current) if(!self.porto_forbidden) if(weapon_prepareattack(0, WEP_CVAR_PRI(porto, refire))) diff --git a/qcsrc/common/weapons/weapon/rifle.qc b/qcsrc/common/weapons/weapon/rifle.qc index 09df647ba..3d69e2d8f 100644 --- a/qcsrc/common/weapons/weapon/rifle.qc +++ b/qcsrc/common/weapons/weapon/rifle.qc @@ -162,14 +162,14 @@ void W_Rifle_BulletHail(float mode, void(void) AttackFunc, float fr, float animt return true; } - METHOD(Rifle, wr_think, bool(entity thiswep)) + 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(self.BUTTON_ATCK) + if(fire1) if(weapon_prepareattack_check(0, WEP_CVAR_PRI(rifle, refire))) if(time >= self.rifle_accumulator + WEP_CVAR_PRI(rifle, burstcost)) { @@ -177,7 +177,7 @@ void W_Rifle_BulletHail(float mode, void(void) AttackFunc, float fr, float animt 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(self.BUTTON_ATCK2) + if(fire2) { if(WEP_CVAR(rifle, secondary)) { diff --git a/qcsrc/common/weapons/weapon/rpc.qc b/qcsrc/common/weapons/weapon/rpc.qc index 5d8ba4028..836b4be33 100644 --- a/qcsrc/common/weapons/weapon/rpc.qc +++ b/qcsrc/common/weapons/weapon/rpc.qc @@ -154,13 +154,13 @@ void W_RocketPropelledChainsaw_Attack (void) self.BUTTON_ATCK = bot_aim(WEP_CVAR(rpc, speed), 0, WEP_CVAR(rpc, lifetime), false); return true; } - METHOD(RocketPropelledChainsaw, wr_think, bool(entity thiswep)) + METHOD(RocketPropelledChainsaw, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { if(WEP_CVAR(rpc, reload_ammo) && self.clip_load < WEP_CVAR(rpc, ammo)) _WEP_ACTION(self.weapon, WR_RELOAD); else { - if (self.BUTTON_ATCK) + if (fire1) { if(weapon_prepareattack(0, WEP_CVAR(rpc, refire))) { @@ -169,7 +169,7 @@ void W_RocketPropelledChainsaw_Attack (void) } } - if (self.BUTTON_ATCK2) + if (fire2) { // to-do } diff --git a/qcsrc/common/weapons/weapon/seeker.qc b/qcsrc/common/weapons/weapon/seeker.qc index 4b9cf57cb..74be279bc 100644 --- a/qcsrc/common/weapons/weapon/seeker.qc +++ b/qcsrc/common/weapons/weapon/seeker.qc @@ -609,12 +609,12 @@ void W_Seeker_Fire_Tag(void) self.BUTTON_ATCK = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false); return true; } - METHOD(Seeker, wr_think, bool(entity thiswep)) + METHOD(Seeker, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { if(autocvar_g_balance_seeker_reload_ammo && self.clip_load < min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo))) // forced reload _WEP_ACTION(self.weapon, WR_RELOAD); - else if(self.BUTTON_ATCK) + else if(fire1) { if(WEP_CVAR(seeker, type) == 1) { @@ -634,7 +634,7 @@ void W_Seeker_Fire_Tag(void) } } - else if(self.BUTTON_ATCK2) + else if(fire2) { if(WEP_CVAR(seeker, type) == 1) { diff --git a/qcsrc/common/weapons/weapon/shockwave.qc b/qcsrc/common/weapons/weapon/shockwave.qc index 859c80e89..713ac59c7 100644 --- a/qcsrc/common/weapons/weapon/shockwave.qc +++ b/qcsrc/common/weapons/weapon/shockwave.qc @@ -677,9 +677,9 @@ void W_Shockwave_Attack(void) return true; } - METHOD(Shockwave, wr_think, bool(entity thiswep)) + METHOD(Shockwave, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { - if(self.BUTTON_ATCK) + if(fire1) { if(time >= self.shockwave_blasttime) // handle refire separately so the secondary can be fired straight after a primary { @@ -691,7 +691,7 @@ void W_Shockwave_Attack(void) } } } - else if(self.BUTTON_ATCK2) + else if(fire2) { //if(self.clip_load >= 0) // we are not currently reloading if(!self.crouch) // no crouchmelee please diff --git a/qcsrc/common/weapons/weapon/shotgun.qc b/qcsrc/common/weapons/weapon/shotgun.qc index 519cd51ad..578e9284c 100644 --- a/qcsrc/common/weapons/weapon/shotgun.qc +++ b/qcsrc/common/weapons/weapon/shotgun.qc @@ -234,7 +234,7 @@ void W_Shotgun_Attack3_Frame1() return true; } - METHOD(Shotgun, wr_think, bool(entity thiswep)) + METHOD(Shotgun, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { if(WEP_CVAR(shotgun, reload_ammo) && self.clip_load < WEP_CVAR_PRI(shotgun, ammo)) // forced reload { @@ -244,7 +244,7 @@ void W_Shotgun_Attack3_Frame1() } else { - if(self.BUTTON_ATCK) + if(fire1) { if(time >= self.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary { @@ -256,7 +256,7 @@ void W_Shotgun_Attack3_Frame1() } } } - else if(self.BUTTON_ATCK2 && WEP_CVAR(shotgun, secondary) == 2) + else if(fire2 && WEP_CVAR(shotgun, secondary) == 2) { if(time >= self.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary { @@ -272,7 +272,7 @@ void W_Shotgun_Attack3_Frame1() if(self.clip_load >= 0) // we are not currently reloading if(!self.crouch) // no crouchmelee please if(WEP_CVAR(shotgun, secondary) == 1) - if((self.BUTTON_ATCK && self.WEP_AMMO(SHOTGUN) <= 0 && !(self.items & IT_UNLIMITED_WEAPON_AMMO)) || self.BUTTON_ATCK2) + if((fire1 && self.WEP_AMMO(SHOTGUN) <= 0 && !(self.items & IT_UNLIMITED_WEAPON_AMMO)) || fire2) if(weapon_prepareattack(1, WEP_CVAR_SEC(shotgun, refire))) { // attempt forcing playback of the anim by switching to another anim (that we never play) here... diff --git a/qcsrc/common/weapons/weapon/tuba.qc b/qcsrc/common/weapons/weapon/tuba.qc index 590a57609..bf2372c7d 100644 --- a/qcsrc/common/weapons/weapon/tuba.qc +++ b/qcsrc/common/weapons/weapon/tuba.qc @@ -381,16 +381,16 @@ void W_Tuba_NoteOn(float hittype) return true; } - METHOD(Tuba, wr_think, bool(entity thiswep)) + METHOD(Tuba, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { - if(self.BUTTON_ATCK) + if(fire1) if(weapon_prepareattack(0, WEP_CVAR(tuba, refire))) { W_Tuba_NoteOn(0); //weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_tuba_animtime, w_ready); weapon_thinkf(WFRAME_IDLE, WEP_CVAR(tuba, animtime), w_ready); } - if(self.BUTTON_ATCK2) + if(fire2) if(weapon_prepareattack(1, WEP_CVAR(tuba, refire))) { W_Tuba_NoteOn(HITTYPE_SECONDARY); @@ -399,7 +399,7 @@ void W_Tuba_NoteOn(float hittype) } if(self.tuba_note) { - if(!self.BUTTON_ATCK && !self.BUTTON_ATCK2) + if(!fire1 && !fire2) { WITH(entity, self, self.tuba_note, W_Tuba_NoteOff()); } diff --git a/qcsrc/common/weapons/weapon/vaporizer.qc b/qcsrc/common/weapons/weapon/vaporizer.qc index 2f6d94dd7..3cfbf3b38 100644 --- a/qcsrc/common/weapons/weapon/vaporizer.qc +++ b/qcsrc/common/weapons/weapon/vaporizer.qc @@ -246,7 +246,7 @@ void W_RocketMinsta_Attack3 (void) return true; } - METHOD(Vaporizer, wr_think, bool(entity thiswep)) + METHOD(Vaporizer, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo)); // if the laser uses load, we also consider its ammo for reloading @@ -254,7 +254,7 @@ void W_RocketMinsta_Attack3 (void) _WEP_ACTION(self.weapon, WR_RELOAD); else if(WEP_CVAR(vaporizer, reload_ammo) && self.clip_load < vaporizer_ammo) // forced reload _WEP_ACTION(self.weapon, WR_RELOAD); - if(self.BUTTON_ATCK && (self.ammo_cells || !autocvar_g_rm) && !forbidWeaponUse(self)) + if(fire1 && (self.ammo_cells || !autocvar_g_rm) && !forbidWeaponUse(self)) { if(weapon_prepareattack(0, WEP_CVAR_PRI(vaporizer, refire))) { @@ -262,7 +262,7 @@ void W_RocketMinsta_Attack3 (void) weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(vaporizer, animtime), w_ready); } } - if(self.BUTTON_ATCK2 || (self.BUTTON_ATCK && !self.ammo_cells && autocvar_g_rm)) + if(fire2 || (fire1 && !self.ammo_cells && autocvar_g_rm)) { if((autocvar_g_rm && autocvar_g_rm_laser) || autocvar_g_rm_laser == 2) { diff --git a/qcsrc/common/weapons/weapon/vortex.qc b/qcsrc/common/weapons/weapon/vortex.qc index e9e659e0c..a4e0fb5e0 100644 --- a/qcsrc/common/weapons/weapon/vortex.qc +++ b/qcsrc/common/weapons/weapon/vortex.qc @@ -144,7 +144,7 @@ void W_Vortex_Attack(float issecondary) } return true; } - METHOD(Vortex, wr_think, bool(entity thiswep)) + METHOD(Vortex, wr_think, bool(entity thiswep, bool fire1, bool fire2)) { if(WEP_CVAR(vortex, charge) && self.vortex_charge < WEP_CVAR(vortex, charge_limit)) self.vortex_charge = min(1, self.vortex_charge + WEP_CVAR(vortex, charge_rate) * frametime / W_TICSPERFRAME); @@ -161,7 +161,7 @@ void W_Vortex_Attack(float issecondary) _WEP_ACTION(self.weapon, WR_RELOAD); else { - if(self.BUTTON_ATCK) + if(fire1) { if(weapon_prepareattack(0, WEP_CVAR_PRI(vortex, refire))) { @@ -169,7 +169,7 @@ void W_Vortex_Attack(float issecondary) weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(vortex, animtime), w_ready); } } - if((WEP_CVAR(vortex, charge) && !WEP_CVAR(vortex, secondary)) ? (self.BUTTON_ZOOM | self.BUTTON_ZOOMSCRIPT) : self.BUTTON_ATCK2) + if((WEP_CVAR(vortex, charge) && !WEP_CVAR(vortex, secondary)) ? (self.BUTTON_ZOOM | self.BUTTON_ZOOMSCRIPT) : fire2) { if(WEP_CVAR(vortex, charge)) { @@ -196,7 +196,7 @@ void W_Vortex_Attack(float issecondary) else if(WEP_CVAR_SEC(vortex, ammo)) { - if(self.BUTTON_ATCK2) // only eat ammo when the button is pressed + if(fire2) // only eat ammo when the button is pressed { dt = min(dt, (1 - self.vortex_charge) / WEP_CVAR(vortex, charge_rate)); if(!(self.items & IT_UNLIMITED_WEAPON_AMMO)) diff --git a/qcsrc/server/g_hook.qc b/qcsrc/server/g_hook.qc index c101d7271..88c9783f5 100644 --- a/qcsrc/server/g_hook.qc +++ b/qcsrc/server/g_hook.qc @@ -422,6 +422,7 @@ void FireGrapplingHook (void) // // if I have no hook or it's not pulling yet, make sure I'm not flying! // if((self.hook == world || !self.hook.state) && self.movetype == MOVETYPE_FLY) +void _GrapplingHookFrame(); void GrapplingHookFrame() {SELFPARAM(); if(g_grappling_hook && timeout_status != TIMEOUT_ACTIVE && self.weapon != WEP_HOOK.m_id && !self.vehicle) @@ -460,12 +461,16 @@ void GrapplingHookFrame() } self.hook_switchweapon = self.BUTTON_HOOK; - if(!g_grappling_hook && self.weapon != WEP_HOOK.m_id) + if(!g_grappling_hook && self.weapon != WEP_HOOK.m_id && self.offhand != OFFHAND_HOOK) { self.hook_state &= ~HOOK_FIRING; self.hook_state |= HOOK_REMOVING; } + _GrapplingHookFrame(); +} +void _GrapplingHookFrame() +{ if (self.hook_state & HOOK_FIRING) { if (self.hook) diff --git a/qcsrc/server/g_hook.qh b/qcsrc/server/g_hook.qh index aa641a56b..26189143c 100644 --- a/qcsrc/server/g_hook.qh +++ b/qcsrc/server/g_hook.qh @@ -4,6 +4,7 @@ // Wazat's grappling hook .entity hook; void GrapplingHookFrame(); +void _GrapplingHookFrame(); void RemoveGrapplingHook(entity pl); void SetGrappleHookBindings(); // (note: you can change the hook impulse #'s to whatever you please) diff --git a/qcsrc/server/mutators/gamemode_nexball.qc b/qcsrc/server/mutators/gamemode_nexball.qc index 10690001d..bdcb9ee8f 100644 --- a/qcsrc/server/mutators/gamemode_nexball.qc +++ b/qcsrc/server/mutators/gamemode_nexball.qc @@ -841,16 +841,9 @@ float ball_customize() return true; } -float w_nexball_weapon(float req); -METHOD(BallStealer, weapon_func, bool(entity this, int req)) { - return w_nexball_weapon(req); -} - -float w_nexball_weapon(float req) -{SELFPARAM(); - if(req == WR_THINK) + METHOD(BallStealer, wr_think, bool(BallStealer thiswep, bool fire1, bool fire2)) { - if(self.BUTTON_ATCK) + if(fire1) if(weapon_prepareattack(0, autocvar_g_balance_nexball_primary_refire)) if(autocvar_g_nexball_basketball_meter) { @@ -864,30 +857,42 @@ float w_nexball_weapon(float req) W_Nexball_Attack(-1); weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); } - if(self.BUTTON_ATCK2) + if(fire2) if(weapon_prepareattack(1, autocvar_g_balance_nexball_secondary_refire)) { W_Nexball_Attack2(); weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_nexball_secondary_animtime, w_ready); } - if(!self.BUTTON_ATCK && self.metertime && self.ballcarried) + if(!fire1 && self.metertime && self.ballcarried) { W_Nexball_Attack(time - self.metertime); // DropBall or stealing will set metertime back to 0 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); } + return true; } - else if(req == WR_INIT) + METHOD(BallStealer, wr_init, bool(BallStealer thiswep)) { + return true; } - else if(req == WR_SETUP) + METHOD(BallStealer, wr_setup, bool(BallStealer thiswep)) { //weapon_setup(WEP_PORTO.m_id); + return true; + } + METHOD(BallStealer, wr_aim, bool(BallStealer thiswep)) + { + return true; + } + METHOD(BallStealer, wr_checkammo1, bool(BallStealer thiswep)) + { + return true; + } + METHOD(BallStealer, wr_checkammo2, bool(BallStealer thiswep)) + { + return true; } - // No need to check WR_CHECKAMMO* or WR_AIM, it should always return true - return true; -} MUTATOR_HOOKFUNCTION(nexball_BallDrop) {SELFPARAM(); diff --git a/qcsrc/server/mutators/mutator_hook.qc b/qcsrc/server/mutators/mutator_hook.qc new file mode 100644 index 000000000..dbf1681cb --- /dev/null +++ b/qcsrc/server/mutators/mutator_hook.qc @@ -0,0 +1,7 @@ +REGISTER_MUTATOR(hook, cvar("_g_grappling_hook")); + +MUTATOR_HOOKFUNCTION(hook, PlayerSpawn) +{ + SELFPARAM(); + self.offhand = OFFHAND_HOOK; +} diff --git a/qcsrc/server/mutators/mutator_nades.qc b/qcsrc/server/mutators/mutator_nades.qc index 19a0aa462..088f3f529 100644 --- a/qcsrc/server/mutators/mutator_nades.qc +++ b/qcsrc/server/mutators/mutator_nades.qc @@ -9,7 +9,7 @@ #include "../../common/monsters/spawn.qh" #include "../../common/monsters/sv_monsters.qh" -.float lifetime; +.float nade_time_primed; .entity nade_spawnloc; @@ -822,7 +822,7 @@ void nade_prime() n.colormap = self.colormap; n.glowmod = self.glowmod; n.wait = time + autocvar_g_nades_nade_lifetime; - n.lifetime = time; + n.nade_time_primed = time; n.think = nade_beep; n.nextthink = max(n.wait - 3, time); n.projectiledeathtype = DEATH_NADE; @@ -868,9 +868,10 @@ void nades_CheckThrow() if(!CanThrowNade()) return; - if(!self.nade) + entity held_nade = self.nade; + if (!held_nade) { - if(self.nade_refire < time) + if(time > self.nade_refire) { Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_NADE_THROW); nade_prime(); @@ -879,10 +880,9 @@ void nades_CheckThrow() } else { - if(time - self.nade.lifetime >= 1) - { + if (time >= held_nade.nade_time_primed + 1) { makevectors(self.v_angle); - float _force = time - self.nade.lifetime; + float _force = time - held_nade.nade_time_primed; _force /= autocvar_g_nades_nade_lifetime; _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce)); toss_nade(self, (v_forward * 0.75 + v_up * 0.2 + v_right * 0.05) * _force, 0); @@ -915,51 +915,46 @@ MUTATOR_HOOKFUNCTION(nades_VehicleEnter) return false; } -MUTATOR_HOOKFUNCTION(nades_PlayerPreThink) -{SELFPARAM(); - if(!IS_PLAYER(self)) { return false; } - - float key_pressed = self.BUTTON_HOOK; - float time_score; - - if(g_grappling_hook || client_hasweapon(self, WEP_HOOK.m_id, false, false) || (weaponsInMap & WEPSET_HOOK)) - key_pressed = self.button16; // if hook is enabled, use an alternate key - - if(self.nade) - { - self.nade_timer = bound(0, (time - self.nade.lifetime) / autocvar_g_nades_nade_lifetime, 1); - //print(sprintf("%d %d\n", self.nade_timer, time - self.nade.lifetime)); - makevectors(self.angles); - self.nade.velocity = self.velocity; - - setorigin(self.nade, self.origin + self.view_ofs + v_forward * 8 + v_right * -8 + v_up * 0); - self.nade.angles_y = self.angles.y; - } - - if(self.nade) - if(self.nade.wait - 0.1 <= time) - toss_nade(self, '0 0 0', time + 0.05); - - if(CanThrowNade()) - if(self.nade_refire < time) - { - if(key_pressed) +CLASS(NadeOffhand, OffhandWeapon) + METHOD(NadeOffhand, offhand_think, void(NadeOffhand this, entity player, bool key_pressed)) + { + entity held_nade = player.nade; + if (held_nade) { - if(!self.nade) - nade_prime(); + player.nade_timer = bound(0, (time - held_nade.nade_time_primed) / autocvar_g_nades_nade_lifetime, 1); + // LOG_TRACEF("%d %d\n", player.nade_timer, time - held_nade.nade_time_primed); + makevectors(player.angles); + held_nade.velocity = player.velocity; + setorigin(held_nade, player.origin + player.view_ofs + v_forward * 8 + v_right * -8 + v_up * 0); + held_nade.angles_y = player.angles.y; + + if (time + 0.1 >= held_nade.wait) + toss_nade(player, '0 0 0', time + 0.05); } - else if(time - self.nade.lifetime >= 1) - { - if(self.nade) - { - makevectors(self.v_angle); - float _force = time - self.nade.lifetime; + + if (!CanThrowNade()) return; + if (!(time > player.nade_refire)) return; + if (key_pressed) { + if (!held_nade) { + nade_prime(); + held_nade = player.nade; + } + } else if (time >= held_nade.nade_time_primed + 1) { + if (held_nade) { + makevectors(player.v_angle); + float _force = time - held_nade.nade_time_primed; _force /= autocvar_g_nades_nade_lifetime; _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce)); - toss_nade(self, (v_forward * 0.7 + v_up * 0.2 + v_right * 0.1) * _force, 0); + toss_nade(player, (v_forward * 0.7 + v_up * 0.2 + v_right * 0.1) * _force, 0); } } - } + } +ENDCLASS(NadeOffhand) +NadeOffhand OFFHAND_NADE; STATIC_INIT(OFFHAND_NADE) { OFFHAND_NADE = NEW(NadeOffhand); } + +MUTATOR_HOOKFUNCTION(nades_PlayerPreThink) +{SELFPARAM(); + if (!IS_PLAYER(self)) { return false; } if(IS_PLAYER(self)) { @@ -969,6 +964,7 @@ MUTATOR_HOOKFUNCTION(nades_PlayerPreThink) float key_count = 0; FOR_EACH_KH_KEY(key) if(key.owner == self) { ++key_count; } + float time_score; if(self.flagcarried || self.ballcarried) // this player is important time_score = autocvar_g_nades_bonus_score_time_flagcarrier; else @@ -1058,6 +1054,8 @@ MUTATOR_HOOKFUNCTION(nades_PlayerSpawn) self.nade_timer = 0; + self.offhand = OFFHAND_NADE; + if(self.nade_spawnloc) { setorigin(self, self.nade_spawnloc.origin); diff --git a/qcsrc/server/mutators/mutators_include.qc b/qcsrc/server/mutators/mutators_include.qc index 7f238b88e..92dc131cb 100644 --- a/qcsrc/server/mutators/mutators_include.qc +++ b/qcsrc/server/mutators/mutators_include.qc @@ -109,6 +109,7 @@ #include "mutator_bloodloss.qc" #include "mutator_random_gravity.qc" #include "mutator_multijump.qc" +#include "mutator_hook.qc" #include "mutator_melee_only.qc" #include "mutator_nades.qc" #include "mutator_campcheck.qc" diff --git a/qcsrc/server/weapons/weaponsystem.qc b/qcsrc/server/weapons/weaponsystem.qc index d26a6102f..20f497054 100644 --- a/qcsrc/server/weapons/weaponsystem.qc +++ b/qcsrc/server/weapons/weaponsystem.qc @@ -767,10 +767,23 @@ void W_WeaponFrame() v_right = ri; v_up = up; - if(w) - _WEP_ACTION(self.weapon, WR_THINK); - else + { + bool key_pressed; + if (g_grappling_hook || client_hasweapon(self, WEP_HOOK.m_id, false, false) || (weaponsInMap & WEPSET_HOOK)) + key_pressed = self.button16; // if hook is enabled, use an alternate key + else + key_pressed = self.BUTTON_HOOK; + + entity e = self.offhand; + if (e.offhand_think) e.offhand_think(e, self, key_pressed); + } + + if (w) { + entity e = get_weaponinfo(self.weapon); + if (e.wr_think) e.wr_think(e, self.BUTTON_ATCK, self.BUTTON_ATCK2); + } else { _WEP_ACTION(self.weapon, WR_GONETHINK); + } if (time + self.weapon_frametime * 0.5 >= self.weapon_nextthink) { -- 2.39.2