weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(hmg, refire), W_HeavyMachineGun_Attack_Auto);
}
- METHOD(HeavyMachineGun, wr_aim, void(entity thiswep))
- {
- if(vdist(self.origin - self.enemy.origin, <, 3000 - bound(0, skill, 10) * 200))
- self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, false);
- else
- self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, false);
- }
- METHOD(HeavyMachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(WEP_CVAR(hmg, reload_ammo) && actor.clip_load < WEP_CVAR(hmg, ammo)) { // forced reload
- thiswep.wr_reload(thiswep, actor, weaponentity);
- } else
- {
- if (fire & 1)
- if (weapon_prepareattack(thiswep, actor, weaponentity, false, 0))
- {
- actor.misc_bulletcounter = 0;
- W_HeavyMachineGun_Attack_Auto(thiswep, actor, weaponentity, fire);
- }
- }
- }
- METHOD(HeavyMachineGun, wr_checkammo1, bool(entity thiswep))
- {
- float ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo);
-
- if(autocvar_g_balance_hmg_reload_ammo)
- ammo_amount += self.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo);
-
- return ammo_amount;
- }
- METHOD(HeavyMachineGun, wr_checkammo2, bool(entity thiswep))
- {
- float ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo);
-
- if(autocvar_g_balance_hmg_reload_ammo)
- ammo_amount += self.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo);
-
- return ammo_amount;
- }
- METHOD(HeavyMachineGun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- W_Reload(self, WEP_CVAR(hmg, ammo), SND(RELOAD));
- }
- METHOD(HeavyMachineGun, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_THINKING_WITH_PORTALS;
- }
- METHOD(HeavyMachineGun, wr_killmessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- return WEAPON_HMG_MURDER_SNIPE;
- else
- return WEAPON_HMG_MURDER_SPRAY;
- }
+ METHOD(HeavyMachineGun, wr_aim, void(entity thiswep))
+ {
+ if(vdist(self.origin - self.enemy.origin, <, 3000 - bound(0, skill, 10) * 200))
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 0.001, false);
+ else
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(1000000, 0, 0.001, false);
+ }
+
+ METHOD(HeavyMachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(WEP_CVAR(hmg, reload_ammo) && actor.clip_load < WEP_CVAR(hmg, ammo)) { // forced reload
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ } else
+ {
+ if (fire & 1)
+ if (weapon_prepareattack(thiswep, actor, weaponentity, false, 0))
+ {
+ actor.misc_bulletcounter = 0;
+ W_HeavyMachineGun_Attack_Auto(thiswep, actor, weaponentity, fire);
+ }
+ }
+ }
+
+ METHOD(HeavyMachineGun, wr_checkammo1, bool(entity thiswep))
+ {
+ float ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo);
+
+ if(autocvar_g_balance_hmg_reload_ammo)
+ ammo_amount += self.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo);
+
+ return ammo_amount;
+ }
+
+ METHOD(HeavyMachineGun, wr_checkammo2, bool(entity thiswep))
+ {
+ float ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo);
+
+ if(autocvar_g_balance_hmg_reload_ammo)
+ ammo_amount += self.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo);
+
+ return ammo_amount;
+ }
+
+ METHOD(HeavyMachineGun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ W_Reload(self, WEP_CVAR(hmg, ammo), SND(RELOAD));
+ }
+
-METHOD(HeavyMachineGun, wr_suicidemessage, int(entity thiswep))
++METHOD(HeavyMachineGun, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_THINKING_WITH_PORTALS;
+ }
+
-METHOD(HeavyMachineGun, wr_killmessage, int(entity thiswep))
++METHOD(HeavyMachineGun, wr_killmessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_HMG_MURDER_SNIPE;
+ else
+ return WEAPON_HMG_MURDER_SPRAY;
+ }
#endif
#ifdef CSQC
MUTATOR_CALLHOOK(EditProjectile, self, missile);
}
- METHOD(RocketPropelledChainsaw, wr_aim, void(entity thiswep))
- {
- self.BUTTON_ATCK = bot_aim(WEP_CVAR(rpc, speed), 0, WEP_CVAR(rpc, lifetime), false);
- }
- METHOD(RocketPropelledChainsaw, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(WEP_CVAR(rpc, reload_ammo) && actor.clip_load < WEP_CVAR(rpc, ammo)) {
- thiswep.wr_reload(thiswep, actor, weaponentity);
- } else
- {
- if (fire & 1)
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(rpc, refire)))
- {
- W_RocketPropelledChainsaw_Attack(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(rpc, animtime), w_ready);
- }
- }
-
- if (fire & 2)
- {
- // to-do
- }
- }
- }
- METHOD(RocketPropelledChainsaw, wr_checkammo1, bool(entity thiswep))
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(rpc, ammo);
- ammo_amount += self.(weapon_load[WEP_RPC.m_id]) >= WEP_CVAR(rpc, ammo);
- return ammo_amount;
- }
- METHOD(RocketPropelledChainsaw, wr_checkammo2, bool(entity thiswep))
- {
- return false;
- }
- METHOD(RocketPropelledChainsaw, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- W_Reload(self, WEP_CVAR(rpc, ammo), SND(RELOAD));
- }
- METHOD(RocketPropelledChainsaw, wr_suicidemessage, Notification(entity thiswep))
- {
- if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH))
- return WEAPON_RPC_SUICIDE_SPLASH;
- else
- return WEAPON_RPC_SUICIDE_DIRECT;
- }
- METHOD(RocketPropelledChainsaw, wr_killmessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- return WEAPON_BLASTER_MURDER;
- else if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH))
- return WEAPON_RPC_MURDER_SPLASH;
- else
- return WEAPON_RPC_MURDER_DIRECT;
- }
+ METHOD(RocketPropelledChainsaw, wr_aim, void(entity thiswep))
+ {
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(rpc, speed), 0, WEP_CVAR(rpc, lifetime), false);
+ }
+
+ METHOD(RocketPropelledChainsaw, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(WEP_CVAR(rpc, reload_ammo) && actor.clip_load < WEP_CVAR(rpc, ammo)) {
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ } else
+ {
+ if (fire & 1)
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(rpc, refire)))
+ {
+ W_RocketPropelledChainsaw_Attack(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(rpc, animtime), w_ready);
+ }
+ }
+
+ if (fire & 2)
+ {
+ // to-do
+ }
+ }
+ }
+
+ METHOD(RocketPropelledChainsaw, wr_checkammo1, bool(entity thiswep))
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(rpc, ammo);
+ ammo_amount += self.(weapon_load[WEP_RPC.m_id]) >= WEP_CVAR(rpc, ammo);
+ return ammo_amount;
+ }
+
+ METHOD(RocketPropelledChainsaw, wr_checkammo2, bool(entity thiswep))
+ {
+ return false;
+ }
+
+ METHOD(RocketPropelledChainsaw, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ W_Reload(self, WEP_CVAR(rpc, ammo), SND(RELOAD));
+ }
+
-METHOD(RocketPropelledChainsaw, wr_suicidemessage, int(entity thiswep))
++METHOD(RocketPropelledChainsaw, wr_suicidemessage, Notification(entity thiswep))
+ {
+ if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH))
+ return WEAPON_RPC_SUICIDE_SPLASH;
+ else
+ return WEAPON_RPC_SUICIDE_DIRECT;
+ }
+
-METHOD(RocketPropelledChainsaw, wr_killmessage, int(entity thiswep))
++METHOD(RocketPropelledChainsaw, wr_killmessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_BLASTER_MURDER;
+ else if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH))
+ return WEAPON_RPC_MURDER_SPLASH;
+ else
+ return WEAPON_RPC_MURDER_DIRECT;
+ }
#endif
}
}
- METHOD(Arc, wr_aim, void(entity thiswep))
- {
- SELFPARAM();
- if(WEP_CVAR(arc, beam_botaimspeed))
- {
- self.BUTTON_ATCK = bot_aim(
- WEP_CVAR(arc, beam_botaimspeed),
- 0,
- WEP_CVAR(arc, beam_botaimlifetime),
- false
- );
- }
- else
- {
- self.BUTTON_ATCK = bot_aim(
- 1000000,
- 0,
- 0.001,
- false
- );
- }
- }
- METHOD(Arc, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- Arc_Player_SetHeat(actor);
- Arc_Smoke();
-
- bool beam_fire2 = ((fire & 2) && !WEP_CVAR(arc, bolt));
-
- if (time >= actor.arc_overheat)
- if ((fire & 1) || beam_fire2 || actor.arc_beam.beam_bursting)
- {
-
- if(actor.arc_BUTTON_ATCK_prev)
- {
- #if 0
- if(actor.animstate_startframe == actor.anim_shoot.x && actor.animstate_numframes == actor.anim_shoot.y)
- weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, autocvar_g_balance_arc_primary_animtime, w_ready);
- else
- #endif
- weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, WEP_CVAR(arc, beam_animtime), w_ready);
- }
-
- if((!actor.arc_beam) || wasfreed(actor.arc_beam))
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, boolean(beam_fire2), 0))
- {
- W_Arc_Beam(boolean(beam_fire2));
-
- if(!actor.arc_BUTTON_ATCK_prev)
- {
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready);
- actor.arc_BUTTON_ATCK_prev = true;
- }
- }
- }
-
- return;
- }
- else if(fire & 2)
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(arc, bolt_refire)))
- {
- W_Arc_Attack_Bolt(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, bolt_refire), w_ready);
- }
- }
-
- if(actor.arc_BUTTON_ATCK_prev)
- {
- sound(actor, CH_WEAPON_A, SND_ARC_STOP, VOL_BASE, ATTN_NORM);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready);
- int slot = weaponslot(weaponentity);
- ATTACK_FINISHED(actor, slot) = time + WEP_CVAR(arc, beam_refire) * W_WeaponRateFactor();
- }
- actor.arc_BUTTON_ATCK_prev = false;
-
- #if 0
- if(fire & 2)
- if(weapon_prepareattack(thiswep, actor, weaponentity, true, autocvar_g_balance_arc_secondary_refire))
- {
- W_Arc_Attack2();
- actor.arc_count = autocvar_g_balance_arc_secondary_count;
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, autocvar_g_balance_arc_secondary_animtime, w_arc_checkattack);
- actor.arc_secondarytime = time + autocvar_g_balance_arc_secondary_refire2 * W_WeaponRateFactor();
- }
- #endif
- }
- METHOD(Arc, wr_init, void(entity thiswep))
- {
- if(!arc_shotorigin[0])
- {
- arc_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 1);
- arc_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 2);
- arc_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 3);
- arc_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 4);
- }
- }
- METHOD(Arc, wr_checkammo1, bool(entity thiswep))
- {
- SELFPARAM();
- return ((!WEP_CVAR(arc, beam_ammo)) || (self.(thiswep.ammo_field) > 0));
- }
- METHOD(Arc, wr_checkammo2, bool(entity thiswep))
- {
- SELFPARAM();
- if(WEP_CVAR(arc, bolt))
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(arc, bolt_ammo);
- ammo_amount += self.(weapon_load[WEP_ARC.m_id]) >= WEP_CVAR(arc, bolt_ammo);
- return ammo_amount;
- }
- else
- return WEP_CVAR(arc, overheat_max) > 0 &&
- ((!WEP_CVAR(arc, burst_ammo)) || (self.(thiswep.ammo_field) > 0));
- }
- METHOD(Arc, wr_killmessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- return WEAPON_ARC_MURDER_SPRAY;
- else
- return WEAPON_ARC_MURDER;
- }
- METHOD(Arc, wr_drop, void(entity thiswep))
- {
- weapon_dropevent_item.arc_overheat = self.arc_overheat;
- weapon_dropevent_item.arc_cooldown = self.arc_cooldown;
- self.arc_overheat = 0;
- self.arc_cooldown = 0;
- }
- METHOD(Arc, wr_pickup, void(entity thiswep))
- {
- if ( !client_hasweapon(self, thiswep, false, false) &&
- weapon_dropevent_item.arc_overheat > time )
- {
- self.arc_overheat = weapon_dropevent_item.arc_overheat;
- self.arc_cooldown = weapon_dropevent_item.arc_cooldown;
- }
- }
+ METHOD(Arc, wr_aim, void(entity thiswep))
+ {
+ SELFPARAM();
+ if(WEP_CVAR(arc, beam_botaimspeed))
+ {
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(
+ WEP_CVAR(arc, beam_botaimspeed),
+ 0,
+ WEP_CVAR(arc, beam_botaimlifetime),
+ false
+ );
+ }
+ else
+ {
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(
+ 1000000,
+ 0,
+ 0.001,
+ false
+ );
+ }
+ }
+ METHOD(Arc, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ Arc_Player_SetHeat(actor);
+ Arc_Smoke();
+
+ bool beam_fire2 = ((fire & 2) && !WEP_CVAR(arc, bolt));
+
+ if (time >= actor.arc_overheat)
+ if ((fire & 1) || beam_fire2 || actor.arc_beam.beam_bursting)
+ {
+
+ if(actor.arc_BUTTON_ATCK_prev)
+ {
+ #if 0
+ if(actor.animstate_startframe == actor.anim_shoot.x && actor.animstate_numframes == actor.anim_shoot.y)
+ weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, autocvar_g_balance_arc_primary_animtime, w_ready);
+ else
+ #endif
+ weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, WEP_CVAR(arc, beam_animtime), w_ready);
+ }
+
+ if((!actor.arc_beam) || wasfreed(actor.arc_beam))
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, boolean(beam_fire2), 0))
+ {
+ W_Arc_Beam(boolean(beam_fire2));
+
+ if(!actor.arc_BUTTON_ATCK_prev)
+ {
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready);
+ actor.arc_BUTTON_ATCK_prev = true;
+ }
+ }
+ }
+
+ return;
+ }
+ else if(fire & 2)
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(arc, bolt_refire)))
+ {
+ W_Arc_Attack_Bolt(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, bolt_refire), w_ready);
+ }
+ }
+
+ if(actor.arc_BUTTON_ATCK_prev)
+ {
+ sound(actor, CH_WEAPON_A, SND_ARC_STOP, VOL_BASE, ATTN_NORM);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready);
+ int slot = weaponslot(weaponentity);
+ ATTACK_FINISHED(actor, slot) = time + WEP_CVAR(arc, beam_refire) * W_WeaponRateFactor();
+ }
+ actor.arc_BUTTON_ATCK_prev = false;
+
+ #if 0
+ if(fire & 2)
+ if(weapon_prepareattack(thiswep, actor, weaponentity, true, autocvar_g_balance_arc_secondary_refire))
+ {
+ W_Arc_Attack2();
+ actor.arc_count = autocvar_g_balance_arc_secondary_count;
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, autocvar_g_balance_arc_secondary_animtime, w_arc_checkattack);
+ actor.arc_secondarytime = time + autocvar_g_balance_arc_secondary_refire2 * W_WeaponRateFactor();
+ }
+ #endif
+ }
+ METHOD(Arc, wr_init, void(entity thiswep))
+ {
+ if(!arc_shotorigin[0])
+ {
+ arc_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 1);
+ arc_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 2);
+ arc_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 3);
+ arc_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 4);
+ }
+ }
+ METHOD(Arc, wr_checkammo1, bool(entity thiswep))
+ {
+ SELFPARAM();
+ return ((!WEP_CVAR(arc, beam_ammo)) || (self.(thiswep.ammo_field) > 0));
+ }
+ METHOD(Arc, wr_checkammo2, bool(entity thiswep))
+ {
+ SELFPARAM();
+ if(WEP_CVAR(arc, bolt))
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(arc, bolt_ammo);
+ ammo_amount += self.(weapon_load[WEP_ARC.m_id]) >= WEP_CVAR(arc, bolt_ammo);
+ return ammo_amount;
+ }
+ else
+ return WEP_CVAR(arc, overheat_max) > 0 &&
+ ((!WEP_CVAR(arc, burst_ammo)) || (self.(thiswep.ammo_field) > 0));
+ }
-METHOD(Arc, wr_killmessage, int(entity thiswep))
++METHOD(Arc, wr_killmessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_ARC_MURDER_SPRAY;
+ else
+ return WEAPON_ARC_MURDER;
+ }
+ METHOD(Arc, wr_drop, void(entity thiswep))
+ {
+ weapon_dropevent_item.arc_overheat = self.arc_overheat;
+ weapon_dropevent_item.arc_cooldown = self.arc_cooldown;
+ self.arc_overheat = 0;
+ self.arc_cooldown = 0;
+ }
+ METHOD(Arc, wr_pickup, void(entity thiswep))
+ {
+ if ( !client_hasweapon(self, thiswep, false, false) &&
+ weapon_dropevent_item.arc_overheat > time )
+ {
+ self.arc_overheat = weapon_dropevent_item.arc_overheat;
+ self.arc_cooldown = weapon_dropevent_item.arc_cooldown;
+ }
+ }
#endif
#ifdef CSQC
bool autocvar_cl_arcbeam_teamcolor = true;
}
}
- METHOD(Blaster, wr_aim, void(entity thiswep))
- {
- if(WEP_CVAR(blaster, secondary))
- {
- if((random() * (WEP_CVAR_PRI(blaster, damage) + WEP_CVAR_SEC(blaster, damage))) > WEP_CVAR_PRI(blaster, damage))
- { self.BUTTON_ATCK2 = bot_aim(WEP_CVAR_SEC(blaster, speed), 0, WEP_CVAR_SEC(blaster, lifetime), false); }
- else
- { self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
- }
- else
- { self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
- }
+ METHOD(Blaster, wr_aim, void(entity thiswep))
+ {
+ if(WEP_CVAR(blaster, secondary))
+ {
+ if((random() * (WEP_CVAR_PRI(blaster, damage) + WEP_CVAR_SEC(blaster, damage))) > WEP_CVAR_PRI(blaster, damage))
+ { PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR_SEC(blaster, speed), 0, WEP_CVAR_SEC(blaster, lifetime), false); }
+ else
+ { PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
+ }
+ else
+ { PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
+ }
- METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(fire & 1)
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(blaster, refire)))
- {
- W_Blaster_Attack(
- actor,
- WEP_BLASTER.m_id,
- WEP_CVAR_PRI(blaster, shotangle),
- WEP_CVAR_PRI(blaster, damage),
- WEP_CVAR_PRI(blaster, edgedamage),
- WEP_CVAR_PRI(blaster, radius),
- WEP_CVAR_PRI(blaster, force),
- WEP_CVAR_PRI(blaster, speed),
- WEP_CVAR_PRI(blaster, spread),
- WEP_CVAR_PRI(blaster, delay),
- WEP_CVAR_PRI(blaster, lifetime)
- );
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(blaster, animtime), w_ready);
- }
- }
- else if(fire & 2)
- {
- switch(WEP_CVAR(blaster, secondary))
- {
- case 0: // switch to last used weapon
- {
- if(PS(actor).m_switchweapon == WEP_BLASTER) // don't do this if already switching
- W_LastWeapon(actor);
- break;
- }
+ METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(fire & 1)
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(blaster, refire)))
+ {
+ W_Blaster_Attack(
+ actor,
+ WEP_BLASTER.m_id,
+ WEP_CVAR_PRI(blaster, shotangle),
+ WEP_CVAR_PRI(blaster, damage),
+ WEP_CVAR_PRI(blaster, edgedamage),
+ WEP_CVAR_PRI(blaster, radius),
+ WEP_CVAR_PRI(blaster, force),
+ WEP_CVAR_PRI(blaster, speed),
+ WEP_CVAR_PRI(blaster, spread),
+ WEP_CVAR_PRI(blaster, delay),
+ WEP_CVAR_PRI(blaster, lifetime)
+ );
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(blaster, animtime), w_ready);
+ }
+ }
+ else if(fire & 2)
+ {
+ switch(WEP_CVAR(blaster, secondary))
+ {
+ case 0: // switch to last used weapon
+ {
+ if(PS(actor).m_switchweapon == WEP_BLASTER) // don't do this if already switching
+ W_LastWeapon(actor);
+ break;
+ }
- case 1: // normal projectile secondary
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(blaster, refire)))
- {
- W_Blaster_Attack(
- actor,
- WEP_BLASTER.m_id | HITTYPE_SECONDARY,
- WEP_CVAR_SEC(blaster, shotangle),
- WEP_CVAR_SEC(blaster, damage),
- WEP_CVAR_SEC(blaster, edgedamage),
- WEP_CVAR_SEC(blaster, radius),
- WEP_CVAR_SEC(blaster, force),
- WEP_CVAR_SEC(blaster, speed),
- WEP_CVAR_SEC(blaster, spread),
- WEP_CVAR_SEC(blaster, delay),
- WEP_CVAR_SEC(blaster, lifetime)
- );
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(blaster, animtime), w_ready);
- }
+ case 1: // normal projectile secondary
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(blaster, refire)))
+ {
+ W_Blaster_Attack(
+ actor,
+ WEP_BLASTER.m_id | HITTYPE_SECONDARY,
+ WEP_CVAR_SEC(blaster, shotangle),
+ WEP_CVAR_SEC(blaster, damage),
+ WEP_CVAR_SEC(blaster, edgedamage),
+ WEP_CVAR_SEC(blaster, radius),
+ WEP_CVAR_SEC(blaster, force),
+ WEP_CVAR_SEC(blaster, speed),
+ WEP_CVAR_SEC(blaster, spread),
+ WEP_CVAR_SEC(blaster, delay),
+ WEP_CVAR_SEC(blaster, lifetime)
+ );
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(blaster, animtime), w_ready);
+ }
- break;
- }
- }
- }
- }
+ break;
+ }
+ }
+ }
+ }
- METHOD(Blaster, wr_setup, void(entity thiswep))
- {
- self.ammo_field = ammo_none;
- }
+ METHOD(Blaster, wr_setup, void(entity thiswep))
+ {
+ self.ammo_field = ammo_none;
+ }
- METHOD(Blaster, wr_checkammo1, bool(entity thiswep))
- {
- return true; // infinite ammo
- }
+ METHOD(Blaster, wr_checkammo1, bool(entity thiswep))
+ {
+ return true; // infinite ammo
+ }
- METHOD(Blaster, wr_checkammo2, bool(entity thiswep))
- {
- return true; // blaster has infinite ammo
- }
+ METHOD(Blaster, wr_checkammo2, bool(entity thiswep))
+ {
+ return true; // blaster has infinite ammo
+ }
- METHOD(Blaster, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_BLASTER_SUICIDE;
- }
-METHOD(Blaster, wr_suicidemessage, int(entity thiswep))
++METHOD(Blaster, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_BLASTER_SUICIDE;
+ }
- METHOD(Blaster, wr_killmessage, Notification(entity thiswep))
- {
- return WEAPON_BLASTER_MURDER;
- }
-METHOD(Blaster, wr_killmessage, int(entity thiswep))
++METHOD(Blaster, wr_killmessage, Notification(entity thiswep))
+ {
+ return WEAPON_BLASTER_MURDER;
+ }
#endif
#ifdef CSQC
}
}
- METHOD(Crylink, wr_aim, void(entity thiswep))
- {
- SELFPARAM();
- if(random() < 0.10)
- self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(crylink, speed), 0, WEP_CVAR_PRI(crylink, middle_lifetime), false);
- else
- self.BUTTON_ATCK2 = bot_aim(WEP_CVAR_SEC(crylink, speed), 0, WEP_CVAR_SEC(crylink, middle_lifetime), false);
- }
- METHOD(Crylink, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(autocvar_g_balance_crylink_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo))) { // forced reload
- thiswep.wr_reload(thiswep, actor, weaponentity);
- }
-
- if(fire & 1)
- {
- if(actor.crylink_waitrelease != 1)
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(crylink, refire)))
- {
- W_Crylink_Attack(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(crylink, animtime), w_ready);
- }
- }
-
- if((fire & 2) && autocvar_g_balance_crylink_secondary)
- {
- if(actor.crylink_waitrelease != 2)
- if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(crylink, refire)))
- {
- W_Crylink_Attack2(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(crylink, animtime), w_ready);
- }
- }
-
- if((actor.crylink_waitrelease == 1 && !(fire & 1)) || (actor.crylink_waitrelease == 2 && !(fire & 2)))
- {
- if(!actor.crylink_lastgroup || time > actor.crylink_lastgroup.teleport_time)
- {
- // fired and released now!
- if(actor.crylink_lastgroup)
- {
- vector pos;
- entity linkjoineffect;
- float isprimary = (actor.crylink_waitrelease == 1);
-
- pos = W_Crylink_LinkJoin(actor.crylink_lastgroup, WEP_CVAR_BOTH(crylink, isprimary, joinspread) * WEP_CVAR_BOTH(crylink, isprimary, speed));
-
- linkjoineffect = new(linkjoineffect);
- linkjoineffect.think = W_Crylink_LinkJoinEffect_Think;
- linkjoineffect.nextthink = time + w_crylink_linkjoin_time;
- linkjoineffect.owner = actor;
- setorigin(linkjoineffect, pos);
- }
- actor.crylink_waitrelease = 0;
- if(!thiswep.wr_checkammo1(thiswep) && !thiswep.wr_checkammo2(thiswep))
- if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
- {
- // ran out of ammo!
- actor.cnt = WEP_CRYLINK.m_id;
- PS(actor).m_switchweapon = w_getbestweapon(actor);
- }
- }
- }
- }
- METHOD(Crylink, wr_checkammo1, bool(entity thiswep))
- {
- SELFPARAM();
- // don't "run out of ammo" and switch weapons while waiting for release
- if(self.crylink_lastgroup && self.crylink_waitrelease)
- return true;
-
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(crylink, ammo);
- ammo_amount += self.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_PRI(crylink, ammo);
- return ammo_amount;
- }
- METHOD(Crylink, wr_checkammo2, bool(entity thiswep))
- {
- SELFPARAM();
- // don't "run out of ammo" and switch weapons while waiting for release
- if(self.crylink_lastgroup && self.crylink_waitrelease)
- return true;
-
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(crylink, ammo);
- ammo_amount += self.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_SEC(crylink, ammo);
- return ammo_amount;
- }
- METHOD(Crylink, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- W_Reload(self, min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo)), SND(RELOAD));
- }
- METHOD(Crylink, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_CRYLINK_SUICIDE;
- }
- METHOD(Crylink, wr_killmessage, Notification(entity thiswep))
- {
- return WEAPON_CRYLINK_MURDER;
- }
+ METHOD(Crylink, wr_aim, void(entity thiswep))
+ {
+ SELFPARAM();
+ if(random() < 0.10)
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(crylink, speed), 0, WEP_CVAR_PRI(crylink, middle_lifetime), false);
+ else
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR_SEC(crylink, speed), 0, WEP_CVAR_SEC(crylink, middle_lifetime), false);
+ }
+ METHOD(Crylink, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(autocvar_g_balance_crylink_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo))) { // forced reload
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ }
+
+ if(fire & 1)
+ {
+ if(actor.crylink_waitrelease != 1)
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(crylink, refire)))
+ {
+ W_Crylink_Attack(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(crylink, animtime), w_ready);
+ }
+ }
+
+ if((fire & 2) && autocvar_g_balance_crylink_secondary)
+ {
+ if(actor.crylink_waitrelease != 2)
+ if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(crylink, refire)))
+ {
+ W_Crylink_Attack2(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(crylink, animtime), w_ready);
+ }
+ }
+
+ if((actor.crylink_waitrelease == 1 && !(fire & 1)) || (actor.crylink_waitrelease == 2 && !(fire & 2)))
+ {
+ if(!actor.crylink_lastgroup || time > actor.crylink_lastgroup.teleport_time)
+ {
+ // fired and released now!
+ if(actor.crylink_lastgroup)
+ {
+ vector pos;
+ entity linkjoineffect;
+ float isprimary = (actor.crylink_waitrelease == 1);
+
+ pos = W_Crylink_LinkJoin(actor.crylink_lastgroup, WEP_CVAR_BOTH(crylink, isprimary, joinspread) * WEP_CVAR_BOTH(crylink, isprimary, speed));
+
+ linkjoineffect = new(linkjoineffect);
+ linkjoineffect.think = W_Crylink_LinkJoinEffect_Think;
+ linkjoineffect.nextthink = time + w_crylink_linkjoin_time;
+ linkjoineffect.owner = actor;
+ setorigin(linkjoineffect, pos);
+ }
+ actor.crylink_waitrelease = 0;
+ if(!thiswep.wr_checkammo1(thiswep) && !thiswep.wr_checkammo2(thiswep))
+ if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+ {
+ // ran out of ammo!
+ actor.cnt = WEP_CRYLINK.m_id;
+ PS(actor).m_switchweapon = w_getbestweapon(actor);
+ }
+ }
+ }
+ }
+ METHOD(Crylink, wr_checkammo1, bool(entity thiswep))
+ {
+ SELFPARAM();
+ // don't "run out of ammo" and switch weapons while waiting for release
+ if(self.crylink_lastgroup && self.crylink_waitrelease)
+ return true;
+
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(crylink, ammo);
+ ammo_amount += self.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_PRI(crylink, ammo);
+ return ammo_amount;
+ }
+ METHOD(Crylink, wr_checkammo2, bool(entity thiswep))
+ {
+ SELFPARAM();
+ // don't "run out of ammo" and switch weapons while waiting for release
+ if(self.crylink_lastgroup && self.crylink_waitrelease)
+ return true;
+
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(crylink, ammo);
+ ammo_amount += self.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_SEC(crylink, ammo);
+ return ammo_amount;
+ }
+ METHOD(Crylink, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ W_Reload(self, min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo)), SND(RELOAD));
+ }
-METHOD(Crylink, wr_suicidemessage, int(entity thiswep))
++METHOD(Crylink, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_CRYLINK_SUICIDE;
+ }
-METHOD(Crylink, wr_killmessage, int(entity thiswep))
++METHOD(Crylink, wr_killmessage, Notification(entity thiswep))
+ {
+ return WEAPON_CRYLINK_MURDER;
+ }
#endif
#ifdef CSQC
- METHOD(Crylink, wr_impacteffect, void(entity thiswep))
- {
- SELFPARAM();
- vector org2;
- org2 = w_org + w_backoff * 2;
- if(w_deathtype & HITTYPE_SECONDARY)
- {
- pointparticles(EFFECT_CRYLINK_IMPACT2, org2, '0 0 0', 1);
- if(!w_issilent)
- sound(self, CH_SHOTS, SND_CRYLINK_IMPACT2, VOL_BASE, ATTN_NORM);
- }
- else
- {
- pointparticles(EFFECT_CRYLINK_IMPACT, org2, '0 0 0', 1);
- if(!w_issilent)
- sound(self, CH_SHOTS, SND_CRYLINK_IMPACT, VOL_BASE, ATTN_NORM);
- }
- }
+ METHOD(Crylink, wr_impacteffect, void(entity thiswep))
+ {
+ SELFPARAM();
+ vector org2;
+ org2 = w_org + w_backoff * 2;
+ if(w_deathtype & HITTYPE_SECONDARY)
+ {
+ pointparticles(EFFECT_CRYLINK_IMPACT2, org2, '0 0 0', 1);
+ if(!w_issilent)
+ sound(self, CH_SHOTS, SND_CRYLINK_IMPACT2, VOL_BASE, ATTN_NORM);
+ }
+ else
+ {
+ pointparticles(EFFECT_CRYLINK_IMPACT, org2, '0 0 0', 1);
+ if(!w_issilent)
+ sound(self, CH_SHOTS, SND_CRYLINK_IMPACT, VOL_BASE, ATTN_NORM);
+ }
+ }
#endif
#endif
MUTATOR_CALLHOOK(EditProjectile, self, missile);
}
- #if 0
- METHOD(Devastator, wr_aim, void(entity thiswep))
- {
- // aim and decide to fire if appropriate
- self.BUTTON_ATCK = bot_aim(WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false);
- if(skill >= 2) // skill 0 and 1 bots won't detonate rockets!
- {
- // decide whether to detonate rockets
- entity missile, targetlist, targ;
- targetlist = findchainfloat(bot_attack, true);
- for(missile = world; (missile = find(missile, classname, "rocket")); ) if(missile.realowner == self)
- {
- targ = targetlist;
- while(targ)
- {
- if(targ != missile.realowner && vlen(targ.origin - missile.origin) < WEP_CVAR(devastator, radius))
- {
- self.BUTTON_ATCK2 = true;
- break;
- }
- targ = targ.chain;
- }
- }
-
- if(self.BUTTON_ATCK2) self.BUTTON_ATCK = false;
- }
- }
- #else
- METHOD(Devastator, wr_aim, void(entity thiswep))
- {
- // aim and decide to fire if appropriate
- self.BUTTON_ATCK = bot_aim(WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false);
- if(skill >= 2) // skill 0 and 1 bots won't detonate rockets!
- {
- // decide whether to detonate rockets
- entity targetlist, targ;
- float edgedamage, coredamage, edgeradius, recipricoledgeradius, d;
- float selfdamage, teamdamage, enemydamage;
- edgedamage = WEP_CVAR(devastator, edgedamage);
- coredamage = WEP_CVAR(devastator, damage);
- edgeradius = WEP_CVAR(devastator, radius);
- recipricoledgeradius = 1 / edgeradius;
- selfdamage = 0;
- teamdamage = 0;
- enemydamage = 0;
- targetlist = findchainfloat(bot_attack, true);
- FOREACH_ENTITY_ENT(realowner, self,
- {
- if(it.classname != "rocket") continue;
-
- targ = targetlist;
- while(targ)
- {
- d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - it.origin);
- d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
- // count potential damage according to type of target
- if(targ == self)
- selfdamage = selfdamage + d;
- else if(targ.team == self.team && teamplay)
- teamdamage = teamdamage + d;
- else if(bot_shouldattack(targ))
- enemydamage = enemydamage + d;
- targ = targ.chain;
- }
- });
- float desirabledamage;
- desirabledamage = enemydamage;
- if(time > self.invincible_finished && time > self.spawnshieldtime)
- desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent;
- if(teamplay && self.team)
- desirabledamage = desirabledamage - teamdamage;
-
- FOREACH_ENTITY_ENT(realowner, self,
- {
- if(it.classname != "rocket") continue;
-
- makevectors(it.v_angle);
- targ = targetlist;
- if(skill > 9) // normal players only do this for the target they are tracking
- {
- targ = targetlist;
- while(targ)
- {
- if(
- (v_forward * normalize(it.origin - targ.origin)< 0.1)
- && desirabledamage > 0.1*coredamage
- )self.BUTTON_ATCK2 = true;
- targ = targ.chain;
- }
- }
- else
- {
- float distance; distance= bound(300,vlen(self.origin-self.enemy.origin),30000);
- //As the distance gets larger, a correct detonation gets near imposible
- //Bots are assumed to use the rocket spawnfunc_light to see if the rocket gets near a player
- if(v_forward * normalize(it.origin - self.enemy.origin)< 0.1)
- if(IS_PLAYER(self.enemy))
- if(desirabledamage >= 0.1*coredamage)
- if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1))
- self.BUTTON_ATCK2 = true;
- // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n");
- }
- });
- // if we would be doing at X percent of the core damage, detonate it
- // but don't fire a new shot at the same time!
- if(desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events
- self.BUTTON_ATCK2 = true;
- if((skill > 6.5) && (selfdamage > self.health))
- self.BUTTON_ATCK2 = false;
- //if(self.BUTTON_ATCK2 == true)
- // dprint(ftos(desirabledamage),"\n");
- if(self.BUTTON_ATCK2 == true) self.BUTTON_ATCK = false;
- }
- }
- #endif
- METHOD(Devastator, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(WEP_CVAR(devastator, reload_ammo) && actor.clip_load < WEP_CVAR(devastator, ammo)) { // forced reload
- thiswep.wr_reload(thiswep, actor, weaponentity);
- } else {
- if(fire & 1)
- {
- if(actor.rl_release || WEP_CVAR(devastator, guidestop))
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(devastator, refire)))
- {
- W_Devastator_Attack(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(devastator, animtime), w_ready);
- actor.rl_release = 0;
- }
- }
- else
- actor.rl_release = 1;
-
- if(fire & 2)
- if(PS(actor).m_switchweapon == WEP_DEVASTATOR)
- {
- entity rock;
- bool rockfound = false;
- for(rock = world; (rock = find(rock, classname, "rocket")); ) if(rock.realowner == actor)
- {
- if(!rock.rl_detonate_later)
- {
- rock.rl_detonate_later = true;
- rockfound = true;
- }
- }
- if(rockfound)
- sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM);
- }
- }
- }
- METHOD(Devastator, wr_setup, void(entity thiswep))
- {
- self.rl_release = 1;
- }
- METHOD(Devastator, wr_checkammo1, bool(entity thiswep))
- {
- #if 0
- // don't switch while guiding a missile
- if(ATTACK_FINISHED(self, slot) <= time || PS(self).m_weapon != WEP_DEVASTATOR)
- {
- ammo_amount = false;
- if(WEP_CVAR(devastator, reload_ammo))
- {
- if(self.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo) && self.(weapon_load[WEP_DEVASTATOR.m_id]) < WEP_CVAR(devastator, ammo))
- ammo_amount = true;
- }
- else if(self.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo))
- ammo_amount = true;
- return !ammo_amount;
- }
- #endif
- #if 0
- if(self.rl_release == 0)
- {
- LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: TRUE\n", self.rl_release, self.(thiswep.ammo_field), WEP_CVAR(devastator, ammo));
- return true;
- }
- else
- {
- ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(devastator, ammo);
- ammo_amount += self.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo);
- LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: %s\n", self.rl_release, self.(thiswep.ammo_field), WEP_CVAR(devastator, ammo), (ammo_amount ? "TRUE" : "FALSE"));
- return ammo_amount;
- }
- #else
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(devastator, ammo);
- ammo_amount += self.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo);
- return ammo_amount;
- #endif
- }
- METHOD(Devastator, wr_checkammo2, bool(entity thiswep))
- {
- return false;
- }
- METHOD(Devastator, wr_resetplayer, void(entity thiswep))
- {
- self.lastrocket = NULL; // stop rocket guiding, no revenge from the grave!
- self.rl_release = 0;
- }
- METHOD(Devastator, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- W_Reload(self, WEP_CVAR(devastator, ammo), SND(RELOAD));
- }
- METHOD(Devastator, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_DEVASTATOR_SUICIDE;
- }
- METHOD(Devastator, wr_killmessage, Notification(entity thiswep))
- {
- if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH))
- return WEAPON_DEVASTATOR_MURDER_SPLASH;
- else
- return WEAPON_DEVASTATOR_MURDER_DIRECT;
- }
+ #if 0
+ METHOD(Devastator, wr_aim, void(entity thiswep))
+ {
+ // aim and decide to fire if appropriate
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false);
+ if(skill >= 2) // skill 0 and 1 bots won't detonate rockets!
+ {
+ // decide whether to detonate rockets
+ entity missile, targetlist, targ;
+ targetlist = findchainfloat(bot_attack, true);
+ for(missile = world; (missile = find(missile, classname, "rocket")); ) if(missile.realowner == self)
+ {
+ targ = targetlist;
+ while(targ)
+ {
+ if(targ != missile.realowner && vlen(targ.origin - missile.origin) < WEP_CVAR(devastator, radius))
+ {
+ PHYS_INPUT_BUTTON_ATCK2(self) = true;
+ break;
+ }
+ targ = targ.chain;
+ }
+ }
+
+ if(PHYS_INPUT_BUTTON_ATCK2(self)) PHYS_INPUT_BUTTON_ATCK(self) = false;
+ }
+ }
+ #else
+ METHOD(Devastator, wr_aim, void(entity thiswep))
+ {
+ // aim and decide to fire if appropriate
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false);
+ if(skill >= 2) // skill 0 and 1 bots won't detonate rockets!
+ {
+ // decide whether to detonate rockets
+ entity targetlist, targ;
+ float edgedamage, coredamage, edgeradius, recipricoledgeradius, d;
+ float selfdamage, teamdamage, enemydamage;
+ edgedamage = WEP_CVAR(devastator, edgedamage);
+ coredamage = WEP_CVAR(devastator, damage);
+ edgeradius = WEP_CVAR(devastator, radius);
+ recipricoledgeradius = 1 / edgeradius;
+ selfdamage = 0;
+ teamdamage = 0;
+ enemydamage = 0;
+ targetlist = findchainfloat(bot_attack, true);
+ FOREACH_ENTITY_ENT(realowner, self,
+ {
+ if(it.classname != "rocket") continue;
+
+ targ = targetlist;
+ while(targ)
+ {
+ d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - it.origin);
+ d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
+ // count potential damage according to type of target
+ if(targ == self)
+ selfdamage = selfdamage + d;
+ else if(targ.team == self.team && teamplay)
+ teamdamage = teamdamage + d;
+ else if(bot_shouldattack(targ))
+ enemydamage = enemydamage + d;
+ targ = targ.chain;
+ }
+ });
+ float desirabledamage;
+ desirabledamage = enemydamage;
+ if(time > self.invincible_finished && time > self.spawnshieldtime)
+ desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent;
+ if(teamplay && self.team)
+ desirabledamage = desirabledamage - teamdamage;
+
+ FOREACH_ENTITY_ENT(realowner, self,
+ {
+ if(it.classname != "rocket") continue;
+
+ makevectors(it.v_angle);
+ targ = targetlist;
+ if(skill > 9) // normal players only do this for the target they are tracking
+ {
+ targ = targetlist;
+ while(targ)
+ {
+ if(
+ (v_forward * normalize(it.origin - targ.origin)< 0.1)
+ && desirabledamage > 0.1*coredamage
+ ) PHYS_INPUT_BUTTON_ATCK2(self) = true;
+ targ = targ.chain;
+ }
+ }
+ else
+ {
+ float distance; distance= bound(300,vlen(self.origin-self.enemy.origin),30000);
+ //As the distance gets larger, a correct detonation gets near imposible
+ //Bots are assumed to use the rocket spawnfunc_light to see if the rocket gets near a player
+ if(v_forward * normalize(it.origin - self.enemy.origin)< 0.1)
+ if(IS_PLAYER(self.enemy))
+ if(desirabledamage >= 0.1*coredamage)
+ if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1))
+ PHYS_INPUT_BUTTON_ATCK2(self) = true;
+ // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n");
+ }
+ });
+ // if we would be doing at X percent of the core damage, detonate it
+ // but don't fire a new shot at the same time!
+ if(desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events
+ PHYS_INPUT_BUTTON_ATCK2(self) = true;
+ if((skill > 6.5) && (selfdamage > self.health))
+ PHYS_INPUT_BUTTON_ATCK2(self) = false;
+ //if(PHYS_INPUT_BUTTON_ATCK2(self) == true)
+ // dprint(ftos(desirabledamage),"\n");
+ if(PHYS_INPUT_BUTTON_ATCK2(self)) PHYS_INPUT_BUTTON_ATCK(self) = false;
+ }
+ }
+ #endif
+ METHOD(Devastator, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(WEP_CVAR(devastator, reload_ammo) && actor.clip_load < WEP_CVAR(devastator, ammo)) { // forced reload
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ } else {
+ if(fire & 1)
+ {
+ if(actor.rl_release || WEP_CVAR(devastator, guidestop))
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(devastator, refire)))
+ {
+ W_Devastator_Attack(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(devastator, animtime), w_ready);
+ actor.rl_release = 0;
+ }
+ }
+ else
+ actor.rl_release = 1;
+
+ if(fire & 2)
+ if(PS(actor).m_switchweapon == WEP_DEVASTATOR)
+ {
+ entity rock;
+ bool rockfound = false;
+ for(rock = world; (rock = find(rock, classname, "rocket")); ) if(rock.realowner == actor)
+ {
+ if(!rock.rl_detonate_later)
+ {
+ rock.rl_detonate_later = true;
+ rockfound = true;
+ }
+ }
+ if(rockfound)
+ sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM);
+ }
+ }
+ }
+ METHOD(Devastator, wr_setup, void(entity thiswep))
+ {
+ self.rl_release = 1;
+ }
+ METHOD(Devastator, wr_checkammo1, bool(entity thiswep))
+ {
+ #if 0
+ // don't switch while guiding a missile
+ if(ATTACK_FINISHED(self, slot) <= time || PS(self).m_weapon != WEP_DEVASTATOR)
+ {
+ ammo_amount = false;
+ if(WEP_CVAR(devastator, reload_ammo))
+ {
+ if(self.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo) && self.(weapon_load[WEP_DEVASTATOR.m_id]) < WEP_CVAR(devastator, ammo))
+ ammo_amount = true;
+ }
+ else if(self.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo))
+ ammo_amount = true;
+ return !ammo_amount;
+ }
+ #endif
+ #if 0
+ if(self.rl_release == 0)
+ {
+ LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: TRUE\n", self.rl_release, self.(thiswep.ammo_field), WEP_CVAR(devastator, ammo));
+ return true;
+ }
+ else
+ {
+ ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(devastator, ammo);
+ ammo_amount += self.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo);
+ LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: %s\n", self.rl_release, self.(thiswep.ammo_field), WEP_CVAR(devastator, ammo), (ammo_amount ? "TRUE" : "FALSE"));
+ return ammo_amount;
+ }
+ #else
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(devastator, ammo);
+ ammo_amount += self.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo);
+ return ammo_amount;
+ #endif
+ }
+ METHOD(Devastator, wr_checkammo2, bool(entity thiswep))
+ {
+ return false;
+ }
+ METHOD(Devastator, wr_resetplayer, void(entity thiswep))
+ {
+ self.lastrocket = NULL; // stop rocket guiding, no revenge from the grave!
+ self.rl_release = 0;
+ }
+ METHOD(Devastator, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ W_Reload(self, WEP_CVAR(devastator, ammo), SND(RELOAD));
+ }
-METHOD(Devastator, wr_suicidemessage, int(entity thiswep))
++METHOD(Devastator, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_DEVASTATOR_SUICIDE;
+ }
-METHOD(Devastator, wr_killmessage, int(entity thiswep))
++METHOD(Devastator, wr_killmessage, Notification(entity thiswep))
+ {
+ if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH))
+ return WEAPON_DEVASTATOR_MURDER_SPLASH;
+ else
+ return WEAPON_DEVASTATOR_MURDER_DIRECT;
+ }
#endif
#ifdef CSQC
.float bot_secondary_electromooth;
- METHOD(Electro, wr_aim, void(entity thiswep))
- {
- self.BUTTON_ATCK = self.BUTTON_ATCK2 = false;
- if(vdist(self.origin - self.enemy.origin, >, 1000)) { self.bot_secondary_electromooth = 0; }
- if(self.bot_secondary_electromooth == 0)
- {
- float shoot;
-
- if(WEP_CVAR_PRI(electro, speed))
- shoot = bot_aim(WEP_CVAR_PRI(electro, speed), 0, WEP_CVAR_PRI(electro, lifetime), false);
- else
- shoot = bot_aim(1000000, 0, 0.001, false);
-
- if(shoot)
- {
- self.BUTTON_ATCK = true;
- if(random() < 0.01) self.bot_secondary_electromooth = 1;
- }
- }
- else
- {
- if(bot_aim(WEP_CVAR_SEC(electro, speed), WEP_CVAR_SEC(electro, speed_up), WEP_CVAR_SEC(electro, lifetime), true))
- {
- self.BUTTON_ATCK2 = true;
- if(random() < 0.03) self.bot_secondary_electromooth = 0;
- }
- }
- }
- METHOD(Electro, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(autocvar_g_balance_electro_reload_ammo) // forced reload // WEAPONTODO
- {
- float ammo_amount = 0;
- if(actor.clip_load >= WEP_CVAR_PRI(electro, ammo))
- ammo_amount = 1;
- if(actor.clip_load >= WEP_CVAR_SEC(electro, ammo))
- ammo_amount += 1;
-
- if(!ammo_amount)
- {
- thiswep.wr_reload(thiswep, actor, weaponentity);
- return;
- }
- }
-
- if(fire & 1)
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(electro, refire)))
- {
- W_Electro_Attack_Bolt(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
- }
- }
- else if(fire & 2)
- {
- if(time >= actor.electro_secondarytime)
- if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(electro, refire)))
- {
- W_Electro_Attack_Orb(thiswep);
- actor.electro_count = WEP_CVAR_SEC(electro, count);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(electro, animtime), W_Electro_CheckAttack);
- actor.electro_secondarytime = time + WEP_CVAR_SEC(electro, refire2) * W_WeaponRateFactor();
- }
- }
- }
- METHOD(Electro, wr_checkammo1, bool(entity thiswep))
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(electro, ammo);
- ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_PRI(electro, ammo);
- return ammo_amount;
- }
- METHOD(Electro, wr_checkammo2, bool(entity thiswep))
- {
- float ammo_amount;
- if(WEP_CVAR(electro, combo_safeammocheck)) // true if you can fire at least one secondary blob AND one primary shot after it, otherwise false.
- {
- ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo);
- ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo);
- }
- else
- {
- ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(electro, ammo);
- ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo);
- }
- return ammo_amount;
- }
- METHOD(Electro, wr_resetplayer, void(entity thiswep))
- {
- self.electro_secondarytime = time;
- }
- METHOD(Electro, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- W_Reload(self, min(WEP_CVAR_PRI(electro, ammo), WEP_CVAR_SEC(electro, ammo)), SND(RELOAD));
- }
- METHOD(Electro, wr_suicidemessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- return WEAPON_ELECTRO_SUICIDE_ORBS;
- else
- return WEAPON_ELECTRO_SUICIDE_BOLT;
- }
- METHOD(Electro, wr_killmessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- {
- return WEAPON_ELECTRO_MURDER_ORBS;
- }
- else
- {
- if(w_deathtype & HITTYPE_BOUNCE)
- return WEAPON_ELECTRO_MURDER_COMBO;
- else
- return WEAPON_ELECTRO_MURDER_BOLT;
- }
- }
+ METHOD(Electro, wr_aim, void(entity thiswep))
+ {
+ PHYS_INPUT_BUTTON_ATCK(self) = PHYS_INPUT_BUTTON_ATCK2(self) = false;
+ if(vdist(self.origin - self.enemy.origin, >, 1000)) { self.bot_secondary_electromooth = 0; }
+ if(self.bot_secondary_electromooth == 0)
+ {
+ float shoot;
+
+ if(WEP_CVAR_PRI(electro, speed))
+ shoot = bot_aim(WEP_CVAR_PRI(electro, speed), 0, WEP_CVAR_PRI(electro, lifetime), false);
+ else
+ shoot = bot_aim(1000000, 0, 0.001, false);
+
+ if(shoot)
+ {
+ PHYS_INPUT_BUTTON_ATCK(self) = true;
+ if(random() < 0.01) self.bot_secondary_electromooth = 1;
+ }
+ }
+ else
+ {
+ if(bot_aim(WEP_CVAR_SEC(electro, speed), WEP_CVAR_SEC(electro, speed_up), WEP_CVAR_SEC(electro, lifetime), true))
+ {
+ PHYS_INPUT_BUTTON_ATCK2(self) = true;
+ if(random() < 0.03) self.bot_secondary_electromooth = 0;
+ }
+ }
+ }
+ METHOD(Electro, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(autocvar_g_balance_electro_reload_ammo) // forced reload // WEAPONTODO
+ {
+ float ammo_amount = 0;
+ if(actor.clip_load >= WEP_CVAR_PRI(electro, ammo))
+ ammo_amount = 1;
+ if(actor.clip_load >= WEP_CVAR_SEC(electro, ammo))
+ ammo_amount += 1;
+
+ if(!ammo_amount)
+ {
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ return;
+ }
+ }
+
+ if(fire & 1)
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(electro, refire)))
+ {
+ W_Electro_Attack_Bolt(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
+ }
+ }
+ else if(fire & 2)
+ {
+ if(time >= actor.electro_secondarytime)
+ if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(electro, refire)))
+ {
+ W_Electro_Attack_Orb(thiswep);
+ actor.electro_count = WEP_CVAR_SEC(electro, count);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(electro, animtime), W_Electro_CheckAttack);
+ actor.electro_secondarytime = time + WEP_CVAR_SEC(electro, refire2) * W_WeaponRateFactor();
+ }
+ }
+ }
+ METHOD(Electro, wr_checkammo1, bool(entity thiswep))
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(electro, ammo);
+ ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_PRI(electro, ammo);
+ return ammo_amount;
+ }
+ METHOD(Electro, wr_checkammo2, bool(entity thiswep))
+ {
+ float ammo_amount;
+ if(WEP_CVAR(electro, combo_safeammocheck)) // true if you can fire at least one secondary blob AND one primary shot after it, otherwise false.
+ {
+ ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo);
+ ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo);
+ }
+ else
+ {
+ ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(electro, ammo);
+ ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo);
+ }
+ return ammo_amount;
+ }
+ METHOD(Electro, wr_resetplayer, void(entity thiswep))
+ {
+ self.electro_secondarytime = time;
+ }
+ METHOD(Electro, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ W_Reload(self, min(WEP_CVAR_PRI(electro, ammo), WEP_CVAR_SEC(electro, ammo)), SND(RELOAD));
+ }
-METHOD(Electro, wr_suicidemessage, int(entity thiswep))
++METHOD(Electro, wr_suicidemessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_ELECTRO_SUICIDE_ORBS;
+ else
+ return WEAPON_ELECTRO_SUICIDE_BOLT;
+ }
-METHOD(Electro, wr_killmessage, int(entity thiswep))
++METHOD(Electro, wr_killmessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ {
+ return WEAPON_ELECTRO_MURDER_ORBS;
+ }
+ else
+ {
+ if(w_deathtype & HITTYPE_BOUNCE)
+ return WEAPON_ELECTRO_MURDER_COMBO;
+ else
+ return WEAPON_ELECTRO_MURDER_BOLT;
+ }
+ }
#endif
#ifdef CSQC
MUTATOR_CALLHOOK(EditProjectile, self, proj);
}
- METHOD(Fireball, wr_aim, void(entity thiswep))
- {
- self.BUTTON_ATCK = false;
- self.BUTTON_ATCK2 = false;
- if(self.bot_primary_fireballmooth == 0)
- {
- if(bot_aim(WEP_CVAR_PRI(fireball, speed), 0, WEP_CVAR_PRI(fireball, lifetime), false))
- {
- self.BUTTON_ATCK = true;
- if(random() < 0.02) self.bot_primary_fireballmooth = 0;
- }
- }
- else
- {
- if(bot_aim(WEP_CVAR_SEC(fireball, speed), WEP_CVAR_SEC(fireball, speed_up), WEP_CVAR_SEC(fireball, lifetime), true))
- {
- self.BUTTON_ATCK2 = true;
- if(random() < 0.01) self.bot_primary_fireballmooth = 1;
- }
- }
- }
- METHOD(Fireball, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(fire & 1)
- {
- if(time >= actor.fireball_primarytime)
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(fireball, refire)))
- {
- W_Fireball_Attack1_Frame0(thiswep, actor, weaponentity, fire);
- actor.fireball_primarytime = time + WEP_CVAR_PRI(fireball, refire2) * W_WeaponRateFactor();
- }
- }
- else if(fire & 2)
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(fireball, refire)))
- {
- W_Fireball_Attack2();
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(fireball, animtime), w_ready);
- }
- }
- }
- METHOD(Fireball, wr_setup, void(entity thiswep))
- {
- self.ammo_field = ammo_none;
- }
- METHOD(Fireball, wr_checkammo1, bool(entity thiswep))
- {
- return true; // infinite ammo
- }
- METHOD(Fireball, wr_checkammo2, bool(entity thiswep))
- {
- return true; // fireball has infinite ammo
- }
- METHOD(Fireball, wr_resetplayer, void(entity thiswep))
- {
- self.fireball_primarytime = time;
- }
- METHOD(Fireball, wr_suicidemessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- return WEAPON_FIREBALL_SUICIDE_FIREMINE;
- else
- return WEAPON_FIREBALL_SUICIDE_BLAST;
- }
- METHOD(Fireball, wr_killmessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- return WEAPON_FIREBALL_MURDER_FIREMINE;
- else
- return WEAPON_FIREBALL_MURDER_BLAST;
- }
+ METHOD(Fireball, wr_aim, void(entity thiswep))
+ {
+ PHYS_INPUT_BUTTON_ATCK(self) = false;
+ PHYS_INPUT_BUTTON_ATCK2(self) = false;
+ if(self.bot_primary_fireballmooth == 0)
+ {
+ if(bot_aim(WEP_CVAR_PRI(fireball, speed), 0, WEP_CVAR_PRI(fireball, lifetime), false))
+ {
+ PHYS_INPUT_BUTTON_ATCK(self) = true;
+ if(random() < 0.02) self.bot_primary_fireballmooth = 0;
+ }
+ }
+ else
+ {
+ if(bot_aim(WEP_CVAR_SEC(fireball, speed), WEP_CVAR_SEC(fireball, speed_up), WEP_CVAR_SEC(fireball, lifetime), true))
+ {
+ PHYS_INPUT_BUTTON_ATCK2(self) = true;
+ if(random() < 0.01) self.bot_primary_fireballmooth = 1;
+ }
+ }
+ }
+ METHOD(Fireball, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(fire & 1)
+ {
+ if(time >= actor.fireball_primarytime)
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(fireball, refire)))
+ {
+ W_Fireball_Attack1_Frame0(thiswep, actor, weaponentity, fire);
+ actor.fireball_primarytime = time + WEP_CVAR_PRI(fireball, refire2) * W_WeaponRateFactor();
+ }
+ }
+ else if(fire & 2)
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(fireball, refire)))
+ {
+ W_Fireball_Attack2();
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(fireball, animtime), w_ready);
+ }
+ }
+ }
+ METHOD(Fireball, wr_setup, void(entity thiswep))
+ {
+ self.ammo_field = ammo_none;
+ }
+ METHOD(Fireball, wr_checkammo1, bool(entity thiswep))
+ {
+ return true; // infinite ammo
+ }
+ METHOD(Fireball, wr_checkammo2, bool(entity thiswep))
+ {
+ return true; // fireball has infinite ammo
+ }
+ METHOD(Fireball, wr_resetplayer, void(entity thiswep))
+ {
+ self.fireball_primarytime = time;
+ }
-METHOD(Fireball, wr_suicidemessage, int(entity thiswep))
++METHOD(Fireball, wr_suicidemessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_FIREBALL_SUICIDE_FIREMINE;
+ else
+ return WEAPON_FIREBALL_SUICIDE_BLAST;
+ }
-METHOD(Fireball, wr_killmessage, int(entity thiswep))
++METHOD(Fireball, wr_killmessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_FIREBALL_MURDER_FIREMINE;
+ else
+ return WEAPON_FIREBALL_MURDER_BLAST;
+ }
#endif
#ifdef CSQC
}
}
- METHOD(Hagar, wr_aim, void(entity thiswep))
- {
- if(random()>0.15)
- self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
- else // not using secondary_speed since these are only 15% and should cause some ricochets without re-aiming
- self.BUTTON_ATCK2 = bot_aim(WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
- }
- METHOD(Hagar, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- float loadable_secondary;
- loadable_secondary = (WEP_CVAR_SEC(hagar, load) && WEP_CVAR(hagar, secondary));
-
- if(loadable_secondary)
- W_Hagar_Attack2_Load(thiswep, weaponentity); // must always run each frame
- if(autocvar_g_balance_hagar_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo))) { // forced reload
- thiswep.wr_reload(thiswep, actor, weaponentity);
- } else if((fire & 1) && !actor.hagar_load && !actor.hagar_loadblock) // not while secondary is loaded or awaiting reset
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(hagar, refire)))
- {
- W_Hagar_Attack(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hagar, refire), w_ready);
- }
- }
- else if((fire & 2) && !loadable_secondary && WEP_CVAR(hagar, secondary))
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(hagar, refire)))
- {
- W_Hagar_Attack2(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hagar, refire), w_ready);
- }
- }
- }
- METHOD(Hagar, wr_gonethink, void(entity thiswep))
- {
- // we lost the weapon and want to prepare switching away
- if(self.hagar_load)
- {
- .entity weaponentity = weaponentities[0]; // TODO: unhardcode
- self.(weaponentity).state = WS_READY;
- W_Hagar_Attack2_Load_Release(weaponentity);
- }
- }
- METHOD(Hagar, wr_setup, void(entity thiswep))
- {
- self.hagar_loadblock = false;
+ METHOD(Hagar, wr_aim, void(entity thiswep))
+ {
+ if(random()>0.15)
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
+ else // not using secondary_speed since these are only 15% and should cause some ricochets without re-aiming
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
+ }
+ METHOD(Hagar, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ float loadable_secondary;
+ loadable_secondary = (WEP_CVAR_SEC(hagar, load) && WEP_CVAR(hagar, secondary));
+
+ if(loadable_secondary)
+ W_Hagar_Attack2_Load(thiswep, weaponentity); // must always run each frame
+ if(autocvar_g_balance_hagar_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo))) { // forced reload
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ } else if((fire & 1) && !actor.hagar_load && !actor.hagar_loadblock) // not while secondary is loaded or awaiting reset
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(hagar, refire)))
+ {
+ W_Hagar_Attack(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hagar, refire), w_ready);
+ }
+ }
+ else if((fire & 2) && !loadable_secondary && WEP_CVAR(hagar, secondary))
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(hagar, refire)))
+ {
+ W_Hagar_Attack2(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hagar, refire), w_ready);
+ }
+ }
+ }
+ METHOD(Hagar, wr_gonethink, void(entity thiswep))
+ {
+ // we lost the weapon and want to prepare switching away
+ if(self.hagar_load)
+ {
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
+ self.(weaponentity).state = WS_READY;
+ W_Hagar_Attack2_Load_Release(weaponentity);
+ }
+ }
+ METHOD(Hagar, wr_setup, void(entity thiswep))
+ {
+ self.hagar_loadblock = false;
- if(self.hagar_load)
- {
- W_DecreaseAmmo(thiswep, self, WEP_CVAR_SEC(hagar, ammo) * self.hagar_load * -1); // give back ammo if necessary
- self.hagar_load = 0;
- }
- }
- METHOD(Hagar, wr_checkammo1, bool(entity thiswep))
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(hagar, ammo);
- ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_PRI(hagar, ammo);
- return ammo_amount;
- }
- METHOD(Hagar, wr_checkammo2, bool(entity thiswep))
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(hagar, ammo);
- ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_SEC(hagar, ammo);
- return ammo_amount;
- }
- METHOD(Hagar, wr_resetplayer, void(entity thiswep))
- {
- self.hagar_load = 0;
- }
- METHOD(Hagar, wr_playerdeath, void(entity thiswep))
- {
- .entity weaponentity = weaponentities[0]; // TODO: unhardcode
- // if we have any rockets loaded when we die, release them
- if(self.hagar_load && WEP_CVAR_SEC(hagar, load_releasedeath))
- W_Hagar_Attack2_Load_Release(weaponentity);
- }
- METHOD(Hagar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- if(!self.hagar_load) // require releasing loaded rockets first
- W_Reload(self, min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo)), SND(RELOAD));
- }
- METHOD(Hagar, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_HAGAR_SUICIDE;
- }
- METHOD(Hagar, wr_killmessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- return WEAPON_HAGAR_MURDER_BURST;
- else
- return WEAPON_HAGAR_MURDER_SPRAY;
- }
+ if(self.hagar_load)
+ {
+ W_DecreaseAmmo(thiswep, self, WEP_CVAR_SEC(hagar, ammo) * self.hagar_load * -1); // give back ammo if necessary
+ self.hagar_load = 0;
+ }
+ }
+ METHOD(Hagar, wr_checkammo1, bool(entity thiswep))
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(hagar, ammo);
+ ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_PRI(hagar, ammo);
+ return ammo_amount;
+ }
+ METHOD(Hagar, wr_checkammo2, bool(entity thiswep))
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(hagar, ammo);
+ ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_SEC(hagar, ammo);
+ return ammo_amount;
+ }
+ METHOD(Hagar, wr_resetplayer, void(entity thiswep))
+ {
+ self.hagar_load = 0;
+ }
+ METHOD(Hagar, wr_playerdeath, void(entity thiswep))
+ {
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
+ // if we have any rockets loaded when we die, release them
+ if(self.hagar_load && WEP_CVAR_SEC(hagar, load_releasedeath))
+ W_Hagar_Attack2_Load_Release(weaponentity);
+ }
+ METHOD(Hagar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ if(!self.hagar_load) // require releasing loaded rockets first
+ W_Reload(self, min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo)), SND(RELOAD));
+ }
-METHOD(Hagar, wr_suicidemessage, int(entity thiswep))
++METHOD(Hagar, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_HAGAR_SUICIDE;
+ }
-METHOD(Hagar, wr_killmessage, int(entity thiswep))
++METHOD(Hagar, wr_killmessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_HAGAR_MURDER_BURST;
+ else
+ return WEAPON_HAGAR_MURDER_SPRAY;
+ }
#endif
#ifdef CSQC
}
}
- METHOD(HLAC, wr_aim, void(entity thiswep))
- {
- self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(hlac, speed), 0, WEP_CVAR_PRI(hlac, lifetime), false);
- }
- METHOD(HLAC, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(autocvar_g_balance_hlac_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo))) { // forced reload
- thiswep.wr_reload(thiswep, actor, weaponentity);
- } else if(fire & 1)
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(hlac, refire)))
- {
- actor.misc_bulletcounter = 0;
- W_HLAC_Attack(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame);
- }
- }
-
- else if((fire & 2) && WEP_CVAR(hlac, secondary))
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(hlac, refire)))
- {
- W_HLAC_Attack2_Frame(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hlac, animtime), w_ready);
- }
- }
- }
- METHOD(HLAC, wr_checkammo1, bool(entity thiswep))
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(hlac, ammo);
- ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_PRI(hlac, ammo);
- return ammo_amount;
- }
- METHOD(HLAC, wr_checkammo2, bool(entity thiswep))
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(hlac, ammo);
- ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_SEC(hlac, ammo);
- return ammo_amount;
- }
- METHOD(HLAC, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- W_Reload(self, min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo)), SND(RELOAD));
- }
- METHOD(HLAC, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_HLAC_SUICIDE;
- }
- METHOD(HLAC, wr_killmessage, Notification(entity thiswep))
- {
- return WEAPON_HLAC_MURDER;
- }
+ METHOD(HLAC, wr_aim, void(entity thiswep))
+ {
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(hlac, speed), 0, WEP_CVAR_PRI(hlac, lifetime), false);
+ }
+ METHOD(HLAC, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(autocvar_g_balance_hlac_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo))) { // forced reload
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ } else if(fire & 1)
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(hlac, refire)))
+ {
+ actor.misc_bulletcounter = 0;
+ W_HLAC_Attack(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame);
+ }
+ }
+
+ else if((fire & 2) && WEP_CVAR(hlac, secondary))
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(hlac, refire)))
+ {
+ W_HLAC_Attack2_Frame(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hlac, animtime), w_ready);
+ }
+ }
+ }
+ METHOD(HLAC, wr_checkammo1, bool(entity thiswep))
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(hlac, ammo);
+ ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_PRI(hlac, ammo);
+ return ammo_amount;
+ }
+ METHOD(HLAC, wr_checkammo2, bool(entity thiswep))
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(hlac, ammo);
+ ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_SEC(hlac, ammo);
+ return ammo_amount;
+ }
+ METHOD(HLAC, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ W_Reload(self, min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo)), SND(RELOAD));
+ }
-METHOD(HLAC, wr_suicidemessage, int(entity thiswep))
++METHOD(HLAC, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_HLAC_SUICIDE;
+ }
-METHOD(HLAC, wr_killmessage, int(entity thiswep))
++METHOD(HLAC, wr_killmessage, Notification(entity thiswep))
+ {
+ return WEAPON_HLAC_MURDER;
+ }
#endif
#ifdef CSQC
MUTATOR_CALLHOOK(EditProjectile, actor, gren);
}
- 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(weapon_prepareattack(thiswep, actor, weaponentity, false, -1))
- {
- W_DecreaseAmmo(thiswep, actor, thiswep.ammo_factor * WEP_CVAR_PRI(hook, ammo));
- actor.hook_state |= HOOK_FIRING;
- actor.hook_state |= HOOK_WAITING_FOR_RELEASE;
- 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;
- }
-
- if(fire & 2)
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(hook, refire)))
- {
- W_Hook_Attack2(thiswep, actor);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hook, animtime), w_ready);
- }
- }
-
- if(actor.hook)
- {
- // if hooked, no bombs, and increase the timer
- actor.hook_refire = max(actor.hook_refire, time + WEP_CVAR_PRI(hook, refire) * W_WeaponRateFactor());
-
- // 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)
- {
- 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;
- }
-
- float hooked_fuel = thiswep.ammo_factor * WEP_CVAR_PRI(hook, hooked_ammo);
- if(hooked_fuel > 0)
- {
- if( time > actor.hook_time_fueldecrease )
- {
- if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
- {
- if( actor.ammo_fuel >= (time - actor.hook_time_fueldecrease) * hooked_fuel )
- {
- W_DecreaseAmmo(thiswep, actor, (time - actor.hook_time_fueldecrease) * hooked_fuel);
- actor.hook_time_fueldecrease = time;
- // decrease next frame again
- }
- else
- {
- actor.ammo_fuel = 0;
- actor.hook_state |= HOOK_REMOVING;
- W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
- }
- }
- }
- }
- }
- else
- {
- actor.hook_time_hooked = time;
- actor.hook_time_fueldecrease = time + WEP_CVAR_PRI(hook, hooked_time_free);
- }
-
- actor.hook_state = BITSET(actor.hook_state, HOOK_PULLING, (!actor.BUTTON_CROUCH || !autocvar_g_balance_grapplehook_crouchslide));
-
- if (actor.hook_state & HOOK_FIRING)
- {
- if (actor.hook)
- RemoveGrapplingHook(actor);
- WITH(entity, self, actor, FireGrapplingHook());
- actor.hook_state &= ~HOOK_FIRING;
- actor.hook_refire = max(actor.hook_refire, time + autocvar_g_balance_grapplehook_refire * W_WeaponRateFactor());
- }
- else if (actor.hook_state & HOOK_REMOVING)
- {
- if (actor.hook)
- RemoveGrapplingHook(actor);
- actor.hook_state &= ~HOOK_REMOVING;
- }
- }
- METHOD(Hook, wr_setup, void(entity thiswep))
- {
- self.hook_state &= ~HOOK_WAITING_FOR_RELEASE;
- }
- METHOD(Hook, wr_checkammo1, bool(Hook thiswep))
- {
- if (!thiswep.ammo_factor) return true;
- if(self.hook)
- return self.ammo_fuel > 0;
- else
- return self.ammo_fuel >= WEP_CVAR_PRI(hook, ammo);
- }
- METHOD(Hook, wr_checkammo2, bool(Hook thiswep))
- {
- // infinite ammo for now
- return true; // self.ammo_cells >= WEP_CVAR_SEC(hook, ammo); // WEAPONTODO: see above
- }
- METHOD(Hook, wr_resetplayer, void(entity thiswep))
- {
- RemoveGrapplingHook(self);
- self.hook_time = 0;
- self.hook_refire = time;
- }
- METHOD(Hook, wr_suicidemessage, Notification(entity thiswep))
- {
- return NULL;
- }
- METHOD(Hook, wr_killmessage, Notification(entity thiswep))
- {
- return WEAPON_HOOK_MURDER;
- }
+ 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(weapon_prepareattack(thiswep, actor, weaponentity, false, -1))
+ {
+ W_DecreaseAmmo(thiswep, actor, thiswep.ammo_factor * WEP_CVAR_PRI(hook, ammo));
+ actor.hook_state |= HOOK_FIRING;
+ actor.hook_state |= HOOK_WAITING_FOR_RELEASE;
+ 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;
+ }
+
+ if(fire & 2)
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(hook, refire)))
+ {
+ W_Hook_Attack2(thiswep, actor);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hook, animtime), w_ready);
+ }
+ }
+
+ if(actor.hook)
+ {
+ // if hooked, no bombs, and increase the timer
+ actor.hook_refire = max(actor.hook_refire, time + WEP_CVAR_PRI(hook, refire) * W_WeaponRateFactor());
+
+ // 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)
+ {
+ 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;
+ }
+
+ float hooked_fuel = thiswep.ammo_factor * WEP_CVAR_PRI(hook, hooked_ammo);
+ if(hooked_fuel > 0)
+ {
+ if( time > actor.hook_time_fueldecrease )
+ {
+ if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+ {
+ if( actor.ammo_fuel >= (time - actor.hook_time_fueldecrease) * hooked_fuel )
+ {
+ W_DecreaseAmmo(thiswep, actor, (time - actor.hook_time_fueldecrease) * hooked_fuel);
+ actor.hook_time_fueldecrease = time;
+ // decrease next frame again
+ }
+ else
+ {
+ actor.ammo_fuel = 0;
+ actor.hook_state |= HOOK_REMOVING;
+ W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ actor.hook_time_hooked = time;
+ actor.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));
+
+ if (actor.hook_state & HOOK_FIRING)
+ {
+ if (actor.hook)
+ RemoveGrapplingHook(actor);
+ WITH(entity, self, actor, FireGrapplingHook());
+ actor.hook_state &= ~HOOK_FIRING;
+ actor.hook_refire = max(actor.hook_refire, time + autocvar_g_balance_grapplehook_refire * W_WeaponRateFactor());
+ }
+ else if (actor.hook_state & HOOK_REMOVING)
+ {
+ if (actor.hook)
+ RemoveGrapplingHook(actor);
+ actor.hook_state &= ~HOOK_REMOVING;
+ }
+ }
+ METHOD(Hook, wr_setup, void(entity thiswep))
+ {
+ self.hook_state &= ~HOOK_WAITING_FOR_RELEASE;
+ }
+ METHOD(Hook, wr_checkammo1, bool(Hook thiswep))
+ {
+ if (!thiswep.ammo_factor) return true;
+ if(self.hook)
+ return self.ammo_fuel > 0;
+ else
+ return self.ammo_fuel >= WEP_CVAR_PRI(hook, ammo);
+ }
+ METHOD(Hook, wr_checkammo2, bool(Hook thiswep))
+ {
+ // infinite ammo for now
+ return true; // self.ammo_cells >= WEP_CVAR_SEC(hook, ammo); // WEAPONTODO: see above
+ }
+ METHOD(Hook, wr_resetplayer, void(entity thiswep))
+ {
+ RemoveGrapplingHook(self);
+ self.hook_time = 0;
+ self.hook_refire = time;
+ }
-METHOD(Hook, wr_suicidemessage, int(entity thiswep))
-{
- return false;
-}
-METHOD(Hook, wr_killmessage, int(entity thiswep))
++METHOD(Hook, wr_killmessage, Notification(entity thiswep))
+ {
+ return WEAPON_HOOK_MURDER;
+ }
#endif
#ifdef CSQC
}
- METHOD(MachineGun, wr_aim, void(entity thiswep))
- {
- if(vdist(self.origin - self.enemy.origin, <, 3000 - bound(0, skill, 10) * 200))
- self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, false);
- else
- self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, false);
- }
- METHOD(MachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(WEP_CVAR(machinegun, reload_ammo) && actor.clip_load < min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo))) { // forced reload
- thiswep.wr_reload(thiswep, actor, weaponentity);
- } else
- if(WEP_CVAR(machinegun, mode) == 1)
- {
- if(fire & 1)
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0))
- {
- actor.misc_bulletcounter = 0;
- W_MachineGun_Attack_Auto(thiswep, actor, weaponentity, fire);
- }
-
- if(fire & 2)
- if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0))
- {
- if(!thiswep.wr_checkammo2(thiswep))
- if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
- {
- W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
- w_ready(thiswep, actor, weaponentity, fire);
- return;
- }
-
- W_DecreaseAmmo(thiswep, actor, WEP_CVAR(machinegun, burst_ammo));
-
- actor.misc_bulletcounter = WEP_CVAR(machinegun, burst) * -1;
- W_MachineGun_Attack_Burst(thiswep, actor, weaponentity, fire);
- }
- }
- else
- {
-
- if(fire & 1)
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0))
- {
- actor.misc_bulletcounter = 1;
- W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id, weaponentity); // sets attack_finished
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame);
- }
-
- if((fire & 2) && WEP_CVAR(machinegun, first))
- if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0))
- {
- actor.misc_bulletcounter = 1;
- W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id | HITTYPE_SECONDARY, weaponentity); // sets attack_finished
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(machinegun, first_refire), w_ready);
- }
- }
- }
- METHOD(MachineGun, wr_checkammo1, bool(entity thiswep))
- {
- float ammo_amount;
- if(WEP_CVAR(machinegun, mode) == 1)
- ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, sustained_ammo);
- else
- ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, first_ammo);
-
- if(WEP_CVAR(machinegun, reload_ammo))
- {
- if(WEP_CVAR(machinegun, mode) == 1)
- ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, sustained_ammo);
- else
- ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo);
- }
- return ammo_amount;
- }
- METHOD(MachineGun, wr_checkammo2, bool(entity thiswep))
- {
- float ammo_amount;
- if(WEP_CVAR(machinegun, mode) == 1)
- ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, burst_ammo);
- else
- ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, first_ammo);
-
- if(WEP_CVAR(machinegun, reload_ammo))
- {
- if(WEP_CVAR(machinegun, mode) == 1)
- ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, burst_ammo);
- else
- ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo);
- }
- return ammo_amount;
- }
- METHOD(MachineGun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- W_Reload(self, min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo)), SND(RELOAD));
- }
- METHOD(MachineGun, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_THINKING_WITH_PORTALS;
- }
- METHOD(MachineGun, wr_killmessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- return WEAPON_MACHINEGUN_MURDER_SNIPE;
- else
- return WEAPON_MACHINEGUN_MURDER_SPRAY;
- }
+ METHOD(MachineGun, wr_aim, void(entity thiswep))
+ {
+ if(vdist(self.origin - self.enemy.origin, <, 3000 - bound(0, skill, 10) * 200))
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 0.001, false);
+ else
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(1000000, 0, 0.001, false);
+ }
+ METHOD(MachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(WEP_CVAR(machinegun, reload_ammo) && actor.clip_load < min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo))) { // forced reload
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ } else
+ if(WEP_CVAR(machinegun, mode) == 1)
+ {
+ if(fire & 1)
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0))
+ {
+ actor.misc_bulletcounter = 0;
+ W_MachineGun_Attack_Auto(thiswep, actor, weaponentity, fire);
+ }
+
+ if(fire & 2)
+ if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0))
+ {
+ if(!thiswep.wr_checkammo2(thiswep))
+ if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+ {
+ W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
+ w_ready(thiswep, actor, weaponentity, fire);
+ return;
+ }
+
+ W_DecreaseAmmo(thiswep, actor, WEP_CVAR(machinegun, burst_ammo));
+
+ actor.misc_bulletcounter = WEP_CVAR(machinegun, burst) * -1;
+ W_MachineGun_Attack_Burst(thiswep, actor, weaponentity, fire);
+ }
+ }
+ else
+ {
+
+ if(fire & 1)
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0))
+ {
+ actor.misc_bulletcounter = 1;
+ W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id, weaponentity); // sets attack_finished
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame);
+ }
+
+ if((fire & 2) && WEP_CVAR(machinegun, first))
+ if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0))
+ {
+ actor.misc_bulletcounter = 1;
+ W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id | HITTYPE_SECONDARY, weaponentity); // sets attack_finished
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(machinegun, first_refire), w_ready);
+ }
+ }
+ }
+ METHOD(MachineGun, wr_checkammo1, bool(entity thiswep))
+ {
+ float ammo_amount;
+ if(WEP_CVAR(machinegun, mode) == 1)
+ ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, sustained_ammo);
+ else
+ ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, first_ammo);
+
+ if(WEP_CVAR(machinegun, reload_ammo))
+ {
+ if(WEP_CVAR(machinegun, mode) == 1)
+ ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, sustained_ammo);
+ else
+ ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo);
+ }
+ return ammo_amount;
+ }
+ METHOD(MachineGun, wr_checkammo2, bool(entity thiswep))
+ {
+ float ammo_amount;
+ if(WEP_CVAR(machinegun, mode) == 1)
+ ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, burst_ammo);
+ else
+ ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, first_ammo);
+
+ if(WEP_CVAR(machinegun, reload_ammo))
+ {
+ if(WEP_CVAR(machinegun, mode) == 1)
+ ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, burst_ammo);
+ else
+ ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo);
+ }
+ return ammo_amount;
+ }
+ METHOD(MachineGun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ W_Reload(self, min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo)), SND(RELOAD));
+ }
-METHOD(MachineGun, wr_suicidemessage, int(entity thiswep))
++METHOD(MachineGun, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_THINKING_WITH_PORTALS;
+ }
-METHOD(MachineGun, wr_killmessage, int(entity thiswep))
++METHOD(MachineGun, wr_killmessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_MACHINEGUN_MURDER_SNIPE;
+ else
+ return WEAPON_MACHINEGUN_MURDER_SPRAY;
+ }
#endif
#ifdef CSQC
return minfound;
}
- METHOD(MineLayer, wr_aim, void(entity thiswep))
- {
- // aim and decide to fire if appropriate
- if(self.minelayer_mines >= WEP_CVAR(minelayer, limit))
- self.BUTTON_ATCK = false;
- else
- self.BUTTON_ATCK = bot_aim(WEP_CVAR(minelayer, speed), 0, WEP_CVAR(minelayer, lifetime), false);
- if(skill >= 2) // skill 0 and 1 bots won't detonate mines!
- {
- // decide whether to detonate mines
- entity targetlist, targ;
- float edgedamage, coredamage, edgeradius, recipricoledgeradius, d;
- float selfdamage, teamdamage, enemydamage;
- edgedamage = WEP_CVAR(minelayer, edgedamage);
- coredamage = WEP_CVAR(minelayer, damage);
- edgeradius = WEP_CVAR(minelayer, radius);
- recipricoledgeradius = 1 / edgeradius;
- selfdamage = 0;
- teamdamage = 0;
- enemydamage = 0;
- targetlist = findchainfloat(bot_attack, true);
- entity mine = find(world, classname, "mine");
- while(mine)
- {
- if(mine.realowner != self)
- {
- mine = find(mine, classname, "mine");
- continue;
- }
- targ = targetlist;
- while(targ)
- {
- d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - mine.origin);
- d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
- // count potential damage according to type of target
- if(targ == self)
- selfdamage = selfdamage + d;
- else if(targ.team == self.team && teamplay)
- teamdamage = teamdamage + d;
- else if(bot_shouldattack(targ))
- enemydamage = enemydamage + d;
- targ = targ.chain;
- }
- mine = find(mine, classname, "mine");
- }
- float desirabledamage;
- desirabledamage = enemydamage;
- if(time > self.invincible_finished && time > self.spawnshieldtime)
- desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent;
- if(teamplay && self.team)
- desirabledamage = desirabledamage - teamdamage;
-
- mine = find(world, classname, "mine");
- while(mine)
- {
- if(mine.realowner != self)
- {
- mine = find(mine, classname, "mine");
- continue;
- }
- makevectors(mine.v_angle);
- targ = targetlist;
- if(skill > 9) // normal players only do this for the target they are tracking
- {
- targ = targetlist;
- while(targ)
- {
- if(
- (v_forward * normalize(mine.origin - targ.origin)< 0.1)
- && desirabledamage > 0.1*coredamage
- )self.BUTTON_ATCK2 = true;
- targ = targ.chain;
- }
- }else{
- float distance; distance= bound(300,vlen(self.origin-self.enemy.origin),30000);
- //As the distance gets larger, a correct detonation gets near imposible
- //Bots are assumed to use the mine spawnfunc_light to see if the mine gets near a player
- if(v_forward * normalize(mine.origin - self.enemy.origin)< 0.1)
- if(IS_PLAYER(self.enemy))
- if(desirabledamage >= 0.1*coredamage)
- if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1))
- self.BUTTON_ATCK2 = true;
- // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n");
- }
-
- mine = find(mine, classname, "mine");
- }
- // if we would be doing at X percent of the core damage, detonate it
- // but don't fire a new shot at the same time!
- if(desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events
- self.BUTTON_ATCK2 = true;
- if((skill > 6.5) && (selfdamage > self.health))
- self.BUTTON_ATCK2 = false;
- //if(self.BUTTON_ATCK2 == true)
- // dprint(ftos(desirabledamage),"\n");
- if(self.BUTTON_ATCK2 == true) self.BUTTON_ATCK = false;
- }
- }
- METHOD(MineLayer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(autocvar_g_balance_minelayer_reload_ammo && actor.clip_load < WEP_CVAR(minelayer, ammo)) // forced reload
- {
- // not if we're holding the minelayer without enough ammo, but can detonate existing mines
- if(!(W_MineLayer_PlacedMines(false) && actor.(thiswep.ammo_field) < WEP_CVAR(minelayer, ammo))) {
- thiswep.wr_reload(thiswep, actor, weaponentity);
- }
- }
- else if(fire & 1)
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(minelayer, refire)))
- {
- W_MineLayer_Attack(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(minelayer, animtime), w_ready);
- }
- }
-
- if(fire & 2)
- {
- if(W_MineLayer_PlacedMines(true))
- sound(actor, CH_WEAPON_B, SND_MINE_DET, VOL_BASE, ATTN_NORM);
- }
- }
- METHOD(MineLayer, wr_checkammo1, bool(entity thiswep))
- {
- int slot = 0; // TODO: unhardcode
- // don't switch while placing a mine
- if(ATTACK_FINISHED(self, slot) <= time || PS(self).m_weapon != WEP_MINE_LAYER)
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(minelayer, ammo);
- ammo_amount += self.(weapon_load[WEP_MINE_LAYER.m_id]) >= WEP_CVAR(minelayer, ammo);
- return ammo_amount;
- }
- return true;
- }
- METHOD(MineLayer, wr_checkammo2, bool(entity thiswep))
- {
- if(W_MineLayer_PlacedMines(false))
- return true;
- else
- return false;
- }
- METHOD(MineLayer, wr_resetplayers, void(entity thiswep))
- {
- self.minelayer_mines = 0;
- }
- METHOD(MineLayer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- W_Reload(self, WEP_CVAR(minelayer, ammo), SND(RELOAD));
- }
- METHOD(MineLayer, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_MINELAYER_SUICIDE;
- }
- METHOD(MineLayer, wr_killmessage, Notification(entity thiswep))
- {
- return WEAPON_MINELAYER_MURDER;
- }
+ METHOD(MineLayer, wr_aim, void(entity thiswep))
+ {
+ // aim and decide to fire if appropriate
+ if(self.minelayer_mines >= WEP_CVAR(minelayer, limit))
+ PHYS_INPUT_BUTTON_ATCK(self) = false;
+ else
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(minelayer, speed), 0, WEP_CVAR(minelayer, lifetime), false);
+ if(skill >= 2) // skill 0 and 1 bots won't detonate mines!
+ {
+ // decide whether to detonate mines
+ entity targetlist, targ;
+ float edgedamage, coredamage, edgeradius, recipricoledgeradius, d;
+ float selfdamage, teamdamage, enemydamage;
+ edgedamage = WEP_CVAR(minelayer, edgedamage);
+ coredamage = WEP_CVAR(minelayer, damage);
+ edgeradius = WEP_CVAR(minelayer, radius);
+ recipricoledgeradius = 1 / edgeradius;
+ selfdamage = 0;
+ teamdamage = 0;
+ enemydamage = 0;
+ targetlist = findchainfloat(bot_attack, true);
+ entity mine = find(world, classname, "mine");
+ while(mine)
+ {
+ if(mine.realowner != self)
+ {
+ mine = find(mine, classname, "mine");
+ continue;
+ }
+ targ = targetlist;
+ while(targ)
+ {
+ d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - mine.origin);
+ d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
+ // count potential damage according to type of target
+ if(targ == self)
+ selfdamage = selfdamage + d;
+ else if(targ.team == self.team && teamplay)
+ teamdamage = teamdamage + d;
+ else if(bot_shouldattack(targ))
+ enemydamage = enemydamage + d;
+ targ = targ.chain;
+ }
+ mine = find(mine, classname, "mine");
+ }
+ float desirabledamage;
+ desirabledamage = enemydamage;
+ if(time > self.invincible_finished && time > self.spawnshieldtime)
+ desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent;
+ if(teamplay && self.team)
+ desirabledamage = desirabledamage - teamdamage;
+
+ mine = find(world, classname, "mine");
+ while(mine)
+ {
+ if(mine.realowner != self)
+ {
+ mine = find(mine, classname, "mine");
+ continue;
+ }
+ makevectors(mine.v_angle);
+ targ = targetlist;
+ if(skill > 9) // normal players only do this for the target they are tracking
+ {
+ targ = targetlist;
+ while(targ)
+ {
+ if(
+ (v_forward * normalize(mine.origin - targ.origin)< 0.1)
+ && desirabledamage > 0.1*coredamage
+ ) PHYS_INPUT_BUTTON_ATCK2(self) = true;
+ targ = targ.chain;
+ }
+ }else{
+ float distance; distance= bound(300,vlen(self.origin-self.enemy.origin),30000);
+ //As the distance gets larger, a correct detonation gets near imposible
+ //Bots are assumed to use the mine spawnfunc_light to see if the mine gets near a player
+ if(v_forward * normalize(mine.origin - self.enemy.origin)< 0.1)
+ if(IS_PLAYER(self.enemy))
+ if(desirabledamage >= 0.1*coredamage)
+ if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1))
+ PHYS_INPUT_BUTTON_ATCK2(self) = true;
+ // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n");
+ }
+
+ mine = find(mine, classname, "mine");
+ }
+ // if we would be doing at X percent of the core damage, detonate it
+ // but don't fire a new shot at the same time!
+ if(desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events
+ PHYS_INPUT_BUTTON_ATCK2(self) = true;
+ if((skill > 6.5) && (selfdamage > self.health))
+ PHYS_INPUT_BUTTON_ATCK2(self) = false;
+ //if(PHYS_INPUT_BUTTON_ATCK2(self) == true)
+ // dprint(ftos(desirabledamage),"\n");
+ if(PHYS_INPUT_BUTTON_ATCK2(self)) PHYS_INPUT_BUTTON_ATCK(self) = false;
+ }
+ }
+ METHOD(MineLayer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(autocvar_g_balance_minelayer_reload_ammo && actor.clip_load < WEP_CVAR(minelayer, ammo)) // forced reload
+ {
+ // not if we're holding the minelayer without enough ammo, but can detonate existing mines
+ if(!(W_MineLayer_PlacedMines(false) && actor.(thiswep.ammo_field) < WEP_CVAR(minelayer, ammo))) {
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ }
+ }
+ else if(fire & 1)
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(minelayer, refire)))
+ {
+ W_MineLayer_Attack(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(minelayer, animtime), w_ready);
+ }
+ }
+
+ if(fire & 2)
+ {
+ if(W_MineLayer_PlacedMines(true))
+ sound(actor, CH_WEAPON_B, SND_MINE_DET, VOL_BASE, ATTN_NORM);
+ }
+ }
+ METHOD(MineLayer, wr_checkammo1, bool(entity thiswep))
+ {
+ int slot = 0; // TODO: unhardcode
+ // don't switch while placing a mine
+ if(ATTACK_FINISHED(self, slot) <= time || PS(self).m_weapon != WEP_MINE_LAYER)
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(minelayer, ammo);
+ ammo_amount += self.(weapon_load[WEP_MINE_LAYER.m_id]) >= WEP_CVAR(minelayer, ammo);
+ return ammo_amount;
+ }
+ return true;
+ }
+ METHOD(MineLayer, wr_checkammo2, bool(entity thiswep))
+ {
+ if(W_MineLayer_PlacedMines(false))
+ return true;
+ else
+ return false;
+ }
+ METHOD(MineLayer, wr_resetplayers, void(entity thiswep))
+ {
+ self.minelayer_mines = 0;
+ }
+ METHOD(MineLayer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ W_Reload(self, WEP_CVAR(minelayer, ammo), SND(RELOAD));
+ }
-METHOD(MineLayer, wr_suicidemessage, int(entity thiswep))
++METHOD(MineLayer, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_MINELAYER_SUICIDE;
+ }
-METHOD(MineLayer, wr_killmessage, int(entity thiswep))
++METHOD(MineLayer, wr_killmessage, Notification(entity thiswep))
+ {
+ return WEAPON_MINELAYER_MURDER;
+ }
#endif
#ifdef CSQC
.float bot_secondary_grenademooth;
- METHOD(Mortar, wr_aim, void(entity thiswep))
- {
- self.BUTTON_ATCK = false;
- self.BUTTON_ATCK2 = false;
- if(self.bot_secondary_grenademooth == 0) // WEAPONTODO: merge this into using WEP_CVAR_BOTH
- {
- if(bot_aim(WEP_CVAR_PRI(mortar, speed), WEP_CVAR_PRI(mortar, speed_up), WEP_CVAR_PRI(mortar, lifetime), true))
- {
- self.BUTTON_ATCK = true;
- if(random() < 0.01) self.bot_secondary_grenademooth = 1;
- }
- }
- else
- {
- if(bot_aim(WEP_CVAR_SEC(mortar, speed), WEP_CVAR_SEC(mortar, speed_up), WEP_CVAR_SEC(mortar, lifetime), true))
- {
- self.BUTTON_ATCK2 = true;
- if(random() < 0.02) self.bot_secondary_grenademooth = 0;
- }
- }
- }
- /*case WR_CALCINFO:
- {
- wepinfo_pri_refire = max3(sys_frametime, WEP_CVAR_PRI(mortar, refire), WEP_CVAR_PRI(mortar, animtime));
- wepinfo_pri_dps = (WEP_CVAR_PRI(mortar, damage) * (1 / wepinfo_pri_refire));
- wepinfo_pri_speed = (1 / max(1, (10000 / max(1, WEP_CVAR_PRI(mortar, speed)))));
-
- // for the range calculation, closer to 1 is better
- wepinfo_pri_range_max = 2000 * wepinfo_pri_speed;
- wepinfo_pri_range = wepinfo_pri_speed * WEP_CVAR_PRI(mortar,
-
- wepinfo_sec_refire = max3(sys_frametime, WEP_CVAR_SEC(mortar, refire), WEP_CVAR_SEC(mortar, animtime));
- wepinfo_sec_dps = (WEP_CVAR_SEC(mortar, damage) * (1 / wepinfo_sec_refire));
-
- 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, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(autocvar_g_balance_mortar_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo))) { // forced reload
- thiswep.wr_reload(thiswep, actor, weaponentity);
- } else if(fire & 1)
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(mortar, refire)))
- {
- W_Mortar_Attack(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(mortar, animtime), w_ready);
- }
- }
- else if(fire & 2)
- {
- if(WEP_CVAR_SEC(mortar, remote_detonateprimary))
- {
- bool nadefound = false;
- entity nade;
- for(nade = world; (nade = find(nade, classname, "grenade")); ) if(nade.realowner == actor)
- {
- if(!nade.gl_detonate_later)
- {
- nade.gl_detonate_later = true;
- nadefound = true;
- }
- }
- if(nadefound)
- sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM);
- }
- else if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(mortar, refire)))
- {
- W_Mortar_Attack2(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(mortar, animtime), w_ready);
- }
- }
- }
- METHOD(Mortar, wr_checkammo1, bool(entity thiswep))
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(mortar, ammo);
- ammo_amount += self.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_PRI(mortar, ammo);
- return ammo_amount;
- }
- METHOD(Mortar, wr_checkammo2, bool(entity thiswep))
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(mortar, ammo);
- ammo_amount += self.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_SEC(mortar, ammo);
- return ammo_amount;
- }
- METHOD(Mortar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- W_Reload(self, min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo)), SND(RELOAD)); // WEAPONTODO
- }
- METHOD(Mortar, wr_suicidemessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- return WEAPON_MORTAR_SUICIDE_BOUNCE;
- else
- return WEAPON_MORTAR_SUICIDE_EXPLODE;
- }
- METHOD(Mortar, wr_killmessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- return WEAPON_MORTAR_MURDER_BOUNCE;
- else
- return WEAPON_MORTAR_MURDER_EXPLODE;
- }
+ METHOD(Mortar, wr_aim, void(entity thiswep))
+ {
+ PHYS_INPUT_BUTTON_ATCK(self) = false;
+ PHYS_INPUT_BUTTON_ATCK2(self) = false;
+ if(self.bot_secondary_grenademooth == 0) // WEAPONTODO: merge this into using WEP_CVAR_BOTH
+ {
+ if(bot_aim(WEP_CVAR_PRI(mortar, speed), WEP_CVAR_PRI(mortar, speed_up), WEP_CVAR_PRI(mortar, lifetime), true))
+ {
+ PHYS_INPUT_BUTTON_ATCK(self) = true;
+ if(random() < 0.01) self.bot_secondary_grenademooth = 1;
+ }
+ }
+ else
+ {
+ if(bot_aim(WEP_CVAR_SEC(mortar, speed), WEP_CVAR_SEC(mortar, speed_up), WEP_CVAR_SEC(mortar, lifetime), true))
+ {
+ PHYS_INPUT_BUTTON_ATCK2(self) = true;
+ if(random() < 0.02) self.bot_secondary_grenademooth = 0;
+ }
+ }
+ }
+ /*case WR_CALCINFO:
+ {
+ wepinfo_pri_refire = max3(sys_frametime, WEP_CVAR_PRI(mortar, refire), WEP_CVAR_PRI(mortar, animtime));
+ wepinfo_pri_dps = (WEP_CVAR_PRI(mortar, damage) * (1 / wepinfo_pri_refire));
+ wepinfo_pri_speed = (1 / max(1, (10000 / max(1, WEP_CVAR_PRI(mortar, speed)))));
+
+ // for the range calculation, closer to 1 is better
+ wepinfo_pri_range_max = 2000 * wepinfo_pri_speed;
+ wepinfo_pri_range = wepinfo_pri_speed * WEP_CVAR_PRI(mortar,
+
+ wepinfo_sec_refire = max3(sys_frametime, WEP_CVAR_SEC(mortar, refire), WEP_CVAR_SEC(mortar, animtime));
+ wepinfo_sec_dps = (WEP_CVAR_SEC(mortar, damage) * (1 / wepinfo_sec_refire));
+
+ 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, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(autocvar_g_balance_mortar_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo))) { // forced reload
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ } else if(fire & 1)
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(mortar, refire)))
+ {
+ W_Mortar_Attack(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(mortar, animtime), w_ready);
+ }
+ }
+ else if(fire & 2)
+ {
+ if(WEP_CVAR_SEC(mortar, remote_detonateprimary))
+ {
+ bool nadefound = false;
+ entity nade;
+ for(nade = world; (nade = find(nade, classname, "grenade")); ) if(nade.realowner == actor)
+ {
+ if(!nade.gl_detonate_later)
+ {
+ nade.gl_detonate_later = true;
+ nadefound = true;
+ }
+ }
+ if(nadefound)
+ sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM);
+ }
+ else if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(mortar, refire)))
+ {
+ W_Mortar_Attack2(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(mortar, animtime), w_ready);
+ }
+ }
+ }
+ METHOD(Mortar, wr_checkammo1, bool(entity thiswep))
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(mortar, ammo);
+ ammo_amount += self.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_PRI(mortar, ammo);
+ return ammo_amount;
+ }
+ METHOD(Mortar, wr_checkammo2, bool(entity thiswep))
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(mortar, ammo);
+ ammo_amount += self.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_SEC(mortar, ammo);
+ return ammo_amount;
+ }
+ METHOD(Mortar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ W_Reload(self, min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo)), SND(RELOAD)); // WEAPONTODO
+ }
-METHOD(Mortar, wr_suicidemessage, int(entity thiswep))
++METHOD(Mortar, wr_suicidemessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_MORTAR_SUICIDE_BOUNCE;
+ else
+ return WEAPON_MORTAR_SUICIDE_EXPLODE;
+ }
-METHOD(Mortar, wr_killmessage, int(entity thiswep))
++METHOD(Mortar, wr_killmessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_MORTAR_MURDER_BOUNCE;
+ else
+ return WEAPON_MORTAR_MURDER_EXPLODE;
+ }
#endif
#ifdef CSQC
.float bot_secondary_riflemooth;
- METHOD(Rifle, wr_aim, void(entity thiswep))
- {
- self.BUTTON_ATCK=false;
- self.BUTTON_ATCK2=false;
- if(vdist(self.origin - self.enemy.origin, >, 1000))
- self.bot_secondary_riflemooth = 0;
- if(self.bot_secondary_riflemooth == 0)
- {
- if(bot_aim(1000000, 0, 0.001, false))
- {
- self.BUTTON_ATCK = true;
- if(random() < 0.01) self.bot_secondary_riflemooth = 1;
- }
- }
- else
- {
- if(bot_aim(1000000, 0, 0.001, false))
- {
- self.BUTTON_ATCK2 = true;
- if(random() < 0.03) self.bot_secondary_riflemooth = 0;
- }
- }
- }
- METHOD(Rifle, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(autocvar_g_balance_rifle_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo))) { // forced reload
- thiswep.wr_reload(thiswep, actor, weaponentity);
- } else
- {
- actor.rifle_accumulator = bound(time - WEP_CVAR(rifle, bursttime), actor.rifle_accumulator, time);
- if(fire & 1)
- if(weapon_prepareattack_check(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire)))
- if(time >= actor.rifle_accumulator + WEP_CVAR_PRI(rifle, burstcost))
- {
- weapon_prepareattack_do(actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire));
- W_Rifle_BulletHail(weaponentity, WEP_CVAR_PRI(rifle, bullethail), W_Rifle_Attack, WFRAME_FIRE1, WEP_CVAR_PRI(rifle, animtime), WEP_CVAR_PRI(rifle, refire));
- actor.rifle_accumulator += WEP_CVAR_PRI(rifle, burstcost);
- }
- if(fire & 2)
- {
- if(WEP_CVAR(rifle, secondary))
- {
- if(WEP_CVAR_SEC(rifle, reload)) {
- thiswep.wr_reload(thiswep, actor, weaponentity);
- } else
- {
- if(weapon_prepareattack_check(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire)))
- if(time >= actor.rifle_accumulator + WEP_CVAR_SEC(rifle, burstcost))
- {
- weapon_prepareattack_do(actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire));
- W_Rifle_BulletHail(weaponentity, WEP_CVAR_SEC(rifle, bullethail), W_Rifle_Attack2, WFRAME_FIRE2, WEP_CVAR_SEC(rifle, animtime), WEP_CVAR_PRI(rifle, refire));
- actor.rifle_accumulator += WEP_CVAR_SEC(rifle, burstcost);
- }
- }
- }
- }
- }
- }
- METHOD(Rifle, wr_checkammo1, bool(entity thiswep))
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(rifle, ammo);
- ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_PRI(rifle, ammo);
- return ammo_amount;
- }
- METHOD(Rifle, wr_checkammo2, bool(entity thiswep))
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(rifle, ammo);
- ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_SEC(rifle, ammo);
- return ammo_amount;
- }
- METHOD(Rifle, wr_resetplayer, void(entity thiswep))
- {
- self.rifle_accumulator = time - WEP_CVAR(rifle, bursttime);
- }
- METHOD(Rifle, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- W_Reload(self, min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo)), SND(RELOAD));
- }
- METHOD(Rifle, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_THINKING_WITH_PORTALS;
- }
- METHOD(Rifle, wr_killmessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- {
- if(w_deathtype & HITTYPE_BOUNCE)
- return WEAPON_RIFLE_MURDER_HAIL_PIERCING;
- else
- return WEAPON_RIFLE_MURDER_HAIL;
- }
- else
- {
- if(w_deathtype & HITTYPE_BOUNCE)
- return WEAPON_RIFLE_MURDER_PIERCING;
- else
- return WEAPON_RIFLE_MURDER;
- }
- }
+ METHOD(Rifle, wr_aim, void(entity thiswep))
+ {
+ PHYS_INPUT_BUTTON_ATCK(self) = false;
+ PHYS_INPUT_BUTTON_ATCK2(self) = false;
+ if(vdist(self.origin - self.enemy.origin, >, 1000))
+ self.bot_secondary_riflemooth = 0;
+ if(self.bot_secondary_riflemooth == 0)
+ {
+ if(bot_aim(1000000, 0, 0.001, false))
+ {
+ PHYS_INPUT_BUTTON_ATCK(self) = true;
+ if(random() < 0.01) self.bot_secondary_riflemooth = 1;
+ }
+ }
+ else
+ {
+ if(bot_aim(1000000, 0, 0.001, false))
+ {
+ PHYS_INPUT_BUTTON_ATCK2(self) = true;
+ if(random() < 0.03) self.bot_secondary_riflemooth = 0;
+ }
+ }
+ }
+ METHOD(Rifle, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(autocvar_g_balance_rifle_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo))) { // forced reload
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ } else
+ {
+ actor.rifle_accumulator = bound(time - WEP_CVAR(rifle, bursttime), actor.rifle_accumulator, time);
+ if(fire & 1)
+ if(weapon_prepareattack_check(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire)))
+ if(time >= actor.rifle_accumulator + WEP_CVAR_PRI(rifle, burstcost))
+ {
+ weapon_prepareattack_do(actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire));
+ W_Rifle_BulletHail(weaponentity, WEP_CVAR_PRI(rifle, bullethail), W_Rifle_Attack, WFRAME_FIRE1, WEP_CVAR_PRI(rifle, animtime), WEP_CVAR_PRI(rifle, refire));
+ actor.rifle_accumulator += WEP_CVAR_PRI(rifle, burstcost);
+ }
+ if(fire & 2)
+ {
+ if(WEP_CVAR(rifle, secondary))
+ {
+ if(WEP_CVAR_SEC(rifle, reload)) {
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ } else
+ {
+ if(weapon_prepareattack_check(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire)))
+ if(time >= actor.rifle_accumulator + WEP_CVAR_SEC(rifle, burstcost))
+ {
+ weapon_prepareattack_do(actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire));
+ W_Rifle_BulletHail(weaponentity, WEP_CVAR_SEC(rifle, bullethail), W_Rifle_Attack2, WFRAME_FIRE2, WEP_CVAR_SEC(rifle, animtime), WEP_CVAR_PRI(rifle, refire));
+ actor.rifle_accumulator += WEP_CVAR_SEC(rifle, burstcost);
+ }
+ }
+ }
+ }
+ }
+ }
+ METHOD(Rifle, wr_checkammo1, bool(entity thiswep))
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(rifle, ammo);
+ ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_PRI(rifle, ammo);
+ return ammo_amount;
+ }
+ METHOD(Rifle, wr_checkammo2, bool(entity thiswep))
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(rifle, ammo);
+ ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_SEC(rifle, ammo);
+ return ammo_amount;
+ }
+ METHOD(Rifle, wr_resetplayer, void(entity thiswep))
+ {
+ self.rifle_accumulator = time - WEP_CVAR(rifle, bursttime);
+ }
+ METHOD(Rifle, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ W_Reload(self, min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo)), SND(RELOAD));
+ }
-METHOD(Rifle, wr_suicidemessage, int(entity thiswep))
++METHOD(Rifle, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_THINKING_WITH_PORTALS;
+ }
-METHOD(Rifle, wr_killmessage, int(entity thiswep))
++METHOD(Rifle, wr_killmessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ {
+ if(w_deathtype & HITTYPE_BOUNCE)
+ return WEAPON_RIFLE_MURDER_HAIL_PIERCING;
+ else
+ return WEAPON_RIFLE_MURDER_HAIL;
+ }
+ else
+ {
+ if(w_deathtype & HITTYPE_BOUNCE)
+ return WEAPON_RIFLE_MURDER_PIERCING;
+ else
+ return WEAPON_RIFLE_MURDER;
+ }
+ }
#endif
#ifdef CSQC
// Begin: Genereal weapon functions
// ============================
- METHOD(Seeker, wr_aim, void(entity thiswep))
- {
- if(WEP_CVAR(seeker, type) == 1)
- if(W_Seeker_Tagged_Info(self, self.enemy) != world)
- self.BUTTON_ATCK = bot_aim(WEP_CVAR(seeker, missile_speed_max), 0, WEP_CVAR(seeker, missile_lifetime), false);
- else
- self.BUTTON_ATCK2 = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false);
- else
- self.BUTTON_ATCK = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false);
- }
- METHOD(Seeker, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(autocvar_g_balance_seeker_reload_ammo && actor.clip_load < min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo))) { // forced reload
- thiswep.wr_reload(thiswep, actor, weaponentity);
- } else if(fire & 1)
- {
- if(WEP_CVAR(seeker, type) == 1)
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, missile_refire)))
- {
- W_Seeker_Attack();
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, missile_animtime), w_ready);
- }
- }
- else
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, tag_refire)))
- {
- W_Seeker_Fire_Tag(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready);
- }
- }
- }
-
- else if(fire & 2)
- {
- if(WEP_CVAR(seeker, type) == 1)
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, tag_refire)))
- {
- W_Seeker_Fire_Tag(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready);
- }
- }
- else
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, flac_refire)))
- {
- W_Seeker_Fire_Flac(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, flac_animtime), w_ready);
- }
- }
- }
- }
- METHOD(Seeker, wr_checkammo1, bool(entity thiswep))
- {
- float ammo_amount;
- if(WEP_CVAR(seeker, type) == 1)
- {
- ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, missile_ammo);
- ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, missile_ammo);
- }
- else
- {
- ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, tag_ammo);
- ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo);
- }
- return ammo_amount;
- }
- METHOD(Seeker, wr_checkammo2, bool(entity thiswep))
- {
- float ammo_amount;
- if(WEP_CVAR(seeker, type) == 1)
- {
- ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, tag_ammo);
- ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo);
- }
- else
- {
- ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, flac_ammo);
- ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, flac_ammo);
- }
- return ammo_amount;
- }
- METHOD(Seeker, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- W_Reload(self, min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo)), SND(RELOAD));
- }
- METHOD(Seeker, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_SEEKER_SUICIDE;
- }
- METHOD(Seeker, wr_killmessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- return WEAPON_SEEKER_MURDER_TAG;
- else
- return WEAPON_SEEKER_MURDER_SPRAY;
- }
+ METHOD(Seeker, wr_aim, void(entity thiswep))
+ {
+ if(WEP_CVAR(seeker, type) == 1)
+ if(W_Seeker_Tagged_Info(self, self.enemy) != world)
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(seeker, missile_speed_max), 0, WEP_CVAR(seeker, missile_lifetime), false);
+ else
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false);
+ else
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false);
+ }
+ METHOD(Seeker, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(autocvar_g_balance_seeker_reload_ammo && actor.clip_load < min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo))) { // forced reload
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ } else if(fire & 1)
+ {
+ if(WEP_CVAR(seeker, type) == 1)
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, missile_refire)))
+ {
+ W_Seeker_Attack();
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, missile_animtime), w_ready);
+ }
+ }
+ else
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, tag_refire)))
+ {
+ W_Seeker_Fire_Tag(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready);
+ }
+ }
+ }
+
+ else if(fire & 2)
+ {
+ if(WEP_CVAR(seeker, type) == 1)
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, tag_refire)))
+ {
+ W_Seeker_Fire_Tag(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready);
+ }
+ }
+ else
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, flac_refire)))
+ {
+ W_Seeker_Fire_Flac(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, flac_animtime), w_ready);
+ }
+ }
+ }
+ }
+ METHOD(Seeker, wr_checkammo1, bool(entity thiswep))
+ {
+ float ammo_amount;
+ if(WEP_CVAR(seeker, type) == 1)
+ {
+ ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, missile_ammo);
+ ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, missile_ammo);
+ }
+ else
+ {
+ ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, tag_ammo);
+ ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo);
+ }
+ return ammo_amount;
+ }
+ METHOD(Seeker, wr_checkammo2, bool(entity thiswep))
+ {
+ float ammo_amount;
+ if(WEP_CVAR(seeker, type) == 1)
+ {
+ ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, tag_ammo);
+ ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo);
+ }
+ else
+ {
+ ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, flac_ammo);
+ ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, flac_ammo);
+ }
+ return ammo_amount;
+ }
+ METHOD(Seeker, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ W_Reload(self, min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo)), SND(RELOAD));
+ }
-METHOD(Seeker, wr_suicidemessage, int(entity thiswep))
++METHOD(Seeker, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_SEEKER_SUICIDE;
+ }
-METHOD(Seeker, wr_killmessage, int(entity thiswep))
++METHOD(Seeker, wr_killmessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_SEEKER_MURDER_TAG;
+ else
+ return WEAPON_SEEKER_MURDER_SPRAY;
+ }
#endif
#ifdef CSQC
}
}
- METHOD(Shockwave, wr_aim, void(entity thiswep))
- {
- if(vlen(self.origin - self.enemy.origin) <= WEP_CVAR(shockwave, melee_range))
- { self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, false); }
- else
- { self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, false); }
- }
- METHOD(Shockwave, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(fire & 1)
- {
- if(time >= actor.shockwave_blasttime) // handle refire separately so the secondary can be fired straight after a primary
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(shockwave, blast_animtime)))
- {
- W_Shockwave_Attack();
- actor.shockwave_blasttime = time + WEP_CVAR(shockwave, blast_refire) * W_WeaponRateFactor();
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(shockwave, blast_animtime), w_ready);
- }
- }
- }
- else if(fire & 2)
- {
- //if(actor.clip_load >= 0) // we are not currently reloading
- if(!actor.crouch) // no crouchmelee please
- if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR(shockwave, melee_refire)))
- {
- // attempt forcing playback of the anim by switching to another anim (that we never play) here...
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shockwave_Melee);
- }
- }
- }
- METHOD(Shockwave, wr_checkammo1, bool(entity thiswep))
- {
- return true; // infinite ammo
- }
- METHOD(Shockwave, wr_checkammo2, bool(entity thiswep))
- {
- // shockwave has infinite ammo
- return true;
- }
- METHOD(Shockwave, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_THINKING_WITH_PORTALS;
- }
- METHOD(Shockwave, wr_killmessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- return WEAPON_SHOCKWAVE_MURDER_SLAP;
- else
- return WEAPON_SHOCKWAVE_MURDER;
- }
+ METHOD(Shockwave, wr_aim, void(entity thiswep))
+ {
+ if(vlen(self.origin - self.enemy.origin) <= WEP_CVAR(shockwave, melee_range))
+ { PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(1000000, 0, 0.001, false); }
+ else
+ { PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 0.001, false); }
+ }
+ METHOD(Shockwave, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(fire & 1)
+ {
+ if(time >= actor.shockwave_blasttime) // handle refire separately so the secondary can be fired straight after a primary
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(shockwave, blast_animtime)))
+ {
+ W_Shockwave_Attack();
+ actor.shockwave_blasttime = time + WEP_CVAR(shockwave, blast_refire) * W_WeaponRateFactor();
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(shockwave, blast_animtime), w_ready);
+ }
+ }
+ }
+ else if(fire & 2)
+ {
+ //if(actor.clip_load >= 0) // we are not currently reloading
+ if(!actor.crouch) // no crouchmelee please
+ if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR(shockwave, melee_refire)))
+ {
+ // attempt forcing playback of the anim by switching to another anim (that we never play) here...
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shockwave_Melee);
+ }
+ }
+ }
+ METHOD(Shockwave, wr_checkammo1, bool(entity thiswep))
+ {
+ return true; // infinite ammo
+ }
+ METHOD(Shockwave, wr_checkammo2, bool(entity thiswep))
+ {
+ // shockwave has infinite ammo
+ return true;
+ }
-METHOD(Shockwave, wr_suicidemessage, int(entity thiswep))
++METHOD(Shockwave, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_THINKING_WITH_PORTALS;
+ }
-METHOD(Shockwave, wr_killmessage, int(entity thiswep))
++METHOD(Shockwave, wr_killmessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_SHOCKWAVE_MURDER_SLAP;
+ else
+ return WEAPON_SHOCKWAVE_MURDER;
+ }
#endif
#ifdef CSQC
.float shotgun_primarytime;
- METHOD(Shotgun, wr_aim, void(entity thiswep))
- {
- if(vdist(self.origin - self.enemy.origin, <=, WEP_CVAR_SEC(shotgun, melee_range)))
- self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, false);
- else
- self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, false);
- }
- METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(WEP_CVAR(shotgun, reload_ammo) && actor.clip_load < WEP_CVAR_PRI(shotgun, ammo)) // forced reload
- {
- // don't force reload an empty shotgun if its melee attack is active
- if(WEP_CVAR(shotgun, secondary) < 2) {
- thiswep.wr_reload(thiswep, actor, weaponentity);
- }
- }
- else
- {
- if(fire & 1)
- {
- if(time >= actor.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(shotgun, animtime)))
- {
- W_Shotgun_Attack(thiswep, true);
- actor.shotgun_primarytime = time + WEP_CVAR_PRI(shotgun, refire) * W_WeaponRateFactor();
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(shotgun, animtime), w_ready);
- }
- }
- }
- else if((fire & 2) && WEP_CVAR(shotgun, secondary) == 2)
- {
- if(time >= actor.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(shotgun, alt_animtime)))
- {
- W_Shotgun_Attack(thiswep, false);
- actor.shotgun_primarytime = time + WEP_CVAR_SEC(shotgun, alt_refire) * W_WeaponRateFactor();
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(shotgun, alt_animtime), W_Shotgun_Attack3_Frame1);
- }
- }
- }
- }
- if(actor.clip_load >= 0) // we are not currently reloading
- if(!actor.crouch) // no crouchmelee please
- if(WEP_CVAR(shotgun, secondary) == 1)
- if(((fire & 1) && actor.(thiswep.ammo_field) <= 0 && !(actor.items & IT_UNLIMITED_WEAPON_AMMO)) || (fire & 2))
- if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(shotgun, refire)))
- {
- // attempt forcing playback of the anim by switching to another anim (that we never play) here...
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shotgun_Attack2);
- }
- }
- METHOD(Shotgun, wr_setup, void(entity thiswep))
- {
- self.ammo_field = ammo_none;
- }
- METHOD(Shotgun, wr_checkammo1, bool(entity thiswep))
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(shotgun, ammo);
- ammo_amount += self.(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo);
- return ammo_amount;
- }
- METHOD(Shotgun, wr_checkammo2, bool(entity thiswep))
- {
- if(IS_BOT_CLIENT(self))
- if(vdist(self.origin - self.enemy.origin, >, WEP_CVAR_SEC(shotgun, melee_range)))
- return false; // bots cannot use secondary out of range (fixes constant melee when out of ammo)
- switch(WEP_CVAR(shotgun, secondary))
- {
- case 1: return true; // melee does not use ammo
- case 2: // secondary triple shot
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(shotgun, ammo);
- ammo_amount += self.(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo);
- return ammo_amount;
- }
- default: return false; // secondary unavailable
- }
- }
- METHOD(Shotgun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- W_Reload(self, WEP_CVAR_PRI(shotgun, ammo), SND(RELOAD)); // WEAPONTODO
- }
- METHOD(Shotgun, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_THINKING_WITH_PORTALS;
- }
- METHOD(Shotgun, wr_killmessage, Notification(entity thiswep))
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- return WEAPON_SHOTGUN_MURDER_SLAP;
- else
- return WEAPON_SHOTGUN_MURDER;
- }
+ METHOD(Shotgun, wr_aim, void(entity thiswep))
+ {
+ if(vdist(self.origin - self.enemy.origin, <=, WEP_CVAR_SEC(shotgun, melee_range)))
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(1000000, 0, 0.001, false);
+ else
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 0.001, false);
+ }
+ METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(WEP_CVAR(shotgun, reload_ammo) && actor.clip_load < WEP_CVAR_PRI(shotgun, ammo)) // forced reload
+ {
+ // don't force reload an empty shotgun if its melee attack is active
+ if(WEP_CVAR(shotgun, secondary) < 2) {
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ }
+ }
+ else
+ {
+ if(fire & 1)
+ {
+ if(time >= actor.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(shotgun, animtime)))
+ {
+ W_Shotgun_Attack(thiswep, true);
+ actor.shotgun_primarytime = time + WEP_CVAR_PRI(shotgun, refire) * W_WeaponRateFactor();
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(shotgun, animtime), w_ready);
+ }
+ }
+ }
+ else if((fire & 2) && WEP_CVAR(shotgun, secondary) == 2)
+ {
+ if(time >= actor.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(shotgun, alt_animtime)))
+ {
+ W_Shotgun_Attack(thiswep, false);
+ actor.shotgun_primarytime = time + WEP_CVAR_SEC(shotgun, alt_refire) * W_WeaponRateFactor();
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(shotgun, alt_animtime), W_Shotgun_Attack3_Frame1);
+ }
+ }
+ }
+ }
+ if(actor.clip_load >= 0) // we are not currently reloading
+ if(!actor.crouch) // no crouchmelee please
+ if(WEP_CVAR(shotgun, secondary) == 1)
+ if(((fire & 1) && actor.(thiswep.ammo_field) <= 0 && !(actor.items & IT_UNLIMITED_WEAPON_AMMO)) || (fire & 2))
+ if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(shotgun, refire)))
+ {
+ // attempt forcing playback of the anim by switching to another anim (that we never play) here...
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shotgun_Attack2);
+ }
+ }
+ METHOD(Shotgun, wr_setup, void(entity thiswep))
+ {
+ self.ammo_field = ammo_none;
+ }
+ METHOD(Shotgun, wr_checkammo1, bool(entity thiswep))
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(shotgun, ammo);
+ ammo_amount += self.(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo);
+ return ammo_amount;
+ }
+ METHOD(Shotgun, wr_checkammo2, bool(entity thiswep))
+ {
+ if(IS_BOT_CLIENT(self))
+ if(vdist(self.origin - self.enemy.origin, >, WEP_CVAR_SEC(shotgun, melee_range)))
+ return false; // bots cannot use secondary out of range (fixes constant melee when out of ammo)
+ switch(WEP_CVAR(shotgun, secondary))
+ {
+ case 1: return true; // melee does not use ammo
+ case 2: // secondary triple shot
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(shotgun, ammo);
+ ammo_amount += self.(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo);
+ return ammo_amount;
+ }
+ default: return false; // secondary unavailable
+ }
+ }
+ METHOD(Shotgun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ W_Reload(self, WEP_CVAR_PRI(shotgun, ammo), SND(RELOAD)); // WEAPONTODO
+ }
-METHOD(Shotgun, wr_suicidemessage, int(entity thiswep))
++METHOD(Shotgun, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_THINKING_WITH_PORTALS;
+ }
-METHOD(Shotgun, wr_killmessage, int(entity thiswep))
++METHOD(Shotgun, wr_killmessage, Notification(entity thiswep))
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_SHOTGUN_MURDER_SLAP;
+ else
+ return WEAPON_SHOTGUN_MURDER;
+ }
#endif
#ifdef CSQC
}
}
- METHOD(Vaporizer, wr_aim, void(entity thiswep))
- {
- if(self.(thiswep.ammo_field) > 0)
- self.BUTTON_ATCK = bot_aim(1000000, 0, 1, false);
- else
- self.BUTTON_ATCK2 = bot_aim(WEP_CVAR_SEC(vaporizer, speed), 0, WEP_CVAR_SEC(vaporizer, lifetime), false); // WEAPONTODO: replace with proper vaporizer cvars
- }
- METHOD(Vaporizer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
- // if the laser uses load, we also consider its ammo for reloading
- if(WEP_CVAR(vaporizer, reload_ammo) && WEP_CVAR_SEC(vaporizer, ammo) && actor.clip_load < min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo))) { // forced reload
- thiswep.wr_reload(thiswep, actor, weaponentity);
- } else if(WEP_CVAR(vaporizer, reload_ammo) && actor.clip_load < vaporizer_ammo) { // forced reload
- thiswep.wr_reload(thiswep, actor, weaponentity);
- }
- if((fire & 1) && (actor.ammo_cells || !autocvar_g_rm) && !forbidWeaponUse(actor))
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(vaporizer, refire)))
- {
- W_Vaporizer_Attack(thiswep);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(vaporizer, animtime), w_ready);
- }
- }
- if((fire & 2) || ((fire & 1) && !actor.ammo_cells && autocvar_g_rm))
- {
- if((autocvar_g_rm && autocvar_g_rm_laser) || autocvar_g_rm_laser == 2)
- {
- bool rapid = autocvar_g_rm_laser_rapid;
- if(actor.jump_interval <= time && !actor.held_down)
- {
- if(rapid)
- actor.held_down = true;
- actor.jump_interval = time + autocvar_g_rm_laser_refire;
- actor.jump_interval2 = time + autocvar_g_rm_laser_rapid_delay;
- damage_goodhits = 0;
- W_RocketMinsta_Attack2();
- }
- else if(rapid && actor.jump_interval2 <= time && actor.held_down)
- {
- actor.jump_interval2 = time + autocvar_g_rm_laser_rapid_refire;
- damage_goodhits = 0;
- W_RocketMinsta_Attack3();
- //weapon_thinkf(actor, WFRAME_FIRE2, autocvar_g_rm_laser_rapid_animtime, w_ready);
- }
- }
- else if (actor.jump_interval <= time)
- {
- // handle refire manually, so that primary and secondary can be fired without conflictions (important for instagib)
- actor.jump_interval = time + WEP_CVAR_SEC(vaporizer, refire) * W_WeaponRateFactor();
-
- // decrease ammo for the laser?
- if(WEP_CVAR_SEC(vaporizer, ammo))
- W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(vaporizer, ammo));
-
- // ugly instagib hack to reuse the fire mode of the laser
- makevectors(actor.v_angle);
- Weapon oldwep = PS(actor).m_weapon; // we can't avoid this hack
- PS(actor).m_weapon = WEP_BLASTER;
- W_Blaster_Attack(
- actor,
- WEP_BLASTER.m_id | HITTYPE_SECONDARY,
- WEP_CVAR_SEC(vaporizer, shotangle),
- WEP_CVAR_SEC(vaporizer, damage),
- WEP_CVAR_SEC(vaporizer, edgedamage),
- WEP_CVAR_SEC(vaporizer, radius),
- WEP_CVAR_SEC(vaporizer, force),
- WEP_CVAR_SEC(vaporizer, speed),
- WEP_CVAR_SEC(vaporizer, spread),
- WEP_CVAR_SEC(vaporizer, delay),
- WEP_CVAR_SEC(vaporizer, lifetime)
- );
- PS(actor).m_weapon = oldwep;
-
- // now do normal refire
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(vaporizer, animtime), w_ready);
- }
- }
- else
- actor.held_down = false;
- }
- METHOD(Vaporizer, wr_setup, void(entity thiswep))
- {
- self.ammo_field = (thiswep.ammo_field);
- self.vaporizer_lasthit = 0;
- }
- METHOD(Vaporizer, wr_checkammo1, bool(entity thiswep))
- {
- float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
- float ammo_amount = self.(thiswep.ammo_field) >= vaporizer_ammo;
- ammo_amount += self.(weapon_load[WEP_VAPORIZER.m_id]) >= vaporizer_ammo;
- return ammo_amount;
- }
- METHOD(Vaporizer, wr_checkammo2, bool(entity thiswep))
- {
- if(!WEP_CVAR_SEC(vaporizer, ammo))
- return true;
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(vaporizer, ammo);
- ammo_amount += self.(weapon_load[WEP_VAPORIZER.m_id]) >= WEP_CVAR_SEC(vaporizer, ammo);
- return ammo_amount;
- }
- METHOD(Vaporizer, wr_resetplayer, void(entity thiswep))
- {
- self.vaporizer_lasthit = 0;
- }
- METHOD(Vaporizer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
- float used_ammo;
- if(WEP_CVAR_SEC(vaporizer, ammo))
- used_ammo = min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo));
- else
- used_ammo = vaporizer_ammo;
-
- W_Reload(self, used_ammo, SND(RELOAD));
- }
- METHOD(Vaporizer, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_THINKING_WITH_PORTALS;
- }
- METHOD(Vaporizer, wr_killmessage, Notification(entity thiswep))
- {
- return WEAPON_VAPORIZER_MURDER;
- }
+ METHOD(Vaporizer, wr_aim, void(entity thiswep))
+ {
+ if(self.(thiswep.ammo_field) > 0)
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 1, false);
+ else
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR_SEC(vaporizer, speed), 0, WEP_CVAR_SEC(vaporizer, lifetime), false); // WEAPONTODO: replace with proper vaporizer cvars
+ }
+ METHOD(Vaporizer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
+ // if the laser uses load, we also consider its ammo for reloading
+ if(WEP_CVAR(vaporizer, reload_ammo) && WEP_CVAR_SEC(vaporizer, ammo) && actor.clip_load < min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo))) { // forced reload
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ } else if(WEP_CVAR(vaporizer, reload_ammo) && actor.clip_load < vaporizer_ammo) { // forced reload
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ }
+ if((fire & 1) && (actor.ammo_cells || !autocvar_g_rm) && !forbidWeaponUse(actor))
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(vaporizer, refire)))
+ {
+ W_Vaporizer_Attack(thiswep);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(vaporizer, animtime), w_ready);
+ }
+ }
+ if((fire & 2) || ((fire & 1) && !actor.ammo_cells && autocvar_g_rm))
+ {
+ if((autocvar_g_rm && autocvar_g_rm_laser) || autocvar_g_rm_laser == 2)
+ {
+ bool rapid = autocvar_g_rm_laser_rapid;
+ if(actor.jump_interval <= time && !actor.held_down)
+ {
+ if(rapid)
+ actor.held_down = true;
+ actor.jump_interval = time + autocvar_g_rm_laser_refire;
+ actor.jump_interval2 = time + autocvar_g_rm_laser_rapid_delay;
+ damage_goodhits = 0;
+ W_RocketMinsta_Attack2();
+ }
+ else if(rapid && actor.jump_interval2 <= time && actor.held_down)
+ {
+ actor.jump_interval2 = time + autocvar_g_rm_laser_rapid_refire;
+ damage_goodhits = 0;
+ W_RocketMinsta_Attack3();
+ //weapon_thinkf(actor, WFRAME_FIRE2, autocvar_g_rm_laser_rapid_animtime, w_ready);
+ }
+ }
+ else if (actor.jump_interval <= time)
+ {
+ // handle refire manually, so that primary and secondary can be fired without conflictions (important for instagib)
+ actor.jump_interval = time + WEP_CVAR_SEC(vaporizer, refire) * W_WeaponRateFactor();
+
+ // decrease ammo for the laser?
+ if(WEP_CVAR_SEC(vaporizer, ammo))
+ W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(vaporizer, ammo));
+
+ // ugly instagib hack to reuse the fire mode of the laser
+ makevectors(actor.v_angle);
+ Weapon oldwep = PS(actor).m_weapon; // we can't avoid this hack
+ PS(actor).m_weapon = WEP_BLASTER;
+ W_Blaster_Attack(
+ actor,
+ WEP_BLASTER.m_id | HITTYPE_SECONDARY,
+ WEP_CVAR_SEC(vaporizer, shotangle),
+ WEP_CVAR_SEC(vaporizer, damage),
+ WEP_CVAR_SEC(vaporizer, edgedamage),
+ WEP_CVAR_SEC(vaporizer, radius),
+ WEP_CVAR_SEC(vaporizer, force),
+ WEP_CVAR_SEC(vaporizer, speed),
+ WEP_CVAR_SEC(vaporizer, spread),
+ WEP_CVAR_SEC(vaporizer, delay),
+ WEP_CVAR_SEC(vaporizer, lifetime)
+ );
+ PS(actor).m_weapon = oldwep;
+
+ // now do normal refire
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(vaporizer, animtime), w_ready);
+ }
+ }
+ else
+ actor.held_down = false;
+ }
+ METHOD(Vaporizer, wr_setup, void(entity thiswep))
+ {
+ self.ammo_field = (thiswep.ammo_field);
+ self.vaporizer_lasthit = 0;
+ }
+ METHOD(Vaporizer, wr_checkammo1, bool(entity thiswep))
+ {
+ float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
+ float ammo_amount = self.(thiswep.ammo_field) >= vaporizer_ammo;
+ ammo_amount += self.(weapon_load[WEP_VAPORIZER.m_id]) >= vaporizer_ammo;
+ return ammo_amount;
+ }
+ METHOD(Vaporizer, wr_checkammo2, bool(entity thiswep))
+ {
+ if(!WEP_CVAR_SEC(vaporizer, ammo))
+ return true;
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(vaporizer, ammo);
+ ammo_amount += self.(weapon_load[WEP_VAPORIZER.m_id]) >= WEP_CVAR_SEC(vaporizer, ammo);
+ return ammo_amount;
+ }
+ METHOD(Vaporizer, wr_resetplayer, void(entity thiswep))
+ {
+ self.vaporizer_lasthit = 0;
+ }
+ METHOD(Vaporizer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
+ float used_ammo;
+ if(WEP_CVAR_SEC(vaporizer, ammo))
+ used_ammo = min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo));
+ else
+ used_ammo = vaporizer_ammo;
+
+ W_Reload(self, used_ammo, SND(RELOAD));
+ }
-METHOD(Vaporizer, wr_suicidemessage, int(entity thiswep))
++METHOD(Vaporizer, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_THINKING_WITH_PORTALS;
+ }
-METHOD(Vaporizer, wr_killmessage, int(entity thiswep))
++METHOD(Vaporizer, wr_killmessage, Notification(entity thiswep))
+ {
+ return WEAPON_VAPORIZER_MURDER;
+ }
#endif
#ifdef CSQC
.float vortex_chargepool_pauseregen_finished;
- METHOD(Vortex, wr_aim, void(entity thiswep))
- {
- if(bot_aim(1000000, 0, 1, false))
- self.BUTTON_ATCK = true;
- else
- {
- if(WEP_CVAR(vortex, charge))
- self.BUTTON_ATCK2 = true;
- }
- }
- METHOD(Vortex, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
- {
- if(WEP_CVAR(vortex, charge) && actor.vortex_charge < WEP_CVAR(vortex, charge_limit))
- actor.vortex_charge = min(1, actor.vortex_charge + WEP_CVAR(vortex, charge_rate) * frametime / W_TICSPERFRAME);
-
- if(WEP_CVAR_SEC(vortex, chargepool))
- if(actor.vortex_chargepool_ammo < 1)
- {
- if(actor.vortex_chargepool_pauseregen_finished < time)
- actor.vortex_chargepool_ammo = min(1, actor.vortex_chargepool_ammo + WEP_CVAR_SEC(vortex, chargepool_regen) * frametime / W_TICSPERFRAME);
- actor.pauseregen_finished = max(actor.pauseregen_finished, time + WEP_CVAR_SEC(vortex, chargepool_pause_regen));
- }
-
- if(autocvar_g_balance_vortex_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo))) { // forced reload
- thiswep.wr_reload(thiswep, actor, weaponentity);
- } else
- {
- if(fire & 1)
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(vortex, refire)))
- {
- W_Vortex_Attack(thiswep, 0);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(vortex, animtime), w_ready);
- }
- }
- if((WEP_CVAR(vortex, charge) && !WEP_CVAR(vortex, secondary)) ? (actor.BUTTON_ZOOM | actor.BUTTON_ZOOMSCRIPT) : (fire & 2))
- {
- if(WEP_CVAR(vortex, charge))
- {
- actor.vortex_charge_rottime = time + WEP_CVAR(vortex, charge_rot_pause);
- float dt = frametime / W_TICSPERFRAME;
-
- if(actor.vortex_charge < 1)
- {
- if(WEP_CVAR_SEC(vortex, chargepool))
- {
- if(WEP_CVAR_SEC(vortex, ammo))
- {
- // always deplete if secondary is held
- actor.vortex_chargepool_ammo = max(0, actor.vortex_chargepool_ammo - WEP_CVAR_SEC(vortex, ammo) * dt);
-
- dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate));
- actor.vortex_chargepool_pauseregen_finished = time + WEP_CVAR_SEC(vortex, chargepool_pause_regen);
- dt = min(dt, actor.vortex_chargepool_ammo);
- dt = max(0, dt);
-
- actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate);
- }
- }
-
- else if(WEP_CVAR_SEC(vortex, ammo))
- {
- if(fire & 2) // only eat ammo when the button is pressed
- {
- dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate));
- if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
- {
- // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
- if(autocvar_g_balance_vortex_reload_ammo)
- {
- dt = min(dt, (actor.clip_load - WEP_CVAR_PRI(vortex, ammo)) / WEP_CVAR_SEC(vortex, ammo));
- dt = max(0, dt);
- if(dt > 0)
- {
- actor.clip_load = max(WEP_CVAR_SEC(vortex, ammo), actor.clip_load - WEP_CVAR_SEC(vortex, ammo) * dt);
- }
- actor.(weapon_load[WEP_VORTEX.m_id]) = actor.clip_load;
- }
- else
- {
- dt = min(dt, (actor.(thiswep.ammo_field) - WEP_CVAR_PRI(vortex, ammo)) / WEP_CVAR_SEC(vortex, ammo));
- dt = max(0, dt);
- if(dt > 0)
- {
- actor.(thiswep.ammo_field) = max(WEP_CVAR_SEC(vortex, ammo), actor.(thiswep.ammo_field) - WEP_CVAR_SEC(vortex, ammo) * dt);
- }
- }
- }
- actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate);
- }
- }
-
- else
- {
- dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate));
- actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate);
- }
- }
- }
- else if(WEP_CVAR(vortex, secondary))
- {
- if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(vortex, refire)))
- {
- W_Vortex_Attack(thiswep, 1);
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(vortex, animtime), w_ready);
- }
- }
- }
- }
- }
- METHOD(Vortex, wr_setup, void(entity thiswep))
- {
- self.vortex_lasthit = 0;
- }
- METHOD(Vortex, wr_checkammo1, bool(entity thiswep))
- {
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(vortex, ammo);
- ammo_amount += (autocvar_g_balance_vortex_reload_ammo && self.(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_PRI(vortex, ammo));
- return ammo_amount;
- }
- METHOD(Vortex, wr_checkammo2, bool(entity thiswep))
- {
- if(WEP_CVAR(vortex, secondary))
- {
- // don't allow charging if we don't have enough ammo
- float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(vortex, ammo);
- ammo_amount += self.(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_SEC(vortex, ammo);
- return ammo_amount;
- }
- else
- {
- return false; // zoom is not a fire mode
- }
- }
- METHOD(Vortex, wr_resetplayer, void(entity thiswep))
- {
- if (WEP_CVAR(vortex, charge)) {
- if (WEP_CVAR_SEC(vortex, chargepool)) {
- self.vortex_chargepool_ammo = 1;
- }
- self.vortex_charge = WEP_CVAR(vortex, charge_start);
- }
- self.vortex_lasthit = 0;
- }
- METHOD(Vortex, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
- {
- W_Reload(self, min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo)), SND(RELOAD));
- }
- METHOD(Vortex, wr_suicidemessage, Notification(entity thiswep))
- {
- return WEAPON_THINKING_WITH_PORTALS;
- }
- METHOD(Vortex, wr_killmessage, Notification(entity thiswep))
- {
- return WEAPON_VORTEX_MURDER;
- }
+ METHOD(Vortex, wr_aim, void(entity thiswep))
+ {
+ if(bot_aim(1000000, 0, 1, false))
+ PHYS_INPUT_BUTTON_ATCK(self) = true;
+ else
+ {
+ if(WEP_CVAR(vortex, charge))
+ PHYS_INPUT_BUTTON_ATCK2(self) = true;
+ }
+ }
+ METHOD(Vortex, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
+ {
+ if(WEP_CVAR(vortex, charge) && actor.vortex_charge < WEP_CVAR(vortex, charge_limit))
+ actor.vortex_charge = min(1, actor.vortex_charge + WEP_CVAR(vortex, charge_rate) * frametime / W_TICSPERFRAME);
+
+ if(WEP_CVAR_SEC(vortex, chargepool))
+ if(actor.vortex_chargepool_ammo < 1)
+ {
+ if(actor.vortex_chargepool_pauseregen_finished < time)
+ actor.vortex_chargepool_ammo = min(1, actor.vortex_chargepool_ammo + WEP_CVAR_SEC(vortex, chargepool_regen) * frametime / W_TICSPERFRAME);
+ actor.pauseregen_finished = max(actor.pauseregen_finished, time + WEP_CVAR_SEC(vortex, chargepool_pause_regen));
+ }
+
+ if(autocvar_g_balance_vortex_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo))) { // forced reload
+ thiswep.wr_reload(thiswep, actor, weaponentity);
+ } else
+ {
+ if(fire & 1)
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(vortex, refire)))
+ {
+ W_Vortex_Attack(thiswep, 0);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(vortex, animtime), w_ready);
+ }
+ }
+ if((WEP_CVAR(vortex, charge) && !WEP_CVAR(vortex, secondary)) ? (PHYS_INPUT_BUTTON_ZOOM(actor) | PHYS_INPUT_BUTTON_ZOOMSCRIPT(actor)) : (fire & 2))
+ {
+ if(WEP_CVAR(vortex, charge))
+ {
+ actor.vortex_charge_rottime = time + WEP_CVAR(vortex, charge_rot_pause);
+ float dt = frametime / W_TICSPERFRAME;
+
+ if(actor.vortex_charge < 1)
+ {
+ if(WEP_CVAR_SEC(vortex, chargepool))
+ {
+ if(WEP_CVAR_SEC(vortex, ammo))
+ {
+ // always deplete if secondary is held
+ actor.vortex_chargepool_ammo = max(0, actor.vortex_chargepool_ammo - WEP_CVAR_SEC(vortex, ammo) * dt);
+
+ dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate));
+ actor.vortex_chargepool_pauseregen_finished = time + WEP_CVAR_SEC(vortex, chargepool_pause_regen);
+ dt = min(dt, actor.vortex_chargepool_ammo);
+ dt = max(0, dt);
+
+ actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate);
+ }
+ }
+
+ else if(WEP_CVAR_SEC(vortex, ammo))
+ {
+ if(fire & 2) // only eat ammo when the button is pressed
+ {
+ dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate));
+ if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+ {
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
+ if(autocvar_g_balance_vortex_reload_ammo)
+ {
+ dt = min(dt, (actor.clip_load - WEP_CVAR_PRI(vortex, ammo)) / WEP_CVAR_SEC(vortex, ammo));
+ dt = max(0, dt);
+ if(dt > 0)
+ {
+ actor.clip_load = max(WEP_CVAR_SEC(vortex, ammo), actor.clip_load - WEP_CVAR_SEC(vortex, ammo) * dt);
+ }
+ actor.(weapon_load[WEP_VORTEX.m_id]) = actor.clip_load;
+ }
+ else
+ {
+ dt = min(dt, (actor.(thiswep.ammo_field) - WEP_CVAR_PRI(vortex, ammo)) / WEP_CVAR_SEC(vortex, ammo));
+ dt = max(0, dt);
+ if(dt > 0)
+ {
+ actor.(thiswep.ammo_field) = max(WEP_CVAR_SEC(vortex, ammo), actor.(thiswep.ammo_field) - WEP_CVAR_SEC(vortex, ammo) * dt);
+ }
+ }
+ }
+ actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate);
+ }
+ }
+
+ else
+ {
+ dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate));
+ actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate);
+ }
+ }
+ }
+ else if(WEP_CVAR(vortex, secondary))
+ {
+ if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(vortex, refire)))
+ {
+ W_Vortex_Attack(thiswep, 1);
+ weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(vortex, animtime), w_ready);
+ }
+ }
+ }
+ }
+ }
+ METHOD(Vortex, wr_setup, void(entity thiswep))
+ {
+ self.vortex_lasthit = 0;
+ }
+ METHOD(Vortex, wr_checkammo1, bool(entity thiswep))
+ {
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(vortex, ammo);
+ ammo_amount += (autocvar_g_balance_vortex_reload_ammo && self.(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_PRI(vortex, ammo));
+ return ammo_amount;
+ }
+ METHOD(Vortex, wr_checkammo2, bool(entity thiswep))
+ {
+ if(WEP_CVAR(vortex, secondary))
+ {
+ // don't allow charging if we don't have enough ammo
+ float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(vortex, ammo);
+ ammo_amount += self.(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_SEC(vortex, ammo);
+ return ammo_amount;
+ }
+ else
+ {
+ return false; // zoom is not a fire mode
+ }
+ }
+ METHOD(Vortex, wr_resetplayer, void(entity thiswep))
+ {
+ if (WEP_CVAR(vortex, charge)) {
+ if (WEP_CVAR_SEC(vortex, chargepool)) {
+ self.vortex_chargepool_ammo = 1;
+ }
+ self.vortex_charge = WEP_CVAR(vortex, charge_start);
+ }
+ self.vortex_lasthit = 0;
+ }
+ METHOD(Vortex, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+ {
+ W_Reload(self, min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo)), SND(RELOAD));
+ }
-METHOD(Vortex, wr_suicidemessage, int(entity thiswep))
++METHOD(Vortex, wr_suicidemessage, Notification(entity thiswep))
+ {
+ return WEAPON_THINKING_WITH_PORTALS;
+ }
-METHOD(Vortex, wr_killmessage, int(entity thiswep))
++METHOD(Vortex, wr_killmessage, Notification(entity thiswep))
+ {
+ return WEAPON_VORTEX_MURDER;
+ }
#endif
#ifdef CSQC
self.motd_actived_time = time;
else if ((time - self.motd_actived_time > 2) && IS_PLAYER(self)) { // hide it some seconds after BUTTON_INFO has been released
self.motd_actived_time = 0;
- Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD);
+ Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CPID_MOTD);
}
} else {
- if (self.BUTTON_INFO)
+ if (PHYS_INPUT_BUTTON_INFO(self))
self.motd_actived_time = time;
else if (time - self.motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
self.motd_actived_time = 0;