Merge branch 'master' into TimePath/notifications 292/head
authorTimePath <andrew.hardaker1995@gmail.com>
Thu, 10 Mar 2016 06:35:55 +0000 (17:35 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Thu, 10 Mar 2016 06:39:13 +0000 (17:39 +1100)
# Conflicts:
# qcsrc/common/mutators/mutator/overkill/hmg.qc
# qcsrc/common/mutators/mutator/overkill/rpc.qc
# qcsrc/common/weapons/weapon/arc.qc
# qcsrc/common/weapons/weapon/blaster.qc
# qcsrc/common/weapons/weapon/crylink.qc
# qcsrc/common/weapons/weapon/devastator.qc
# qcsrc/common/weapons/weapon/electro.qc
# qcsrc/common/weapons/weapon/fireball.qc
# qcsrc/common/weapons/weapon/hagar.qc
# qcsrc/common/weapons/weapon/hlac.qc
# qcsrc/common/weapons/weapon/hook.qc
# qcsrc/common/weapons/weapon/machinegun.qc
# qcsrc/common/weapons/weapon/minelayer.qc
# qcsrc/common/weapons/weapon/mortar.qc
# qcsrc/common/weapons/weapon/rifle.qc
# qcsrc/common/weapons/weapon/seeker.qc
# qcsrc/common/weapons/weapon/shockwave.qc
# qcsrc/common/weapons/weapon/shotgun.qc
# qcsrc/common/weapons/weapon/vaporizer.qc
# qcsrc/common/weapons/weapon/vortex.qc

34 files changed:
1  2 
qcsrc/common/constants.qh
qcsrc/common/mutators/mutator/campcheck/campcheck.qc
qcsrc/common/mutators/mutator/instagib/instagib.qc
qcsrc/common/mutators/mutator/nades/nades.qc
qcsrc/common/mutators/mutator/overkill/hmg.qc
qcsrc/common/mutators/mutator/overkill/rpc.qc
qcsrc/common/t_items.qc
qcsrc/common/util.qh
qcsrc/common/weapons/weapon/arc.qc
qcsrc/common/weapons/weapon/blaster.qc
qcsrc/common/weapons/weapon/crylink.qc
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/electro.qc
qcsrc/common/weapons/weapon/fireball.qc
qcsrc/common/weapons/weapon/hagar.qc
qcsrc/common/weapons/weapon/hlac.qc
qcsrc/common/weapons/weapon/hook.qc
qcsrc/common/weapons/weapon/machinegun.qc
qcsrc/common/weapons/weapon/minelayer.qc
qcsrc/common/weapons/weapon/mortar.qc
qcsrc/common/weapons/weapon/rifle.qc
qcsrc/common/weapons/weapon/seeker.qc
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/common/weapons/weapon/shotgun.qc
qcsrc/common/weapons/weapon/tuba.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/common/weapons/weapon/vortex.qc
qcsrc/server/cl_client.qc
qcsrc/server/g_damage.qc
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/mutator/gamemode_ctf.qc
qcsrc/server/mutators/mutator/gamemode_keyhunt.qc
qcsrc/server/weapons/weaponsystem.qc

Simple merge
@@@ -98,60 -98,66 +98,66 @@@ void W_HeavyMachineGun_Attack_Auto(Weap
        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
@@@ -150,61 -150,67 +150,67 @@@ void W_RocketPropelledChainsaw_Attack (
        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
  
Simple merge
Simple merge
@@@ -726,145 -726,145 +726,145 @@@ void Arc_Smoke(
        }
  }
  
-               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;
@@@ -150,102 -150,102 +150,102 @@@ void W_Blaster_Attack
        }
  }
  
              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
@@@ -567,123 -567,123 +567,123 @@@ void W_Crylink_Attack2(Weapon thiswep
        }
  }
  
-               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
@@@ -404,221 -404,221 +404,221 @@@ void W_Devastator_Attack(Weapon thiswep
        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
@@@ -425,121 -425,121 +425,121 @@@ void W_Electro_CheckAttack(Weapon thisw
  
  .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
@@@ -351,77 -351,77 +351,77 @@@ void W_Fireball_Attack2(
        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
@@@ -397,98 -397,98 +397,98 @@@ void W_Hagar_Attack2_Load(Weapon thiswe
        }
  }
  
              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
@@@ -207,57 -207,57 +207,57 @@@ void W_HLAC_Attack2_Frame(Weapon thiswe
        }
  }
  
-               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
@@@ -180,129 -180,129 +180,125 @@@ void W_Hook_Attack2(Weapon thiswep, ent
        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
@@@ -242,113 -242,113 +242,113 @@@ void W_MachineGun_Attack_Burst(Weapon t
  
  }
  
-               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
@@@ -404,163 -404,163 +404,163 @@@ float W_MineLayer_PlacedMines(float det
        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
@@@ -298,109 -298,109 +298,109 @@@ void W_Mortar_Attack2(Weapon thiswep
  
  .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
@@@ -138,105 -138,105 +138,105 @@@ void W_Rifle_BulletHail(.entity weapone
  
  .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
@@@ -598,105 -598,105 +598,105 @@@ void W_Seeker_Fire_Tag(Weapon thiswep
  // 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
@@@ -672,58 -672,58 +672,58 @@@ void W_Shockwave_Attack(
        }
  }
  
-               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
@@@ -227,101 -227,101 +227,101 @@@ void W_Shotgun_Attack3_Frame1(Weapon th
  
  .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
Simple merge
@@@ -339,130 -339,130 +339,130 @@@ void W_RocketMinsta_Attack3 (
      }
  }
  
-               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
@@@ -210,162 -210,162 +210,162 @@@ void W_Vortex_Attack(Weapon thiswep, fl
  
  .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
@@@ -1921,10 -1845,10 +1845,10 @@@ void PrintWelcomeMessage(
                                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;
Simple merge
Simple merge
Simple merge
Simple merge