alias weapon_group_8 "impulse 8"
alias weapon_group_9 "impulse 9"
alias weapon_group_0 "impulse 14" // cycles the superweapons
-exec weapons.cfg
// score log
set sv_logscores_console 0 "print scores to server console"
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); }
}
}
{
case WEP_TUBA.m_id: // no aim
case WEP_PORTO.m_id: // shoots from eye
+ case WEP_NEXBALL.m_id: // shoots from eye
case WEP_HOOK.m_id: // no trueaim
case WEP_MORTAR.m_id: // toss curve
return SHOTTYPE_HITWORLD;
return true;
if(MUTATOR_CALLHOOK(WantEventchase, self))
return true;
- if(autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(WepSet_GetFromStat() & WepSet_FromWeapon(WEP_PORTO.m_id)))
+ if(autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(WepSet_GetFromStat() & WepSet_FromWeapon(WEP_NEXBALL.m_id)))
return true;
if(autocvar_cl_eventchase_death && (getstati(STAT_HEALTH) <= 0))
{
// 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; }
#endif
}
+#include "../../weapons/all.qh"
+
+CLASS(MageSpike, PortoLaunch)
+/* flags */ ATTRIB(MageSpike, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse */ ATTRIB(MageSpike, impulse, int, 9);
+/* refname */ ATTRIB(MageSpike, netname, string, "magespike");
+/* wepname */ ATTRIB(MageSpike, message, string, _("Mage spike"));
+ENDCLASS(MageSpike)
+REGISTER_WEAPON(MAGE_SPIKE, NEW(MageSpike));
+
#ifdef SVQC
+
+void M_Mage_Attack_Spike(vector dir);
+METHOD(MageSpike, wr_think, bool(entity thiswep)) {
+ SELFPARAM();
+ if (self.BUTTON_ATCK)
+ if (weapon_prepareattack(0, WEP_CVAR_PRI(electro, refire))) {
+ if (!self.target_range) self.target_range = autocvar_g_monsters_target_range;
+ self.enemy = Monster_FindTarget(self);
+ W_SetupShot_Dir(self, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0);
+ M_Mage_Attack_Spike(w_shotdir);
+ weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
+ }
+ return true;
+}
+
float autocvar_g_monster_mage_health;
float autocvar_g_monster_mage_damageforcescale = 0.5;
float autocvar_g_monster_mage_attack_spike_damage;
// copied from W_Seeker_Think
void M_Mage_Attack_Spike_Think()
{SELFPARAM();
- entity e;
- vector desireddir, olddir, newdir, eorg;
- float turnrate;
- float dist;
- float spd;
-
- if (time > self.ltime || self.enemy.health <= 0 || self.owner.health <= 0)
- {
+ if (time > self.ltime || (self.enemy && self.enemy.health <= 0) || self.owner.health <= 0) {
self.projectiledeathtype |= HITTYPE_SPLASH;
M_Mage_Attack_Spike_Explode();
}
- spd = vlen(self.velocity);
+ float spd = vlen(self.velocity);
spd = bound(
spd - (autocvar_g_monster_mage_attack_spike_decel) * frametime,
(autocvar_g_monster_mage_attack_spike_speed_max),
if (self.enemy != world)
{
- e = self.enemy;
- eorg = 0.5 * (e.absmin + e.absmax);
- turnrate = (autocvar_g_monster_mage_attack_spike_turnrate); // how fast to turn
- desireddir = normalize(eorg - self.origin);
- olddir = normalize(self.velocity); // get my current direction
- dist = vlen(eorg - self.origin);
+ entity e = self.enemy;
+ vector eorg = 0.5 * (e.absmin + e.absmax);
+ float turnrate = (autocvar_g_monster_mage_attack_spike_turnrate); // how fast to turn
+ vector desireddir = normalize(eorg - self.origin);
+ vector olddir = normalize(self.velocity); // get my current direction
+ float dist = vlen(eorg - self.origin);
// Do evasive maneuvers for world objects? ( this should be a cpu hog. :P )
if ((autocvar_g_monster_mage_attack_spike_smart) && (dist > (autocvar_g_monster_mage_attack_spike_smart_mindist)))
desireddir = normalize(((trace_plane_normal * (1 - trace_fraction)) + (desireddir * trace_fraction)) * 0.5);
}
- newdir = normalize(olddir + desireddir * turnrate); // take the average of the 2 directions; not the best method but simple & easy
+ vector newdir = normalize(olddir + desireddir * turnrate); // take the average of the 2 directions; not the best method but simple & easy
self.velocity = newdir * spd; // make me fly in the new direction at my flight speed
}
- else
- dist = 0;
///////////////
UpdateCSQCProjectile(self);
}
-void M_Mage_Attack_Spike()
-{SELFPARAM();
- entity missile;
- vector dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
+void M_Mage_Attack_Spike(vector dir);
+void M_Mage_Attack_Spike_Aim()
+{
+ SELFPARAM();
+ return M_Mage_Attack_Spike(normalize((self.enemy.origin + '0 0 10') - self.origin));
+}
+void M_Mage_Attack_Spike(vector dir)
+{
+ SELFPARAM();
makevectors(self.angles);
- missile = spawn ();
+ entity missile = spawn();
missile.owner = missile.realowner = self;
missile.think = M_Mage_Attack_Spike_Think;
missile.ltime = time + 7;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.flags = FL_PROJECTILE;
setorigin(missile, self.origin + v_forward * 14 + '0 0 30' + v_right * -14);
- setsize (missile, '0 0 0', '0 0 0');
+ setsize(missile, '0 0 0', '0 0 0');
missile.velocity = dir * 400;
missile.avelocity = '300 300 300';
missile.enemy = self.enemy;
setanim(self, self.anim_shoot, true, true, true);
self.attack_finished_single = time + (autocvar_g_monster_mage_attack_spike_delay);
self.anim_finished = time + 1;
- Monster_Delay(1, 0, 0.2, M_Mage_Attack_Spike);
+ Monster_Delay(1, 0, 0.2, M_Mage_Attack_Spike_Aim);
return true;
}
}
/* fullname */ _("Dual Plasma Cannon")
);
#else
+
+#include "../../weapons/all.qh"
+
+CLASS(PlasmaDualAttack, PortoLaunch)
+/* flags */ ATTRIB(PlasmaDualAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse */ ATTRIB(PlasmaDualAttack, impulse, int, 5);
+/* refname */ ATTRIB(PlasmaDualAttack, netname, string, "plasmadual");
+/* wepname */ ATTRIB(PlasmaDualAttack, message, string, _("Dual plasma"));
+ENDCLASS(PlasmaDualAttack)
+REGISTER_WEAPON(PLASMA_DUAL, NEW(PlasmaDualAttack));
+
#ifdef SVQC
+
+float t_plasma_dual(float req);
+METHOD(PlasmaDualAttack, wr_think, bool(entity thiswep)) {
+ SELFPARAM();
+ if (self.BUTTON_ATCK)
+ if (weapon_prepareattack(0, WEP_CVAR_PRI(electro, refire))) {
+ W_SetupShot_Dir(self, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0);
+ self.tur_shotdir_updated = w_shotdir;
+ self.tur_shotorg = w_shotorg;
+ self.tur_head = self;
+ self.shot_speed = max(1, ((!self.shot_speed) ? 2500 : self.shot_speed));
+ self.shot_spread = bound(0.0001, ((!self.shot_spread) ? 0.0125 : self.shot_spread), 500);
+ t_plasma_dual(TR_ATTACK);
+ weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
+ }
+ return true;
+}
+
void spawnfunc_turret_plasma_dual() { SELFPARAM(); if(!turret_initialize(TUR_PLASMA_DUAL.m_id)) remove(self); }
float t_plasma_dual(float req)
#ifndef VEHICLE_RACER
#define VEHICLE_RACER
+
#ifndef MENUQC
int v_racer(int);
#endif
this.vehicle_func = v_racer;
#endif
}
+
+#include "../../weapons/all.qh"
+
+CLASS(RacerAttack, PortoLaunch)
+/* flags */ ATTRIB(RacerAttack, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse */ ATTRIB(RacerAttack, impulse, int, 3);
+/* refname */ ATTRIB(RacerAttack, netname, string, "racercannon");
+/* wepname */ ATTRIB(RacerAttack, message, string, _("Racer cannon"));
+ENDCLASS(RacerAttack)
+REGISTER_WEAPON(RACER, NEW(RacerAttack));
+
#endif
#ifdef IMPLEMENTATION
#include "../../effects/effects.qh"
#include "../../triggers/trigger/impulse.qh"
+void racer_fire_cannon(string tagname);
+METHOD(RacerAttack, wr_think, bool(entity thiswep)) {
+ SELFPARAM();
+ if (self.BUTTON_ATCK)
+ if (weapon_prepareattack(0, 0)) {
+ W_SetupShot_Dir(self, v_forward, false, 0, W_Sound("lasergun_fire"), CH_WEAPON_B, 0);
+ racer_fire_cannon("tag_fire1");
+ weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), w_ready);
+ }
+ return true;
+}
+
bool autocvar_g_vehicle_racer;
float autocvar_g_vehicle_racer_speed_afterburn;
#include "weapon/arc.qc"
#include "weapon/hmg.qc"
#include "weapon/rpc.qc"
+
+#include "../../server/mutators/gamemode_nexball_weapon.qc"
// 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;
// weapon name macros
const int WEP_FIRST = 1;
-#define WEP_MAXCOUNT 24 // Increase as needed. Can be up to three times as much.
+#define WEP_MAXCOUNT 32 // Increase as needed. Can be up to 72.
int WEP_COUNT;
#define WEP_LAST (WEP_FIRST + WEP_COUNT - 1)
WepSet WEPSET_ALL;
.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);
+ 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 */
}
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); \
- }
+ localcmd(sprintf("alias weapon_%s \"impulse %d\"\n", this.netname, 230 + this.m_id - 1)); \
+ } \
+ REGISTER_INIT(WEP, 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)
{
#ifndef IMPLEMENTATION
-REGISTER_WEAPON(
-/* WEP_##id */ PORTO,
-/* function */ W_Porto,
-/* ammotype */ ammo_none,
-/* impulse */ 0,
-/* flags */ WEP_TYPE_OTHER | WEP_FLAG_SUPERWEAPON,
-/* rating */ 0,
-/* color */ '0.5 0.5 0.5',
-/* modelname */ "porto",
-/* simplemdl */ "foobar",
-/* crosshair */ "gfx/crosshairporto 0.6",
-/* wepimg */ "weaponporto",
-/* refname */ "porto",
-/* wepname */ _("Port-O-Launch")
-);
+CLASS(PortoLaunch, Weapon)
+/* ammotype */ ATTRIB(PortoLaunch, ammo_field, .int, ammo_none)
+/* impulse */ ATTRIB(PortoLaunch, impulse, int, 0)
+/* flags */ ATTRIB(PortoLaunch, spawnflags, int, WEP_TYPE_OTHER | WEP_FLAG_SUPERWEAPON);
+/* rating */ ATTRIB(PortoLaunch, bot_pickupbasevalue, float, 0);
+/* color */ ATTRIB(PortoLaunch, wpcolor, vector, '0.5 0.5 0.5');
+/* modelname */ ATTRIB(PortoLaunch, mdl, string, "porto");
+/* model */ ATTRIB(PortoLaunch, model, string, strzone(W_Model(strcat("g_", this.mdl, ".md3"))));
+/* simplemdl */ ATTRIB(PortoLaunch, w_simplemdl, string, "foobar");
+/* crosshair */ ATTRIB(PortoLaunch, w_crosshair, string, "gfx/crosshairporto");
+/* crosshair */ ATTRIB(PortoLaunch, w_crosshair_size, float, 0.6);
+/* wepimg */ ATTRIB(PortoLaunch, model2, string, "weaponporto");
+/* refname */ ATTRIB(PortoLaunch, netname, string, "porto");
+/* wepname */ ATTRIB(PortoLaunch, message, string, _("Port-O-Launch"));
+ENDCLASS(PortoLaunch)
+REGISTER_WEAPON(PORTO, NEW(PortoLaunch));
#define PORTO_SETTINGS(w_cvar,w_prop) PORTO_SETTINGS_LIST(w_cvar, w_prop, PORTO, porto)
#define PORTO_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
MUTATOR_CALLHOOK(EditProjectile, self, gren);
}
-bool w_nexball_weapon(int req); // WEAPONTODO
-bool W_Porto(int req)
-{SELFPARAM();
- //vector v_angle_save;
-
- if(g_nexball) { return w_nexball_weapon(req); }
-
- switch(req)
- {
- case WR_AIM:
+ METHOD(PortoLaunch, wr_aim, bool(entity thiswep))
{
+ SELFPARAM();
self.BUTTON_ATCK = false;
self.BUTTON_ATCK2 = false;
if(!WEP_CVAR(porto, secondary))
return true;
}
- case WR_CONFIG:
+ METHOD(PortoLaunch, wr_config, bool(entity this))
{
PORTO_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS);
return true;
}
- case WR_THINK:
+ METHOD(PortoLaunch, wr_think, bool(entity thiswep))
{
+ SELFPARAM();
if(WEP_CVAR(porto, secondary))
{
if(self.BUTTON_ATCK)
return true;
}
- case WR_CHECKAMMO1:
- case WR_CHECKAMMO2:
+ METHOD(PortoLaunch, wr_checkammo1, bool(entity this))
{
// always allow infinite ammo
return true;
}
- case WR_INIT:
+ METHOD(PortoLaunch, wr_checkammo2, bool(entity this))
+ {
+ // always allow infinite ammo
+ return true;
+ }
+ METHOD(PortoLaunch, wr_init, bool(entity this))
{
PORTO_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
return true;
}
- case WR_SETUP:
+ METHOD(PortoLaunch, wr_setup, bool(entity thiswep))
{
+ SELFPARAM();
self.ammo_field = ammo_none;
return true;
}
- case WR_RESETPLAYER:
+ METHOD(PortoLaunch, wr_resetplayer, bool(entity thiswep))
{
+ SELFPARAM();
self.porto_current = world;
return true;
}
- }
- return false;
-}
#endif
#ifdef CSQC
-bool W_Porto(int req)
-{SELFPARAM();
- switch(req)
- {
- case WR_IMPACTEFFECT:
- {
- LOG_INFO("Since when does Porto send DamageInfo?\n");
+ METHOD(PortoLaunch, wr_impacteffect, bool(entity this)) {
+ LOG_WARNING("Since when does Porto send DamageInfo?\n");
return true;
}
- case WR_INIT:
- {
+ METHOD(PortoLaunch, wr_init, bool(entity this)) {
// nothing to do
return true;
}
- case WR_ZOOMRETICLE:
- {
+ METHOD(PortoLaunch, wr_zoomreticle, bool(entity this)) {
// no weapon specific image for this weapon
return false;
}
- }
- return false;
-}
#endif
#endif
}
.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)
{
float autocvar_g_multijump_maxspeed;
float autocvar_g_multijump_dodging = 1;
string autocvar_g_mutatormsg;
-float autocvar_g_nexball_basketball_bouncefactor;
-float autocvar_g_nexball_basketball_bouncestop;
-float autocvar_g_nexball_basketball_carrier_highspeed;
-bool autocvar_g_nexball_basketball_meter;
-float autocvar_g_nexball_basketball_meter_maxpower;
-float autocvar_g_nexball_basketball_meter_minpower;
-float autocvar_g_nexball_delay_collect;
-float autocvar_g_nexball_delay_goal;
-float autocvar_g_nexball_delay_start;
-float autocvar_g_nexball_football_bouncefactor;
-float autocvar_g_nexball_football_bouncestop;
int autocvar_g_nexball_goalleadlimit;
#define autocvar_g_nexball_goallimit cvar("g_nexball_goallimit")
-bool autocvar_g_nexball_radar_showallplayers;
-bool autocvar_g_nexball_sound_bounce;
-int autocvar_g_nexball_trail_color;
//float autocvar_g_nick_flood_penalty;
int autocvar_g_nick_flood_penalty_red;
int autocvar_g_nick_flood_penalty_yellow;
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();
}
#include "gamemode.qh"
+float autocvar_g_nexball_basketball_bouncefactor;
+float autocvar_g_nexball_basketball_bouncestop;
+float autocvar_g_nexball_basketball_carrier_highspeed;
+bool autocvar_g_nexball_basketball_meter;
+float autocvar_g_nexball_basketball_meter_maxpower;
+float autocvar_g_nexball_basketball_meter_minpower;
+float autocvar_g_nexball_delay_collect;
+float autocvar_g_nexball_delay_goal;
+float autocvar_g_nexball_delay_start;
+float autocvar_g_nexball_football_bouncefactor;
+float autocvar_g_nexball_football_bouncestop;
+bool autocvar_g_nexball_radar_showallplayers;
+bool autocvar_g_nexball_sound_bounce;
+int autocvar_g_nexball_trail_color;
+
float autocvar_g_nexball_safepass_turnrate;
float autocvar_g_nexball_safepass_maxdist;
float autocvar_g_nexball_safepass_holdtime;
plyr.weaponentity.weapons = plyr.weapons;
plyr.weaponentity.switchweapon = plyr.weapon;
- plyr.weapons = WEPSET_PORTO;
+ plyr.weapons = WEPSET_NEXBALL;
setself(plyr);
- WEP_ACTION(WEP_PORTO.m_id, WR_RESETPLAYER);
- plyr.switchweapon = WEP_PORTO.m_id;
- W_SwitchWeapon(WEP_PORTO.m_id);
+ WEP_ACTION(WEP_NEXBALL, WR_RESETPLAYER);
+ plyr.switchweapon = WEP_NEXBALL.m_id;
+ W_SwitchWeapon(WEP_NEXBALL.m_id);
setself(this);
}
return true;
}
+float w_nexball_weapon(float req);
+METHOD(BallStealer, weapon_func, bool(entity this, int req)) {
+ return w_nexball_weapon(req);
+}
+
float w_nexball_weapon(float req)
{SELFPARAM();
if(req == WR_THINK)
if(self.weaponentity.weapons)
{
self.weapons = self.weaponentity.weapons;
- WEP_ACTION(WEP_PORTO.m_id, WR_RESETPLAYER);
+ WEP_ACTION(WEP_NEXBALL, WR_RESETPLAYER);
self.switchweapon = self.weaponentity.switchweapon;
W_SwitchWeapon(self.switchweapon);
self.weaponentity.weapons = '0 0 0';
if(nexball_mode & NBM_BASKETBALL)
- self.weapons |= WEPSET_PORTO;
+ self.weapons |= WEPSET_NEXBALL;
else
self.weapons = '0 0 0';
return false;
}
-MUTATOR_HOOKFUNCTION(nexball_SetStartItems)
-{
- start_items |= IT_UNLIMITED_SUPERWEAPONS; // FIXME BAD BAD BAD BAD HACK, NEXBALL SHOULDN'T ABUSE PORTO'S WEAPON SLOT
-
- return false;
-}
-
MUTATOR_HOOKFUNCTION(nexball_ForbidThrowing)
{SELFPARAM();
if(self.weapon == WEP_MORTAR.m_id)
MUTATOR_HOOK(PlayerSpawn, nexball_PlayerSpawn, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerPreThink, nexball_PlayerPreThink, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerPhysics, nexball_PlayerPhysics, CBC_ORDER_ANY);
- MUTATOR_HOOK(SetStartItems, nexball_SetStartItems, CBC_ORDER_ANY);
MUTATOR_HOOK(ForbidThrowCurrentWeapon, nexball_ForbidThrowing, CBC_ORDER_ANY);
MUTATOR_HOOK(FilterItem, nexball_FilterItem, CBC_ORDER_ANY);
--- /dev/null
+#ifndef IMPLEMENTATION
+
+CLASS(BallStealer, PortoLaunch)
+/* flags */ ATTRIB(BallStealer, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse */ ATTRIB(BallStealer, impulse, int, 2);
+/* refname */ ATTRIB(BallStealer, netname, string, "ballstealer");
+/* wepname */ ATTRIB(BallStealer, message, string, _("Ball Stealer"));
+ENDCLASS(BallStealer)
+REGISTER_WEAPON(NEXBALL, NEW(BallStealer));
+
+#endif
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, SND(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, SND(POWERUP), SND(POWEROFF));
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)
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);
+ _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);
}
+++ /dev/null
-alias weapon_blaster "impulse 230"
-alias weapon_shotgun "impulse 231"
-alias weapon_machinegun "impulse 232"
-alias weapon_mortar "impulse 233"
-alias weapon_minelayer "impulse 234"
-alias weapon_electro "impulse 235"
-alias weapon_crylink "impulse 236"
-alias weapon_vortex "impulse 237"
-alias weapon_hagar "impulse 238"
-alias weapon_devastator "impulse 239"
-alias weapon_porto "impulse 240"
-alias weapon_vaporizer "impulse 241"
-alias weapon_hook "impulse 242"
-alias weapon_hlac "impulse 243"
-alias weapon_tuba "impulse 244"
-alias weapon_rifle "impulse 245"
-alias weapon_fireball "impulse 246"
-alias weapon_seeker "impulse 247"
-alias weapon_shockwave "impulse 248"
-alias weapon_arc "impulse 249"
-
-// Backwards compatibility with 0.7.0
-alias weapon_laser "weapon_blaster"
-alias weapon_uzi "weapon_machinegun"
-alias weapon_grenadelauncher "weapon_mortar"
-alias weapon_nex "weapon_vortex"
-alias weapon_rocketlauncher "weapon_devastator"
-alias weapon_minstanex "weapon_vaporizer"