w_backoff = -1 * normalize(force);
setorigin(self, w_org + w_backoff * 2); // for sound() calls
- if(!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)) { _WEP_ACTION(hitwep, WR_IMPACTEFFECT); }
+ if(!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)) {
+ Weapon w = get_weaponinfo(hitwep); w.wr_impacteffect(w);
+ }
}
}
if(autocvar_cl_reticle)
{
+ Weapon wep = get_weaponinfo(activeweapon);
// Draw the aiming reticle for weapons that use it
// reticle_type is changed to the item we are zooming / aiming with, to decide which reticle to use
// It must be a persisted float for fading out to work properly (you let go of the zoom button for
// no zoom reticle while dead
reticle_type = 0;
}
- else if(_WEP_ACTION(activeweapon, WR_ZOOMRETICLE) && autocvar_cl_reticle_weapon)
+ else if(wep.wr_zoomreticle(wep) && autocvar_cl_reticle_weapon)
{
if(reticle_image != "") { reticle_type = 2; }
else { reticle_type = 0; }
return dummy_weapon_info;
}
-#define REGISTER_WEAPON(...) EVAL(OVERLOAD(REGISTER_WEAPON, __VA_ARGS__))
-
-#define REGISTER_WEAPON_2(id, inst) \
+#define REGISTER_WEAPON(id, inst) \
WepSet WEPSET_##id; \
REGISTER(RegisterWeapons, WEP, weapon_info, WEP_COUNT, id, m_id, inst) { \
this.m_id++; \
} \
REGISTER_INIT(WEP, id)
-#define _REGISTER_WEAPON(id, function, ammotype, impulse, flags, rating, color, modelname, mdl, crosshair, wepimg, refname, wepname) \
- REGISTER_WEAPON_2(id, NEW(Weapon, function, ammotype, impulse, flags, rating, color, modelname, mdl, crosshair, wepimg, refname, wepname))
-
-#ifndef MENUQC
- #define REGISTER_WEAPON_13(id, function, ammotype, impulse, flags, rating, color, modelname, mdl, crosshair, wepimg, refname, wepname) \
- bool function(entity this, int); \
- _REGISTER_WEAPON(id, function, ammotype, impulse, flags, rating, color, modelname, mdl, crosshair, wepimg, refname, wepname)
-#else
- #define REGISTER_WEAPON_13(id, function, ammotype, impulse, flags, rating, color, modelname, mdl, crosshair, wepimg, refname, wepname) \
- _REGISTER_WEAPON(id, w_new, ammotype, impulse, flags, rating, color, modelname, NULL, crosshair, wepimg, refname, wepname)
-#endif
-
// create cvars for weapon settings
#define WEP_ADD_CVAR_NONE(wepname,name) [[last]] float autocvar_g_balance_##wepname##_##name;
{ wep_config_queue[x] = string_null; }
// step 2: build new queue
- _WEP_ACTION(i, WR_CONFIG);
+ Weapon w = get_weaponinfo(i);
+ w.wr_config(w);
// step 3: sort queue
heapsort(WEP_CONFIG_COUNT, W_Config_Queue_Swap, W_Config_Queue_Compare, world);
#ifndef WEAPON_H
#define WEAPON_H
-bool w_new(entity this, int req);
-
.int ammo_shells;
.int ammo_nails;
.int ammo_rockets;
.int ammo_fuel;
.int ammo_none;
-// weapon requests
-const int WR_SETUP = 1; // (SERVER) setup weapon data
-.bool(entity this) wr_setup;
-/** (SERVER) logic to run every frame */
-.bool(entity this, bool fire1, bool fire2) wr_think;
-const int WR_CHECKAMMO1 = 3; // (SERVER) checks ammo for weapon primary
-.bool(entity this) wr_checkammo1;
-const int WR_CHECKAMMO2 = 4; // (SERVER) checks ammo for weapon second
-.bool(entity this) wr_checkammo2;
-const int WR_AIM = 5; // (SERVER) runs bot aiming code for this weapon
-.bool(entity this) wr_aim;
-const int WR_INIT = 6; // (BOTH) precaches models/sounds used by this weapon, also sets up weapon properties
-.bool(entity this) wr_init;
-const int WR_SUICIDEMESSAGE = 7; // (SERVER) notification number for suicide message (may inspect w_deathtype for details)
-.bool(entity this) wr_suicidemessage;
-const int WR_KILLMESSAGE = 8; // (SERVER) notification number for kill message (may inspect w_deathtype for details)
-.bool(entity this) wr_killmessage;
-const int WR_RELOAD = 9; // (SERVER) handles reloading for weapon
-.bool(entity this) wr_reload;
-const int WR_RESETPLAYER = 10; // (SERVER) clears fields that the weapon may use
-.bool(entity this) wr_resetplayer;
-const int WR_IMPACTEFFECT = 11; // (CLIENT) impact effect for weapon explosion
-.bool(entity this) wr_impacteffect;
-const int WR_PLAYERDEATH = 12; // (SERVER) called whenever a player dies
-.bool(entity this) wr_playerdeath;
-const int WR_GONETHINK = 13; // (SERVER) logic to run when weapon is lost
-.bool(entity this) wr_gonethink;
-const int WR_CONFIG = 14; // (ALL) dump weapon cvars to config in data directory (see: sv_cmd dumpweapons)
-.bool(entity this) wr_config;
-const int WR_ZOOMRETICLE = 15; // (CLIENT) weapon specific zoom reticle
-.bool(entity this) wr_zoomreticle;
-const int WR_DROP = 16; // (SERVER) the weapon is dropped
-.bool(entity this) wr_drop;
-const int WR_PICKUP = 17; // (SERVER) a weapon is picked up
-.bool(entity this) wr_pickup;
-
/** fields which are explicitly/manually set are marked with "M", fields set automatically are marked with "A" */
CLASS(Weapon, Object)
ATTRIB(Weapon, m_id, int, 0)
ATTRIB(Weapon, weapon, int, 0);
/** A: WEPSET_id : WEPSET_... */
ATTRIB(Weapon, weapons, WepSet, '0 0 0');
- /** M: function : w_... */
- METHOD(Weapon, weapon_func, bool(entity this, int req)) { return w_new(this, req); }
/** M: ammotype : main ammo field */
ATTRIB(Weapon, ammo_field, .int, ammo_none);
/** M: impulse : weapon impulse */
/** M: wepname : human readable name */
ATTRIB(Weapon, message, string, "AOL CD Thrower");
+ /** (SERVER) setup weapon data */
+ METHOD(Weapon, wr_setup, bool(Weapon this)) {return false;}
+ /** (SERVER) logic to run every frame */
+ METHOD(Weapon, wr_think, bool(Weapon this, bool fire1, bool fire2)) {return false;}
+ /** (SERVER) checks ammo for weapon primary */
+ METHOD(Weapon, wr_checkammo1, bool(Weapon this)) {return false;}
+ /** (SERVER) checks ammo for weapon second */
+ METHOD(Weapon, wr_checkammo2, bool(Weapon this)) {return false;}
+ /** (SERVER) runs bot aiming code for this weapon */
+ METHOD(Weapon, wr_aim, bool(Weapon this)) {return false;}
+ /** (BOTH) precaches models/sounds used by this weapon, also sets up weapon properties */
+ METHOD(Weapon, wr_init, bool(Weapon this)) {return false;}
+ /** (SERVER) notification number for suicide message (may inspect w_deathtype for details) */
+ METHOD(Weapon, wr_suicidemessage, bool(Weapon this)) {return false;}
+ /** (SERVER) notification number for kill message (may inspect w_deathtype for details) */
+ METHOD(Weapon, wr_killmessage, bool(Weapon this)) {return false;}
+ /** (SERVER) handles reloading for weapon */
+ METHOD(Weapon, wr_reload, bool(Weapon this)) {return false;}
+ /** (SERVER) clears fields that the weapon may use */
+ METHOD(Weapon, wr_resetplayer, bool(Weapon this)) {return false;}
+ /** (CLIENT) impact effect for weapon explosion */
+ METHOD(Weapon, wr_impacteffect, bool(Weapon this)) {return false;}
+ /** (SERVER) called whenever a player dies */
+ METHOD(Weapon, wr_playerdeath, bool(Weapon this)) {return false;}
+ /** (SERVER) logic to run when weapon is lost */
+ METHOD(Weapon, wr_gonethink, bool(Weapon this)) {return false;}
+ /** (ALL) dump weapon cvars to config in data directory (see: sv_cmd dumpweapons) */
+ METHOD(Weapon, wr_config, bool(Weapon this)) {return false;}
+ /** (CLIENT) weapon specific zoom reticle */
+ METHOD(Weapon, wr_zoomreticle, bool(Weapon this)) {return false;}
+ /** (SERVER) the weapon is dropped */
+ METHOD(Weapon, wr_drop, bool(Weapon this)) {return false;}
+ /** (SERVER) a weapon is picked up */
+ METHOD(Weapon, wr_pickup, bool(Weapon this)) {return false;}
+
METHOD(Weapon, display, void(entity this, void(string name, string icon) returns)) {
returns(this.message, this.model2 ? sprintf("/gfx/hud/%s/%s", cvar_string("menu_skin"), this.model2) : string_null);
}
- CONSTRUCTOR(Weapon,
- bool(entity this, int req) function,
- .int ammotype,
- int i,
- int weapontype,
- float pickupbasevalue,
- vector clr,
- string modelname,
- entity m,
- string crosshair,
- string wepimg,
- string refname,
- string wepname
- ) {
- CONSTRUCT(Weapon);
- this.weapon_func = function;
- this.ammo_field = ammotype;
- this.impulse = i;
- this.spawnflags = weapontype;
- this.bot_pickupbasevalue = pickupbasevalue;
- this.wpcolor = clr;
- this.mdl = modelname;
- this.m_model = m;
- this.w_crosshair = strzone(car(crosshair));
- string s = cdr(crosshair);
- this.w_crosshair_size = ((s != "") ? stof(s) : 1); // so that we can scale the crosshair from code (for compat)
- this.model2 = strzone(wepimg);
- this.netname = refname;
- this.message = wepname;
- }
void register_weapon(entity this, int id, WepSet bit)
{
this.weapon = id;
this.weapons = bit;
this.wpmodel = strzone(strcat("wpn-", ftos(id)));
#ifdef CSQC
- this.weapon_func(this, WR_INIT);
+ this.wr_init(this);
#endif
}
ENDCLASS(Weapon)
const int WEP_FLAG_SUPERWEAPON = 0x100; // powerup timer
const int WEP_FLAG_MUTATORBLOCKED = 0x200; // hides from impulse 99 etc. (mutators are allowed to clear this flag)
-bool w_new(entity this, int req) {
- if (req == WR_SETUP) return this.wr_setup ? this.wr_setup(this) : false;
- if (req == WR_CHECKAMMO1) return this.wr_checkammo1 ? this.wr_checkammo1(this) : false;
- if (req == WR_CHECKAMMO2) return this.wr_checkammo2 ? this.wr_checkammo2(this) : false;
- if (req == WR_AIM) return this.wr_aim ? this.wr_aim(this) : false;
- if (req == WR_INIT) return this.wr_init ? this.wr_init(this) : false;
- if (req == WR_SUICIDEMESSAGE) return this.wr_suicidemessage ? this.wr_suicidemessage(this) : false;
- if (req == WR_KILLMESSAGE) return this.wr_killmessage ? this.wr_killmessage(this) : false;
- if (req == WR_RELOAD) return this.wr_reload ? this.wr_reload(this) : false;
- if (req == WR_RESETPLAYER) return this.wr_resetplayer ? this.wr_resetplayer(this) : false;
- if (req == WR_IMPACTEFFECT) return this.wr_impacteffect ? this.wr_impacteffect(this) : false;
- if (req == WR_PLAYERDEATH) return this.wr_playerdeath ? this.wr_playerdeath(this) : false;
- if (req == WR_GONETHINK) return this.wr_gonethink ? this.wr_gonethink(this) : false;
- if (req == WR_CONFIG) return this.wr_config ? this.wr_config(this) : false;
- if (req == WR_ZOOMRETICLE) return this.wr_zoomreticle ? this.wr_zoomreticle(this) : false;
- if (req == WR_DROP) return this.wr_drop ? this.wr_drop(this) : false;
- if (req == WR_PICKUP) return this.wr_pickup ? this.wr_pickup(this) : false;
- return false;
-}
-
// variables:
string weaponorder_byid;
// other useful macros
-#define WEP_ACTION(wpn,wrequest) wpn.weapon_func(wpn, wrequest)
-#define _WEP_ACTION(wpn,wrequest) WEP_ACTION(get_weaponinfo(wpn), wrequest)
#define WEP_AMMO(wpn) (WEP_##wpn.ammo_field) // only used inside weapon files/with direct name, don't duplicate prefix
#define WEP_NAME(wpn) ((get_weaponinfo(wpn)).message)
if(self == self.owner.arc_beam) { self.owner.arc_beam = world; }
setself(self.owner);
- if(!WEP_ACTION(WEP_ARC, WR_CHECKAMMO1) && !WEP_ACTION(WEP_ARC, WR_CHECKAMMO2))
+ Weapon w = WEP_ARC;
+ if(!w.wr_checkammo1(w) && !w.wr_checkammo2(w))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
// note: this doesn't force the switch
METHOD(Crylink, wr_think, bool(entity thiswep, bool fire1, bool fire2))
{
SELFPARAM();
- if(autocvar_g_balance_crylink_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo))) // forced reload
- _WEP_ACTION(self.weapon, WR_RELOAD);
+ if(autocvar_g_balance_crylink_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo))) { // forced reload
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ }
if(fire1)
{
#endif
METHOD(Devastator, wr_think, bool(entity thiswep, bool fire1, bool fire2))
{
- if(WEP_CVAR(devastator, reload_ammo) && self.clip_load < WEP_CVAR(devastator, ammo)) // forced reload
- _WEP_ACTION(self.weapon, WR_RELOAD);
- else
+ if(WEP_CVAR(devastator, reload_ammo) && self.clip_load < WEP_CVAR(devastator, ammo)) { // forced reload
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ } else
{
if(fire1)
{
if(!ammo_amount)
{
- _WEP_ACTION(self.weapon, WR_RELOAD);
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
return false;
}
self.hagar_warning = false;
// we aren't checking ammo during an attack, so we must do it here
- if(!(_WEP_ACTION(self.weapon, WR_CHECKAMMO1) + _WEP_ACTION(self.weapon, WR_CHECKAMMO2)))
+ Weapon w = get_weaponinfo(self.weapon);
+ if(!(w.wr_checkammo1(w) + w.wr_checkammo2(w)))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
// note: this doesn't force the switch
if(loadable_secondary)
W_Hagar_Attack2_Load(thiswep); // must always run each frame
- if(autocvar_g_balance_hagar_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo))) // forced reload
- _WEP_ACTION(self.weapon, WR_RELOAD);
- else if(fire1 && !self.hagar_load && !self.hagar_loadblock) // not while secondary is loaded or awaiting reset
+ if(autocvar_g_balance_hagar_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo))) { // forced reload
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ } else if(fire1 && !self.hagar_load && !self.hagar_loadblock) // not while secondary is loaded or awaiting reset
{
if(weapon_prepareattack(false, WEP_CVAR_PRI(hagar, refire)))
{
if(self.BUTTON_ATCK)
{
- if(!_WEP_ACTION(self.weapon, WR_CHECKAMMO1))
+ Weapon w = get_weaponinfo(self.weapon);
+ if(!w.wr_checkammo1(w))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
}
METHOD(HLAC, wr_think, bool(entity thiswep, bool fire1, bool fire2))
{
- if(autocvar_g_balance_hlac_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo))) // forced reload
- _WEP_ACTION(self.weapon, WR_RELOAD);
- else if(fire1)
+ if(autocvar_g_balance_hlac_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo))) { // forced reload
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ } else if(fire1)
{
if(weapon_prepareattack(false, WEP_CVAR_PRI(hlac, refire)))
{
return;
}
- if(!_WEP_ACTION(self.weapon, WR_CHECKAMMO1))
+ Weapon w = get_weaponinfo(self.weapon);
+ if(!w.wr_checkammo1(w))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
}
METHOD(HeavyMachineGun, wr_think, bool(entity thiswep, bool fire1, bool fire2))
{
- if(WEP_CVAR(hmg, reload_ammo) && self.clip_load < WEP_CVAR(hmg, ammo)) // forced reload
- _WEP_ACTION(self.weapon, WR_RELOAD);
- else
+ if(WEP_CVAR(hmg, reload_ammo) && self.clip_load < WEP_CVAR(hmg, ammo)) { // forced reload
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ } else
{
if (fire1)
if (weapon_prepareattack(false, 0))
}
if(self.BUTTON_ATCK)
{
- if(!_WEP_ACTION(self.weapon, WR_CHECKAMMO2))
+ Weapon w = get_weaponinfo(self.weapon);
+ if(!w.wr_checkammo2(w))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
return;
}
- if(!_WEP_ACTION(self.weapon, WR_CHECKAMMO1))
+ Weapon w = get_weaponinfo(self.weapon);
+ if(!w.wr_checkammo1(w))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
}
METHOD(MachineGun, wr_think, bool(entity thiswep, bool fire1, bool fire2))
{
- if(WEP_CVAR(machinegun, reload_ammo) && self.clip_load < min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo))) // forced reload
- _WEP_ACTION(self.weapon, WR_RELOAD);
- else
+ if(WEP_CVAR(machinegun, reload_ammo) && self.clip_load < min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo))) { // forced reload
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ } else
if(WEP_CVAR(machinegun, mode) == 1)
{
if(fire1)
if(fire2)
if(weapon_prepareattack(true, 0))
{
- if(!_WEP_ACTION(self.weapon, WR_CHECKAMMO2))
+ Weapon w = get_weaponinfo(self.weapon);
+ if(!w.wr_checkammo2(w))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
if(self.realowner.weapon == WEP_MINE_LAYER.m_id)
{
setself(self.realowner);
- if(!WEP_ACTION(WEP_MINE_LAYER, WR_CHECKAMMO1))
+ Weapon w = WEP_MINE_LAYER;
+ if(!w.wr_checkammo1(w))
{
self.cnt = WEP_MINE_LAYER.m_id;
ATTACK_FINISHED(self) = time;
if(self.realowner.weapon == WEP_MINE_LAYER.m_id)
{
setself(self.realowner);
- if(!WEP_ACTION(WEP_MINE_LAYER, WR_CHECKAMMO1))
+ Weapon w = WEP_MINE_LAYER;
+ if(!w.wr_checkammo1(w))
{
self.cnt = WEP_MINE_LAYER.m_id;
ATTACK_FINISHED(self) = time;
if(autocvar_g_balance_minelayer_reload_ammo && self.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) && self.WEP_AMMO(MINE_LAYER) < WEP_CVAR(minelayer, ammo)))
- _WEP_ACTION(self.weapon, WR_RELOAD);
+ if(!(W_MineLayer_PlacedMines(false) && self.WEP_AMMO(MINE_LAYER) < WEP_CVAR(minelayer, ammo))) {
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ }
}
else if(fire1)
{
*/
METHOD(Mortar, wr_think, bool(entity thiswep, bool fire1, bool fire2))
{
- if(autocvar_g_balance_mortar_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo))) // forced reload
- _WEP_ACTION(self.weapon, WR_RELOAD);
- else if(fire1)
+ if(autocvar_g_balance_mortar_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo))) { // forced reload
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ } else if(fire1)
{
if(weapon_prepareattack(false, WEP_CVAR_PRI(mortar, refire)))
{
}
METHOD(Rifle, wr_think, bool(entity thiswep, bool fire1, bool fire2))
{
- if(autocvar_g_balance_rifle_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo))) // forced reload
- _WEP_ACTION(self.weapon, WR_RELOAD);
- else
+ if(autocvar_g_balance_rifle_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo))) { // forced reload
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ } else
{
self.rifle_accumulator = bound(time - WEP_CVAR(rifle, bursttime), self.rifle_accumulator, time);
if(fire1)
{
if(WEP_CVAR(rifle, secondary))
{
- if(WEP_CVAR_SEC(rifle, reload))
- _WEP_ACTION(self.weapon, WR_RELOAD);
- else
+ if(WEP_CVAR_SEC(rifle, reload)) {
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ } else
{
if(weapon_prepareattack_check(true, WEP_CVAR_SEC(rifle, refire)))
if(time >= self.rifle_accumulator + WEP_CVAR_SEC(rifle, burstcost))
}
METHOD(RocketPropelledChainsaw, wr_think, bool(entity thiswep, bool fire1, bool fire2))
{
- if(WEP_CVAR(rpc, reload_ammo) && self.clip_load < WEP_CVAR(rpc, ammo))
- _WEP_ACTION(self.weapon, WR_RELOAD);
- else
+ if(WEP_CVAR(rpc, reload_ammo) && self.clip_load < WEP_CVAR(rpc, ammo)) {
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ } else
{
if (fire1)
{
}
METHOD(Seeker, wr_think, bool(entity thiswep, bool fire1, bool fire2))
{
- if(autocvar_g_balance_seeker_reload_ammo && self.clip_load < min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo))) // forced reload
- _WEP_ACTION(self.weapon, WR_RELOAD);
-
- else if(fire1)
+ if(autocvar_g_balance_seeker_reload_ammo && self.clip_load < min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo))) { // forced reload
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ } else if(fire1)
{
if(WEP_CVAR(seeker, type) == 1)
{
// alternate secondary weapon frames
void W_Shotgun_Attack3_Frame2(Weapon thiswep, bool fire1, bool fire2)
{SELFPARAM();
- if (!_WEP_ACTION(self.weapon, WR_CHECKAMMO2))
+ Weapon w = get_weaponinfo(self.weapon);
+ if (!w.wr_checkammo2(w))
if (!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
}
void W_Shotgun_Attack3_Frame1(Weapon thiswep, bool fire1, bool fire2)
{SELFPARAM();
- if (!_WEP_ACTION(self.weapon, WR_CHECKAMMO2))
+ Weapon w = get_weaponinfo(self.weapon);
+ if (!w.wr_checkammo2(w))
if (!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
if(WEP_CVAR(shotgun, reload_ammo) && self.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)
- _WEP_ACTION(self.weapon, WR_RELOAD);
+ if(WEP_CVAR(shotgun, secondary) < 2) {
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ }
}
else
{
{
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) && self.clip_load < min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo))) // forced reload
- _WEP_ACTION(self.weapon, WR_RELOAD);
- else if(WEP_CVAR(vaporizer, reload_ammo) && self.clip_load < vaporizer_ammo) // forced reload
- _WEP_ACTION(self.weapon, WR_RELOAD);
+ if(WEP_CVAR(vaporizer, reload_ammo) && WEP_CVAR_SEC(vaporizer, ammo) && self.clip_load < min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo))) { // forced reload
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ } else if(WEP_CVAR(vaporizer, reload_ammo) && self.clip_load < vaporizer_ammo) { // forced reload
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ }
if(fire1 && (self.ammo_cells || !autocvar_g_rm) && !forbidWeaponUse(self))
{
if(weapon_prepareattack(false, WEP_CVAR_PRI(vaporizer, refire)))
self.pauseregen_finished = max(self.pauseregen_finished, time + WEP_CVAR_SEC(vortex, chargepool_pause_regen));
}
- if(autocvar_g_balance_vortex_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo))) // forced reload
- _WEP_ACTION(self.weapon, WR_RELOAD);
- else
+ if(autocvar_g_balance_vortex_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo))) { // forced reload
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ } else
{
if(fire1)
{
if(self.weapons)
{
- _WEP_ACTION(self.weapon, WR_AIM);
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_aim(w);
if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(self))
{
self.BUTTON_ATCK = false;
float i, other_weapon_available = false;
for(i = WEP_FIRST; i <= WEP_LAST; ++i)
{
+ Weapon w = get_weaponinfo(i);
// if we are out of ammo for all other weapons, it's an emergency to switch to anything else
- if (_WEP_ACTION(i, WR_CHECKAMMO1) + _WEP_ACTION(i, WR_CHECKAMMO2))
+ if (w.wr_checkammo1(w) + w.wr_checkammo2(w))
other_weapon_available = true;
}
if(other_weapon_available)
// reset fields the weapons may use
for (int j = WEP_FIRST; j <= WEP_LAST; ++j)
{
- _WEP_ACTION(j, WR_RESETPLAYER);
+ Weapon w = get_weaponinfo(j);
+ w.wr_resetplayer(w);
// all weapons must be fully loaded when we spawn
entity e = get_weaponinfo(j);
W_PreviousWeapon(1);
break;
case 20:
- if(!forbidWeaponUse(self)) { _WEP_ACTION(self.weapon, WR_RELOAD); }
+ if(!forbidWeaponUse(self)) {
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ }
break;
}
}
MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, self, deathtype);
excess = frag_damage;
- _WEP_ACTION(self.weapon, WR_PLAYERDEATH);
+ Weapon wep = get_weaponinfo(self.weapon);
+ wep.wr_playerdeath(wep);
RemoveGrapplingHook(self);
// reset fields the weapons may use just in case
for (j = WEP_FIRST; j <= WEP_LAST; ++j)
{
- _WEP_ACTION(j, WR_RESETPLAYER);
+ Weapon w = get_weaponinfo(j);
+ w.wr_resetplayer(w);
ATTACK_FINISHED_FOR(self, j) = 0;
}
}
// WEAPONTODO
.float autoswitch;
-//float _WEP_ACTION(float wpn, float wrequest);
float client_hasweapon(entity cl, float wpn, float andammo, float complain);
void w_clear(Weapon thiswep, bool fire1, bool fire2);
void w_ready(Weapon thiswep, bool fire1, bool fire2);
if(death_weapon)
{
w_deathtype = deathtype;
- int death_message = _WEP_ACTION(death_weapon, ((murder) ? WR_KILLMESSAGE : WR_SUICIDEMESSAGE));
+ Weapon w = get_weaponinfo(death_weapon);
+ int death_message = ((murder) ? w.wr_killmessage : w.wr_suicidemessage)(w);
w_deathtype = false;
if (death_message)
}
else
{
- WEP_ACTION(WEP_HOOK, WR_INIT);
+ Weapon w = WEP_HOOK;
+ w.wr_init(w);
hook_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK.m_id), false, false, 1);
hook_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK.m_id), false, false, 2);
hook_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK.m_id), false, false, 3);
for (i = WEP_FIRST; i <= WEP_LAST; ++i)
{
e = get_weaponinfo(i);
- if(precache_weapons & WepSet_FromWeapon(i))
- _WEP_ACTION(i, WR_INIT);
+ if(precache_weapons & WepSet_FromWeapon(i)) {
+ Weapon w = get_weaponinfo(i);
+ w.wr_init(w);
+ }
}
start_ammo_shells = max(0, start_ammo_shells);
if (!warmup_stage)
game_starttime = time + cvar("g_start_delay");
- for(int i = WEP_FIRST; i <= WEP_LAST; ++i)
- _WEP_ACTION(i, WR_INIT);
+ for(int i = WEP_FIRST; i <= WEP_LAST; ++i) {
+ Weapon w = get_weaponinfo(i);
+ w.wr_init(w);
+ }
readplayerstartcvars();
}
plyr.weaponentity.switchweapon = plyr.weapon;
plyr.weapons = WEPSET_NEXBALL;
setself(plyr);
- WEP_ACTION(WEP_NEXBALL, WR_RESETPLAYER);
+ Weapon w = WEP_NEXBALL;
+ w.wr_resetplayer(w);
plyr.switchweapon = WEP_NEXBALL.m_id;
W_SwitchWeapon(WEP_NEXBALL.m_id);
setself(this);
if(self.weaponentity.weapons)
{
self.weapons = self.weaponentity.weapons;
- WEP_ACTION(WEP_NEXBALL, WR_RESETPLAYER);
+ Weapon w = WEP_NEXBALL;
+ w.wr_resetplayer(w);
self.switchweapon = self.weaponentity.switchweapon;
W_SwitchWeapon(self.switchweapon);
nix_nextchange = time; // start the first round now!
else
nix_nextchange = time + autocvar_g_balance_nix_roundtime;
- //_WEP_ACTION(nix_weapon, WR_INIT); // forget it, too slow
+ // Weapon w = get_weaponinfo(nix_weapon);
+ // w.wr_init(w); // forget it, too slow
}
// get weapon info
else
Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_NIX_NEWWEAPON, nix_weapon);
- _WEP_ACTION(nix_weapon, WR_RESETPLAYER);
+ Weapon w = get_weaponinfo(nix_weapon);
+ w.wr_resetplayer(w);
// all weapons must be fully loaded when we spawn
if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
{
float i;
for (i = WEP_FIRST; i <= WEP_LAST; ++i)
- if (NIX_CanChooseWeapon(i))
- _WEP_ACTION(i, WR_INIT);
+ if (NIX_CanChooseWeapon(i)) {
+ Weapon w = get_weaponinfo(i);
+ w.wr_init(w);
+ }
}
MUTATOR_HOOKFUNCTION(nix_ForbidThrowCurrentWeapon)
for(i = WEP_FIRST; i <= WEP_LAST; ++i)
if(it & WepSet_FromWeapon(i))
{
- W_DropEvent(WR_PICKUP, player, i, item);
+ W_DropEvent(wr_pickup, player, i, item);
W_GiveWeapon(player, i);
}
}
if(s == e.netname)
{
self.weapons |= WepSet_FromWeapon(j);
- if(self.spawnflags == 0 || self.spawnflags == 2)
- _WEP_ACTION(e.weapon, WR_INIT);
+ if(self.spawnflags == 0 || self.spawnflags == 2) {
+ Weapon w = get_weaponinfo(e.weapon);
+ w.wr_init(w);
+ }
break;
}
}
e = get_weaponinfo(j);
if(argv(i) == e.netname)
{
- _WEP_ACTION(e.weapon, WR_INIT);
+ Weapon w = get_weaponinfo(e.weapon);
+ w.wr_init(w);
break;
}
}
{
POSTGIVE_WEAPON(e, j, SND(WEAPONPICKUP), string_null);
if (!(save_weapons & WepSet_FromWeapon(j)))
- if(e.weapons & WepSet_FromWeapon(j))
- _WEP_ACTION(wi.weapon, WR_INIT);
+ if(e.weapons & WepSet_FromWeapon(j)) {
+ Weapon w = get_weaponinfo(wi.weapon);
+ w.wr_init(w);
+ }
}
}
POSTGIVE_VALUE(e, strength_finished, 1, SND(POWERUP), SND(POWEROFF));
else
{
setself(cl);
- f = _WEP_ACTION(wpn, WR_CHECKAMMO1);
- f = f + _WEP_ACTION(wpn, WR_CHECKAMMO2);
+ Weapon w = get_weaponinfo(wpn);
+ f = w.wr_checkammo1(w) + w.wr_checkammo2(w);
// always allow selecting the Mine Layer if we placed mines, so that we can detonate them
entity mine;
else
self.selectweapon = imp; // update selectweapon ANYWAY
}
- else if(!forbidWeaponUse(self)) { _WEP_ACTION(self.weapon, WR_RELOAD); }
+ else if(!forbidWeaponUse(self)) {
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_reload(w);
+ }
}
void W_CycleWeapon(string weaponorder, float dir)
StartItem(strzone(e.m_model.model_str()), string_null, self.respawntime, self.respawntimejitter, e.message, 0, e.weapon, f, weapon_pickupevalfunc, e.bot_pickupbasevalue);
self.item_pickupsound_ent = SND_WEAPONPICKUP;
#if 0 // WEAPONTODO
- if (self.modelindex) // don't precache if self was removed
- _WEP_ACTION(e.weapon, WR_INIT);
+ if (self.modelindex) { // don't precache if self was removed
+ Weapon w = get_weaponinfo(e.weapon);
+ w.wr_init(w);
+ }
#endif
}
wep.flags |= FL_TOSSED;
wep.colormap = own.colormap;
- W_DropEvent(WR_DROP,own,wpn,wep);
+ W_DropEvent(wr_drop,own,wpn,wep);
if(WepSet_FromWeapon(wpn) & WEPSET_SUPERWEAPONS)
{
.float prevwarntime;
float weapon_prepareattack_checkammo(float secondary)
{SELFPARAM();
+ Weapon w = get_weaponinfo(self.weapon);
if (!(self.items & IT_UNLIMITED_WEAPON_AMMO))
- if (!_WEP_ACTION(self.weapon, WR_CHECKAMMO1 + secondary))
+ if (!w.(secondary ? wr_checkammo2 : wr_checkammo1)(w))
{
// always keep the Mine Layer if we placed mines, so that we can detonate them
entity mine;
self.prevdryfire = time;
}
- if(_WEP_ACTION(self.weapon, WR_CHECKAMMO2 - secondary)) // check if the other firing mode has enough ammo
+ if(w.(secondary ? wr_checkammo1 : wr_checkammo2)(w)) // check if the other firing mode has enough ammo
{
if(time - self.prevwarntime > 1)
{
self.weaponname = newwep.mdl;
self.bulletcounter = 0;
self.ammo_field = newwep.ammo_field;
- _WEP_ACTION(self.switchweapon, WR_SETUP);
+ Weapon w = get_weaponinfo(self.switchweapon);
+ w.wr_setup(w);
self.weaponentity.state = WS_RAISE;
// set our clip load to the load of the weapon we switched to, if it's reloadable
entity e = get_weaponinfo(self.weapon);
if (e.wr_think) e.wr_think(e, self.BUTTON_ATCK, self.BUTTON_ATCK2);
} else {
- _WEP_ACTION(self.weapon, WR_GONETHINK);
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_gonethink(w);
}
if (time + self.weapon_frametime * 0.5 >= self.weapon_nextthink)
self.reload_complain = time + 1;
}
// switch away if the amount of ammo is not enough to keep using this weapon
- if (!(_WEP_ACTION(self.weapon, WR_CHECKAMMO1) + _WEP_ACTION(self.weapon, WR_CHECKAMMO2)))
+ Weapon w = get_weaponinfo(self.weapon);
+ if (!(w.wr_checkammo1(w) + w.wr_checkammo2(w)))
{
self.clip_load = -1; // reload later
W_SwitchToOtherWeapon(self);
self.clip_load = self.(weapon_load[self.weapon]) = -1;
}
-void W_DropEvent(float event, entity player, float weapon_type, entity weapon_item)
+void W_DropEvent(.bool(Weapon) event, entity player, float weapon_type, entity weapon_item)
{SELFPARAM();
setself(player);
weapon_dropevent_item = weapon_item;
- _WEP_ACTION(weapon_type, event);
+ Weapon w = get_weaponinfo(weapon_type);
+ w.event(w);
setself(this);
}
void W_DecreaseAmmo(Weapon wep, float ammo_use);
-void W_DropEvent(float event, entity player, float weapon_type, entity weapon_item);
+void W_DropEvent(.bool(Weapon) event, entity player, float weapon_type, entity weapon_item);
void W_Reload(float sent_ammo_min, string sent_sound);