--- /dev/null
+REGISTER_MUTATOR(mutator_mod, cvar("g_mod"));
+
+MUTATOR_HOOKFUNCTION(mutator_mod, BuildMutatorsString) {
+ ret_string = strcat(ret_string, ":mod");
+}
+
+MUTATOR_HOOKFUNCTION(mutator_mod, BuildMutatorsPrettyString) {
+ ret_string = strcat(ret_string, ", Mod");
+}
--- /dev/null
+#if BUILD_MOD
+#include "main.qc"
+#endif
--- /dev/null
+REGISTER_MUTATOR(mutator_mod, cvar("g_mod"));
+
+MUTATOR_HOOKFUNCTION(mutator_mod, BuildMutatorsString) {
+ ret_string = strcat(ret_string, ":mod");
+}
+
+MUTATOR_HOOKFUNCTION(mutator_mod, BuildMutatorsPrettyString) {
+ ret_string = strcat(ret_string, ", Mod");
+}
--- /dev/null
+#if BUILD_MOD
+#include "main.qc"
+#endif
--- /dev/null
+REGISTER_MUTATOR(mutator_mod, cvar("g_mod"));
+
+MUTATOR_HOOKFUNCTION(mutator_mod, BuildMutatorsString) {
+ ret_string = strcat(ret_string, ":mod");
+}
+
+MUTATOR_HOOKFUNCTION(mutator_mod, BuildMutatorsPrettyString) {
+ ret_string = strcat(ret_string, ", Mod");
+}
--- /dev/null
+#if BUILD_MOD
+#include "main.qc"
+#endif
-std=gmqcc \
-O3 -flno \
-Werror -fno-bail-on-werror -Wall \
- -fftepp -fftepp-predefs -Wcpp -futf8 -frelaxed-switch \
+ -fftepp -fftepp-predefs -Wcpp -futf8 -frelaxed-switch -freturn-assignments \
$(QCCFLAGS_WTFS) \
$(QCCFLAGS_FEATURES) \
$(QCCFLAGS_EXTRA) $(QCCFLAGS_WATERMARK)
QCCFLAGS_FEATURES ?= \
-DVEHICLES_ENABLED=1 \
- -DVEHICLES_USE_ODE=0
+ -DVEHICLES_USE_ODE=0 \
+ -DBUILD_MOD=$(BUILD_MOD)
# xonotic build system overrides this by command line argument to turn off the update-cvarcount step
XON_BUILDSYSTEM =
w_random = prandom();
traceline(w_org - normalize(force) * 16, w_org + normalize(force) * 16, MOVE_NOMONSTERS, world);
- if(trace_fraction < 1 && hitwep != WEP_VORTEX && hitwep != WEP_VAPORIZER)
+ if(trace_fraction < 1 && hitwep != WEP_VORTEX.m_id && hitwep != WEP_VAPORIZER.m_id)
w_backoff = trace_plane_normal;
else
w_backoff = -1 * normalize(force);
#include "../common/items/all.qh"
+#include "../common/mutators/base.qh"
+
#include "../common/weapons/all.qh"
#include "../csqcmodellib/cl_model.qh"
// needs to be done so early because of the constants they create
static_init();
- CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
CALL_ACCUMULATED_FUNCTION(RegisterHUD_Panels);
../warpzonelib/common.qc
../warpzonelib/mathlib.qc
../warpzonelib/util_server.qc
+
+../../mod/client/progs.inc
vector p, dir, ang, q, nextdir;
float portal_number, portal1_idx;
- if(activeweapon != WEP_PORTO || spectatee_status || gametype == MAPINFO_TYPE_NEXBALL)
+ if(activeweapon != WEP_PORTO.m_id || spectatee_status || gametype == MAPINFO_TYPE_NEXBALL)
return;
if(g_balance_porto_secondary)
return;
zoomdir = button_zoom;
if(hud == HUD_NORMAL)
- if((activeweapon == WEP_VORTEX && vortex_scope) || (activeweapon == WEP_RIFLE && rifle_scope)) // do NOT use switchweapon here
+ if((activeweapon == WEP_VORTEX.m_id && vortex_scope) || (activeweapon == WEP_RIFLE.m_id && rifle_scope)) // do NOT use switchweapon here
zoomdir += button_attack2;
if(spectatee_status > 0 || isdemo())
{
switch(activeweapon) // WEAPONTODO
{
- case WEP_TUBA: // no aim
- case WEP_PORTO: // shoots from eye
- case WEP_HOOK: // no trueaim
- case WEP_MORTAR: // toss curve
+ case WEP_TUBA.m_id: // no aim
+ case WEP_PORTO.m_id: // shoots from eye
+ case WEP_HOOK.m_id: // no trueaim
+ case WEP_MORTAR.m_id: // toss curve
return SHOTTYPE_HITWORLD;
- case WEP_VORTEX:
- case WEP_VAPORIZER:
+ case WEP_VORTEX.m_id:
+ case WEP_VAPORIZER.m_id:
mv = MOVE_NORMAL;
break;
- case WEP_RIFLE:
+ case WEP_RIFLE.m_id:
ta = trueaim_rifle;
mv = MOVE_NORMAL;
if(zoomscript_caught)
return EnemyHitCheck();
}
break;
- case WEP_DEVASTATOR: // projectile has a size!
+ case WEP_DEVASTATOR.m_id: // projectile has a size!
mi = '-3 -3 -3';
ma = '3 3 3';
break;
- case WEP_FIREBALL: // projectile has a size!
+ case WEP_FIREBALL.m_id: // projectile has a size!
mi = '-16 -16 -16';
ma = '16 16 16';
break;
- case WEP_SEEKER: // projectile has a size!
+ case WEP_SEEKER.m_id: // projectile has a size!
mi = '-2 -2 -2';
ma = '2 2 2';
break;
- case WEP_ELECTRO: // projectile has a size!
+ case WEP_ELECTRO.m_id: // projectile has a size!
mi = '0 0 -3';
ma = '0 0 -3';
break;
return true;
if(spectatee_status >= 0)
{
- if(autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(WepSet_GetFromStat() & WepSet_FromWeapon(WEP_PORTO)))
+ if(autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(WepSet_GetFromStat() & WepSet_FromWeapon(WEP_PORTO.m_id)))
return true;
if(autocvar_cl_eventchase_death && (getstati(STAT_HEALTH) <= 0))
{
static float hitsound_time_prev = 0;
// HACK: the only way to get the arc to sound consistent with pitch shift is to ignore cl_hitsound_antispam_time
- float arc_hack = activeweapon == WEP_ARC && autocvar_cl_hitsound >= 2;
+ float arc_hack = activeweapon == WEP_ARC.m_id && autocvar_cl_hitsound >= 2;
if (arc_hack || COMPARE_INCREASING(time, hitsound_time_prev) > autocvar_cl_hitsound_antispam_time)
{
if (autocvar_cl_hitsound && unaccounted_damage)
// handle the values
- if (autocvar_crosshair_ring && activeweapon == WEP_VORTEX && vortex_charge && autocvar_crosshair_ring_vortex) // ring around crosshair representing velocity-dependent damage for the vortex
+ if (autocvar_crosshair_ring && activeweapon == WEP_VORTEX.m_id && vortex_charge && autocvar_crosshair_ring_vortex) // ring around crosshair representing velocity-dependent damage for the vortex
{
if (vortex_chargepool || use_vortex_chargepool) {
use_vortex_chargepool = 1;
ring_rgb = wcross_color;
ring_image = "gfx/crosshair_ring_nexgun.tga";
}
- else if (autocvar_crosshair_ring && activeweapon == WEP_MINE_LAYER && minelayer_maxmines && autocvar_crosshair_ring_minelayer)
+ else if (autocvar_crosshair_ring && activeweapon == WEP_MINE_LAYER.m_id && minelayer_maxmines && autocvar_crosshair_ring_minelayer)
{
ring_value = bound(0, getstati(STAT_LAYED_MINES) / minelayer_maxmines, 1); // if you later need to use the count of bullets in another place, then add a float for it. For now, no need to.
ring_alpha = autocvar_crosshair_ring_minelayer_alpha;
ring_rgb = wcross_color;
ring_image = "gfx/crosshair_ring.tga";
}
- else if (activeweapon == WEP_HAGAR && getstati(STAT_HAGAR_LOAD) && autocvar_crosshair_ring_hagar)
+ else if (activeweapon == WEP_HAGAR.m_id && getstati(STAT_HAGAR_LOAD) && autocvar_crosshair_ring_hagar)
{
ring_value = bound(0, getstati(STAT_HAGAR_LOAD) / hagar_maxrockets, 1);
ring_alpha = autocvar_crosshair_ring_hagar_alpha;
// Note: This is to stop Taoki from complaining that the image doesn't match all potential balances.
// if a new image for another weapon is added, add the code (and its respective file/value) here
- if ((activeweapon == WEP_RIFLE) && (weapon_clipsize == 80))
+ if ((activeweapon == WEP_RIFLE.m_id) && (weapon_clipsize == 80))
ring_image = "gfx/crosshair_ring_rifle.tga";
else
ring_image = "gfx/crosshair_ring.tga";
}
- else if ( autocvar_crosshair_ring && autocvar_crosshair_ring_arc && arc_heat && activeweapon == WEP_ARC )
+ else if ( autocvar_crosshair_ring && autocvar_crosshair_ring_arc && arc_heat && activeweapon == WEP_ARC.m_id )
{
ring_value = arc_heat;
ring_alpha = (1-arc_heat)*autocvar_crosshair_ring_arc_cold_alpha +
self.monster_loot = spawnfunc_item_health_mega;
self.monster_attackfunc = shambler_attack;
self.frame = shambler_anim_stand;
- self.weapon = WEP_VORTEX;
+ self.weapon = WEP_VORTEX.m_id;
return true;
}
self.health += autocvar_g_monsters_miniboss_healthboost;
self.effects |= EF_RED;
if(!self.weapon)
- self.weapon = WEP_VORTEX;
+ self.weapon = WEP_VORTEX.m_id;
}
}
--- /dev/null
+#ifndef MUTATORS_BASE_H
+#define MUTATORS_BASE_H
+
+const int CBC_ORDER_FIRST = 1;
+const int CBC_ORDER_LAST = 2;
+const int CBC_ORDER_EXCLUSIVE = 3;
+const int CBC_ORDER_ANY = 4;
+
+bool CallbackChain_ReturnValue; // read-only field of the current return value
+
+/**
+ * Callbacks may be added to zero or more callback chains.
+ */
+CLASS(Callback, Object)
+ /**
+ * a callback function is like this:
+ * bool mycallback()
+ * {
+ * do something
+ * return false;
+ * }
+ */
+ ATTRIB(Callback, cbc_func, bool(), func_null)
+ CONSTRUCTOR(Callback, bool() func) {
+ CONSTRUCT(Callback);
+ this.cbc_func = func;
+ return this;
+ }
+ENDCLASS(Callback)
+
+/**
+ * Callback chains contain zero or more callbacks.
+ */
+CLASS(CallbackChain, Object)
+ CLASS(CallbackNode, Object)
+ ATTRIB(CallbackNode, cbc, Callback, NULL)
+ ATTRIB(CallbackNode, cbc_next, CallbackNode, NULL)
+ ATTRIB(CallbackNode, cbc_order, int, 0)
+ CONSTRUCTOR(CallbackNode, Callback it, int order) {
+ CONSTRUCT(CallbackNode);
+ this.cbc = it;
+ this.cbc_order = order;
+ return this;
+ }
+ ENDCLASS(CallbackNode)
+
+ ATTRIB(CallbackChain, cbc_next, CallbackNode, NULL)
+ ATTRIB(CallbackChain, cbc_order, int, 0)
+ CONSTRUCTOR(CallbackChain, string _name) {
+ CONSTRUCT(CallbackChain);
+ this.netname = _name;
+ return this;
+ }
+
+ bool CallbackChain_Add(CallbackChain this, Callback cb, int order)
+ {
+ if (order & CBC_ORDER_FIRST) {
+ if (order & CBC_ORDER_LAST)
+ if (this.cbc_order & CBC_ORDER_ANY)
+ return false;
+ if (this.cbc_order & CBC_ORDER_FIRST)
+ return false;
+ } else if (order & CBC_ORDER_LAST) {
+ if (this.cbc_order & CBC_ORDER_LAST)
+ return false;
+ }
+ entity node = NEW(CallbackNode, cb, order);
+ if (order & CBC_ORDER_FIRST) {
+ node.cbc_next = this.cbc_next;
+ this.cbc_next = node;
+ } else if (order & CBC_ORDER_LAST) {
+ CallbackNode prev = NULL, it = this.cbc_next;
+ while (it) { prev = it, it = it.cbc_next; }
+ if (prev) prev.cbc_next = node;
+ else this.cbc_next = node;
+ } else {
+ // by default we execute last, but before a possible CBC_ORDER_LAST callback
+ CallbackNode prev = NULL, it = this.cbc_next;
+ while (it && !(it.cbc_order & CBC_ORDER_LAST)) { prev = it, it = it.cbc_next; }
+ node.cbc_next = it;
+ if (prev) prev.cbc_next = node;
+ else this.cbc_next = node;
+ }
+ this.cbc_order |= (order | CBC_ORDER_ANY);
+ return true;
+ }
+ int CallbackChain_Remove(CallbackChain this, Callback cb)
+ {
+ int n = 0, order = 0;
+ for (Callback prev = NULL, it = this.cbc_next; it; prev = it, it = it.cbc_next) {
+ if (it.cbc == cb) {
+ // remove it from the chain
+ Callback next = it.cbc_next;
+ if (prev) prev.cbc_next = next;
+ else this.cbc_next = next;
+ ++n;
+ }
+ // it is now something we want to keep
+ order |= (it.cbc_order & CBC_ORDER_ANY);
+ }
+ this.cbc_order = order;
+ return n;
+ }
+ bool CallbackChain_Call(CallbackChain this)
+ {
+ bool r = false;
+ for (Callback it = this.cbc_next; it; it = it.cbc_next) {
+ CallbackChain_ReturnValue = r;
+ r |= it.cbc.cbc_func();
+ }
+ return r; // callbacks return an error status, so 0 is default return value
+ }
+ENDCLASS(CallbackChain)
+
+#define _MUTATOR_HANDLE_NOP(type, id)
+#define _MUTATOR_HANDLE_PARAMS(type, id) , type in_##id
+#define _MUTATOR_HANDLE_PREPARE(type, id) id = in_##id;
+#define _MUTATOR_HANDLE_PUSHTMP(type, id) type tmp_##id = id;
+#define _MUTATOR_HANDLE_PUSHOUT(type, id) type out_##id = id;
+#define _MUTATOR_HANDLE_POPTMP(type, id) id = tmp_##id;
+#define _MUTATOR_HANDLE_POPOUT(type, id) id = out_##id;
+
+void RegisterHooks() {};
+void RegisterCallbacks() {};
+void RegisterMutators() {};
+
+#define _MUTATOR_HOOKABLE(id, ...) CallbackChain HOOK_##id; bool __Mutator_Send_##id(__VA_ARGS__)
+#define MUTATOR_HOOKABLE(id, params) \
+ _MUTATOR_HOOKABLE(id, int params(_MUTATOR_HANDLE_PARAMS, _MUTATOR_HANDLE_NOP)) { \
+ params(_MUTATOR_HANDLE_PUSHTMP, _MUTATOR_HANDLE_NOP) \
+ params(_MUTATOR_HANDLE_PREPARE, _MUTATOR_HANDLE_NOP) \
+ bool ret = CallbackChain_Call(HOOK_##id); \
+ params(_MUTATOR_HANDLE_NOP, _MUTATOR_HANDLE_PUSHOUT) \
+ params(_MUTATOR_HANDLE_POPTMP, _MUTATOR_HANDLE_NOP) \
+ params(_MUTATOR_HANDLE_NOP, _MUTATOR_HANDLE_POPOUT) \
+ return ret; \
+ } \
+ [[accumulate]] void RegisterHooks() { HOOK_##id = NEW(CallbackChain, #id); }
+#define MUTATOR_CALLHOOK(id, ...) APPLY(__Mutator_Send_##id, 0, ##__VA_ARGS__)
+
+enum {
+ MUTATOR_REMOVING,
+ MUTATOR_ADDING,
+ MUTATOR_ROLLING_BACK
+};
+
+typedef bool(int) mutatorfunc_t;
+
+CLASS(Mutator, Object)
+ ATTRIB(Mutator, m_id, int, 0)
+ ATTRIB(Mutator, mutatorname, string, string_null)
+ ATTRIB(Mutator, mutatorfunc, mutatorfunc_t, func_null)
+ ATTRIB(Mutator, mutatorcheck, bool(), func_null)
+ CONSTRUCTOR(Mutator, string _name, mutatorfunc_t func) {
+ CONSTRUCT(Mutator);
+ this.mutatorname = _name;
+ this.mutatorfunc = func;
+ return this;
+ }
+ENDCLASS(Mutator)
+
+const int MAX_MUTATORS = 15;
+Mutator loaded_mutators[MAX_MUTATORS];
+
+bool Mutator_Add(Mutator mut)
+{
+ int j = -1;
+ for (int i = 0; i < MAX_MUTATORS; ++i) {
+ if (loaded_mutators[i] == mut)
+ return true; // already added
+ if (!(loaded_mutators[i]))
+ j = i;
+ }
+ if (j < 0) {
+ backtrace("WARNING: too many mutators, cannot add any more\n");
+ return false;
+ }
+ loaded_mutators[j] = mut;
+ mutatorfunc_t func = mut.mutatorfunc;
+ if (!func(MUTATOR_ADDING)) {
+ // good
+ return true;
+ }
+ backtrace("WARNING: when adding mutator: adding failed, rolling back\n");
+ if (func(MUTATOR_ROLLING_BACK)) {
+ // baaaaad
+ error("WARNING: when adding mutator: rolling back failed");
+ }
+ return false;
+}
+
+void Mutator_Remove(Mutator mut)
+{
+ int i;
+ for (i = 0; i < MAX_MUTATORS; ++i)
+ if (loaded_mutators[i] == mut)
+ break;
+ if (i >= MAX_MUTATORS) {
+ backtrace("WARNING: removing not-added mutator\n");
+ return;
+ }
+ loaded_mutators[i] = NULL;
+ mutatorfunc_t func = mut.mutatorfunc;
+ if (func(MUTATOR_REMOVING)) {
+ // baaaaad
+ error("Mutator_Remove: removing mutator failed");
+ }
+}
+
+#define MUTATOR_DECLARATION(name) \
+ Mutator MUTATOR_##name
+#define MUTATOR_DEFINITION(name) \
+ bool MUTATORFUNCTION_##name(int mode); \
+ [[accumulate]] void RegisterMutators() { MUTATOR_##name = NEW(Mutator, #name, MUTATORFUNCTION_##name); } \
+ [[last]] bool MUTATORFUNCTION_##name(int mode)
+
+const int MUTATORS_MAX = MAX_MUTATORS;
+noref entity MUTATORS[MUTATORS_MAX], MUTATORS_first, MUTATORS_last;
+noref int MUTATORS_COUNT;
+#define REGISTER_MUTATOR(id, dependence) \
+ bool MUTATORFUNCTION_##id##_hooks(int mode) { return = false; } \
+ bool MUTATORFUNCTION_##id(int mode) { \
+ return = false; \
+ bool ret = MUTATORFUNCTION_##id##_hooks(mode); if (ret) return ret; \
+ } \
+ bool MUTATOR_##id##_check() { return dependence; } \
+ REGISTER(RegisterMutators, MUTATOR, MUTATORS, MUTATORS_COUNT, id, m_id, NEW(Mutator, #id, MUTATORFUNCTION_##id)) \
+ { this.mutatorcheck = MUTATOR_##id##_check; } \
+ [[accumulate]] bool MUTATORFUNCTION_##id(int mode)
+
+STATIC_INIT(Mutators) {
+ RegisterHooks();
+ RegisterCallbacks();
+ RegisterMutators();
+ FOREACH(MUTATORS, it.mutatorcheck(), LAMBDA(Mutator_Add(it)));
+}
+
+#define MUTATOR_ONADD if (mode == MUTATOR_ADDING)
+#define MUTATOR_ONREMOVE if (mode == MUTATOR_REMOVING)
+#define MUTATOR_ONROLLBACK_OR_REMOVE if (mode == MUTATOR_REMOVING || mode == MUTATOR_ROLLING_BACK)
+#define MUTATOR_ADD(name) Mutator_Add(MUTATOR_##name)
+#define MUTATOR_REMOVE(name) Mutator_Remove(MUTATOR_##name)
+#define MUTATOR_RETURNVALUE CallbackChain_ReturnValue
+
+#define _MUTATOR_CALLBACK(name, func) \
+ Callback CALLBACK_##name; \
+ bool func(); \
+ [[accumulate]] void RegisterCallbacks() { CALLBACK_##name = NEW(Callback, func); }
+
+#define MUTATOR_HOOKFUNCTION(...) \
+ OVERLOAD(MUTATOR_HOOKFUNCTION, __VA_ARGS__)
+
+#define MUTATOR_HOOKFUNCTION_1(name) \
+ _MUTATOR_CALLBACK(name, HOOKFUNCTION_##name) \
+ bool HOOKFUNCTION_##name()
+
+#define MUTATOR_HOOKFUNCTION_2(mut, cb) \
+ MUTATOR_HOOKFUNCTION(mut, cb, CBC_ORDER_ANY)
+
+#define MUTATOR_HOOKFUNCTION_3(mut, cb, order) \
+ _MUTATOR_CALLBACK(mut##_##cb, mut##_##cb) \
+ [[accumulate]] bool MUTATORFUNCTION_##mut##_hooks(int mode) { MUTATOR_HOOK(cb, mut##_##cb, order); } \
+ bool mut##_##cb() { return = false; } \
+ [[accumulate]] bool mut##_##cb()
+
+#define MUTATOR_HOOK(cb, func, order) do { \
+ MUTATOR_ONADD { \
+ if (!CallbackChain_Add(HOOK_##cb, CALLBACK_##func, order)) { \
+ print("HOOK FAILED: ", #cb, ":", #func, "\n"); \
+ return true; \
+ } \
+ } \
+ MUTATOR_ONROLLBACK_OR_REMOVE { \
+ CallbackChain_Remove(HOOK_##cb, CALLBACK_##func); \
+ } \
+} while (0)
+
+#include "events.qh"
+
+#endif
--- /dev/null
+#ifndef COMMON_MUTATORS_EVENTS_H
+#define COMMON_MUTATORS_EVENTS_H
+
+#define EV_NO_ARGS(i, o)
+
+string ret_string;
+
+/** appends ":mutatorname" to ret_string for logging */
+#define EV_BuildMutatorsString(i, o) \
+ /**/ i(string, ret_string) \
+ /**/ o(string, ret_string) \
+ /**/
+MUTATOR_HOOKABLE(BuildMutatorsString, EV_BuildMutatorsString);
+
+/** appends ", Mutator name" to ret_string for display */
+#define EV_BuildMutatorsPrettyString(i, o) \
+ /**/ i(string, ret_string) \
+ /**/ o(string, ret_string) \
+ /**/
+MUTATOR_HOOKABLE(BuildMutatorsPrettyString, EV_BuildMutatorsPrettyString);
+
+#endif
#ifdef SVQC
// WEAPONTODO
float xyspeed = vlen(vec2(self.velocity));
- if (self.weapon == WEP_VORTEX && WEP_CVAR(vortex, charge) && WEP_CVAR(vortex, charge_velocity_rate) && xyspeed > WEP_CVAR(vortex, charge_minspeed))
+ if (self.weapon == WEP_VORTEX.m_id && WEP_CVAR(vortex, charge) && WEP_CVAR(vortex, charge_velocity_rate) && xyspeed > WEP_CVAR(vortex, charge_minspeed))
{
// add a maximum of charge_velocity_rate when going fast (f = 1), gradually increasing from minspeed (f = 0) to maxspeed
xyspeed = min(xyspeed, WEP_CVAR(vortex, charge_maxspeed));
#ifndef MENUQC
#include "calculations.qc"
#endif
+#define IMPLEMENTATION
#include "all.inc"
+#undef IMPLEMENTATION
// WEAPON PLUGIN SYSTEM
-entity weapon_info[WEP_MAXCOUNT];
-entity dummy_weapon_info;
#if WEP_MAXCOUNT > 72
# error Kein Weltraum links auf dem Gerät
}
#endif
-void register_weapon(
- int id,
- WepSet bit,
- bool(int) func,
- .int ammotype,
- int i,
- int weapontype,
- float pickupbasevalue,
- vector clr,
- string modelname,
- string simplemdl,
- string crosshair,
- string wepimg,
- string refname,
- string wepname)
-{
- entity e;
- weapon_info[id - 1] = e = spawn();
- e.classname = "weapon_info";
- e.weapon = id;
- e.weapons = bit;
- e.weapon_func = func;
- e.ammo_field = ammotype;
- e.impulse = i;
- e.spawnflags = weapontype;
- e.bot_pickupbasevalue = pickupbasevalue;
- e.wpcolor = clr;
- e.wpmodel = strzone(strcat("wpn-", ftos(id)));
- e.mdl = modelname;
- e.model = strzone(strcat("models/weapons/g_", modelname, ".md3"));
- e.w_simplemdl = strzone(simplemdl); // simpleitems weapon model/image
- e.w_crosshair = strzone(car(crosshair));
- string s = cdr(crosshair);
- e.w_crosshair_size = ((s != "") ? stof(s) : 1); // so that we can scale the crosshair from code (for compat)
- e.model2 = strzone(wepimg);
- e.netname = refname;
- e.message = wepname;
-
- #ifdef CSQC
- func(WR_INIT);
- #endif
-}
-bool w_null(int dummy)
-{
- return 0;
-}
void register_weapons_done()
{
- dummy_weapon_info = spawn();
- dummy_weapon_info.classname = "weapon_info";
- dummy_weapon_info.weapon = 0; // you can recognize dummies by this
- dummy_weapon_info.weapons = '0 0 0';
- dummy_weapon_info.netname = "";
- dummy_weapon_info.message = "AOL CD Thrower";
- dummy_weapon_info.weapon_func = w_null;
- dummy_weapon_info.wpmodel = "";
- dummy_weapon_info.mdl = "";
- dummy_weapon_info.model = "";
- dummy_weapon_info.spawnflags = 0;
- dummy_weapon_info.impulse = -1;
- dummy_weapon_info.bot_pickupbasevalue = 0;
- dummy_weapon_info.ammo_field = ammo_none;
-
- dummy_weapon_info.w_crosshair = "gfx/crosshair1";
- dummy_weapon_info.w_crosshair_size = 1;
- dummy_weapon_info.model2 = "";
+ dummy_weapon_info = NEW(Weapon);
- int i;
weaponorder_byid = "";
- for(i = WEP_MAXCOUNT; i >= 1; --i)
- if(weapon_info[i-1])
+ for (int i = WEP_MAXCOUNT - 1; i >= 0; --i)
+ if (weapon_info[i])
weaponorder_byid = strcat(weaponorder_byid, " ", ftos(i));
weaponorder_byid = strzone(substring(weaponorder_byid, 1, strlen(weaponorder_byid) - 1));
}
#endif
// weapon name macros
-#define WEP_FIRST 1
+const int WEP_FIRST = 1;
#define WEP_MAXCOUNT 24 // Increase as needed. Can be up to three times as much.
int WEP_COUNT;
-int WEP_LAST;
+#define WEP_LAST (WEP_FIRST + WEP_COUNT - 1)
WepSet WEPSET_ALL;
WepSet WEPSET_SUPERWEAPONS;
// other useful macros
#define WEP_ACTION(wpn,wrequest) (get_weaponinfo(wpn)).weapon_func(wrequest)
-#define WEP_AMMO(wpn) ((get_weaponinfo(WEP_##wpn)).ammo_field) // only used inside weapon files/with direct name, don't duplicate prefix
+#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)
// set initialization values for weapon settings
#define WEP_SKIP_CVAR(unuseda,unusedb,unusedc,unusedd) /* skip cvars */
-#define WEP_SET_PROP(wepid,wepname,type,prop,name) get_weaponinfo(WEP_##wepid).##prop = autocvar_g_balance_##wepname##_##name;
+#define WEP_SET_PROP(wepid,wepname,type,prop,name) WEP_##wepid.prop = autocvar_g_balance_##wepname##_##name;
// =====================
// Weapon Registration
// =====================
-bool w_null(int dummy);
-
-void register_weapon(
- int id,
- WepSet bit,
- bool(int) func,
- .int ammotype,
- int i,
- int weapontype,
- float pickupbasevalue,
- vector clr,
- string modelname,
- string simplemdl,
- string crosshair,
- string wepimg,
- string refname,
- string wepname);
+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)
+ /**
+ * M: WEP_id : WEP_...
+ * you can recognize dummies when this == 0
+ */
+ ATTRIB(Weapon, weapon, int, 0);
+ /** A: WEPSET_id : WEPSET_... */
+ ATTRIB(Weapon, weapons, WepSet, '0 0 0');
+ /** M: function : w_... */
+ ATTRIB(Weapon, weapon_func, bool(int), w_null);
+ /** M: ammotype : main ammo field */
+ ATTRIB(Weapon, ammo_field, .int, ammo_none);
+ /** M: impulse : weapon impulse */
+ ATTRIB(Weapon, impulse, int, -1);
+ /** M: flags : WEPSPAWNFLAG_... combined */
+ ATTRIB(Weapon, spawnflags, int, 0);
+ /** M: rating : bot weapon priority */
+ ATTRIB(Weapon, bot_pickupbasevalue, float, 0);
+ /** M: color : waypointsprite color */
+ ATTRIB(Weapon, wpcolor, vector, '0 0 0');
+ /** A: wpn-id : wpn- sprite name */
+ ATTRIB(Weapon, wpmodel, string, "");
+ /** M: modelname : name of model (without g_ v_ or h_ prefixes) */
+ ATTRIB(Weapon, mdl, string, "");
+ /** A: modelname : full path to g_ model */
+ ATTRIB(Weapon, model, string, "");
+ /** M: simplemdl : simpleitems weapon model/image */
+ ATTRIB(Weapon, w_simplemdl, string, "foobar");
+ /** M: crosshair : per-weapon crosshair: "CrosshairImage Size" */
+ ATTRIB(Weapon, w_crosshair, string, "gfx/crosshair1");
+ /** A: crosshair : per-weapon crosshair size (argument two of "crosshair" field) */
+ ATTRIB(Weapon, w_crosshair_size, float, 1);
+ /** M: wepimg : "weaponfoobar" side view image file of weapon. WEAPONTODO: Move out of skin files, move to common files */
+ ATTRIB(Weapon, model2, string, "");
+ /** M: refname : reference name name */
+ ATTRIB(Weapon, netname, string, "");
+ /** M: wepname : human readable name */
+ ATTRIB(Weapon, message, string, "AOL CD Thrower");
+
+ CONSTRUCTOR(Weapon,
+ bool(int) function,
+ .int ammotype,
+ int i,
+ int weapontype,
+ float pickupbasevalue,
+ vector clr,
+ string modelname,
+ string simplemdl,
+ 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.model = strzone(strcat("models/weapons/g_", modelname, ".md3"));
+ this.w_simplemdl = strzone(simplemdl); // simpleitems weapon model/image
+ 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;
+ return this;
+ }
+ void register_weapon(entity this, int id, WepSet bit)
+ {
+ this.classname = "weapon_info";
+ this.weapon = id;
+ this.weapons = bit;
+ this.wpmodel = strzone(strcat("wpn-", ftos(id)));
+ #ifdef CSQC
+ this.weapon_func(WR_INIT);
+ #endif
+ }
+ENDCLASS(Weapon)
+
+void RegisterWeapons();
+REGISTER_REGISTRY(RegisterWeapons)
+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) \
+ 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) \
+ ) { \
+ this.m_id++; \
+ WEPSET_ALL |= (WEPSET_##id = WepSet_FromWeapon(this.m_id)); \
+ if ((flags) & WEP_FLAG_SUPERWEAPON) WEPSET_SUPERWEAPONS |= WEPSET_##id; \
+ register_weapon(this, this.m_id, WEPSET_##id); \
+ }
-void register_weapons_done();
-
-// entity properties of weaponinfo:
-// fields which are explicitly/manually set are marked with "M", fields set automatically are marked with "A"
-.int weapon; // M: WEP_id // WEP_...
-.WepSet weapons; // A: WEPSET_id // WEPSET_...
-.float(float) weapon_func; // M: function // w_...
-..int ammo_field; // M: ammotype // main ammo field
-.int impulse; // M: impulse // weapon impulse
-.int spawnflags; // M: flags // WEPSPAWNFLAG_... combined
-.float bot_pickupbasevalue; // M: rating // bot weapon priority
-.vector wpcolor; // M: color // waypointsprite color
-.string wpmodel; // A: wpn-id // wpn- sprite name
-.string mdl; // M: modelname // name of model (without g_ v_ or h_ prefixes)
-.string model; // A: modelname // full path to g_ model
-.string w_simplemdl; // M: simplemdl // simpleitems weapon model/image
-.string w_crosshair; // M: crosshair // per-weapon crosshair: "CrosshairImage Size"
-.float w_crosshair_size; // A: crosshair // per-weapon crosshair size (argument two of "crosshair" field)
-.string model2; // M: wepimg // "weaponfoobar" side view image file of weapon // WEAPONTODO: Move out of skin files, move to common files
-.string netname; // M: refname // reference name name
-.string message; // M: wepname // human readable name
-
-
-// note: the fabs call is just there to hide "if result is constant" warning
-#define REGISTER_WEAPON_2(id,bit,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
- int id; \
- WepSet bit; \
- bool function(int); \
- void RegisterWeapons_##id() \
- { \
- WEP_LAST = (id = WEP_FIRST + WEP_COUNT); \
- bit = WepSet_FromWeapon(id); \
- WEPSET_ALL |= bit; \
- if((flags) & WEP_FLAG_SUPERWEAPON) \
- WEPSET_SUPERWEAPONS |= bit; \
- ++WEP_COUNT; \
- register_weapon(id,bit,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname); \
- } \
- ACCUMULATE_FUNCTION(RegisterWeapons, RegisterWeapons_##id)
-#ifdef MENUQC
-#define REGISTER_WEAPON(id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
- REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,w_null,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); \
+ _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_2(WEP_##id,WEPSET_##id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname)
+ #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)
#endif
#include "all.inc"
#undef WEP_ADD_CVAR_MO_NONE
#undef WEP_ADD_CVAR
#undef WEP_ADD_PROP
-#undef REGISTER_WEAPON
-
+void register_weapons_done();
ACCUMULATE_FUNCTION(RegisterWeapons, register_weapons_done);
#endif
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ ARC,
/* function */ W_Arc,
vector Draw_ArcBeam_callback_last_top; // NOTE: in same coordinate system as player.
vector Draw_ArcBeam_callback_last_bottom; // NOTE: in same coordinate system as player.
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_arc(void) { weapon_defaultspawnfunc(WEP_ARC); }
+void spawnfunc_weapon_arc(void) { weapon_defaultspawnfunc(WEP_ARC.m_id); }
float W_Arc_Beam_Send(entity to, int sf)
{
if(self == self.owner.arc_beam) { self.owner.arc_beam = world; }
entity oldself = self;
self = self.owner;
- if(!WEP_ACTION(WEP_ARC, WR_CHECKAMMO1) && !WEP_ACTION(WEP_ARC, WR_CHECKAMMO2))
+ if(!WEP_ACTION(WEP_ARC.m_id, WR_CHECKAMMO1) && !WEP_ACTION(WEP_ARC.m_id, WR_CHECKAMMO2))
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
// note: this doesn't force the switch
{
accuracy_add(
self.owner,
- WEP_ARC,
+ WEP_ARC.m_id,
0,
rootdamage * coefficient * falloff
);
self.owner,
self.owner,
rootdamage * coefficient * falloff,
- WEP_ARC,
+ WEP_ARC.m_id,
hitorigin,
WEP_CVAR(arc, beam_force) * new_dir * coefficient * falloff
);
}
if ( self.arc_smoke_sound && ( self.arc_overheat <= time ||
- !( self.BUTTON_ATCK || self.BUTTON_ATCK2 ) ) || self.switchweapon != WEP_ARC )
+ !( self.BUTTON_ATCK || self.BUTTON_ATCK2 ) ) || self.switchweapon != WEP_ARC.m_id )
{
self.arc_smoke_sound = 0;
sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
precache_sound("weapons/arc_loop_overheat.wav");
if(!arc_shotorigin[0])
{
- arc_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC), false, false, 1);
- arc_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC), false, false, 2);
- arc_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC), false, false, 3);
- arc_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC), false, false, 4);
+ arc_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 1);
+ arc_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 2);
+ arc_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 3);
+ arc_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 4);
}
ARC_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
return true;
}
case WR_PICKUP:
{
- if ( !client_hasweapon(self, WEP_ARC, false, false) &&
+ if ( !client_hasweapon(self, WEP_ARC.m_id, false, false) &&
weapon_dropevent_item.arc_overheat > time )
{
self.arc_overheat = weapon_dropevent_item.arc_overheat;
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ BLASTER,
/* function */ W_Blaster,
.float blaster_force;
.float blaster_lifetime;
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_blaster(void) { weapon_defaultspawnfunc(WEP_BLASTER); }
+void spawnfunc_weapon_blaster(void) { weapon_defaultspawnfunc(WEP_BLASTER.m_id); }
void spawnfunc_weapon_laser(void) { spawnfunc_weapon_blaster(); }
void W_Blaster_Touch(void)
if(weapon_prepareattack(0, WEP_CVAR_PRI(blaster, refire)))
{
W_Blaster_Attack(
- WEP_BLASTER,
+ WEP_BLASTER.m_id,
WEP_CVAR_PRI(blaster, shotangle),
WEP_CVAR_PRI(blaster, damage),
WEP_CVAR_PRI(blaster, edgedamage),
{
case 0: // switch to last used weapon
{
- if(self.switchweapon == WEP_BLASTER) // don't do this if already switching
+ if(self.switchweapon == WEP_BLASTER.m_id) // don't do this if already switching
W_LastWeapon();
break;
}
if(weapon_prepareattack(1, WEP_CVAR_SEC(blaster, refire)))
{
W_Blaster_Attack(
- WEP_BLASTER | HITTYPE_SECONDARY,
+ WEP_BLASTER.m_id | HITTYPE_SECONDARY,
WEP_CVAR_SEC(blaster, shotangle),
WEP_CVAR_SEC(blaster, damage),
WEP_CVAR_SEC(blaster, edgedamage),
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ CRYLINK,
/* function */ W_Crylink,
.entity queuenext;
.entity queueprev;
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_crylink(void) { weapon_defaultspawnfunc(WEP_CRYLINK); }
+void spawnfunc_weapon_crylink(void) { weapon_defaultspawnfunc(WEP_CRYLINK.m_id); }
void W_Crylink_CheckLinks(entity e)
{
proj.movetype = MOVETYPE_BOUNCEMISSILE;
PROJECTILE_MAKETRIGGER(proj);
- proj.projectiledeathtype = WEP_CRYLINK;
+ proj.projectiledeathtype = WEP_CRYLINK.m_id;
//proj.gravity = 0.001;
setorigin(proj, w_shotorg);
proj.movetype = MOVETYPE_BOUNCEMISSILE;
PROJECTILE_MAKETRIGGER(proj);
- proj.projectiledeathtype = WEP_CRYLINK | HITTYPE_SECONDARY;
+ proj.projectiledeathtype = WEP_CRYLINK.m_id | HITTYPE_SECONDARY;
//proj.gravity = 0.001;
setorigin(proj, w_shotorg);
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
{
// ran out of ammo!
- self.cnt = WEP_CRYLINK;
+ self.cnt = WEP_CRYLINK.m_id;
self.switchweapon = w_getbestweapon(self);
}
}
return true;
ammo_amount = self.WEP_AMMO(CRYLINK) >= WEP_CVAR_PRI(crylink, ammo);
- ammo_amount += self.(weapon_load[WEP_CRYLINK]) >= WEP_CVAR_PRI(crylink, ammo);
+ ammo_amount += self.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_PRI(crylink, ammo);
return ammo_amount;
}
case WR_CHECKAMMO2:
return true;
ammo_amount = self.WEP_AMMO(CRYLINK) >= WEP_CVAR_SEC(crylink, ammo);
- ammo_amount += self.(weapon_load[WEP_CRYLINK]) >= WEP_CVAR_SEC(crylink, ammo);
+ ammo_amount += self.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_SEC(crylink, ammo);
return ammo_amount;
}
case WR_CONFIG:
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ DEVASTATOR,
/* function */ W_Devastator,
.float rl_release;
.float rl_detonate_later;
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_devastator(void) { weapon_defaultspawnfunc(WEP_DEVASTATOR); }
+void spawnfunc_weapon_devastator(void) { weapon_defaultspawnfunc(WEP_DEVASTATOR.m_id); }
void spawnfunc_weapon_rocketlauncher(void) { spawnfunc_weapon_devastator(); }
void W_Devastator_Unregister(void)
other
);
- if(self.realowner.weapon == WEP_DEVASTATOR)
+ if(self.realowner.weapon == WEP_DEVASTATOR.m_id)
{
if(self.realowner.WEP_AMMO(DEVASTATOR) < WEP_CVAR(devastator, ammo))
if(!(self.realowner.items & IT_UNLIMITED_WEAPON_AMMO))
{
- self.realowner.cnt = WEP_DEVASTATOR;
+ self.realowner.cnt = WEP_DEVASTATOR.m_id;
ATTACK_FINISHED(self.realowner) = time;
self.realowner.switchweapon = w_getbestweapon(self.realowner);
}
world
);
- if(self.realowner.weapon == WEP_DEVASTATOR)
+ if(self.realowner.weapon == WEP_DEVASTATOR.m_id)
{
if(self.realowner.WEP_AMMO(DEVASTATOR) < WEP_CVAR(devastator, ammo))
if(!(self.realowner.items & IT_UNLIMITED_WEAPON_AMMO))
{
- self.realowner.cnt = WEP_DEVASTATOR;
+ self.realowner.cnt = WEP_DEVASTATOR.m_id;
ATTACK_FINISHED(self.realowner) = time;
self.realowner.switchweapon = w_getbestweapon(self.realowner);
}
self.velocity = self.velocity + v_forward * min(WEP_CVAR(devastator, speedaccel) * W_WeaponSpeedFactor() * frametime, velspeed);
// laser guided, or remote detonation
- if(self.realowner.weapon == WEP_DEVASTATOR)
+ if(self.realowner.weapon == WEP_DEVASTATOR.m_id)
{
if(self == self.realowner.lastrocket)
if(!self.realowner.rl_release)
missile.movetype = MOVETYPE_FLY;
PROJECTILE_MAKETRIGGER(missile);
- missile.projectiledeathtype = WEP_DEVASTATOR;
+ missile.projectiledeathtype = WEP_DEVASTATOR.m_id;
setsize(missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
setorigin(missile, w_shotorg - v_forward * 3); // move it back so it hits the wall at the right point
self.rl_release = 1;
if(self.BUTTON_ATCK2)
- if(self.switchweapon == WEP_DEVASTATOR)
+ if(self.switchweapon == WEP_DEVASTATOR.m_id)
{
rockfound = 0;
for(rock = world; (rock = find(rock, classname, "rocket")); ) if(rock.realowner == self)
{
#if 0
// don't switch while guiding a missile
- if(ATTACK_FINISHED(self) <= time || self.weapon != WEP_DEVASTATOR)
+ if(ATTACK_FINISHED(self) <= time || self.weapon != WEP_DEVASTATOR.m_id)
{
ammo_amount = false;
if(WEP_CVAR(devastator, reload_ammo))
{
- if(self.WEP_AMMO(DEVASTATOR) < WEP_CVAR(devastator, ammo) && self.(weapon_load[WEP_DEVASTATOR]) < WEP_CVAR(devastator, ammo))
+ if(self.WEP_AMMO(DEVASTATOR) < WEP_CVAR(devastator, ammo) && self.(weapon_load[WEP_DEVASTATOR.m_id]) < WEP_CVAR(devastator, ammo))
ammo_amount = true;
}
else if(self.WEP_AMMO(DEVASTATOR) < WEP_CVAR(devastator, ammo))
else
{
ammo_amount = self.WEP_AMMO(DEVASTATOR) >= WEP_CVAR(devastator, ammo);
- ammo_amount += self.(weapon_load[WEP_DEVASTATOR]) >= WEP_CVAR(devastator, ammo);
+ ammo_amount += self.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo);
printf("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: %s\n", self.rl_release, self.WEP_AMMO(DEVASTATOR), WEP_CVAR(devastator, ammo), (ammo_amount ? "TRUE" : "FALSE"));
return ammo_amount;
}
#else
ammo_amount = self.WEP_AMMO(DEVASTATOR) >= WEP_CVAR(devastator, ammo);
- ammo_amount += self.(weapon_load[WEP_DEVASTATOR]) >= WEP_CVAR(devastator, ammo);
+ ammo_amount += self.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo);
return ammo_amount;
#endif
}
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ ELECTRO,
/* function */ W_Electro,
.float electro_secondarytime;
void W_Electro_ExplodeCombo(void);
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_electro(void) { weapon_defaultspawnfunc(WEP_ELECTRO); }
+void spawnfunc_weapon_electro(void) { weapon_defaultspawnfunc(WEP_ELECTRO.m_id); }
void W_Electro_TriggerCombo(vector org, float rad, entity own)
{
world,
world,
WEP_CVAR(electro, combo_force),
- WEP_ELECTRO | HITTYPE_BOUNCE, // use THIS type for a combo because primary can't bounce
+ WEP_ELECTRO.m_id | HITTYPE_BOUNCE, // use THIS type for a combo because primary can't bounce
world
);
proj.nextthink = time;
proj.ltime = time + WEP_CVAR_PRI(electro, lifetime);
PROJECTILE_MAKETRIGGER(proj);
- proj.projectiledeathtype = WEP_ELECTRO;
+ proj.projectiledeathtype = WEP_ELECTRO.m_id;
setorigin(proj, w_shotorg);
proj.movetype = MOVETYPE_FLY;
proj.bot_dodgerating = WEP_CVAR_SEC(electro, damage);
proj.nextthink = time + WEP_CVAR_SEC(electro, lifetime);
PROJECTILE_MAKETRIGGER(proj);
- proj.projectiledeathtype = WEP_ELECTRO | HITTYPE_SECONDARY;
+ proj.projectiledeathtype = WEP_ELECTRO.m_id | HITTYPE_SECONDARY;
setorigin(proj, w_shotorg);
//proj.glow_size = 50;
case WR_CHECKAMMO1:
{
ammo_amount = self.WEP_AMMO(ELECTRO) >= WEP_CVAR_PRI(electro, ammo);
- ammo_amount += self.(weapon_load[WEP_ELECTRO]) >= WEP_CVAR_PRI(electro, ammo);
+ ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_PRI(electro, ammo);
return ammo_amount;
}
case WR_CHECKAMMO2:
if(WEP_CVAR(electro, combo_safeammocheck)) // true if you can fire at least one secondary blob AND one primary shot after it, otherwise false.
{
ammo_amount = self.WEP_AMMO(ELECTRO) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo);
- ammo_amount += self.(weapon_load[WEP_ELECTRO]) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo);
+ ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo);
}
else
{
ammo_amount = self.WEP_AMMO(ELECTRO) >= WEP_CVAR_SEC(electro, ammo);
- ammo_amount += self.(weapon_load[WEP_ELECTRO]) >= WEP_CVAR_SEC(electro, ammo);
+ ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo);
}
return ammo_amount;
}
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ FIREBALL,
/* function */ W_Fireball,
.vector fireball_impactvec;
.float fireball_primarytime;
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_fireball(void) { weapon_defaultspawnfunc(WEP_FIREBALL); }
+void spawnfunc_weapon_fireball(void) { weapon_defaultspawnfunc(WEP_FIREBALL.m_id); }
void W_Fireball_Explode(void)
{
dir = normalize(e.origin + e.view_ofs - self.origin);
if(accuracy_isgooddamage(self.realowner, e))
- accuracy_add(self.realowner, WEP_FIREBALL, 0, WEP_CVAR_PRI(fireball, bfgdamage) * points);
+ accuracy_add(self.realowner, WEP_FIREBALL.m_id, 0, WEP_CVAR_PRI(fireball, bfgdamage) * points);
Damage(e, self, self.realowner, WEP_CVAR_PRI(fireball, bfgdamage) * points, self.projectiledeathtype | HITTYPE_BOUNCE | HITTYPE_SPLASH, e.origin + e.view_ofs, WEP_CVAR_PRI(fireball, bfgforce) * dir);
Send_Effect("fireball_bfgdamage", e.origin, -1 * dir, 1);
proj.takedamage = DAMAGE_YES;
proj.damageforcescale = WEP_CVAR_PRI(fireball, damageforcescale);
PROJECTILE_MAKETRIGGER(proj);
- proj.projectiledeathtype = WEP_FIREBALL;
+ proj.projectiledeathtype = WEP_FIREBALL.m_id;
setorigin(proj, w_shotorg);
proj.movetype = MOVETYPE_FLY;
proj.bot_dodge = true;
proj.bot_dodgerating = WEP_CVAR_SEC(fireball, damage);
proj.movetype = MOVETYPE_BOUNCE;
- proj.projectiledeathtype = WEP_FIREBALL | HITTYPE_SECONDARY;
+ proj.projectiledeathtype = WEP_FIREBALL.m_id | HITTYPE_SECONDARY;
proj.touch = W_Fireball_Firemine_Touch;
PROJECTILE_MAKETRIGGER(proj);
setsize(proj, '-4 -4 -4', '4 4 4');
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ HAGAR,
/* function */ W_Hagar,
#ifdef SVQC
HAGAR_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_hagar(void) { weapon_defaultspawnfunc(WEP_HAGAR); }
+void spawnfunc_weapon_hagar(void) { weapon_defaultspawnfunc(WEP_HAGAR.m_id); }
// NO bounce protection, as bounces are limited!
missile.think = adaptor_think2use_hittype_splash;
missile.nextthink = time + WEP_CVAR_PRI(hagar, lifetime);
PROJECTILE_MAKETRIGGER(missile);
- missile.projectiledeathtype = WEP_HAGAR;
+ missile.projectiledeathtype = WEP_HAGAR.m_id;
setorigin(missile, w_shotorg);
setsize(missile, '0 0 0', '0 0 0');
missile.think = adaptor_think2use_hittype_splash;
missile.nextthink = time + WEP_CVAR_SEC(hagar, lifetime_min) + random() * WEP_CVAR_SEC(hagar, lifetime_rand);
PROJECTILE_MAKETRIGGER(missile);
- missile.projectiledeathtype = WEP_HAGAR | HITTYPE_SECONDARY;
+ missile.projectiledeathtype = WEP_HAGAR.m_id | HITTYPE_SECONDARY;
setorigin(missile, w_shotorg);
setsize(missile, '0 0 0', '0 0 0');
missile.think = adaptor_think2use_hittype_splash;
missile.nextthink = time + WEP_CVAR_SEC(hagar, lifetime_min) + random() * WEP_CVAR_SEC(hagar, lifetime_rand);
PROJECTILE_MAKETRIGGER(missile);
- missile.projectiledeathtype = WEP_HAGAR | HITTYPE_SECONDARY;
+ missile.projectiledeathtype = WEP_HAGAR.m_id | HITTYPE_SECONDARY;
setorigin(missile, w_shotorg);
setsize(missile, '0 0 0', '0 0 0');
missile.movetype = MOVETYPE_FLY;
if(self.items & IT_UNLIMITED_WEAPON_AMMO)
enough_ammo = true;
else if(autocvar_g_balance_hagar_reload_ammo)
- enough_ammo = self.(weapon_load[WEP_HAGAR]) >= WEP_CVAR_SEC(hagar, ammo);
+ enough_ammo = self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_SEC(hagar, ammo);
else
enough_ammo = self.WEP_AMMO(HAGAR) >= WEP_CVAR_SEC(hagar, ammo);
case WR_CHECKAMMO1:
{
ammo_amount = self.WEP_AMMO(HAGAR) >= WEP_CVAR_PRI(hagar, ammo);
- ammo_amount += self.(weapon_load[WEP_HAGAR]) >= WEP_CVAR_PRI(hagar, ammo);
+ ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_PRI(hagar, ammo);
return ammo_amount;
}
case WR_CHECKAMMO2:
{
ammo_amount = self.WEP_AMMO(HAGAR) >= WEP_CVAR_SEC(hagar, ammo);
- ammo_amount += self.(weapon_load[WEP_HAGAR]) >= WEP_CVAR_SEC(hagar, ammo);
+ ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_SEC(hagar, ammo);
return ammo_amount;
}
case WR_CONFIG:
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ HLAC,
/* function */ W_HLAC,
#ifdef SVQC
HLAC_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_hlac(void) { weapon_defaultspawnfunc(WEP_HLAC); }
+void spawnfunc_weapon_hlac(void) { weapon_defaultspawnfunc(WEP_HLAC.m_id); }
void W_HLAC_Touch(void)
{
missile.nextthink = time + WEP_CVAR_PRI(hlac, lifetime);
missile.flags = FL_PROJECTILE;
- missile.projectiledeathtype = WEP_HLAC;
+ missile.projectiledeathtype = WEP_HLAC.m_id;
CSQCProjectile(missile, true, PROJECTILE_HLAC, true);
missile.flags = FL_PROJECTILE;
missile.missile_flags = MIF_SPLASH;
- missile.projectiledeathtype = WEP_HLAC | HITTYPE_SECONDARY;
+ missile.projectiledeathtype = WEP_HLAC.m_id | HITTYPE_SECONDARY;
CSQCProjectile(missile, true, PROJECTILE_HLAC, true);
case WR_CHECKAMMO1:
{
ammo_amount = self.WEP_AMMO(HLAC) >= WEP_CVAR_PRI(hlac, ammo);
- ammo_amount += self.(weapon_load[WEP_HLAC]) >= WEP_CVAR_PRI(hlac, ammo);
+ ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_PRI(hlac, ammo);
return ammo_amount;
}
case WR_CHECKAMMO2:
{
ammo_amount = self.WEP_AMMO(HLAC) >= WEP_CVAR_SEC(hlac, ammo);
- ammo_amount += self.(weapon_load[WEP_HLAC]) >= WEP_CVAR_SEC(hlac, ammo);
+ ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_SEC(hlac, ammo);
return ammo_amount;
}
case WR_CONFIG:
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ HMG,
/* function */ W_HeavyMachineGun,
#ifdef SVQC
HMG_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_hmg() { weapon_defaultspawnfunc(WEP_HMG); }
+void spawnfunc_weapon_hmg() { weapon_defaultspawnfunc(WEP_HMG.m_id); }
void W_HeavyMachineGun_Attack_Auto()
{
}
float hmg_spread = bound(WEP_CVAR(hmg, spread_min), WEP_CVAR(hmg, spread_min) + (WEP_CVAR(hmg, spread_add) * self.misc_bulletcounter), WEP_CVAR(hmg, spread_max));
- fireBullet(w_shotorg, w_shotdir, hmg_spread, WEP_CVAR(hmg, solidpenetration), WEP_CVAR(hmg, damage), WEP_CVAR(hmg, force), WEP_HMG, 0);
+ fireBullet(w_shotorg, w_shotdir, hmg_spread, WEP_CVAR(hmg, solidpenetration), WEP_CVAR(hmg, damage), WEP_CVAR(hmg, force), WEP_HMG.m_id, 0);
self.misc_bulletcounter = self.misc_bulletcounter + 1;
ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo);
if(autocvar_g_balance_hmg_reload_ammo)
- ammo_amount += self.(weapon_load[WEP_HMG]) >= WEP_CVAR(hmg, ammo);
+ ammo_amount += self.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo);
return ammo_amount;
}
ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo);
if(autocvar_g_balance_hmg_reload_ammo)
- ammo_amount += self.(weapon_load[WEP_HMG]) >= WEP_CVAR(hmg, ammo);
+ ammo_amount += self.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo);
return ammo_amount;
}
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ HOOK,
/* function */ W_Hook,
.float hook_time_hooked;
.float hook_time_fueldecrease;
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
void spawnfunc_weapon_hook(void)
remove(self);
return;
}
- weapon_defaultspawnfunc(WEP_HOOK);
+ weapon_defaultspawnfunc(WEP_HOOK.m_id);
}
void W_Hook_ExplodeThink(void)
gren.bot_dodgerating = WEP_CVAR_SEC(hook, damage);
gren.movetype = MOVETYPE_TOSS;
PROJECTILE_MAKETRIGGER(gren);
- gren.projectiledeathtype = WEP_HOOK | HITTYPE_SECONDARY;
+ gren.projectiledeathtype = WEP_HOOK.m_id | HITTYPE_SECONDARY;
setorigin(gren, w_shotorg);
setsize(gren, '0 0 0', '0 0 0');
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ MACHINEGUN,
/* function */ W_MachineGun,
#ifdef SVQC
MACHINEGUN_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
void spawnfunc_weapon_machinegun(void)
if(autocvar_sv_q3acompat_machineshotgunswap)
if(self.classname != "droppedweapon")
{
- weapon_defaultspawnfunc(WEP_SHOCKWAVE);
+ weapon_defaultspawnfunc(WEP_SHOCKWAVE.m_id);
return;
}
- weapon_defaultspawnfunc(WEP_MACHINEGUN);
+ weapon_defaultspawnfunc(WEP_MACHINEGUN.m_id);
}
void spawnfunc_weapon_uzi(void) { spawnfunc_weapon_machinegun(); }
return;
}
self.misc_bulletcounter = self.misc_bulletcounter + 1;
- W_MachineGun_Attack(WEP_MACHINEGUN);
+ W_MachineGun_Attack(WEP_MACHINEGUN.m_id);
weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame);
}
else
}
machinegun_spread = bound(WEP_CVAR(machinegun, spread_min), WEP_CVAR(machinegun, spread_min) + (WEP_CVAR(machinegun, spread_add) * self.misc_bulletcounter), WEP_CVAR(machinegun, spread_max));
- fireBullet(w_shotorg, w_shotdir, machinegun_spread, WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), WEP_MACHINEGUN, 0);
+ fireBullet(w_shotorg, w_shotdir, machinegun_spread, WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), WEP_MACHINEGUN.m_id, 0);
self.misc_bulletcounter = self.misc_bulletcounter + 1;
self.punchangle_y = random() - 0.5;
}
- fireBullet(w_shotorg, w_shotdir, WEP_CVAR(machinegun, burst_speed), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), WEP_MACHINEGUN, 0);
+ fireBullet(w_shotorg, w_shotdir, WEP_CVAR(machinegun, burst_speed), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), WEP_MACHINEGUN.m_id, 0);
Send_Effect("uzi_muzzleflash", w_shotorg, w_shotdir * 1000, 1);
if(weapon_prepareattack(0, 0))
{
self.misc_bulletcounter = 1;
- W_MachineGun_Attack(WEP_MACHINEGUN); // sets attack_finished
+ W_MachineGun_Attack(WEP_MACHINEGUN.m_id); // sets attack_finished
weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame);
}
if(weapon_prepareattack(1, 0))
{
self.misc_bulletcounter = 1;
- W_MachineGun_Attack(WEP_MACHINEGUN | HITTYPE_SECONDARY); // sets attack_finished
+ W_MachineGun_Attack(WEP_MACHINEGUN.m_id | HITTYPE_SECONDARY); // sets attack_finished
weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(machinegun, first_refire), w_ready);
}
}
if(WEP_CVAR(machinegun, reload_ammo))
{
if(WEP_CVAR(machinegun, mode) == 1)
- ammo_amount += self.(weapon_load[WEP_MACHINEGUN]) >= WEP_CVAR(machinegun, sustained_ammo);
+ ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, sustained_ammo);
else
- ammo_amount += self.(weapon_load[WEP_MACHINEGUN]) >= WEP_CVAR(machinegun, first_ammo);
+ ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo);
}
return ammo_amount;
}
if(WEP_CVAR(machinegun, reload_ammo))
{
if(WEP_CVAR(machinegun, mode) == 1)
- ammo_amount += self.(weapon_load[WEP_MACHINEGUN]) >= WEP_CVAR(machinegun, burst_ammo);
+ ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, burst_ammo);
else
- ammo_amount += self.(weapon_load[WEP_MACHINEGUN]) >= WEP_CVAR(machinegun, first_ammo);
+ ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo);
}
return ammo_amount;
}
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ MINE_LAYER,
/* function */ W_MineLayer,
.float mine_time;
.vector mine_orientation;
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_minelayer(void) { weapon_defaultspawnfunc(WEP_MINE_LAYER); }
+void spawnfunc_weapon_minelayer(void) { weapon_defaultspawnfunc(WEP_MINE_LAYER.m_id); }
void W_MineLayer_Stick(entity to)
{
RadiusDamage(self, self.realowner, WEP_CVAR(minelayer, damage), WEP_CVAR(minelayer, edgedamage), WEP_CVAR(minelayer, radius), world, world, WEP_CVAR(minelayer, force), self.projectiledeathtype, other);
- if(self.realowner.weapon == WEP_MINE_LAYER)
+ if(self.realowner.weapon == WEP_MINE_LAYER.m_id)
{
entity oldself;
oldself = self;
self = self.realowner;
- if(!WEP_ACTION(WEP_MINE_LAYER, WR_CHECKAMMO1))
+ if(!WEP_ACTION(WEP_MINE_LAYER.m_id, WR_CHECKAMMO1))
{
- self.cnt = WEP_MINE_LAYER;
+ self.cnt = WEP_MINE_LAYER.m_id;
ATTACK_FINISHED(self) = time;
self.switchweapon = w_getbestweapon(self);
}
RadiusDamage(self, self.realowner, WEP_CVAR(minelayer, remote_damage), WEP_CVAR(minelayer, remote_edgedamage), WEP_CVAR(minelayer, remote_radius), world, world, WEP_CVAR(minelayer, remote_force), self.projectiledeathtype | HITTYPE_BOUNCE, world);
- if(self.realowner.weapon == WEP_MINE_LAYER)
+ if(self.realowner.weapon == WEP_MINE_LAYER.m_id)
{
entity oldself;
oldself = self;
self = self.realowner;
- if(!WEP_ACTION(WEP_MINE_LAYER, WR_CHECKAMMO1))
+ if(!WEP_ACTION(WEP_MINE_LAYER.m_id, WR_CHECKAMMO1))
{
- self.cnt = WEP_MINE_LAYER;
+ self.cnt = WEP_MINE_LAYER.m_id;
ATTACK_FINISHED(self) = time;
self.switchweapon = w_getbestweapon(self);
}
}
// remote detonation
- if(self.realowner.weapon == WEP_MINE_LAYER)
+ if(self.realowner.weapon == WEP_MINE_LAYER.m_id)
if(self.realowner.deadflag == DEAD_NO)
if(self.minelayer_detonate)
W_MineLayer_RemoteExplode();
mine.movetype = MOVETYPE_TOSS;
PROJECTILE_MAKETRIGGER(mine);
- mine.projectiledeathtype = WEP_MINE_LAYER;
+ mine.projectiledeathtype = WEP_MINE_LAYER.m_id;
setsize(mine, '-4 -4 -4', '4 4 4'); // give it some size so it can be shot
setorigin(mine, w_shotorg - v_forward * 4); // move it back so it hits the wall at the right point
case WR_CHECKAMMO1:
{
// don't switch while placing a mine
- if(ATTACK_FINISHED(self) <= time || self.weapon != WEP_MINE_LAYER)
+ if(ATTACK_FINISHED(self) <= time || self.weapon != WEP_MINE_LAYER.m_id)
{
ammo_amount = self.WEP_AMMO(MINE_LAYER) >= WEP_CVAR(minelayer, ammo);
- ammo_amount += self.(weapon_load[WEP_MINE_LAYER]) >= WEP_CVAR(minelayer, ammo);
+ ammo_amount += self.(weapon_load[WEP_MINE_LAYER.m_id]) >= WEP_CVAR(minelayer, ammo);
return ammo_amount;
}
return true;
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ MORTAR,
/* function */ W_Mortar,
.float gl_detonate_later;
.float gl_bouncecnt;
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_mortar(void) { weapon_defaultspawnfunc(WEP_MORTAR); }
+void spawnfunc_weapon_mortar(void) { weapon_defaultspawnfunc(WEP_MORTAR.m_id); }
void spawnfunc_weapon_grenadelauncher(void) { spawnfunc_weapon_mortar(); }
void W_Mortar_Grenade_Explode(void)
gren.bouncefactor = WEP_CVAR(mortar, bouncefactor);
gren.bouncestop = WEP_CVAR(mortar, bouncestop);
PROJECTILE_MAKETRIGGER(gren);
- gren.projectiledeathtype = WEP_MORTAR;
+ gren.projectiledeathtype = WEP_MORTAR.m_id;
setorigin(gren, w_shotorg);
setsize(gren, '-3 -3 -3', '3 3 3');
gren.bouncefactor = WEP_CVAR(mortar, bouncefactor);
gren.bouncestop = WEP_CVAR(mortar, bouncestop);
PROJECTILE_MAKETRIGGER(gren);
- gren.projectiledeathtype = WEP_MORTAR | HITTYPE_SECONDARY;
+ gren.projectiledeathtype = WEP_MORTAR.m_id | HITTYPE_SECONDARY;
setorigin(gren, w_shotorg);
setsize(gren, '-3 -3 -3', '3 3 3');
case WR_CHECKAMMO1:
{
ammo_amount = self.WEP_AMMO(MORTAR) >= WEP_CVAR_PRI(mortar, ammo);
- ammo_amount += self.(weapon_load[WEP_MORTAR]) >= WEP_CVAR_PRI(mortar, ammo);
+ ammo_amount += self.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_PRI(mortar, ammo);
return ammo_amount;
}
case WR_CHECKAMMO2:
{
ammo_amount = self.WEP_AMMO(MORTAR) >= WEP_CVAR_SEC(mortar, ammo);
- ammo_amount += self.(weapon_load[WEP_MORTAR]) >= WEP_CVAR_SEC(mortar, ammo);
+ ammo_amount += self.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_SEC(mortar, ammo);
return ammo_amount;
}
case WR_CONFIG:
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ PORTO,
/* function */ W_Porto,
.float porto_v_angle_held;
.vector right_vector;
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
#include "../triggers/trigger/jumppads.qh"
-void spawnfunc_weapon_porto(void) { weapon_defaultspawnfunc(WEP_PORTO); }
+void spawnfunc_weapon_porto(void) { weapon_defaultspawnfunc(WEP_PORTO.m_id); }
void W_Porto_Success(void)
{
tracetoss(self, self);
if(vlen(trace_endpos - self.realowner.origin) < 128)
{
- W_ThrowNewWeapon(self.realowner, WEP_PORTO, 0, self.origin, self.velocity);
+ W_ThrowNewWeapon(self.realowner, WEP_PORTO.m_id, 0, self.origin, self.velocity);
Send_Notification(NOTIF_ONE, self.realowner, MSG_CENTER, CENTER_PORTO_FAILED);
}
}
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ RIFLE,
/* function */ W_Rifle,
RIFLE_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
.float rifle_accumulator;
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_rifle(void) { weapon_defaultspawnfunc(WEP_RIFLE); }
+void spawnfunc_weapon_rifle(void) { weapon_defaultspawnfunc(WEP_RIFLE.m_id); }
void spawnfunc_weapon_campingrifle(void) { spawnfunc_weapon_rifle(); }
void spawnfunc_weapon_sniperrifle(void) { spawnfunc_weapon_rifle(); }
void W_Rifle_Attack(void)
{
- W_Rifle_FireBullet(WEP_CVAR_PRI(rifle, spread), WEP_CVAR_PRI(rifle, damage), WEP_CVAR_PRI(rifle, force), WEP_CVAR_PRI(rifle, solidpenetration), WEP_CVAR_PRI(rifle, ammo), WEP_RIFLE, WEP_CVAR_PRI(rifle, tracer), WEP_CVAR_PRI(rifle, shots), "weapons/campingrifle_fire.wav");
+ W_Rifle_FireBullet(WEP_CVAR_PRI(rifle, spread), WEP_CVAR_PRI(rifle, damage), WEP_CVAR_PRI(rifle, force), WEP_CVAR_PRI(rifle, solidpenetration), WEP_CVAR_PRI(rifle, ammo), WEP_RIFLE.m_id, WEP_CVAR_PRI(rifle, tracer), WEP_CVAR_PRI(rifle, shots), "weapons/campingrifle_fire.wav");
}
void W_Rifle_Attack2(void)
{
- W_Rifle_FireBullet(WEP_CVAR_SEC(rifle, spread), WEP_CVAR_SEC(rifle, damage), WEP_CVAR_SEC(rifle, force), WEP_CVAR_SEC(rifle, solidpenetration), WEP_CVAR_SEC(rifle, ammo), WEP_RIFLE | HITTYPE_SECONDARY, WEP_CVAR_SEC(rifle, tracer), WEP_CVAR_SEC(rifle, shots), "weapons/campingrifle_fire2.wav");
+ W_Rifle_FireBullet(WEP_CVAR_SEC(rifle, spread), WEP_CVAR_SEC(rifle, damage), WEP_CVAR_SEC(rifle, force), WEP_CVAR_SEC(rifle, solidpenetration), WEP_CVAR_SEC(rifle, ammo), WEP_RIFLE.m_id | HITTYPE_SECONDARY, WEP_CVAR_SEC(rifle, tracer), WEP_CVAR_SEC(rifle, shots), "weapons/campingrifle_fire2.wav");
}
.void(void) rifle_bullethail_attackfunc;
case WR_CHECKAMMO1:
{
ammo_amount = self.WEP_AMMO(RIFLE) >= WEP_CVAR_PRI(rifle, ammo);
- ammo_amount += self.(weapon_load[WEP_RIFLE]) >= WEP_CVAR_PRI(rifle, ammo);
+ ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_PRI(rifle, ammo);
return ammo_amount;
}
case WR_CHECKAMMO2:
{
ammo_amount = self.WEP_AMMO(RIFLE) >= WEP_CVAR_SEC(rifle, ammo);
- ammo_amount += self.(weapon_load[WEP_RIFLE]) >= WEP_CVAR_SEC(rifle, ammo);
+ ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_SEC(rifle, ammo);
return ammo_amount;
}
case WR_CONFIG:
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ RPC,
/* function */ W_RocketPropelledChainsaw,
#ifdef SVQC
RPC_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_rpc() { weapon_defaultspawnfunc(WEP_RPC); }
+void spawnfunc_weapon_rpc() { weapon_defaultspawnfunc(WEP_RPC.m_id); }
void W_RocketPropelledChainsaw_Explode()
{
missile.damagedbycontents = true;
missile.movetype = MOVETYPE_FLY;
- missile.projectiledeathtype = WEP_RPC;
+ missile.projectiledeathtype = WEP_RPC.m_id;
setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
setorigin (missile, w_shotorg - v_forward * 3); // move it back so it hits the wall at the right point
case WR_CHECKAMMO1:
{
ammo_amount = self.WEP_AMMO(RPC) >= WEP_CVAR(rpc, ammo);
- ammo_amount += self.(weapon_load[WEP_RPC]) >= WEP_CVAR(rpc, ammo);
+ ammo_amount += self.(weapon_load[WEP_RPC.m_id]) >= WEP_CVAR(rpc, ammo);
return ammo_amount;
}
case WR_CHECKAMMO2:
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ SEEKER,
/* function */ W_Seeker,
.entity tag_target, wps_tag_tracker;
.float tag_time;
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_seeker(void) { weapon_defaultspawnfunc(WEP_SEEKER); }
+void spawnfunc_weapon_seeker(void) { weapon_defaultspawnfunc(WEP_SEEKER.m_id); }
// ============================
// Begin: Missile functions, these are general functions to be manipulated by other code
//missile.think = W_Seeker_Missile_Animate; // csqc projectiles.
if(missile.enemy != world)
- missile.projectiledeathtype = WEP_SEEKER | HITTYPE_SECONDARY;
+ missile.projectiledeathtype = WEP_SEEKER.m_id | HITTYPE_SECONDARY;
else
- missile.projectiledeathtype = WEP_SEEKER;
+ missile.projectiledeathtype = WEP_SEEKER.m_id;
setorigin(missile, w_shotorg);
missile.nextthink = time + WEP_CVAR(seeker, flac_lifetime) + WEP_CVAR(seeker, flac_lifetime_rand);
missile.solid = SOLID_BBOX;
missile.movetype = MOVETYPE_FLY;
- missile.projectiledeathtype = WEP_SEEKER;
- missile.projectiledeathtype = WEP_SEEKER | HITTYPE_SECONDARY;
+ missile.projectiledeathtype = WEP_SEEKER.m_id;
+ missile.projectiledeathtype = WEP_SEEKER.m_id | HITTYPE_SECONDARY;
missile.flags = FL_PROJECTILE;
missile.missile_flags = MIF_SPLASH;
entity oldself,oldenemy;
self.cnt = self.cnt - 1;
- if((!(self.realowner.items & IT_UNLIMITED_AMMO) && self.realowner.WEP_AMMO(SEEKER) < WEP_CVAR(seeker, missile_ammo)) || (self.cnt <= -1) || (self.realowner.deadflag != DEAD_NO) || (self.realowner.switchweapon != WEP_SEEKER))
+ if((!(self.realowner.items & IT_UNLIMITED_AMMO) && self.realowner.WEP_AMMO(SEEKER) < WEP_CVAR(seeker, missile_ammo)) || (self.cnt <= -1) || (self.realowner.deadflag != DEAD_NO) || (self.realowner.switchweapon != WEP_SEEKER.m_id))
{
remove(self);
return;
void W_Seeker_Tracker_Think(void)
{
// commit suicide if: You die OR target dies OR you switch away from the seeker OR commit suicide if lifetime is up
- if((self.realowner.deadflag != DEAD_NO) || (self.tag_target.deadflag != DEAD_NO) || (self.realowner.switchweapon != WEP_SEEKER)
+ if((self.realowner.deadflag != DEAD_NO) || (self.tag_target.deadflag != DEAD_NO) || (self.realowner.switchweapon != WEP_SEEKER.m_id)
|| (time > self.tag_time + WEP_CVAR(seeker, tag_tracker_lifetime)))
{
if(self)
{
//if(other==self.realowner)
// return;
- Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER | HITTYPE_BOUNCE, other.species, self);
+ Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE, other.species, self);
remove(self);
}
te_knightspike(org2);
self.event_damage = func_null;
- Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER | HITTYPE_BOUNCE | HITTYPE_SECONDARY, other.species, self);
+ Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE | HITTYPE_SECONDARY, other.species, self);
if(other.takedamage == DAMAGE_AIM && other.deadflag == DEAD_NO)
{
if(WEP_CVAR(seeker, type) == 1)
{
ammo_amount = self.WEP_AMMO(SEEKER) >= WEP_CVAR(seeker, missile_ammo);
- ammo_amount += self.(weapon_load[WEP_SEEKER]) >= WEP_CVAR(seeker, missile_ammo);
+ ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, missile_ammo);
}
else
{
ammo_amount = self.WEP_AMMO(SEEKER) >= WEP_CVAR(seeker, tag_ammo);
- ammo_amount += self.(weapon_load[WEP_SEEKER]) >= WEP_CVAR(seeker, tag_ammo);
+ ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo);
}
return ammo_amount;
}
if(WEP_CVAR(seeker, type) == 1)
{
ammo_amount = self.WEP_AMMO(SEEKER) >= WEP_CVAR(seeker, tag_ammo);
- ammo_amount += self.(weapon_load[WEP_SEEKER]) >= WEP_CVAR(seeker, tag_ammo);
+ ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo);
}
else
{
ammo_amount = self.WEP_AMMO(SEEKER) >= WEP_CVAR(seeker, flac_ammo);
- ammo_amount += self.(weapon_load[WEP_SEEKER]) >= WEP_CVAR(seeker, flac_ammo);
+ ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, flac_ammo);
}
return ammo_amount;
}
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ SHOCKWAVE,
/* function */ W_Shockwave,
.float sw_spread_min;
.float sw_time;
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
void spawnfunc_weapon_shockwave(void)
{
if(autocvar_sv_q3acompat_machineshotgunswap)
if(self.classname != "droppedweapon")
{
- weapon_defaultspawnfunc(WEP_MACHINEGUN);
+ weapon_defaultspawnfunc(WEP_MACHINEGUN.m_id);
return;
}
- weapon_defaultspawnfunc(WEP_SHOCKWAVE);
+ weapon_defaultspawnfunc(WEP_SHOCKWAVE.m_id);
}
const float MAX_SHOCKWAVE_HITS = 10;
self.realowner,
self.realowner,
swing_damage,
- (WEP_SHOCKWAVE | HITTYPE_SECONDARY),
+ (WEP_SHOCKWAVE.m_id | HITTYPE_SECONDARY),
(self.realowner.origin + self.realowner.view_ofs),
(v_forward * WEP_CVAR(shockwave, melee_force))
);
// handle accuracy
if(accuracy_isgooddamage(self.realowner, target_victim))
- { accuracy_add(self.realowner, WEP_SHOCKWAVE, 0, swing_damage); }
+ { accuracy_add(self.realowner, WEP_SHOCKWAVE.m_id, 0, swing_damage); }
#ifdef DEBUG_SHOCKWAVE
print(sprintf(
WEP_CVAR(shockwave, blast_splash_edgedamage),
WEP_CVAR(shockwave, blast_splash_radius),
w_shotdir * WEP_CVAR(shockwave, blast_splash_force),
- WEP_SHOCKWAVE,
+ WEP_SHOCKWAVE.m_id,
0,
self
);
self,
self,
final_damage,
- WEP_SHOCKWAVE,
+ WEP_SHOCKWAVE.m_id,
head.origin,
final_force
);
self,
self,
final_damage,
- WEP_SHOCKWAVE,
+ WEP_SHOCKWAVE.m_id,
head.origin,
final_force
);
if(accuracy_isgooddamage(self.realowner, head))
{
print("wtf\n");
- accuracy_add(self.realowner, WEP_SHOCKWAVE, 0, final_damage);
+ accuracy_add(self.realowner, WEP_SHOCKWAVE.m_id, 0, final_damage);
}
#ifdef DEBUG_SHOCKWAVE
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ SHOTGUN,
/* function */ W_Shotgun,
#ifdef SVQC
SHOTGUN_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_shotgun(void) { weapon_defaultspawnfunc(WEP_SHOTGUN); }
+void spawnfunc_weapon_shotgun(void) { weapon_defaultspawnfunc(WEP_SHOTGUN.m_id); }
void W_Shotgun_Attack(float isprimary)
{
W_SetupShot(self, true, 5, "weapons/shotgun_fire.wav", ((isprimary) ? CH_WEAPON_A : CH_WEAPON_SINGLE), WEP_CVAR_PRI(shotgun, damage) * WEP_CVAR_PRI(shotgun, bullets));
for(sc = 0;sc < WEP_CVAR_PRI(shotgun, bullets);sc = sc + 1)
- fireBullet(w_shotorg, w_shotdir, WEP_CVAR_PRI(shotgun, spread), WEP_CVAR_PRI(shotgun, solidpenetration), WEP_CVAR_PRI(shotgun, damage), WEP_CVAR_PRI(shotgun, force), WEP_SHOTGUN, 0);
+ fireBullet(w_shotorg, w_shotdir, WEP_CVAR_PRI(shotgun, spread), WEP_CVAR_PRI(shotgun, solidpenetration), WEP_CVAR_PRI(shotgun, damage), WEP_CVAR_PRI(shotgun, force), WEP_SHOTGUN.m_id, 0);
Send_Effect("shotgun_muzzleflash", w_shotorg, w_shotdir * 1000, WEP_CVAR_PRI(shotgun, ammo));
//print(strcat(self.realowner.netname, " hitting ", target_victim.netname, " with ", strcat(ftos(swing_damage), " damage (factor: ", ftos(swing_factor), ") at "), ftos(time), " seconds.\n"));
Damage(target_victim, self.realowner, self.realowner,
- swing_damage, WEP_SHOTGUN | HITTYPE_SECONDARY,
+ swing_damage, WEP_SHOTGUN.m_id | HITTYPE_SECONDARY,
self.realowner.origin + self.realowner.view_ofs,
v_forward * WEP_CVAR_SEC(shotgun, force));
- if(accuracy_isgooddamage(self.realowner, target_victim)) { accuracy_add(self.realowner, WEP_SHOTGUN, 0, swing_damage); }
+ if(accuracy_isgooddamage(self.realowner, target_victim)) { accuracy_add(self.realowner, WEP_SHOTGUN.m_id, 0, swing_damage); }
// draw large red flash for debugging
//te_customflash(targpos, 200, 2, '15 0 0');
case WR_CHECKAMMO1:
{
ammo_amount = self.WEP_AMMO(SHOTGUN) >= WEP_CVAR_PRI(shotgun, ammo);
- ammo_amount += self.(weapon_load[WEP_SHOTGUN]) >= WEP_CVAR_PRI(shotgun, ammo);
+ ammo_amount += self.(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo);
return ammo_amount;
}
case WR_CHECKAMMO2:
case 2: // secondary triple shot
{
ammo_amount = self.WEP_AMMO(SHOTGUN) >= WEP_CVAR_PRI(shotgun, ammo);
- ammo_amount += self.(weapon_load[WEP_SHOTGUN]) >= WEP_CVAR_PRI(shotgun, ammo);
+ ammo_amount += self.(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo);
return ammo_amount;
}
default: return false; // secondary unavailable
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ TUBA,
/* function */ W_Tuba,
.float tuba_lastnotes_cnt; // over
.vector tuba_lastnotes[MAX_TUBANOTES];
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_tuba(void) { weapon_defaultspawnfunc(WEP_TUBA); }
+void spawnfunc_weapon_tuba(void) { weapon_defaultspawnfunc(WEP_TUBA.m_id); }
bool W_Tuba_HasPlayed(entity pl, string melody, int instrument, bool ignorepitch, float mintempo, float maxtempo)
{
self.tuba_note.teleport_time = time + WEP_CVAR(tuba, refire) * 2 * W_WeaponRateFactor(); // so it can get prolonged safely
//sound(self, c, TUBA_NOTE(n), bound(0, VOL_BASE * cvar("g_balance_tuba_volume"), 1), autocvar_g_balance_tuba_attenuation);
- RadiusDamage(self, self, WEP_CVAR(tuba, damage), WEP_CVAR(tuba, edgedamage), WEP_CVAR(tuba, radius), world, world, WEP_CVAR(tuba, force), hittype | WEP_TUBA, world);
+ RadiusDamage(self, self, WEP_CVAR(tuba, damage), WEP_CVAR(tuba, edgedamage), WEP_CVAR(tuba, radius), world, world, WEP_CVAR(tuba, force), hittype | WEP_TUBA.m_id, world);
o = gettaginfo(self.exteriorweaponentity, 0);
if(time > self.tuba_smoketime)
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ VAPORIZER,
/* function */ W_Vaporizer,
.float vaporizer_lasthit;
.float jump_interval;
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_vaporizer(void) { weapon_defaultspawnfunc(WEP_VAPORIZER); }
+void spawnfunc_weapon_vaporizer(void) { weapon_defaultspawnfunc(WEP_VAPORIZER.m_id); }
void spawnfunc_weapon_minstanex(void) { spawnfunc_weapon_vaporizer(); }
void W_Vaporizer_Attack(void)
yoda = 0;
damage_goodhits = 0;
- FireRailgunBullet(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, 10000, 800, 0, 0, 0, 0, WEP_VAPORIZER);
+ FireRailgunBullet(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, 10000, 800, 0, 0, 0, 0, WEP_VAPORIZER.m_id);
if(yoda && flying)
Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA);
// ugly instagib hack to reuse the fire mode of the laser
int oldwep = self.weapon; // we can't avoid this hack
- self.weapon = WEP_BLASTER;
+ self.weapon = WEP_BLASTER.m_id;
W_Blaster_Attack(
- WEP_BLASTER | HITTYPE_SECONDARY,
+ WEP_BLASTER.m_id | HITTYPE_SECONDARY,
WEP_CVAR_SEC(vaporizer, shotangle),
WEP_CVAR_SEC(vaporizer, damage),
WEP_CVAR_SEC(vaporizer, edgedamage),
case WR_CHECKAMMO1:
{
ammo_amount = self.WEP_AMMO(VAPORIZER) >= vaporizer_ammo;
- ammo_amount += self.(weapon_load[WEP_VAPORIZER]) >= vaporizer_ammo;
+ ammo_amount += self.(weapon_load[WEP_VAPORIZER.m_id]) >= vaporizer_ammo;
return ammo_amount;
}
case WR_CHECKAMMO2:
if(!WEP_CVAR_SEC(vaporizer, ammo))
return true;
ammo_amount = self.WEP_AMMO(VAPORIZER) >= WEP_CVAR_SEC(vaporizer, ammo);
- ammo_amount += self.(weapon_load[WEP_VAPORIZER]) >= WEP_CVAR_SEC(vaporizer, ammo);
+ ammo_amount += self.(weapon_load[WEP_VAPORIZER.m_id]) >= WEP_CVAR_SEC(vaporizer, ammo);
return ammo_amount;
}
case WR_CONFIG:
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
REGISTER_WEAPON(
/* WEP_##id */ VORTEX,
/* function */ W_Vortex,
.float vortex_lasthit;
#endif
-#else
+#endif
+#ifdef IMPLEMENTATION
#ifdef SVQC
-void spawnfunc_weapon_vortex(void) { weapon_defaultspawnfunc(WEP_VORTEX); }
+void spawnfunc_weapon_vortex(void) { weapon_defaultspawnfunc(WEP_VORTEX.m_id); }
void spawnfunc_weapon_nex(void) { spawnfunc_weapon_vortex(); }
void SendCSQCVortexBeamParticle(float charge) {
yoda = 0;
damage_goodhits = 0;
- FireRailgunBullet(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, WEP_VORTEX);
+ FireRailgunBullet(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, WEP_VORTEX.m_id);
if(yoda && flying)
Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA);
{
self.clip_load = max(WEP_CVAR_SEC(vortex, ammo), self.clip_load - WEP_CVAR_SEC(vortex, ammo) * dt);
}
- self.(weapon_load[WEP_VORTEX]) = self.clip_load;
+ self.(weapon_load[WEP_VORTEX.m_id]) = self.clip_load;
}
else
{
case WR_CHECKAMMO1:
{
ammo_amount = self.WEP_AMMO(VORTEX) >= WEP_CVAR_PRI(vortex, ammo);
- ammo_amount += (autocvar_g_balance_vortex_reload_ammo && self.(weapon_load[WEP_VORTEX]) >= WEP_CVAR_PRI(vortex, ammo));
+ ammo_amount += (autocvar_g_balance_vortex_reload_ammo && self.(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_PRI(vortex, ammo));
return ammo_amount;
}
case WR_CHECKAMMO2:
{
// don't allow charging if we don't have enough ammo
ammo_amount = self.WEP_AMMO(VORTEX) >= WEP_CVAR_SEC(vortex, ammo);
- ammo_amount += self.(weapon_load[WEP_VORTEX]) >= WEP_CVAR_SEC(vortex, ammo);
+ ammo_amount += self.(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_SEC(vortex, ammo);
return ammo_amount;
}
else
#include "../common/items/all.qh"
#include "../common/weapons/all.qh"
#include "../common/mapinfo.qh"
+#include "../common/mutators/base.qh"
///////////////////////////////////////////////
// Menu Source File
// needs to be done so early because of the constants they create
static_init();
- CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
RegisterSLCategories();
#include "../classes.inc"
#define IMPLEMENTATION
#include "../classes.inc"
+#undef IMPLEMENTATION
#endif
../common/weapons/all.qc // TODO
../warpzonelib/mathlib.qc
+
+../../mod/menu/progs.inc
else if(self.health>WEP_CVAR(devastator, damage)*0.5)
{
if(self.velocity.z < 0)
- if(client_hasweapon(self, WEP_DEVASTATOR, true, false))
+ if(client_hasweapon(self, WEP_DEVASTATOR.m_id, true, false))
{
self.movement_x = maxspeed;
return;
}
- self.switchweapon = WEP_DEVASTATOR;
+ self.switchweapon = WEP_DEVASTATOR.m_id;
self.v_angle_x = 90;
self.BUTTON_ATCK = true;
self.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay);
// I want to do a second scan if no enemy was found or I don't have weapons
// TODO: Perform the scan when using the rifle (requires changes on the rifle code)
- if(best || self.weapons) // || self.weapon == WEP_RIFLE
+ if(best || self.weapons) // || self.weapon == WEP_RIFLE.m_id
break;
if(i)
break;
// ;)
if(g_weaponarena_weapons == WEPSET_TUBA)
{
- self.switchweapon = WEP_TUBA;
+ self.switchweapon = WEP_TUBA.m_id;
return;
}
{
// If no weapon was chosen get the first available weapon
if(self.weapon==0)
- for(i = WEP_FIRST; i <= WEP_LAST; ++i) if(i != WEP_BLASTER)
+ for(i = WEP_FIRST; i <= WEP_LAST; ++i) if(i != WEP_BLASTER.m_id)
{
if(client_hasweapon(self, i, true, false))
{
if(frametime)
{
- if(self.weapon == WEP_VORTEX && WEP_CVAR(vortex, charge))
+ if(self.weapon == WEP_VORTEX.m_id && WEP_CVAR(vortex, charge))
{
self.weaponentity_glowmod_x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit));
self.weaponentity_glowmod_y = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit));
// WEAPONTODO: THIS SHIT NEEDS TO GO EVENTUALLY
// It cannot be predicted by the engine!
- if((self.weapon == WEP_SHOCKWAVE || self.weapon == WEP_SHOTGUN) && self.weaponentity.wframe == WFRAME_FIRE2 && time < self.weapon_nextthink)
+ if((self.weapon == WEP_SHOCKWAVE.m_id || self.weapon == WEP_SHOTGUN.m_id) && self.weaponentity.wframe == WFRAME_FIRE2 && time < self.weapon_nextthink)
do_crouch = 0;
if (do_crouch)
// WEAPONTODO: Add weapon request for this
if(!zoomstate_set)
- SetZoomState(self.BUTTON_ZOOM || self.BUTTON_ZOOMSCRIPT || (self.BUTTON_ATCK2 && self.weapon == WEP_VORTEX) || (self.BUTTON_ATCK2 && self.weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0)); // WEAPONTODO
+ SetZoomState(self.BUTTON_ZOOM || self.BUTTON_ZOOMSCRIPT || (self.BUTTON_ATCK2 && self.weapon == WEP_VORTEX.m_id) || (self.BUTTON_ATCK2 && self.weapon == WEP_RIFLE.m_id && WEP_CVAR(rifle, secondary) == 0)); // WEAPONTODO
float oldspectatee_status;
oldspectatee_status = self.spectatee_status;
damage /= sqrt(bound(1.0, attacker.cvar_cl_handicap, 100.0));
}
- if(DEATH_ISWEAPON(deathtype, WEP_TUBA))
+ if(DEATH_ISWEAPON(deathtype, WEP_TUBA.m_id))
{
// tuba causes blood to come out of the ears
vector ear1, ear2;
else if(!(attacker.weapons & WepSet_FromWeapon(culprit)))
culprit = attacker.weapon;
- if(g_weaponarena_random_with_blaster && culprit == WEP_BLASTER) // WEAPONTODO: Shouldn't this be in a mutator?
+ if(g_weaponarena_random_with_blaster && culprit == WEP_BLASTER.m_id) // WEAPONTODO: Shouldn't this be in a mutator?
{
// no exchange
}
RemoveGrapplingHook(targ); // STOP THAT, you parasite!
// special rule: gravity bomb does not hit team mates (other than for disconnecting the hook)
- if(DEATH_ISWEAPON(deathtype, WEP_HOOK) || DEATH_ISWEAPON(deathtype, WEP_TUBA))
+ if(DEATH_ISWEAPON(deathtype, WEP_HOOK.m_id) || DEATH_ISWEAPON(deathtype, WEP_TUBA.m_id))
{
if(IS_PLAYER(targ))
if(SAME_TEAM(targ, attacker))
total_damage_to_creatures = 0;
- if(deathtype != (WEP_HOOK | HITTYPE_SECONDARY | HITTYPE_BOUNCE)) // only send gravity bomb damage once
- if(DEATH_WEAPONOF(deathtype) != WEP_TUBA) // do not send tuba damage (bandwidth hog)
+ if(deathtype != (WEP_HOOK.m_id | HITTYPE_SECONDARY | HITTYPE_BOUNCE)) // only send gravity bomb damage once
+ if(DEATH_WEAPONOF(deathtype) != WEP_TUBA.m_id) // do not send tuba damage (bandwidth hog)
{
force = inflictorvelocity;
if(vlen(force) == 0)
force = force * (finaldmg / coredamage) * forceintensity;
hitloc = nearest;
- if(deathtype & WEP_BLASTER)
+ if(deathtype & WEP_BLASTER.m_id)
force *= WEP_CVAR_BOTH(blaster, !(deathtype & HITTYPE_SECONDARY), force_zscale);
if(targ != directhitentity)
void GrapplingHookFrame()
{
- if(g_grappling_hook && timeout_status != TIMEOUT_ACTIVE && self.weapon != WEP_HOOK)
+ if(g_grappling_hook && timeout_status != TIMEOUT_ACTIVE && self.weapon != WEP_HOOK.m_id)
{
// offhand hook controls
if(self.BUTTON_HOOK)
//self.hook_state &= ~HOOK_RELEASING;
}
}
- else if(!g_grappling_hook && self.switchweapon != WEP_HOOK)
+ else if(!g_grappling_hook && self.switchweapon != WEP_HOOK.m_id)
{
if(self.BUTTON_HOOK && !self.hook_switchweapon)
- W_SwitchWeapon(WEP_HOOK);
+ W_SwitchWeapon(WEP_HOOK.m_id);
}
self.hook_switchweapon = self.BUTTON_HOOK;
- if(!g_grappling_hook && self.weapon != WEP_HOOK)
+ if(!g_grappling_hook && self.weapon != WEP_HOOK.m_id)
{
self.hook_state &= ~HOOK_FIRING;
self.hook_state |= HOOK_REMOVING;
}
else
{
- WEP_ACTION(WEP_HOOK, WR_INIT);
- hook_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), false, false, 1);
- hook_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), false, false, 2);
- hook_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), false, false, 3);
- hook_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), false, false, 4);
+ WEP_ACTION(WEP_HOOK.m_id, 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);
+ hook_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK.m_id), false, false, 4);
}
}
// needs to be done so early because of the constants they create
static_init();
- CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
CALL_ACCUMULATED_FUNCTION(RegisterEffects);
// needs to be done so early because of the constants they create
static_init();
- CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
CALL_ACCUMULATED_FUNCTION(RegisterEffects);
d = false;
}
else if (g_cts)
- d = (i == WEP_SHOTGUN);
+ d = (i == WEP_SHOTGUN.m_id);
else if (g_nexball)
d = 0; // weapon is set a few lines later
else
d = !(!weaponinfo.weaponstart);
if(g_grappling_hook) // if possible, redirect off-hand hook to on-hand hook
- d |= (i == WEP_HOOK);
+ d |= (i == WEP_HOOK.m_id);
if(!g_cts && (weaponinfo.spawnflags & WEP_FLAG_MUTATORBLOCKED)) // never default mutator blocked guns
d = 0;
#include "t_items.qh"
-#include "mutators/base.qh"
+#include "mutators/events.qh"
#include "mutators/gamemode_race.qh"
#include "../common/constants.qh"
float DistributeEvenly_amount;
float DistributeEvenly_totalweight;
-var void remove(entity e);
void objerror(string s);
void droptofloor();
void() spawnfunc_info_player_deathmatch; // needed for the other spawnpoints
+++ /dev/null
-#include "base.qh"
-#include "../_all.qh"
-
-.bool() cbc_func;
-.entity cbc_next;
-.int cbc_order;
-
-entity CallbackChain_New(string name)
-{
- entity e = spawn();
- e.classname = "callbackchain";
- e.netname = name;
- return e;
-}
-
-bool CallbackChain_Add(entity cb, bool() func, int order)
-{
- if (order & CBC_ORDER_FIRST) {
- if (order & CBC_ORDER_LAST)
- if (cb.cbc_order & CBC_ORDER_ANY)
- return false;
- if (cb.cbc_order & CBC_ORDER_FIRST)
- return false;
- } else if (order & CBC_ORDER_LAST) {
- if (cb.cbc_order & CBC_ORDER_LAST)
- return false;
- }
- entity thiscb = spawn();
- thiscb.classname = "callback";
- thiscb.cbc_func = func;
- thiscb.cbc_order = order;
- if (order & CBC_ORDER_FIRST) {
- thiscb.cbc_next = cb.cbc_next;
- cb.cbc_next = thiscb;
- } else if (order & CBC_ORDER_LAST) {
- entity e = cb;
- while (e.cbc_next) e = e.cbc_next;
- e.cbc_next = thiscb;
- } else {
- // by default we execute last, but before a possible CBC_ORDER_LAST callback
- entity e = cb;
- // we must make sure that we insert BEFORE an CBC_ORDER_LAST mutator!
- while (e.cbc_next && !(e.cbc_next.cbc_order & CBC_ORDER_LAST)) e = e.cbc_next;
- thiscb.cbc_next = e.cbc_next;
- e.cbc_next = thiscb;
- }
- cb.cbc_order |= (order | CBC_ORDER_ANY);
- return true;
-}
-
-int CallbackChain_Remove(entity cb, bool() func)
-{
- int n = 0, order = 0;
- for (entity e = cb; e.cbc_next; e = e.cbc_next) {
- while (e.cbc_next.cbc_func == func) {
- // remove e.cbc_next from the chain
- entity e2 = e.cbc_next.cbc_next;
- remove(e.cbc_next);
- e.cbc_next = e2;
- ++n;
- }
- // e.cbc_next is now something we want to keep
- order |= (e.cbc_next.cbc_order & CBC_ORDER_ANY);
- }
- cb.cbc_order = order;
- return n;
-}
-
-bool CallbackChain_Call(entity cb)
-{
- bool r = false;
- for (entity e = cb; e.cbc_next; e = e.cbc_next) {
- CallbackChain_ReturnValue = r;
- r |= e.cbc_next.cbc_func();
- }
- return r; // callbacks return an error status, so 0 is default return value
-}
-
-const int MAX_MUTATORS = 15;
-string loaded_mutators[MAX_MUTATORS];
-bool Mutator_Add(mutatorfunc_t func, string name)
-{
- int j = -1;
- for (int i = 0; i < MAX_MUTATORS; ++i) {
- if (name == loaded_mutators[i])
- return true; // already added
- if (!(loaded_mutators[i]))
- j = i;
- }
- if (j < 0) {
- backtrace("WARNING: too many mutators, cannot add any more\n");
- return false;
- }
- loaded_mutators[j] = name;
-
- if (!func(MUTATOR_ADDING)) {
- // good
- return true;
- }
-
- backtrace("WARNING: when adding mutator: adding failed, rolling back\n");
-
- if (func(MUTATOR_ROLLING_BACK)) {
- // baaaaad
- error("WARNING: when adding mutator: rolling back failed");
- }
- return false;
-}
-void Mutator_Remove(mutatorfunc_t func, string name)
-{
- int i;
- for (i = 0; i < MAX_MUTATORS; ++i)
- if (name == loaded_mutators[i])
- break;
- if (i >= MAX_MUTATORS) {
- backtrace("WARNING: removing not-added mutator\n");
- return;
- }
- loaded_mutators[i] = string_null;
-
- if (func(MUTATOR_REMOVING) != 0) {
- // baaaaad
- error("Mutator_Remove: removing mutator failed");
- }
-}
+++ /dev/null
-#ifndef MUTATORS_BASE_H
-#define MUTATORS_BASE_H
-const int CBC_ORDER_FIRST = 1;
-const int CBC_ORDER_LAST = 2;
-const int CBC_ORDER_EXCLUSIVE = 3;
-const int CBC_ORDER_ANY = 4;
-
-bool CallbackChain_ReturnValue; // read-only field of the current return value
-
-entity CallbackChain_New(string name);
-bool CallbackChain_Add(entity cb, bool() func, int order);
-int CallbackChain_Remove(entity cb, bool() func);
-// a callback function is like this:
-// bool mycallback(entity me)
-// {
-// do something
-// return false;
-// }
-bool CallbackChain_Call(entity cb);
-
-enum {
- MUTATOR_REMOVING,
- MUTATOR_ADDING,
- MUTATOR_ROLLING_BACK
-};
-typedef bool(int) mutatorfunc_t;
-bool Mutator_Add(mutatorfunc_t func, string name);
-void Mutator_Remove(mutatorfunc_t func, string name); // calls error() on fail
-
-#define MUTATOR_ADD(name) Mutator_Add(MUTATOR_##name, #name)
-#define MUTATOR_REMOVE(name) Mutator_Remove(MUTATOR_##name, #name)
-#define MUTATOR_DEFINITION(name) bool MUTATOR_##name(int mode)
-#define MUTATOR_DECLARATION(name) bool MUTATOR_##name(int mode)
-#define MUTATOR_HOOKFUNCTION(name) bool HOOKFUNCTION_##name()
-#define MUTATOR_HOOK(cb, func, order) do { \
- MUTATOR_ONADD { \
- if (!HOOK_##cb) HOOK_##cb = CallbackChain_New(#cb); \
- if (!CallbackChain_Add(HOOK_##cb, HOOKFUNCTION_##func, order)) { \
- print("HOOK FAILED: ", #func, "\n"); \
- return true; \
- } \
- } \
- MUTATOR_ONROLLBACK_OR_REMOVE { \
- if (HOOK_##cb) CallbackChain_Remove(HOOK_##cb, HOOKFUNCTION_##func); \
- } \
-} while(0)
-#define MUTATOR_ONADD if (mode == MUTATOR_ADDING)
-#define MUTATOR_ONREMOVE if (mode == MUTATOR_REMOVING)
-#define MUTATOR_ONROLLBACK_OR_REMOVE if (mode == MUTATOR_REMOVING || mode == MUTATOR_ROLLING_BACK)
-
-#define _MUTATOR_HOOKABLE(id, ...) entity HOOK_##id; bool __Mutator_Send_##id(__VA_ARGS__)
-#define MUTATOR_CALLHOOK(id, ...) APPLY(__Mutator_Send_##id, 0, ##__VA_ARGS__)
-
-#define MUTATOR_RETURNVALUE CallbackChain_ReturnValue
-
-#define HANDLE_NOP(type, id)
-#define HANDLE_PARAMS(type, id) , type in_##id
-#define HANDLE_PREPARE(type, id) id = in_##id;
-#define HANDLE_PUSHTMP(type, id) type tmp_##id = id;
-#define HANDLE_PUSHOUT(type, id) type out_##id = id;
-#define HANDLE_POPTMP(type, id) id = tmp_##id;
-#define HANDLE_POPOUT(type, id) id = out_##id;
-
-#define MUTATOR_HOOKABLE(id, params) \
- _MUTATOR_HOOKABLE(id, int params(HANDLE_PARAMS, HANDLE_NOP)) { \
- params(HANDLE_PUSHTMP, HANDLE_NOP) \
- params(HANDLE_PREPARE, HANDLE_NOP) \
- bool ret = CallbackChain_Call(HOOK_##id); \
- params(HANDLE_NOP, HANDLE_PUSHOUT) \
- params(HANDLE_POPTMP, HANDLE_NOP) \
- params(HANDLE_NOP, HANDLE_POPOUT) \
- return ret; \
- }
-
-
-
-// register all possible hooks here
-// some parameters are commented to avoid duplicate declarations
-
-#define EV_NO_ARGS(i, o)
-
-/** called when a player becomes observer, after shared setup */
-#define EV_MakePlayerObserver(i, o) \
- /**/
-MUTATOR_HOOKABLE(MakePlayerObserver, EV_MakePlayerObserver)
-
-/** */
-#define EV_PutClientInServer(i, o) \
- /** client wanting to spawn */ i(entity, self) \
- /**/
-MUTATOR_HOOKABLE(PutClientInServer, EV_PutClientInServer);
-
-/** called when a player spawns as player, after shared setup, before his weapon is chosen (so items may be changed in here) */
-#define EV_PlayerSpawn(i, o) \
- /** spot that was used, or world */ i(entity, spawn_spot) \
- /**/
-entity spawn_spot;
-MUTATOR_HOOKABLE(PlayerSpawn, EV_PlayerSpawn);
-
-/** called in reset_map */
-#define EV_reset_map_global(i, o) \
- /**/
-MUTATOR_HOOKABLE(reset_map_global, EV_reset_map_global);
-
-/** called in reset_map */
-#define EV_reset_map_players(i, o) \
- /**/
-MUTATOR_HOOKABLE(reset_map_players, EV_reset_map_players);
-
-/** returns 1 if clearing player score shall not be allowed */
-#define EV_ForbidPlayerScore_Clear(i, o) \
- /**/
-MUTATOR_HOOKABLE(ForbidPlayerScore_Clear, EV_ForbidPlayerScore_Clear);
-
-/** called when a player disconnects */
-#define EV_ClientDisconnect(i, o) \
- /**/
-MUTATOR_HOOKABLE(ClientDisconnect, EV_ClientDisconnect);
-
-/** called when a player dies to e.g. remove stuff he was carrying. */
-#define EV_PlayerDies(i, o) \
- /**/ i(entity, frag_inflictor) \
- /**/ i(entity, frag_attacker) \
- /** same as self */ i(entity, frag_target) \
- /**/ i(int, frag_deathtype) \
- /**/
-entity frag_inflictor;
-entity frag_attacker;
-entity frag_target;
-int frag_deathtype;
-MUTATOR_HOOKABLE(PlayerDies, EV_PlayerDies);
-
-/** called when a player presses the jump key */
-#define EV_PlayerJump(i, o) \
- /**/ i(float, player_multijump) \
- /**/ i(float, player_jumpheight) \
- /**/ o(float, player_multijump) \
- /**/ o(float, player_jumpheight) \
- /**/
-float player_multijump;
-float player_jumpheight;
-MUTATOR_HOOKABLE(PlayerJump, EV_PlayerJump);
-
-/** called when someone was fragged by "self", and is expected to change frag_score to adjust scoring for the kill */
-#define EV_GiveFragsForKill(i, o) \
- /** same as self */ i(entity, frag_attacker) \
- /**/ i(entity, frag_target) \
- /**/ i(float, frag_score) \
- /**/ o(float, frag_score) \
- /**/
-float frag_score;
-MUTATOR_HOOKABLE(GiveFragsForKill, EV_GiveFragsForKill);
-
-/** called when the match ends */
-MUTATOR_HOOKABLE(MatchEnd, EV_NO_ARGS);
-
-/** should adjust ret_float to contain the team count */
-#define EV_GetTeamCount(i, o) \
- /**/ i(float, ret_float) \
- /**/ o(float, ret_float) \
- /**/
-float ret_float;
-MUTATOR_HOOKABLE(GetTeamCount, EV_GetTeamCount);
-
-/** copies variables for spectating "other" to "self" */
-#define EV_SpectateCopy(i, o) \
- /**/ i(entity, other) \
- /**/ i(entity, self) \
- /**/
-MUTATOR_HOOKABLE(SpectateCopy, EV_SpectateCopy);
-
-/** returns 1 if throwing the current weapon shall not be allowed */
-MUTATOR_HOOKABLE(ForbidThrowCurrentWeapon, EV_NO_ARGS);
-
-/** allows changing attack rate */
-#define EV_WeaponRateFactor(i, o) \
- /**/ i(float, weapon_rate) \
- /**/ o(float, weapon_rate) \
- /**/
-float weapon_rate;
-MUTATOR_HOOKABLE(WeaponRateFactor, EV_WeaponRateFactor);
-
-/** allows changing weapon speed (projectiles mostly) */
-#define EV_WeaponSpeedFactor(i, o) \
- /**/ i(float, ret_float) \
- /**/ o(float, ret_float) \
- /**/
-MUTATOR_HOOKABLE(WeaponSpeedFactor, EV_WeaponSpeedFactor);
-
-/** adjusts {warmup_}start_{items,weapons,ammo_{cells,plasma,rockets,nails,shells,fuel}} */
-MUTATOR_HOOKABLE(SetStartItems, EV_NO_ARGS);
-
-/** appends ":mutatorname" to ret_string for logging */
-#define EV_BuildMutatorsString(i, o) \
- /**/ i(string, ret_string) \
- /**/ o(string, ret_string) \
- /**/
-string ret_string;
-MUTATOR_HOOKABLE(BuildMutatorsString, EV_BuildMutatorsString);
-
-/** appends ", Mutator name" to ret_string for display */
-#define EV_BuildMutatorsPrettyString(i, o) \
- /**/ i(string, ret_string) \
- /**/ o(string, ret_string) \
- /**/
-MUTATOR_HOOKABLE(BuildMutatorsPrettyString, EV_BuildMutatorsPrettyString);
-
-/** called every frame. customizes the waypoint for spectators */
-#define EV_CustomizeWaypoint(i, o) \
- /** waypoint */ i(entity, self) \
- /** player; other.enemy = spectator */ i(entity, other) \
- /**/
-MUTATOR_HOOKABLE(CustomizeWaypoint, EV_CustomizeWaypoint);
-
-/**
- * checks if the current item may be spawned (self.items and self.weapons may be read and written to, as well as the ammo_ fields)
- * return error to request removal
- */
-MUTATOR_HOOKABLE(FilterItem, EV_NO_ARGS);
-
-/** return error to request removal */
-#define EV_TurretSpawn(i, o) \
- /** turret */ i(entity, self) \
- /**/
-MUTATOR_HOOKABLE(TurretSpawn, EV_TurretSpawn);
-
-/** return error to prevent entity spawn, or modify the entity */
-MUTATOR_HOOKABLE(OnEntityPreSpawn, EV_NO_ARGS);
-
-/** runs in the event loop for players; is called for ALL player entities, also bots, also the dead, or spectators */
-MUTATOR_HOOKABLE(PlayerPreThink, EV_NO_ARGS);
-
-/** TODO change this into a general PlayerPostThink hook? */
-MUTATOR_HOOKABLE(GetPressedKeys, EV_NO_ARGS);
-
-/**
- * called before any player physics, may adjust variables for movement,
- * is run AFTER bot code and idle checking
- */
-MUTATOR_HOOKABLE(PlayerPhysics, EV_NO_ARGS);
-
-/** is meant to call GetCvars_handle*(get_cvars_s, get_cvars_f, cvarfield, "cvarname") for cvars this mutator needs from the client */
-#define EV_GetCvars(i, o) \
- /**/ i(float, get_cvars_f) \
- /**/ i(string, get_cvars_s) \
- /**/
-float get_cvars_f;
-string get_cvars_s;
-MUTATOR_HOOKABLE(GetCvars, EV_NO_ARGS); // NOTE: Can't use EV_GetCvars because of `SZ_GetSpace: overflow`
-
-/** can edit any "just fired" projectile */
-#define EV_EditProjectile(i, o) \
- /**/ i(entity, self) \
- /**/ i(entity, other) \
- /**/
-MUTATOR_HOOKABLE(EditProjectile, EV_EditProjectile);
-
-/** called when a monster spawns */
-MUTATOR_HOOKABLE(MonsterSpawn, EV_NO_ARGS);
-
-/** called when a monster dies */
-#define EV_MonsterDies(i, o) \
- /**/ i(entity, frag_attacker) \
- /**/
-MUTATOR_HOOKABLE(MonsterDies, EV_MonsterDies);
-
-/** called when a monster wants to respawn */
-#define EV_MonsterRespawn(i, o) \
- /**/ i(entity, other) \
- /**/
-MUTATOR_HOOKABLE(MonsterRespawn, EV_MonsterRespawn);
-
-/** called when a monster is dropping loot */
-#define EV_MonsterDropItem(i, o) \
- /**/ i(entity, other) \
- /**/ o(entity, other) \
- /**/
-.void() monster_loot;
-MUTATOR_HOOKABLE(MonsterDropItem, EV_MonsterDropItem);
-
-/**
- * called when a monster moves
- * returning true makes the monster stop
- */
-#define EV_MonsterMove(i, o) \
- /**/ i(float, monster_speed_run) \
- /**/ o(float, monster_speed_run) \
- /**/ i(float, monster_speed_walk) \
- /**/ o(float, monster_speed_walk) \
- /**/ i(entity, monster_target) \
- /**/
-float monster_speed_run;
-float monster_speed_walk;
-entity monster_target;
-MUTATOR_HOOKABLE(MonsterMove, EV_MonsterMove);
-
-/** called when a monster looks for another target */
-MUTATOR_HOOKABLE(MonsterFindTarget, EV_NO_ARGS);
-
-/** called to change a random monster to a miniboss */
-MUTATOR_HOOKABLE(MonsterCheckBossFlag, EV_NO_ARGS);
-
-/**
- * called when a player tries to spawn a monster
- * return 1 to prevent spawning
- */
-MUTATOR_HOOKABLE(AllowMobSpawning, EV_NO_ARGS);
-
-/** called when a player gets damaged to e.g. remove stuff he was carrying. */
-#define EV_PlayerDamage_SplitHealthArmor(i, o) \
- /**/ i(entity, frag_inflictor) \
- /**/ i(entity, frag_attacker) \
- /** same as self */ i(entity, frag_target) \
- /** NOTE: this force already HAS been applied */ i(vector, damage_force) \
- /**/ i(float, damage_take) \
- /**/ o(float, damage_take) \
- /**/ i(float, damage_save) \
- /**/ o(float, damage_save) \
- /**/
-vector damage_force;
-float damage_take;
-float damage_save;
-MUTATOR_HOOKABLE(PlayerDamage_SplitHealthArmor, EV_PlayerDamage_SplitHealthArmor);
-
-/**
- * called to adjust damage and force values which are applied to the player, used for e.g. strength damage/force multiplier
- * i'm not sure if I should change this around slightly (Naming of the entities, and also how they're done in g_damage).
- */
-#define EV_PlayerDamage_Calculate(i, o) \
- /**/ i(entity, frag_attacker) \
- /**/ i(entity, frag_target) \
- /**/ i(float, frag_deathtype) \
- /**/ i(float, frag_damage) \
- /**/ o(float, frag_damage) \
- /**/ i(float, frag_mirrordamage) \
- /**/ o(float, frag_mirrordamage) \
- /**/ i(vector, frag_force) \
- /**/ o(vector, frag_force) \
- /**/
-float frag_damage;
-float frag_mirrordamage;
-vector frag_force;
-MUTATOR_HOOKABLE(PlayerDamage_Calculate, EV_PlayerDamage_Calculate);
-
-/** called at the end of player_powerups() in cl_client.qc, used for manipulating the values which are set by powerup items. */
-#define EV_PlayerPowerups(i, o) \
- /**/ i(entity, self) \
- /**/ i(int, olditems) \
- /**/
-int olditems;
-MUTATOR_HOOKABLE(PlayerPowerups, EV_PlayerPowerups);
-
-/**
- * called every player think frame
- * return 1 to disable regen
- */
-#define EV_PlayerRegen(i, o) \
- /**/ i(float, regen_mod_max) \
- /**/ o(float, regen_mod_max) \
- /**/ i(float, regen_mod_regen) \
- /**/ o(float, regen_mod_regen) \
- /**/ i(float, regen_mod_rot) \
- /**/ o(float, regen_mod_rot) \
- /**/ i(float, regen_mod_limit) \
- /**/ o(float, regen_mod_limit) \
- /**/
-float regen_mod_max;
-float regen_mod_regen;
-float regen_mod_rot;
-float regen_mod_limit;
-MUTATOR_HOOKABLE(PlayerRegen, EV_PlayerRegen);
-
-/**
- * called when the use key is pressed
- * if MUTATOR_RETURNVALUE is 1, don't do anything
- * return 1 if the use key actually did something
- */
-MUTATOR_HOOKABLE(PlayerUseKey, EV_NO_ARGS);
-
-/**
- * called when a client command is parsed
- * NOTE: hooks MUST start with if(MUTATOR_RETURNVALUE) return 0;
- * NOTE: return 1 if you handled the command, return 0 to continue handling
- * NOTE: THESE HOOKS MUST NEVER EVER CALL tokenize()
- * // example:
- * MUTATOR_HOOKFUNCTION(foo_SV_ParseClientCommand)
- * {
- * if (MUTATOR_RETURNVALUE) // command was already handled?
- * return false;
- * if (cmd_name == "echocvar" && cmd_argc >= 2)
- * {
- * print(cvar_string(argv(1)), "\n");
- * return true;
- * }
- * if (cmd_name == "echostring" && cmd_argc >= 2)
- * {
- * print(substring(cmd_string, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)), "\n");
- * return true;
- * }
- * return false;
- * }
- */
-#define EV_SV_ParseClientCommand(i, o) \
- /** command name */ i(string, cmd_name) \
- /** also, argv() can be used */ i(int, cmd_argc) \
- /** whole command, use only if you really have to */ i(string, cmd_string) \
- /**/
-string cmd_name;
-int cmd_argc;
-string cmd_string;
-MUTATOR_HOOKABLE(SV_ParseClientCommand, EV_SV_ParseClientCommand);
-
-/**
- * called when a spawnpoint is being evaluated
- * return 1 to make the spawnpoint unusable
- */
-#define EV_Spawn_Score(i, o) \
- /** player wanting to spawn */ i(entity, self) \
- /** spot to be evaluated */ i(entity, spawn_spot) \
- /** _x is priority, _y is "distance" */ i(vector, spawn_score) \
- /**/ o(vector, spawn_score) \
- /**/
-vector spawn_score;
-MUTATOR_HOOKABLE(Spawn_Score, EV_Spawn_Score);
-
-/** runs globally each server frame */
-MUTATOR_HOOKABLE(SV_StartFrame, EV_NO_ARGS);
-
-#define EV_SetModname(i, o) \
- /** name of the mutator/mod if it warrants showing as such in the server browser */ \
- o(string, modname) \
- /**/
-MUTATOR_HOOKABLE(SetModname, EV_SetModname);
-
-/**
- * called for each item being spawned on a map, including dropped weapons
- * return 1 to remove an item
- */
-#define EV_Item_Spawn(i, o) \
- /** the item */ i(entity, self) \
- /**/
-MUTATOR_HOOKABLE(Item_Spawn, EV_Item_Spawn);
-
-#define EV_SetWeaponreplace(i, o) \
- /** map entity */ i(entity, self) \
- /** weapon info */ i(entity, other) \
- /**/ i(string, ret_string) \
- /**/ o(string, ret_string) \
- /**/
-MUTATOR_HOOKABLE(SetWeaponreplace, EV_SetWeaponreplace);
-
-/** called when an item is about to respawn */
-#define EV_Item_RespawnCountdown(i, o) \
- /**/ i(string, item_name) \
- /**/ o(string, item_name) \
- /**/ i(vector, item_color) \
- /**/ o(vector, item_color) \
- /**/
-string item_name;
-vector item_color;
-MUTATOR_HOOKABLE(Item_RespawnCountdown, EV_Item_RespawnCountdown);
-
-/** called when a bot checks a target to attack */
-#define EV_BotShouldAttack(i, o) \
- /**/ i(entity, checkentity) \
- /**/
-entity checkentity;
-MUTATOR_HOOKABLE(BotShouldAttack, EV_BotShouldAttack);
-
-/**
- * called whenever a player goes through a portal gun teleport
- * allows you to strip a player of an item if they go through the teleporter to help prevent cheating
- */
-#define EV_PortalTeleport(i, o) \
- /**/ i(entity, self) \
- /**/
-MUTATOR_HOOKABLE(PortalTeleport, EV_PortalTeleport);
-
-/**
- * called whenever a player uses impulse 33 (help me) in cl_impulse.qc
- * normally help me ping uses self.waypointsprite_attachedforcarrier,
- * but if your mutator uses something different then you can handle it
- * in a special manner using this hook
- */
-#define EV_HelpMePing(i, o) \
- /** the player who pressed impulse 33 */ i(entity, self) \
- /**/
-MUTATOR_HOOKABLE(HelpMePing, EV_HelpMePing);
-
-/**
- * called when a vehicle initializes
- * return true to remove the vehicle
- */
-MUTATOR_HOOKABLE(VehicleSpawn, EV_NO_ARGS);
-
-/**
- * called when a player enters a vehicle
- * allows mutators to set special settings in this event
- */
-#define EV_VehicleEnter(i, o) \
- /** player */ i(entity, vh_player) \
- /** vehicle */ i(entity, vh_vehicle) \
- /**/
-entity vh_player;
-entity vh_vehicle;
-MUTATOR_HOOKABLE(VehicleEnter, EV_VehicleEnter);
-
-/**
- * called when a player touches a vehicle
- * return true to stop player from entering the vehicle
- */
-#define EV_VehicleTouch(i, o) \
- /** vehicle */ i(entity, self) \
- /** player */ i(entity, other) \
- /**/
-MUTATOR_HOOKABLE(VehicleTouch, EV_VehicleTouch);
-
-/**
- * called when a player exits a vehicle
- * allows mutators to set special settings in this event
- */
-#define EV_VehicleExit(i, o) \
- /** player */ i(entity, vh_player) \
- /** vehicle */ i(entity, vh_vehicle) \
- /**/
-MUTATOR_HOOKABLE(VehicleExit, EV_VehicleExit);
-
-/** called when a speedrun is aborted and the player is teleported back to start position */
-#define EV_AbortSpeedrun(i, o) \
- /** player */ i(entity, self) \
- /**/
-MUTATOR_HOOKABLE(AbortSpeedrun, EV_AbortSpeedrun);
-
-/** called at when a item is touched. Called early, can edit item properties. */
-#define EV_ItemTouch(i, o) \
- /** item */ i(entity, self) \
- /** player */ i(entity, other) \
- /**/
-MUTATOR_HOOKABLE(ItemTouch, EV_ItemTouch);
-
-enum {
- MUT_ITEMTOUCH_CONTINUE, // return this flag to make the function continue as normal
- MUT_ITEMTOUCH_RETURN, // return this flag to make the function return (handled entirely by mutator)
- MUT_ITEMTOUCH_PICKUP // return this flag to have the item "picked up" and taken even after mutator handled it
-};
-
-/** called at when a player connect */
-#define EV_ClientConnect(i, o) \
- /** player */ i(entity, self) \
- /**/
-MUTATOR_HOOKABLE(ClientConnect, EV_ClientConnect);
-
-#define EV_HavocBot_ChooseRole(i, o) \
- /**/ i(entity, self) \
- /**/
-MUTATOR_HOOKABLE(HavocBot_ChooseRole, EV_HavocBot_ChooseRole);
-
-/** called when a target is checked for accuracy */
-#define EV_AccuracyTargetValid(i, o) \
- /** attacker */ i(entity, frag_attacker) \
- /** target */ i(entity, frag_target) \
- /**/
-MUTATOR_HOOKABLE(AccuracyTargetValid, EV_AccuracyTargetValid);
-enum {
- MUT_ACCADD_VALID, // return this flag to make the function continue if target is a client
- MUT_ACCADD_INVALID, // return this flag to make the function always continue
- MUT_ACCADD_INDIFFERENT // return this flag to make the function always return
-};
-#endif
--- /dev/null
+#ifndef SERVER_MUTATORS_EVENTS_H
+#define SERVER_MUTATORS_EVENTS_H
+
+#include "../../common/mutators/base.qh"
+
+// register all possible hooks here
+
+/** called when a player becomes observer, after shared setup */
+#define EV_MakePlayerObserver(i, o) \
+ /**/
+MUTATOR_HOOKABLE(MakePlayerObserver, EV_MakePlayerObserver)
+
+/** */
+#define EV_PutClientInServer(i, o) \
+ /** client wanting to spawn */ i(entity, self) \
+ /**/
+MUTATOR_HOOKABLE(PutClientInServer, EV_PutClientInServer);
+
+/** called when a player spawns as player, after shared setup, before his weapon is chosen (so items may be changed in here) */
+#define EV_PlayerSpawn(i, o) \
+ /** spot that was used, or world */ i(entity, spawn_spot) \
+ /**/
+entity spawn_spot;
+MUTATOR_HOOKABLE(PlayerSpawn, EV_PlayerSpawn);
+
+/** called in reset_map */
+#define EV_reset_map_global(i, o) \
+ /**/
+MUTATOR_HOOKABLE(reset_map_global, EV_reset_map_global);
+
+/** called in reset_map */
+#define EV_reset_map_players(i, o) \
+ /**/
+MUTATOR_HOOKABLE(reset_map_players, EV_reset_map_players);
+
+/** returns 1 if clearing player score shall not be allowed */
+#define EV_ForbidPlayerScore_Clear(i, o) \
+ /**/
+MUTATOR_HOOKABLE(ForbidPlayerScore_Clear, EV_ForbidPlayerScore_Clear);
+
+/** called when a player disconnects */
+#define EV_ClientDisconnect(i, o) \
+ /**/
+MUTATOR_HOOKABLE(ClientDisconnect, EV_ClientDisconnect);
+
+/** called when a player dies to e.g. remove stuff he was carrying. */
+#define EV_PlayerDies(i, o) \
+ /**/ i(entity, frag_inflictor) \
+ /**/ i(entity, frag_attacker) \
+ /** same as self */ i(entity, frag_target) \
+ /**/ i(int, frag_deathtype) \
+ /**/
+entity frag_inflictor;
+entity frag_attacker;
+entity frag_target;
+int frag_deathtype;
+MUTATOR_HOOKABLE(PlayerDies, EV_PlayerDies);
+
+/** called when a player presses the jump key */
+#define EV_PlayerJump(i, o) \
+ /**/ i(float, player_multijump) \
+ /**/ i(float, player_jumpheight) \
+ /**/ o(float, player_multijump) \
+ /**/ o(float, player_jumpheight) \
+ /**/
+float player_multijump;
+float player_jumpheight;
+MUTATOR_HOOKABLE(PlayerJump, EV_PlayerJump);
+
+/** called when someone was fragged by "self", and is expected to change frag_score to adjust scoring for the kill */
+#define EV_GiveFragsForKill(i, o) \
+ /** same as self */ i(entity, frag_attacker) \
+ /**/ i(entity, frag_target) \
+ /**/ i(float, frag_score) \
+ /**/ o(float, frag_score) \
+ /**/
+float frag_score;
+MUTATOR_HOOKABLE(GiveFragsForKill, EV_GiveFragsForKill);
+
+/** called when the match ends */
+MUTATOR_HOOKABLE(MatchEnd, EV_NO_ARGS);
+
+/** should adjust ret_float to contain the team count */
+#define EV_GetTeamCount(i, o) \
+ /**/ i(float, ret_float) \
+ /**/ o(float, ret_float) \
+ /**/
+float ret_float;
+MUTATOR_HOOKABLE(GetTeamCount, EV_GetTeamCount);
+
+/** copies variables for spectating "other" to "self" */
+#define EV_SpectateCopy(i, o) \
+ /**/ i(entity, other) \
+ /**/ i(entity, self) \
+ /**/
+MUTATOR_HOOKABLE(SpectateCopy, EV_SpectateCopy);
+
+/** returns 1 if throwing the current weapon shall not be allowed */
+MUTATOR_HOOKABLE(ForbidThrowCurrentWeapon, EV_NO_ARGS);
+
+/** allows changing attack rate */
+#define EV_WeaponRateFactor(i, o) \
+ /**/ i(float, weapon_rate) \
+ /**/ o(float, weapon_rate) \
+ /**/
+float weapon_rate;
+MUTATOR_HOOKABLE(WeaponRateFactor, EV_WeaponRateFactor);
+
+/** allows changing weapon speed (projectiles mostly) */
+#define EV_WeaponSpeedFactor(i, o) \
+ /**/ i(float, ret_float) \
+ /**/ o(float, ret_float) \
+ /**/
+MUTATOR_HOOKABLE(WeaponSpeedFactor, EV_WeaponSpeedFactor);
+
+/** adjusts {warmup_}start_{items,weapons,ammo_{cells,plasma,rockets,nails,shells,fuel}} */
+MUTATOR_HOOKABLE(SetStartItems, EV_NO_ARGS);
+
+/** called every frame. customizes the waypoint for spectators */
+#define EV_CustomizeWaypoint(i, o) \
+ /** waypoint */ i(entity, self) \
+ /** player; other.enemy = spectator */ i(entity, other) \
+ /**/
+MUTATOR_HOOKABLE(CustomizeWaypoint, EV_CustomizeWaypoint);
+
+/**
+ * checks if the current item may be spawned (self.items and self.weapons may be read and written to, as well as the ammo_ fields)
+ * return error to request removal
+ */
+MUTATOR_HOOKABLE(FilterItem, EV_NO_ARGS);
+
+/** return error to request removal */
+#define EV_TurretSpawn(i, o) \
+ /** turret */ i(entity, self) \
+ /**/
+MUTATOR_HOOKABLE(TurretSpawn, EV_TurretSpawn);
+
+/** return error to prevent entity spawn, or modify the entity */
+MUTATOR_HOOKABLE(OnEntityPreSpawn, EV_NO_ARGS);
+
+/** runs in the event loop for players; is called for ALL player entities, also bots, also the dead, or spectators */
+MUTATOR_HOOKABLE(PlayerPreThink, EV_NO_ARGS);
+
+/** TODO change this into a general PlayerPostThink hook? */
+MUTATOR_HOOKABLE(GetPressedKeys, EV_NO_ARGS);
+
+/**
+ * called before any player physics, may adjust variables for movement,
+ * is run AFTER bot code and idle checking
+ */
+MUTATOR_HOOKABLE(PlayerPhysics, EV_NO_ARGS);
+
+/** is meant to call GetCvars_handle*(get_cvars_s, get_cvars_f, cvarfield, "cvarname") for cvars this mutator needs from the client */
+#define EV_GetCvars(i, o) \
+ /**/ i(float, get_cvars_f) \
+ /**/ i(string, get_cvars_s) \
+ /**/
+float get_cvars_f;
+string get_cvars_s;
+MUTATOR_HOOKABLE(GetCvars, EV_NO_ARGS); // NOTE: Can't use EV_GetCvars because of `SZ_GetSpace: overflow`
+
+/** can edit any "just fired" projectile */
+#define EV_EditProjectile(i, o) \
+ /**/ i(entity, self) \
+ /**/ i(entity, other) \
+ /**/
+MUTATOR_HOOKABLE(EditProjectile, EV_EditProjectile);
+
+/** called when a monster spawns */
+MUTATOR_HOOKABLE(MonsterSpawn, EV_NO_ARGS);
+
+/** called when a monster dies */
+#define EV_MonsterDies(i, o) \
+ /**/ i(entity, frag_attacker) \
+ /**/
+MUTATOR_HOOKABLE(MonsterDies, EV_MonsterDies);
+
+/** called when a monster wants to respawn */
+#define EV_MonsterRespawn(i, o) \
+ /**/ i(entity, other) \
+ /**/
+MUTATOR_HOOKABLE(MonsterRespawn, EV_MonsterRespawn);
+
+/** called when a monster is dropping loot */
+#define EV_MonsterDropItem(i, o) \
+ /**/ i(entity, other) \
+ /**/ o(entity, other) \
+ /**/
+.void() monster_loot;
+MUTATOR_HOOKABLE(MonsterDropItem, EV_MonsterDropItem);
+
+/**
+ * called when a monster moves
+ * returning true makes the monster stop
+ */
+#define EV_MonsterMove(i, o) \
+ /**/ i(float, monster_speed_run) \
+ /**/ o(float, monster_speed_run) \
+ /**/ i(float, monster_speed_walk) \
+ /**/ o(float, monster_speed_walk) \
+ /**/ i(entity, monster_target) \
+ /**/
+float monster_speed_run;
+float monster_speed_walk;
+entity monster_target;
+MUTATOR_HOOKABLE(MonsterMove, EV_MonsterMove);
+
+/** called when a monster looks for another target */
+MUTATOR_HOOKABLE(MonsterFindTarget, EV_NO_ARGS);
+
+/** called to change a random monster to a miniboss */
+MUTATOR_HOOKABLE(MonsterCheckBossFlag, EV_NO_ARGS);
+
+/**
+ * called when a player tries to spawn a monster
+ * return 1 to prevent spawning
+ */
+MUTATOR_HOOKABLE(AllowMobSpawning, EV_NO_ARGS);
+
+/** called when a player gets damaged to e.g. remove stuff he was carrying. */
+#define EV_PlayerDamage_SplitHealthArmor(i, o) \
+ /**/ i(entity, frag_inflictor) \
+ /**/ i(entity, frag_attacker) \
+ /** same as self */ i(entity, frag_target) \
+ /** NOTE: this force already HAS been applied */ i(vector, damage_force) \
+ /**/ i(float, damage_take) \
+ /**/ o(float, damage_take) \
+ /**/ i(float, damage_save) \
+ /**/ o(float, damage_save) \
+ /**/
+vector damage_force;
+float damage_take;
+float damage_save;
+MUTATOR_HOOKABLE(PlayerDamage_SplitHealthArmor, EV_PlayerDamage_SplitHealthArmor);
+
+/**
+ * called to adjust damage and force values which are applied to the player, used for e.g. strength damage/force multiplier
+ * i'm not sure if I should change this around slightly (Naming of the entities, and also how they're done in g_damage).
+ */
+#define EV_PlayerDamage_Calculate(i, o) \
+ /**/ i(entity, frag_attacker) \
+ /**/ i(entity, frag_target) \
+ /**/ i(float, frag_deathtype) \
+ /**/ i(float, frag_damage) \
+ /**/ o(float, frag_damage) \
+ /**/ i(float, frag_mirrordamage) \
+ /**/ o(float, frag_mirrordamage) \
+ /**/ i(vector, frag_force) \
+ /**/ o(vector, frag_force) \
+ /**/
+float frag_damage;
+float frag_mirrordamage;
+vector frag_force;
+MUTATOR_HOOKABLE(PlayerDamage_Calculate, EV_PlayerDamage_Calculate);
+
+/** called at the end of player_powerups() in cl_client.qc, used for manipulating the values which are set by powerup items. */
+#define EV_PlayerPowerups(i, o) \
+ /**/ i(entity, self) \
+ /**/ i(int, olditems) \
+ /**/
+int olditems;
+MUTATOR_HOOKABLE(PlayerPowerups, EV_PlayerPowerups);
+
+/**
+ * called every player think frame
+ * return 1 to disable regen
+ */
+#define EV_PlayerRegen(i, o) \
+ /**/ i(float, regen_mod_max) \
+ /**/ o(float, regen_mod_max) \
+ /**/ i(float, regen_mod_regen) \
+ /**/ o(float, regen_mod_regen) \
+ /**/ i(float, regen_mod_rot) \
+ /**/ o(float, regen_mod_rot) \
+ /**/ i(float, regen_mod_limit) \
+ /**/ o(float, regen_mod_limit) \
+ /**/
+float regen_mod_max;
+float regen_mod_regen;
+float regen_mod_rot;
+float regen_mod_limit;
+MUTATOR_HOOKABLE(PlayerRegen, EV_PlayerRegen);
+
+/**
+ * called when the use key is pressed
+ * if MUTATOR_RETURNVALUE is 1, don't do anything
+ * return 1 if the use key actually did something
+ */
+MUTATOR_HOOKABLE(PlayerUseKey, EV_NO_ARGS);
+
+/**
+ * called when a client command is parsed
+ * NOTE: hooks MUST start with if(MUTATOR_RETURNVALUE) return 0;
+ * NOTE: return 1 if you handled the command, return 0 to continue handling
+ * NOTE: THESE HOOKS MUST NEVER EVER CALL tokenize()
+ * // example:
+ * MUTATOR_HOOKFUNCTION(foo_SV_ParseClientCommand)
+ * {
+ * if (MUTATOR_RETURNVALUE) // command was already handled?
+ * return false;
+ * if (cmd_name == "echocvar" && cmd_argc >= 2)
+ * {
+ * print(cvar_string(argv(1)), "\n");
+ * return true;
+ * }
+ * if (cmd_name == "echostring" && cmd_argc >= 2)
+ * {
+ * print(substring(cmd_string, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)), "\n");
+ * return true;
+ * }
+ * return false;
+ * }
+ */
+#define EV_SV_ParseClientCommand(i, o) \
+ /** command name */ i(string, cmd_name) \
+ /** also, argv() can be used */ i(int, cmd_argc) \
+ /** whole command, use only if you really have to */ i(string, cmd_string) \
+ /**/
+string cmd_name;
+int cmd_argc;
+string cmd_string;
+MUTATOR_HOOKABLE(SV_ParseClientCommand, EV_SV_ParseClientCommand);
+
+/**
+ * called when a spawnpoint is being evaluated
+ * return 1 to make the spawnpoint unusable
+ */
+#define EV_Spawn_Score(i, o) \
+ /** player wanting to spawn */ i(entity, self) \
+ /** spot to be evaluated */ i(entity, spawn_spot) \
+ /** _x is priority, _y is "distance" */ i(vector, spawn_score) \
+ /**/ o(vector, spawn_score) \
+ /**/
+vector spawn_score;
+MUTATOR_HOOKABLE(Spawn_Score, EV_Spawn_Score);
+
+/** runs globally each server frame */
+MUTATOR_HOOKABLE(SV_StartFrame, EV_NO_ARGS);
+
+#define EV_SetModname(i, o) \
+ /** name of the mutator/mod if it warrants showing as such in the server browser */ \
+ o(string, modname) \
+ /**/
+MUTATOR_HOOKABLE(SetModname, EV_SetModname);
+
+/**
+ * called for each item being spawned on a map, including dropped weapons
+ * return 1 to remove an item
+ */
+#define EV_Item_Spawn(i, o) \
+ /** the item */ i(entity, self) \
+ /**/
+MUTATOR_HOOKABLE(Item_Spawn, EV_Item_Spawn);
+
+#define EV_SetWeaponreplace(i, o) \
+ /** map entity */ i(entity, self) \
+ /** weapon info */ i(entity, other) \
+ /**/ i(string, ret_string) \
+ /**/ o(string, ret_string) \
+ /**/
+MUTATOR_HOOKABLE(SetWeaponreplace, EV_SetWeaponreplace);
+
+/** called when an item is about to respawn */
+#define EV_Item_RespawnCountdown(i, o) \
+ /**/ i(string, item_name) \
+ /**/ o(string, item_name) \
+ /**/ i(vector, item_color) \
+ /**/ o(vector, item_color) \
+ /**/
+string item_name;
+vector item_color;
+MUTATOR_HOOKABLE(Item_RespawnCountdown, EV_Item_RespawnCountdown);
+
+/** called when a bot checks a target to attack */
+#define EV_BotShouldAttack(i, o) \
+ /**/ i(entity, checkentity) \
+ /**/
+entity checkentity;
+MUTATOR_HOOKABLE(BotShouldAttack, EV_BotShouldAttack);
+
+/**
+ * called whenever a player goes through a portal gun teleport
+ * allows you to strip a player of an item if they go through the teleporter to help prevent cheating
+ */
+#define EV_PortalTeleport(i, o) \
+ /**/ i(entity, self) \
+ /**/
+MUTATOR_HOOKABLE(PortalTeleport, EV_PortalTeleport);
+
+/**
+ * called whenever a player uses impulse 33 (help me) in cl_impulse.qc
+ * normally help me ping uses self.waypointsprite_attachedforcarrier,
+ * but if your mutator uses something different then you can handle it
+ * in a special manner using this hook
+ */
+#define EV_HelpMePing(i, o) \
+ /** the player who pressed impulse 33 */ i(entity, self) \
+ /**/
+MUTATOR_HOOKABLE(HelpMePing, EV_HelpMePing);
+
+/**
+ * called when a vehicle initializes
+ * return true to remove the vehicle
+ */
+MUTATOR_HOOKABLE(VehicleSpawn, EV_NO_ARGS);
+
+/**
+ * called when a player enters a vehicle
+ * allows mutators to set special settings in this event
+ */
+#define EV_VehicleEnter(i, o) \
+ /** player */ i(entity, vh_player) \
+ /** vehicle */ i(entity, vh_vehicle) \
+ /**/
+entity vh_player;
+entity vh_vehicle;
+MUTATOR_HOOKABLE(VehicleEnter, EV_VehicleEnter);
+
+/**
+ * called when a player touches a vehicle
+ * return true to stop player from entering the vehicle
+ */
+#define EV_VehicleTouch(i, o) \
+ /** vehicle */ i(entity, self) \
+ /** player */ i(entity, other) \
+ /**/
+MUTATOR_HOOKABLE(VehicleTouch, EV_VehicleTouch);
+
+/**
+ * called when a player exits a vehicle
+ * allows mutators to set special settings in this event
+ */
+#define EV_VehicleExit(i, o) \
+ /** player */ i(entity, vh_player) \
+ /** vehicle */ i(entity, vh_vehicle) \
+ /**/
+MUTATOR_HOOKABLE(VehicleExit, EV_VehicleExit);
+
+/** called when a speedrun is aborted and the player is teleported back to start position */
+#define EV_AbortSpeedrun(i, o) \
+ /** player */ i(entity, self) \
+ /**/
+MUTATOR_HOOKABLE(AbortSpeedrun, EV_AbortSpeedrun);
+
+/** called at when a item is touched. Called early, can edit item properties. */
+#define EV_ItemTouch(i, o) \
+ /** item */ i(entity, self) \
+ /** player */ i(entity, other) \
+ /**/
+MUTATOR_HOOKABLE(ItemTouch, EV_ItemTouch);
+
+enum {
+ MUT_ITEMTOUCH_CONTINUE, // return this flag to make the function continue as normal
+ MUT_ITEMTOUCH_RETURN, // return this flag to make the function return (handled entirely by mutator)
+ MUT_ITEMTOUCH_PICKUP // return this flag to have the item "picked up" and taken even after mutator handled it
+};
+
+/** called at when a player connect */
+#define EV_ClientConnect(i, o) \
+ /** player */ i(entity, self) \
+ /**/
+MUTATOR_HOOKABLE(ClientConnect, EV_ClientConnect);
+
+#define EV_HavocBot_ChooseRole(i, o) \
+ /**/ i(entity, self) \
+ /**/
+MUTATOR_HOOKABLE(HavocBot_ChooseRole, EV_HavocBot_ChooseRole);
+
+/** called when a target is checked for accuracy */
+#define EV_AccuracyTargetValid(i, o) \
+ /** attacker */ i(entity, frag_attacker) \
+ /** target */ i(entity, frag_target) \
+ /**/
+MUTATOR_HOOKABLE(AccuracyTargetValid, EV_AccuracyTargetValid);
+enum {
+ MUT_ACCADD_VALID, // return this flag to make the function continue if target is a client
+ MUT_ACCADD_INVALID, // return this flag to make the function always continue
+ MUT_ACCADD_INDIFFERENT // return this flag to make the function always return
+};
+#endif
self.weaponentity.weapons = self.weapons;
self.weaponentity.switchweapon = self.weapon;
self.weapons = WEPSET_PORTO;
- WEP_ACTION(WEP_PORTO, WR_RESETPLAYER);
- self.switchweapon = WEP_PORTO;
- W_SwitchWeapon(WEP_PORTO);
+ WEP_ACTION(WEP_PORTO.m_id, WR_RESETPLAYER);
+ self.switchweapon = WEP_PORTO.m_id;
+ W_SwitchWeapon(WEP_PORTO.m_id);
self = ownr;
}
}
else if(req == WR_SETUP)
{
- //weapon_setup(WEP_PORTO);
+ //weapon_setup(WEP_PORTO.m_id);
}
// No need to check WR_CHECKAMMO* or WR_AIM, it should always return true
return true;
if(self.weaponentity.weapons)
{
self.weapons = self.weaponentity.weapons;
- WEP_ACTION(WEP_PORTO, WR_RESETPLAYER);
+ WEP_ACTION(WEP_PORTO.m_id, WR_RESETPLAYER);
self.switchweapon = self.weaponentity.switchweapon;
W_SwitchWeapon(self.switchweapon);
MUTATOR_HOOKFUNCTION(nexball_ForbidThrowing)
{
- if(self.weapon == WEP_MORTAR)
+ if(self.weapon == WEP_MORTAR.m_id)
return true;
return false;
MUTATOR_HOOKFUNCTION(nexball_FilterItem)
{
if(self.classname == "droppedweapon")
- if(self.weapon == WEP_MORTAR)
+ if(self.weapon == WEP_MORTAR.m_id)
return true;
return false;
#ifndef MUTATOR_H
#define MUTATOR_H
-#include "base.qh"
+#include "../../common/mutators/base.qh"
#include "mutator_nades.qh"
#include "../cl_client.qh"
frag_target.buff_disability_time = time + autocvar_g_buffs_disability_slowtime;
if(frag_attacker.buffs & BUFF_MEDIC.m_itemid)
- if(DEATH_WEAPONOF(frag_deathtype) != WEP_ARC)
+ if(DEATH_WEAPONOF(frag_deathtype) != WEP_ARC.m_id)
if(SAME_TEAM(frag_attacker, frag_target))
if(frag_attacker != frag_target)
{
// this... is ridiculous (TODO: fix!)
if(frag_attacker.buffs & BUFF_VAMPIRE.m_itemid)
if(!frag_target.vehicle)
- if(DEATH_WEAPONOF(frag_deathtype) != WEP_ARC)
+ if(DEATH_WEAPONOF(frag_deathtype) != WEP_ARC.m_id)
if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
if(frag_target.deadflag == DEAD_NO)
if(IS_PLAYER(frag_target) || IS_MONSTER(frag_target))
}
if(IS_PLAYER(frag_attacker))
- if(DEATH_ISWEAPON(frag_deathtype, WEP_VAPORIZER))
+ if(DEATH_ISWEAPON(frag_deathtype, WEP_VAPORIZER.m_id))
{
if(frag_target.armorvalue)
{
}
}
- if(IS_PLAYER(frag_attacker) && DEATH_ISWEAPON(frag_deathtype, WEP_BLASTER))
+ if(IS_PLAYER(frag_attacker) && DEATH_ISWEAPON(frag_deathtype, WEP_BLASTER.m_id))
{
if(frag_deathtype & HITTYPE_SECONDARY)
{
if(self.classname == "item_cells")
return true; // no normal cells?
- if(self.weapon == WEP_VAPORIZER && self.classname == "droppedweapon")
+ if(self.weapon == WEP_VAPORIZER.m_id && self.classname == "droppedweapon")
{
self.ammo_cells = autocvar_g_instagib_ammo_drop;
return false;
}
- if(self.weapon == WEP_DEVASTATOR || self.weapon == WEP_VORTEX)
+ if(self.weapon == WEP_DEVASTATOR.m_id || self.weapon == WEP_VORTEX.m_id)
{
entity e = spawn();
setorigin(e, self.origin);
if(self.nade_type == NADE_TYPE_TRANSLOCATE.m_id || self.nade_type == NADE_TYPE_SPAWN.m_id)
return;
- if(DEATH_ISWEAPON(deathtype, WEP_BLASTER))
+ if(DEATH_ISWEAPON(deathtype, WEP_BLASTER.m_id))
{
force *= 1.5;
damage = 0;
}
- if(DEATH_ISWEAPON(deathtype, WEP_VAPORIZER) && (deathtype & HITTYPE_SECONDARY))
+ if(DEATH_ISWEAPON(deathtype, WEP_VAPORIZER.m_id) && (deathtype & HITTYPE_SECONDARY))
{
force *= 0.5; // too much
frag_damage = 0;
}
- if(DEATH_ISWEAPON(deathtype, WEP_VORTEX) || DEATH_ISWEAPON(deathtype, WEP_VAPORIZER))
+ if(DEATH_ISWEAPON(deathtype, WEP_VORTEX.m_id) || DEATH_ISWEAPON(deathtype, WEP_VAPORIZER.m_id))
{
force *= 6;
damage = self.max_health * 0.55;
}
- if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN) || DEATH_ISWEAPON(deathtype, WEP_HMG))
+ if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN.m_id) || DEATH_ISWEAPON(deathtype, WEP_HMG.m_id))
damage = self.max_health * 0.1;
- if(DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE) || DEATH_ISWEAPON(deathtype, WEP_SHOTGUN)) // WEAPONTODO
+ if(DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE.m_id) || DEATH_ISWEAPON(deathtype, WEP_SHOTGUN.m_id)) // WEAPONTODO
if(deathtype & HITTYPE_SECONDARY)
{
damage = self.max_health * 0.1;
float key_pressed = self.BUTTON_HOOK;
float time_score;
- if(g_grappling_hook || client_hasweapon(self, WEP_HOOK, false, false) || (weaponsInMap & WEPSET_HOOK))
+ if(g_grappling_hook || client_hasweapon(self, WEP_HOOK.m_id, false, false) || (weaponsInMap & WEPSET_HOOK))
key_pressed = self.button16; // if hook is enabled, use an alternate key
if(self.nade)
{
switch(w)
{
- case WEP_SEEKER:
- case WEP_MINE_LAYER:
- case WEP_HLAC:
- case WEP_RIFLE:
- case WEP_SHOCKWAVE:
+ case WEP_SEEKER.m_id:
+ case WEP_MINE_LAYER.m_id:
+ case WEP_HLAC.m_id:
+ case WEP_RIFLE.m_id:
+ case WEP_SHOCKWAVE.m_id:
return true;
default:
return false;
}
else
{
- if(wpn == WEP_BLASTER && g_nix_with_blaster) // WEAPONTODO: rename to g_nix_with_blaster
+ if(wpn == WEP_BLASTER.m_id && g_nix_with_blaster) // WEAPONTODO: rename to g_nix_with_blaster
return false;
if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
return false;
MUTATOR_HOOKFUNCTION(ok_PlayerDamage_Calculate)
{
if(IS_PLAYER(frag_attacker) && IS_PLAYER(frag_target))
- if(DEATH_ISWEAPON(frag_deathtype, WEP_BLASTER))
+ if(DEATH_ISWEAPON(frag_deathtype, WEP_BLASTER.m_id))
{
frag_damage = 0;
makevectors(self.v_angle);
int oldwep = self.weapon;
- self.weapon = WEP_BLASTER;
+ self.weapon = WEP_BLASTER.m_id;
W_Blaster_Attack(
- WEP_BLASTER | HITTYPE_SECONDARY,
+ WEP_BLASTER.m_id | HITTYPE_SECONDARY,
WEP_CVAR_SEC(vaporizer, shotangle),
WEP_CVAR_SEC(vaporizer, damage),
WEP_CVAR_SEC(vaporizer, edgedamage),
{
WepSet ok_start_items = (WEPSET_MACHINEGUN | WEPSET_VORTEX | WEPSET_SHOTGUN);
- if((get_weaponinfo(WEP_RPC)).weaponstart > 0) { ok_start_items |= WEPSET_RPC; }
- if((get_weaponinfo(WEP_HMG)).weaponstart > 0) { ok_start_items |= WEPSET_HMG; }
+ if(WEP_RPC.weaponstart > 0) { ok_start_items |= WEPSET_RPC; }
+ if(WEP_HMG.weaponstart > 0) { ok_start_items |= WEPSET_HMG; }
start_items |= IT_UNLIMITED_WEAPON_AMMO;
start_weapons = warmup_start_weapons = ok_start_items;
addstat(STAT_OK_AMMO_CHARGE, AS_FLOAT, ok_use_ammocharge);
addstat(STAT_OK_AMMO_CHARGEPOOL, AS_FLOAT, ok_ammo_charge);
- (get_weaponinfo(WEP_RPC)).spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
- (get_weaponinfo(WEP_HMG)).spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
+ WEP_RPC.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
+ WEP_HMG.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
- (get_weaponinfo(WEP_SHOTGUN)).mdl = "ok_shotgun";
- (get_weaponinfo(WEP_MACHINEGUN)).mdl = "ok_mg";
- (get_weaponinfo(WEP_VORTEX)).mdl = "ok_sniper";
+ WEP_SHOTGUN.mdl = "ok_shotgun";
+ WEP_MACHINEGUN.mdl = "ok_mg";
+ WEP_VORTEX.mdl = "ok_sniper";
}
MUTATOR_DEFINITION(mutator_overkill)
MUTATOR_ONREMOVE
{
- (get_weaponinfo(WEP_RPC)).spawnflags |= WEP_FLAG_MUTATORBLOCKED;
- (get_weaponinfo(WEP_HMG)).spawnflags |= WEP_FLAG_MUTATORBLOCKED;
+ WEP_RPC.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
+ WEP_HMG.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
}
return false;
#include "../vehicles/all.qh"
#endif
-#include "base.qc"
+#include "../../common/mutators/base.qh"
#include "gamemode_assault.qc"
#include "gamemode_ca.qc"
#include "gamemode_ctf.qc"
#ifndef MUTATORS_INCLUDE_H
#define MUTATORS_INCLUDE_H
-#include "base.qh"
+#include "../../common/mutators/base.qh"
#include "mutators.qh"
#include "gamemode_assault.qh"
#include "gamemode_ca.qh"
../warpzonelib/mathlib.qc
../warpzonelib/server.qc
../warpzonelib/util_server.qc
+
+../../mod/server/progs.inc
var float(string name) cvar;
var string(string name) cvar_string;
var void(string name, string value) cvar_set;
+var void remove(entity e);
#pragma noref 0
self.dmg_time = time;
// WEAPONTODO
- if(DEATH_ISWEAPON(deathtype, WEP_VORTEX))
+ if(DEATH_ISWEAPON(deathtype, WEP_VORTEX.m_id))
damage *= autocvar_g_vehicles_vortex_damagerate;
- if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN))
+ if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN.m_id))
damage *= autocvar_g_vehicles_machinegun_damagerate;
- if(DEATH_ISWEAPON(deathtype, WEP_RIFLE))
+ if(DEATH_ISWEAPON(deathtype, WEP_RIFLE.m_id))
damage *= autocvar_g_vehicles_rifle_damagerate;
- if(DEATH_ISWEAPON(deathtype, WEP_VAPORIZER))
+ if(DEATH_ISWEAPON(deathtype, WEP_VAPORIZER.m_id))
damage *= autocvar_g_vehicles_vaporizer_damagerate;
- if(DEATH_ISWEAPON(deathtype, WEP_SEEKER))
+ if(DEATH_ISWEAPON(deathtype, WEP_SEEKER.m_id))
damage *= autocvar_g_vehicles_tag_damagerate;
self.enemy = attacker;
if(time < self.hasweapon_complain_spam)
complain = 0;
- if(wpn == WEP_HOOK && !g_grappling_hook && autocvar_g_nades && !((cl.weapons | weaponsInMap) & WepSet_FromWeapon(wpn)))
+ if(wpn == WEP_HOOK.m_id && !g_grappling_hook && autocvar_g_nades && !((cl.weapons | weaponsInMap) & WepSet_FromWeapon(wpn)))
complain = 0;
if(complain)
// always allow selecting the Mine Layer if we placed mines, so that we can detonate them
entity mine;
- if(wpn == WEP_MINE_LAYER)
+ if(wpn == WEP_MINE_LAYER.m_id)
for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.owner == self)
f = 1;
return 0;
if (g_cts)
return 0;
- if (g_nexball && w == WEP_MORTAR)
+ if (g_nexball && w == WEP_MORTAR.m_id)
return 0;
if(w == 0)
return 0;
float oldsolid;
vector vecs, dv;
oldsolid = ent.dphitcontentsmask;
- if(ent.weapon == WEP_RIFLE)
+ if(ent.weapon == WEP_RIFLE.m_id)
ent.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_CORPSE;
else
ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
//explosion = spawn();
// Find all non-hit players the beam passed close by
- if(deathtype == WEP_VAPORIZER || deathtype == WEP_VORTEX)
+ if(deathtype == WEP_VAPORIZER.m_id || deathtype == WEP_VORTEX.m_id)
{
FOR_EACH_REALCLIENT(msg_entity)
if(msg_entity != self)
{
// always keep the Mine Layer if we placed mines, so that we can detonate them
entity mine;
- if(self.weapon == WEP_MINE_LAYER)
+ if(self.weapon == WEP_MINE_LAYER.m_id)
for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.owner == self)
return false;
- if(self.weapon == WEP_SHOTGUN)
+ if(self.weapon == WEP_SHOTGUN.m_id)
if(!secondary && WEP_CVAR(shotgun, secondary) == 1)
return false; // no clicking, just allow
if((fr == WFRAME_FIRE1 || fr == WFRAME_FIRE2) && t)
{
- if((self.weapon == WEP_SHOCKWAVE || self.weapon == WEP_SHOTGUN) && fr == WFRAME_FIRE2)
+ if((self.weapon == WEP_SHOCKWAVE.m_id || self.weapon == WEP_SHOTGUN.m_id) && fr == WFRAME_FIRE2)
animdecide_setaction(self, ANIMACTION_MELEE, restartanim);
else
animdecide_setaction(self, ANIMACTION_SHOOT, restartanim);