#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);
#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;
#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");
// 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
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;
}
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;
}
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)
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)
{
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();
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)))
{
weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(blaster, animtime), w_ready);
}
}
- else if(self.BUTTON_ATCK2)
+ else if(fire2)
{
switch(WEP_CVAR(blaster, secondary))
{
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)))
}
}
- 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)))
}
}
- 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)
{
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)))
else
self.rl_release = 1;
- if(self.BUTTON_ATCK2)
+ if(fire2)
if(self.switchweapon == WEP_DEVASTATOR.m_id)
{
entity rock;
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
{
return true;
}
- if(self.BUTTON_ATCK)
+ if(fire1)
{
if(weapon_prepareattack(0, WEP_CVAR_PRI(electro, refire)))
{
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)))
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)))
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)))
{
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));
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)))
{
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)))
{
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)))
{
}
}
- 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)))
{
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;
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) \
// 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))
}
}
- if(self.BUTTON_ATCK2)
+ if(fire2)
{
if(weapon_prepareattack(1, WEP_CVAR_SEC(hook, refire)))
{
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;
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)
}
}
+ _GrapplingHookFrame();
+
return true;
}
METHOD(Hook, wr_init, bool(entity thiswep))
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))
else
{
- if(self.BUTTON_ATCK)
+ if(fire1)
if(weapon_prepareattack(0, 0))
{
self.misc_bulletcounter = 1;
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;
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
{
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)))
{
}
}
- if(self.BUTTON_ATCK2)
+ if(fire2)
{
if(W_MineLayer_PlacedMines(true))
sound(self, CH_WEAPON_B, SND_MINE_DET, VOL_BASE, ATTN_NORM);
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)))
{
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))
{
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)))
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)))
{
if(self.porto_v_angle_held)
{
- if(!self.BUTTON_ATCK2)
+ if(!fire2)
{
self.porto_v_angle_held = 0;
}
else
{
- if(self.BUTTON_ATCK2)
+ if(fire2)
{
self.porto_v_angle = self.v_angle;
self.porto_v_angle_held = 1;
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)))
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))
{
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))
{
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)))
{
}
}
- if (self.BUTTON_ATCK2)
+ if (fire2)
{
// to-do
}
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)
{
}
}
- else if(self.BUTTON_ATCK2)
+ else if(fire2)
{
if(WEP_CVAR(seeker, type) == 1)
{
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
{
}
}
}
- else if(self.BUTTON_ATCK2)
+ else if(fire2)
{
//if(self.clip_load >= 0) // we are not currently reloading
if(!self.crouch) // no crouchmelee please
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
{
}
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
{
}
}
}
- 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
{
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...
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);
}
if(self.tuba_note)
{
- if(!self.BUTTON_ATCK && !self.BUTTON_ATCK2)
+ if(!fire1 && !fire2)
{
WITH(entity, self, self.tuba_note, W_Tuba_NoteOff());
}
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
_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)))
{
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)
{
}
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);
_WEP_ACTION(self.weapon, WR_RELOAD);
else
{
- if(self.BUTTON_ATCK)
+ if(fire1)
{
if(weapon_prepareattack(0, WEP_CVAR_PRI(vortex, refire)))
{
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))
{
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))
// // 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)
}
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)
// 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)
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)
{
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();
--- /dev/null
+REGISTER_MUTATOR(hook, cvar("_g_grappling_hook"));
+
+MUTATOR_HOOKFUNCTION(hook, PlayerSpawn)
+{
+ SELFPARAM();
+ self.offhand = OFFHAND_HOOK;
+}
#include "../../common/monsters/spawn.qh"
#include "../../common/monsters/sv_monsters.qh"
-.float lifetime;
+.float nade_time_primed;
.entity nade_spawnloc;
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;
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();
}
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);
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))
{
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
self.nade_timer = 0;
+ self.offhand = OFFHAND_NADE;
+
if(self.nade_spawnloc)
{
setorigin(self, self.nade_spawnloc.origin);
#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"
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)
{