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)) { _WEP_ACTION(hitwep, WR_IMPACTEFFECT); }
}
}
// no zoom reticle while dead
reticle_type = 0;
}
- else if(WEP_ACTION(activeweapon, WR_ZOOMRETICLE) && autocvar_cl_reticle_weapon)
+ else if(_WEP_ACTION(activeweapon, WR_ZOOMRETICLE) && autocvar_cl_reticle_weapon)
{
if(reticle_image != "") { reticle_type = 2; }
else { reticle_type = 0; }
// weapon requests
const int WR_SETUP = 1; // (SERVER) setup weapon data
+.bool(entity this) wr_setup;
const int WR_THINK = 2; // (SERVER) logic to run every frame
+.bool(entity this) wr_think;
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;
+
+bool w_new(entity this, int req) {
+ if (req == WR_SETUP) return this.wr_setup ? this.wr_setup(this) : false;
+ if (req == WR_THINK) return this.wr_think ? this.wr_think(this) : false;
+ if (req == WR_CHECKAMMO1) return this.wr_checkammo1 ? this.wr_checkammo1(this) : false;
+ if (req == WR_CHECKAMMO2) return this.wr_checkammo2 ? this.wr_checkammo2(this) : false;
+ if (req == WR_AIM) return this.wr_aim ? this.wr_aim(this) : false;
+ 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;
.int ammo_none;
// other useful macros
-#define WEP_ACTION(wpn,wrequest) (get_weaponinfo(wpn)).weapon_func(wrequest)
+#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)
// Weapon Registration
// =====================
-bool w_null(int) { return false; }
-
/** 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)
/** A: WEPSET_id : WEPSET_... */
ATTRIB(Weapon, weapons, WepSet, '0 0 0');
/** M: function : w_... */
- ATTRIB(Weapon, weapon_func, bool(int), w_null);
+ ATTRIB(Weapon, weapon_func, bool(entity thiswep, int req), w_new);
/** M: ammotype : main ammo field */
ATTRIB(Weapon, ammo_field, .int, ammo_none);
/** M: impulse : weapon impulse */
}
CONSTRUCTOR(Weapon,
- bool(int) function,
+ bool(entity this, int req) function,
.int ammotype,
int i,
int weapontype,
this.weapons = bit;
this.wpmodel = strzone(strcat("wpn-", ftos(id)));
#ifdef CSQC
- this.weapon_func(WR_INIT);
+ this.weapon_func(this, WR_INIT);
#endif
}
ENDCLASS(Weapon)
entity weapon_info[WEP_MAXCOUNT], weapon_info_first, weapon_info_last;
entity dummy_weapon_info;
-#define _REGISTER_WEAPON(id, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname) \
+#define REGISTER_WEAPON(...) EVAL(OVERLOAD(REGISTER_WEAPON, __VA_ARGS__))
+
+#define REGISTER_WEAPON_2(id, inst) \
WepSet WEPSET_##id; \
- REGISTER(RegisterWeapons, WEP, weapon_info, WEP_COUNT, id, m_id, \
- NEW(Weapon, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname) \
- ) { \
+ REGISTER(RegisterWeapons, WEP, weapon_info, WEP_COUNT, id, m_id, inst) { \
this.m_id++; \
WEPSET_ALL |= (WEPSET_##id = WepSet_FromWeapon(this.m_id)); \
- if ((flags) & WEP_FLAG_SUPERWEAPON) WEPSET_SUPERWEAPONS |= WEPSET_##id; \
+ if ((this.spawnflags) & WEP_FLAG_SUPERWEAPON) WEPSET_SUPERWEAPONS |= WEPSET_##id; \
register_weapon(this, this.m_id, WEPSET_##id); \
}
+#define _REGISTER_WEAPON(id, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname) \
+ REGISTER_WEAPON_2(id, NEW(Weapon, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname))
+
#ifndef MENUQC
- #define REGISTER_WEAPON(id, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname) \
- bool function(int); \
+ #define REGISTER_WEAPON_13(id, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname) \
+ bool function(entity this, int); \
_REGISTER_WEAPON(id, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname)
#else
- #define REGISTER_WEAPON(id, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname) \
- _REGISTER_WEAPON(id, w_null, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname)
+ #define REGISTER_WEAPON_13(id, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname) \
+ _REGISTER_WEAPON(id, w_new, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname)
#endif
#include "all.inc"
{ wep_config_queue[x] = string_null; }
// step 2: build new queue
- WEP_ACTION(i, WR_CONFIG);
+ _WEP_ACTION(i, WR_CONFIG);
// step 3: sort queue
heapsort(WEP_CONFIG_COUNT, W_Config_Queue_Swap, W_Config_Queue_Compare, world);
if(self == self.owner.arc_beam) { self.owner.arc_beam = world; }
setself(self.owner);
- if(!WEP_ACTION(WEP_ARC.m_id, WR_CHECKAMMO1) && !WEP_ACTION(WEP_ARC.m_id, WR_CHECKAMMO2))
+ if(!WEP_ACTION(WEP_ARC, WR_CHECKAMMO1) && !WEP_ACTION(WEP_ARC, WR_CHECKAMMO2))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
// note: this doesn't force the switch
}
}
-bool W_Arc(int req)
+bool W_Arc(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
}
}
-bool W_Arc(int req)
+bool W_Arc(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
WITH(entity, self, missile, missile.think());
}
}
-bool W_Blaster(int request)
+bool W_Blaster(entity thiswep, int request)
{SELFPARAM();
switch(request)
{
}
#endif
#ifdef CSQC
-bool W_Blaster(int request)
+bool W_Blaster(entity thiswep, int request)
{SELFPARAM();
switch(request)
{
}
}
-bool W_Crylink(int req)
+bool W_Crylink(entity thiswep, int req)
{SELFPARAM();
float ammo_amount;
switch(req)
case WR_THINK:
{
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);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
if(self.BUTTON_ATCK)
{
setorigin(linkjoineffect, pos);
}
self.crylink_waitrelease = 0;
- if(!W_Crylink(WR_CHECKAMMO1) && !W_Crylink(WR_CHECKAMMO2))
+ if(!W_Crylink(WEP_CRYLINK, WR_CHECKAMMO1) && !W_Crylink(WEP_CRYLINK, WR_CHECKAMMO2))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
// ran out of ammo!
}
#endif
#ifdef CSQC
-bool W_Crylink(int req)
+bool W_Crylink(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
MUTATOR_CALLHOOK(EditProjectile, self, missile);
}
-bool W_Devastator(int req)
+bool W_Devastator(entity thiswep, int req)
{SELFPARAM();
entity rock;
float rockfound;
case WR_THINK:
{
if(WEP_CVAR(devastator, reload_ammo) && self.clip_load < WEP_CVAR(devastator, ammo)) // forced reload
- WEP_ACTION(self.weapon, WR_RELOAD);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
else
{
if(self.BUTTON_ATCK)
}
#endif
#ifdef CSQC
-bool W_Devastator(int req)
+bool W_Devastator(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
}
.float bot_secondary_electromooth;
-bool W_Electro(int req)
+bool W_Electro(entity thiswep, int req)
{SELFPARAM();
float ammo_amount;
switch(req)
if(!ammo_amount)
{
- WEP_ACTION(self.weapon, WR_RELOAD);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
return false;
}
}
#endif
#ifdef CSQC
-bool W_Electro(int req)
+bool W_Electro(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
MUTATOR_CALLHOOK(EditProjectile, self, proj);
}
-bool W_Fireball(int req)
+bool W_Fireball(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
}
#endif
#ifdef CSQC
-bool W_Fireball(int req)
+bool W_Fireball(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
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)))
+ if(!(_WEP_ACTION(self.weapon, WR_CHECKAMMO1) + _WEP_ACTION(self.weapon, WR_CHECKAMMO2)))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
// note: this doesn't force the switch
}
}
-bool W_Hagar(int req)
+bool W_Hagar(entity thiswep, int req)
{SELFPARAM();
float ammo_amount;
switch(req)
if(loadable_secondary)
W_Hagar_Attack2_Load(); // must always run each frame
if(autocvar_g_balance_hagar_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo))) // forced reload
- WEP_ACTION(self.weapon, WR_RELOAD);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
else if(self.BUTTON_ATCK && !self.hagar_load && !self.hagar_loadblock) // not while secondary is loaded or awaiting reset
{
if(weapon_prepareattack(0, WEP_CVAR_PRI(hagar, refire)))
}
#endif
#ifdef CSQC
-bool W_Hagar(int req)
+bool W_Hagar(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
if(self.BUTTON_ATCK)
{
- if(!WEP_ACTION(self.weapon, WR_CHECKAMMO1))
+ if(!_WEP_ACTION(self.weapon, WR_CHECKAMMO1))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
}
}
-bool W_HLAC(int req)
+bool W_HLAC(entity thiswep, int req)
{SELFPARAM();
float ammo_amount;
switch(req)
case WR_THINK:
{
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);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
else if(self.BUTTON_ATCK)
{
if(weapon_prepareattack(0, WEP_CVAR_PRI(hlac, refire)))
}
#endif
#ifdef CSQC
-bool W_HLAC(int req)
+bool W_HLAC(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
return;
}
- if(!WEP_ACTION(self.weapon, WR_CHECKAMMO1))
+ if(!_WEP_ACTION(self.weapon, WR_CHECKAMMO1))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(hmg, refire), W_HeavyMachineGun_Attack_Auto);
}
-bool W_HeavyMachineGun(int req)
+bool W_HeavyMachineGun(entity thiswep, int req)
{SELFPARAM();
float ammo_amount;
switch(req)
case WR_THINK:
{
if(WEP_CVAR(hmg, reload_ammo) && self.clip_load < WEP_CVAR(hmg, ammo)) // forced reload
- WEP_ACTION(self.weapon, WR_RELOAD);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
else
{
if (self.BUTTON_ATCK)
}
#endif
#ifdef CSQC
-bool W_HeavyMachineGun(int req)
+bool W_HeavyMachineGun(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
MUTATOR_CALLHOOK(EditProjectile, self, gren);
}
-bool W_Hook(int req)
+bool W_Hook(entity thiswep, int req)
{SELFPARAM();
float hooked_time_max, hooked_fuel;
}
#endif
#ifdef CSQC
-bool W_Hook(int req)
+bool W_Hook(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
}
if(self.BUTTON_ATCK)
{
- if(!WEP_ACTION(self.weapon, WR_CHECKAMMO2))
+ if(!_WEP_ACTION(self.weapon, WR_CHECKAMMO2))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
return;
}
- if(!WEP_ACTION(self.weapon, WR_CHECKAMMO1))
+ if(!_WEP_ACTION(self.weapon, WR_CHECKAMMO1))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
}
-bool W_MachineGun(int req)
+bool W_MachineGun(entity thiswep, int req)
{SELFPARAM();
float ammo_amount;
switch(req)
case WR_THINK:
{
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);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
else if(WEP_CVAR(machinegun, mode) == 1)
{
if(self.BUTTON_ATCK)
if(self.BUTTON_ATCK2)
if(weapon_prepareattack(1, 0))
{
- if(!WEP_ACTION(self.weapon, WR_CHECKAMMO2))
+ if(!_WEP_ACTION(self.weapon, WR_CHECKAMMO2))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
}
#endif
#ifdef CSQC
-bool W_MachineGun(int req)
+bool W_MachineGun(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
if(self.realowner.weapon == WEP_MINE_LAYER.m_id)
{
setself(self.realowner);
- if(!WEP_ACTION(WEP_MINE_LAYER.m_id, WR_CHECKAMMO1))
+ if(!WEP_ACTION(WEP_MINE_LAYER, WR_CHECKAMMO1))
{
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.m_id, WR_CHECKAMMO1))
+ if(!WEP_ACTION(WEP_MINE_LAYER, WR_CHECKAMMO1))
{
self.cnt = WEP_MINE_LAYER.m_id;
ATTACK_FINISHED(self) = time;
return minfound;
}
-bool W_MineLayer(int req)
+bool W_MineLayer(entity thiswep, int req)
{SELFPARAM();
entity mine;
float ammo_amount;
{
// 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);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
}
else if(self.BUTTON_ATCK)
{
}
#endif
#ifdef CSQC
-bool W_MineLayer(int req)
+bool W_MineLayer(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
}
.float bot_secondary_grenademooth;
-bool W_Mortar(int req)
+bool W_Mortar(entity thiswep, int req)
{SELFPARAM();
entity nade;
float nadefound;
case WR_THINK:
{
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);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
else if(self.BUTTON_ATCK)
{
if(weapon_prepareattack(0, WEP_CVAR_PRI(mortar, refire)))
}
#endif
#ifdef CSQC
-bool W_Mortar(int req)
+bool W_Mortar(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
}
bool w_nexball_weapon(int req); // WEAPONTODO
-bool W_Porto(int req)
+bool W_Porto(entity thiswep, int req)
{SELFPARAM();
//vector v_angle_save;
}
#endif
#ifdef CSQC
-bool W_Porto(int req)
+bool W_Porto(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
}
.float bot_secondary_riflemooth;
-bool W_Rifle(int req)
+bool W_Rifle(entity thiswep, int req)
{SELFPARAM();
float ammo_amount;
case WR_THINK:
{
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);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
else
{
self.rifle_accumulator = bound(time - WEP_CVAR(rifle, bursttime), self.rifle_accumulator, time);
if(WEP_CVAR(rifle, secondary))
{
if(WEP_CVAR_SEC(rifle, reload))
- WEP_ACTION(self.weapon, WR_RELOAD);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
else
{
if(weapon_prepareattack_check(1, WEP_CVAR_SEC(rifle, refire)))
}
#endif
#ifdef CSQC
-bool W_Rifle(int req)
+bool W_Rifle(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
MUTATOR_CALLHOOK(EditProjectile, self, missile);
}
-bool W_RocketPropelledChainsaw(int req)
+bool W_RocketPropelledChainsaw(entity thiswep, int req)
{SELFPARAM();
float ammo_amount = false;
switch(req)
case WR_THINK:
{
if(WEP_CVAR(rpc, reload_ammo) && self.clip_load < WEP_CVAR(rpc, ammo))
- WEP_ACTION(self.weapon, WR_RELOAD);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
else
{
if (self.BUTTON_ATCK)
#endif
#ifdef CSQC
-bool W_RocketPropelledChainsaw(int req)
+bool W_RocketPropelledChainsaw(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
// Begin: Genereal weapon functions
// ============================
-bool W_Seeker(int req)
+bool W_Seeker(entity thiswep, int req)
{SELFPARAM();
float ammo_amount;
case WR_THINK:
{
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);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
else if(self.BUTTON_ATCK)
{
}
#endif
#ifdef CSQC
-bool W_Seeker(int req)
+bool W_Seeker(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
}
}
-bool W_Shockwave(int req)
+bool W_Shockwave(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
shockwave.sw_time = time;
}
-bool W_Shockwave(int req)
+bool W_Shockwave(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
// alternate secondary weapon frames
void W_Shotgun_Attack3_Frame2()
{SELFPARAM();
- if (!WEP_ACTION(self.weapon, WR_CHECKAMMO2))
+ if (!_WEP_ACTION(self.weapon, WR_CHECKAMMO2))
if (!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
}
void W_Shotgun_Attack3_Frame1()
{SELFPARAM();
- if (!WEP_ACTION(self.weapon, WR_CHECKAMMO2))
+ if (!_WEP_ACTION(self.weapon, WR_CHECKAMMO2))
if (!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
W_SwitchWeapon_Force(self, w_getbestweapon(self));
.float shotgun_primarytime;
-float W_Shotgun(float req)
+float W_Shotgun(entity thiswep, float req)
{SELFPARAM();
float ammo_amount;
switch(req)
{
// 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);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
}
else
{
#endif
#ifdef CSQC
.float prevric;
-float W_Shotgun(float req)
+float W_Shotgun(entity thiswep, float req)
{SELFPARAM();
switch(req)
{
}
}
-bool W_Tuba(int req)
+bool W_Tuba(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
}
#endif
#ifdef CSQC
-bool W_Tuba(int req)
+bool W_Tuba(entity thiswep, int req)
{SELFPARAM();
// nothing to do here; particles of tuba are handled differently
// WEAPONTODO
}
}
-float W_Vaporizer(float req)
+float W_Vaporizer(entity thiswep, float req)
{SELFPARAM();
float ammo_amount;
float 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);
+ _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);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
if(self.BUTTON_ATCK && (self.ammo_cells || !autocvar_g_rm) && !forbidWeaponUse(self))
{
if(weapon_prepareattack(0, WEP_CVAR_PRI(vaporizer, refire)))
}
#endif
#ifdef CSQC
-float W_Vaporizer(float req)
+float W_Vaporizer(entity thiswep, float req)
{SELFPARAM();
switch(req)
{
void spawnfunc_weapon_vortex(void); // defined in t_items.qc
.float vortex_chargepool_pauseregen_finished;
-bool W_Vortex(int req)
+bool W_Vortex(entity thiswep, int req)
{SELFPARAM();
float dt;
float ammo_amount;
}
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);
+ _WEP_ACTION(self.weapon, WR_RELOAD);
else
{
if(self.BUTTON_ATCK)
#endif
#ifdef CSQC
float autocvar_g_balance_vortex_secondary = 0; // WEAPONTODO
-bool W_Vortex(int req)
+bool W_Vortex(entity thiswep, int req)
{SELFPARAM();
switch(req)
{
if(self.weapons)
{
- WEP_ACTION(self.weapon, WR_AIM);
+ _WEP_ACTION(self.weapon, WR_AIM);
if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(self))
{
self.BUTTON_ATCK = false;
for(i = WEP_FIRST; i <= WEP_LAST; ++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 (_WEP_ACTION(i, WR_CHECKAMMO1) + _WEP_ACTION(i, WR_CHECKAMMO2))
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);
+ _WEP_ACTION(j, WR_RESETPLAYER);
// 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)) { _WEP_ACTION(self.weapon, WR_RELOAD); }
break;
}
}
MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, self, deathtype);
excess = frag_damage;
- WEP_ACTION(self.weapon, WR_PLAYERDEATH);
+ _WEP_ACTION(self.weapon, WR_PLAYERDEATH);
RemoveGrapplingHook(self);
// reset fields the weapons may use just in case
for (j = WEP_FIRST; j <= WEP_LAST; ++j)
{
- WEP_ACTION(j, WR_RESETPLAYER);
+ _WEP_ACTION(j, WR_RESETPLAYER);
ATTACK_FINISHED_FOR(self, j) = 0;
}
}
// WEAPONTODO
.float autoswitch;
-//float WEP_ACTION(float wpn, float wrequest);
+//float _WEP_ACTION(float wpn, float wrequest);
float client_hasweapon(entity cl, float wpn, float andammo, float complain);
void w_clear();
void w_ready();
if(death_weapon)
{
w_deathtype = deathtype;
- int death_message = WEP_ACTION(death_weapon, ((murder) ? WR_KILLMESSAGE : WR_SUICIDEMESSAGE));
+ int death_message = _WEP_ACTION(death_weapon, ((murder) ? WR_KILLMESSAGE : WR_SUICIDEMESSAGE));
w_deathtype = false;
if (death_message)
}
else
{
- WEP_ACTION(WEP_HOOK.m_id, WR_INIT);
+ WEP_ACTION(WEP_HOOK, WR_INIT);
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);
{
e = get_weaponinfo(i);
if(precache_weapons & WepSet_FromWeapon(i))
- WEP_ACTION(i, WR_INIT);
+ _WEP_ACTION(i, WR_INIT);
}
start_ammo_shells = max(0, start_ammo_shells);
game_starttime = time + cvar("g_start_delay");
for(int i = WEP_FIRST; i <= WEP_LAST; ++i)
- WEP_ACTION(i, WR_INIT);
+ _WEP_ACTION(i, WR_INIT);
readplayerstartcvars();
}
plyr.weaponentity.switchweapon = plyr.weapon;
plyr.weapons = WEPSET_PORTO;
setself(plyr);
- WEP_ACTION(WEP_PORTO.m_id, WR_RESETPLAYER);
+ WEP_ACTION(WEP_PORTO, WR_RESETPLAYER);
plyr.switchweapon = WEP_PORTO.m_id;
W_SwitchWeapon(WEP_PORTO.m_id);
setself(this);
if(self.weaponentity.weapons)
{
self.weapons = self.weaponentity.weapons;
- WEP_ACTION(WEP_PORTO.m_id, WR_RESETPLAYER);
+ WEP_ACTION(WEP_PORTO, WR_RESETPLAYER);
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
+ //_WEP_ACTION(nix_weapon, WR_INIT); // 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);
+ _WEP_ACTION(nix_weapon, WR_RESETPLAYER);
// 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);
+ _WEP_ACTION(i, WR_INIT);
}
MUTATOR_HOOKFUNCTION(nix_ForbidThrowCurrentWeapon)
{
self.weapons |= WepSet_FromWeapon(j);
if(self.spawnflags == 0 || self.spawnflags == 2)
- WEP_ACTION(e.weapon, WR_INIT);
+ _WEP_ACTION(e.weapon, WR_INIT);
break;
}
}
e = get_weaponinfo(j);
if(argv(i) == e.netname)
{
- WEP_ACTION(e.weapon, WR_INIT);
+ _WEP_ACTION(e.weapon, WR_INIT);
break;
}
}
POSTGIVE_WEAPON(e, j, W_Sound("weaponpickup"), string_null);
if (!(save_weapons & WepSet_FromWeapon(j)))
if(e.weapons & WepSet_FromWeapon(j))
- WEP_ACTION(wi.weapon, WR_INIT);
+ _WEP_ACTION(wi.weapon, WR_INIT);
}
}
POSTGIVE_VALUE(e, strength_finished, 1, "misc/powerup.wav", "misc/poweroff.wav");
else
{
setself(cl);
- f = WEP_ACTION(wpn, WR_CHECKAMMO1);
- f = f + WEP_ACTION(wpn, WR_CHECKAMMO2);
+ f = _WEP_ACTION(wpn, WR_CHECKAMMO1);
+ f = f + _WEP_ACTION(wpn, WR_CHECKAMMO2);
// 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)) { _WEP_ACTION(self.weapon, WR_RELOAD); }
}
void W_CycleWeapon(string weaponorder, float dir)
StartItem(e.model, "weapons/weaponpickup.wav", self.respawntime, self.respawntimejitter, e.message, 0, e.weapon, f, weapon_pickupevalfunc, e.bot_pickupbasevalue);
#if 0 // WEAPONTODO
if (self.modelindex) // don't precache if self was removed
- WEP_ACTION(e.weapon, WR_INIT);
+ _WEP_ACTION(e.weapon, WR_INIT);
#endif
}
float weapon_prepareattack_checkammo(float secondary)
{SELFPARAM();
if (!(self.items & IT_UNLIMITED_WEAPON_AMMO))
- if (!WEP_ACTION(self.weapon, WR_CHECKAMMO1 + secondary))
+ if (!_WEP_ACTION(self.weapon, WR_CHECKAMMO1 + secondary))
{
// 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(_WEP_ACTION(self.weapon, WR_CHECKAMMO2 - secondary)) // 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);
+ _WEP_ACTION(self.switchweapon, WR_SETUP);
self.weaponentity.state = WS_RAISE;
// set our clip load to the load of the weapon we switched to, if it's reloadable
v_up = up;
if(w)
- WEP_ACTION(self.weapon, WR_THINK);
+ _WEP_ACTION(self.weapon, WR_THINK);
else
- WEP_ACTION(self.weapon, WR_GONETHINK);
+ _WEP_ACTION(self.weapon, WR_GONETHINK);
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)))
+ if (!(_WEP_ACTION(self.weapon, WR_CHECKAMMO1) + _WEP_ACTION(self.weapon, WR_CHECKAMMO2)))
{
self.clip_load = -1; // reload later
W_SwitchToOtherWeapon(self);
{SELFPARAM();
setself(player);
weapon_dropevent_item = weapon_item;
- WEP_ACTION(weapon_type, event);
+ _WEP_ACTION(weapon_type, event);
setself(this);
}