]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branches 'TimePath/weaponsys' and 'Mario/modpack'
authorTimePath <andrew.hardaker1995@gmail.com>
Fri, 21 Aug 2015 06:47:39 +0000 (16:47 +1000)
committerTimePath <andrew.hardaker1995@gmail.com>
Fri, 21 Aug 2015 06:47:39 +0000 (16:47 +1000)
71 files changed:
mod/client/main.qc [new file with mode: 0644]
mod/client/progs.inc [new file with mode: 0644]
mod/menu/main.qc [new file with mode: 0644]
mod/menu/progs.inc [new file with mode: 0644]
mod/server/main.qc [new file with mode: 0644]
mod/server/progs.inc [new file with mode: 0644]
qcsrc/Makefile
qcsrc/client/damage.qc
qcsrc/client/main.qc
qcsrc/client/progs.src
qcsrc/client/view.qc
qcsrc/common/monsters/monster/shambler.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/mutators/base.qh [new file with mode: 0644]
qcsrc/common/mutators/events.qh [new file with mode: 0644]
qcsrc/common/physics.qc
qcsrc/common/weapons/all.qc
qcsrc/common/weapons/all.qh
qcsrc/common/weapons/w_arc.qc
qcsrc/common/weapons/w_blaster.qc
qcsrc/common/weapons/w_crylink.qc
qcsrc/common/weapons/w_devastator.qc
qcsrc/common/weapons/w_electro.qc
qcsrc/common/weapons/w_fireball.qc
qcsrc/common/weapons/w_hagar.qc
qcsrc/common/weapons/w_hlac.qc
qcsrc/common/weapons/w_hmg.qc
qcsrc/common/weapons/w_hook.qc
qcsrc/common/weapons/w_machinegun.qc
qcsrc/common/weapons/w_minelayer.qc
qcsrc/common/weapons/w_mortar.qc
qcsrc/common/weapons/w_porto.qc
qcsrc/common/weapons/w_rifle.qc
qcsrc/common/weapons/w_rpc.qc
qcsrc/common/weapons/w_seeker.qc
qcsrc/common/weapons/w_shockwave.qc
qcsrc/common/weapons/w_shotgun.qc
qcsrc/common/weapons/w_tuba.qc
qcsrc/common/weapons/w_vaporizer.qc
qcsrc/common/weapons/w_vortex.qc
qcsrc/menu/menu.qc
qcsrc/menu/oo/classes.qc
qcsrc/menu/progs.src
qcsrc/server/bot/havocbot/havocbot.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_player.qc
qcsrc/server/g_damage.qc
qcsrc/server/g_hook.qc
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/miscfunctions.qh
qcsrc/server/mutators/base.qc [deleted file]
qcsrc/server/mutators/base.qh [deleted file]
qcsrc/server/mutators/events.qh [new file with mode: 0644]
qcsrc/server/mutators/gamemode_nexball.qc
qcsrc/server/mutators/mutator.qh
qcsrc/server/mutators/mutator_buffs.qc
qcsrc/server/mutators/mutator_instagib.qc
qcsrc/server/mutators/mutator_nades.qc
qcsrc/server/mutators/mutator_new_toys.qc
qcsrc/server/mutators/mutator_nix.qc
qcsrc/server/mutators/mutator_overkill.qc
qcsrc/server/mutators/mutators_include.qc
qcsrc/server/mutators/mutators_include.qh
qcsrc/server/progs.src
qcsrc/server/sys-post.qh
qcsrc/server/vehicles/vehicle.qc
qcsrc/server/weapons/selection.qc
qcsrc/server/weapons/throwing.qc
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/weaponsystem.qc

diff --git a/mod/client/main.qc b/mod/client/main.qc
new file mode 100644 (file)
index 0000000..d84239c
--- /dev/null
@@ -0,0 +1,9 @@
+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");
+}
diff --git a/mod/client/progs.inc b/mod/client/progs.inc
new file mode 100644 (file)
index 0000000..ae91a9e
--- /dev/null
@@ -0,0 +1,3 @@
+#if BUILD_MOD
+#include "main.qc"
+#endif
diff --git a/mod/menu/main.qc b/mod/menu/main.qc
new file mode 100644 (file)
index 0000000..d84239c
--- /dev/null
@@ -0,0 +1,9 @@
+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");
+}
diff --git a/mod/menu/progs.inc b/mod/menu/progs.inc
new file mode 100644 (file)
index 0000000..ae91a9e
--- /dev/null
@@ -0,0 +1,3 @@
+#if BUILD_MOD
+#include "main.qc"
+#endif
diff --git a/mod/server/main.qc b/mod/server/main.qc
new file mode 100644 (file)
index 0000000..d84239c
--- /dev/null
@@ -0,0 +1,9 @@
+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");
+}
diff --git a/mod/server/progs.inc b/mod/server/progs.inc
new file mode 100644 (file)
index 0000000..ae91a9e
--- /dev/null
@@ -0,0 +1,3 @@
+#if BUILD_MOD
+#include "main.qc"
+#endif
index 26797c55a1459fd67fe9599f97158d3707a4f7e4..143f53249b43f3b79f5e9a7cb323e6237ffac117 100644 (file)
@@ -13,14 +13,15 @@ QCCFLAGS ?= \
        -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 =
index 3626c44c617408555c5bb4c4eaede028fe6399db..70df439efe928def46c66cb03e53f15169deb8eb 100644 (file)
@@ -357,7 +357,7 @@ void Ent_DamageInfo(float isNew)
                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);
index 872b7f9baab126e0b6520ac312bce656681af590..87027c3461e376421c38bbe949927626d4c75d0f 100644 (file)
@@ -41,6 +41,8 @@
 
 #include "../common/items/all.qh"
 
+#include "../common/mutators/base.qh"
+
 #include "../common/weapons/all.qh"
 
 #include "../csqcmodellib/cl_model.qh"
@@ -142,7 +144,6 @@ void CSQC_Init(void)
 
        // 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);
index db8817818c5cd6d8a6c331dbe59ffeea1c3e0cb9..e6d8226619f93f379d1c0d2a0d4fd712dba942a4 100644 (file)
@@ -78,3 +78,5 @@ weapons/projectile.qc // TODO
 ../warpzonelib/common.qc
 ../warpzonelib/mathlib.qc
 ../warpzonelib/util_server.qc
+
+../../mod/client/progs.inc
index df8113b412c6f93aaeec1108cd12c4f96e477219..2d4bff52a114b552e1e16d133e1c92fc7617d085 100644 (file)
@@ -34,7 +34,7 @@ void Porto_Draw()
        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;
@@ -133,7 +133,7 @@ vector GetCurrentFov(float fov)
 
        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())
        {
@@ -320,16 +320,16 @@ float TrueAimCheck()
 
        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)
@@ -338,19 +338,19 @@ float TrueAimCheck()
                                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;
@@ -439,7 +439,7 @@ bool WantEventchase()
                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))
                {
@@ -490,7 +490,7 @@ void UpdateHitsound()
 
        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)
@@ -837,7 +837,7 @@ void UpdateCrosshair()
 
 
                                // 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;
@@ -857,14 +857,14 @@ void UpdateCrosshair()
                                        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;
@@ -887,12 +887,12 @@ void UpdateCrosshair()
 
                                        // 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 +
index df796b5188a19b0a84fc81d2192f3eba035bbba9..f4f29d9fbc1d62427f00a89a8cf6dcb2fb5d4fee 100644 (file)
@@ -226,7 +226,7 @@ float m_shambler(float req)
                        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;
                }
index 8668fe710122cfd9a40de8f4b641391d8770ad13..a9de642863672b24bab677fa8dbdcba314ee0702 100644 (file)
@@ -361,7 +361,7 @@ void Monster_CheckMinibossFlag ()
                self.health += autocvar_g_monsters_miniboss_healthboost;
                self.effects |= EF_RED;
                if(!self.weapon)
-                       self.weapon = WEP_VORTEX;
+                       self.weapon = WEP_VORTEX.m_id;
        }
 }
 
diff --git a/qcsrc/common/mutators/base.qh b/qcsrc/common/mutators/base.qh
new file mode 100644 (file)
index 0000000..8394552
--- /dev/null
@@ -0,0 +1,280 @@
+#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
diff --git a/qcsrc/common/mutators/events.qh b/qcsrc/common/mutators/events.qh
new file mode 100644 (file)
index 0000000..e193d5f
--- /dev/null
@@ -0,0 +1,22 @@
+#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
index 41261e6a19d7ed9fa8486a4d29d133b191a66cc9..6c0bd616bcfee30c402a41cc118f921946dfe62a 100644 (file)
@@ -1193,7 +1193,7 @@ void PM_check_vortex(void)
 #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));
index 53974d8d558f4dc63a90ce8d216439197b88dcf7..9f78f6454852d09e390a7e1b44839e3d48b167df 100644 (file)
 #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
@@ -149,77 +149,13 @@ WepSet ReadWepSet()
 }
 #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));
 }
index eab3b0a5ad2879f8f2e2048ff9703444c8062e87..ac839a53a047f6006d5b16e9f41403fb61199033 100644 (file)
@@ -65,10 +65,10 @@ WepSet ReadWepSet();
 #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;
 
@@ -101,7 +101,7 @@ int GetAmmoStat(.int ammotype);
 
 // 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)
 
 
@@ -133,76 +133,123 @@ int GetAmmoStat(.int ammotype);
 
 // 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"
@@ -213,7 +260,6 @@ void register_weapons_done();
 #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
index f07a44a036919851a260324afee0fc2e91db38ea..d0647c912237b318761ce1923caeb36d61a19843 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ ARC,
 /* function  */ W_Arc,
@@ -123,9 +123,10 @@ float Draw_ArcBeam_callback_last_thickness;
 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)
 {
@@ -273,7 +274,7 @@ void W_Arc_Beam_Think(void)
                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
@@ -530,7 +531,7 @@ void W_Arc_Beam_Think(void)
                                {
                                        accuracy_add(
                                                self.owner,
-                                               WEP_ARC,
+                                               WEP_ARC.m_id,
                                                0,
                                                rootdamage * coefficient * falloff
                                        );
@@ -541,7 +542,7 @@ void W_Arc_Beam_Think(void)
                                        self.owner,
                                        self.owner,
                                        rootdamage * coefficient * falloff,
-                                       WEP_ARC,
+                                       WEP_ARC.m_id,
                                        hitorigin,
                                        WEP_CVAR(arc, beam_force) * new_dir * coefficient * falloff
                                );
@@ -629,7 +630,7 @@ void Arc_Smoke()
        }
 
        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);
@@ -730,10 +731,10 @@ bool W_Arc(int req)
                        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;
@@ -766,7 +767,7 @@ bool W_Arc(int req)
                }
                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;
index 31a5151facd2befa3420043a0632961e83aed4e7..95a4167263188f31aff848d0d9e2152779661c3b 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ BLASTER,
 /* function  */ W_Blaster,
@@ -45,9 +45,10 @@ BLASTER_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
 .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)
@@ -173,7 +174,7 @@ bool W_Blaster(int request)
                                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),
@@ -193,7 +194,7 @@ bool W_Blaster(int request)
                                {
                                        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;
                                        }
@@ -203,7 +204,7 @@ bool W_Blaster(int request)
                                                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),
index e9163ad59b0f3623dd9bc8cfe679cae9cf60c0d8..f6484d080bf5b4b6b24e216bd49ec52b33ac4b5b 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ CRYLINK,
 /* function  */ W_Crylink,
@@ -61,9 +61,10 @@ CRYLINK_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
 .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)
 {
@@ -391,7 +392,7 @@ void W_Crylink_Attack(void)
 
                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);
@@ -500,7 +501,7 @@ void W_Crylink_Attack2(void)
 
                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);
@@ -627,7 +628,7 @@ bool W_Crylink(int req)
                                        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);
                                        }
                                }
@@ -653,7 +654,7 @@ bool W_Crylink(int req)
                                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:
@@ -663,7 +664,7 @@ bool W_Crylink(int req)
                                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:
index 2dde60b988781581d67cb0e046452e4c9db2366f..9d77f715897a0e8629ce2a3c679cea8b0fddeb90 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ DEVASTATOR,
 /* function  */ W_Devastator,
@@ -59,9 +59,10 @@ DEVASTATOR_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
 .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)
@@ -100,12 +101,12 @@ void W_Devastator_Explode(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);
                }
@@ -179,12 +180,12 @@ void W_Devastator_DoRemoteExplode(void)
                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);
                }
@@ -260,7 +261,7 @@ void W_Devastator_Think(void)
                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)
@@ -364,7 +365,7 @@ void W_Devastator_Attack(void)
 
        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
@@ -546,7 +547,7 @@ bool W_Devastator(int req)
                                        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)
@@ -588,12 +589,12 @@ bool W_Devastator(int req)
                {
                        #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))
@@ -610,13 +611,13 @@ bool W_Devastator(int req)
                        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
                }
index 6fb0c26df3461c389268e8deca6aaf30dcbaa7a4..d1e79c56135609d84d74ee27b30423da7f1e79f8 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ ELECTRO,
 /* function  */ W_Electro,
@@ -64,9 +64,10 @@ ELECTRO_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
 .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)
 {
@@ -130,7 +131,7 @@ void W_Electro_ExplodeCombo(void)
                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
        );
 
@@ -271,7 +272,7 @@ void W_Electro_Attack_Bolt(void)
        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;
@@ -370,7 +371,7 @@ void W_Electro_Attack_Orb(void)
        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;
@@ -511,7 +512,7 @@ bool W_Electro(int req)
                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:
@@ -519,12 +520,12 @@ bool W_Electro(int req)
                        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;
                }
index 1cec08e9691fb0cc7fb1f611bf11cd5e14965cb2..f9a4928b745b484f7651054a41f7ba37dadb5d59 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ FIREBALL,
 /* function  */ W_Fireball,
@@ -52,9 +52,10 @@ FIREBALL_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
 .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)
 {
@@ -96,7 +97,7 @@ 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);
@@ -200,7 +201,7 @@ void W_Fireball_Attack1(void)
        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;
@@ -327,7 +328,7 @@ void W_Fireball_Attack2(void)
        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');
index 5c5f418f96662e92118db4b17ab65846faa402cd..967fd8f5aa72c2c6d882b8ea982e4001406ed453 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ HAGAR,
 /* function  */ W_Hagar,
@@ -53,9 +53,10 @@ REGISTER_WEAPON(
 #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!
 
@@ -147,7 +148,7 @@ void W_Hagar_Attack(void)
        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');
 
@@ -191,7 +192,7 @@ void W_Hagar_Attack2(void)
        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');
 
@@ -250,7 +251,7 @@ void W_Hagar_Attack2_Load_Release(void)
                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;
@@ -302,7 +303,7 @@ void W_Hagar_Attack2_Load(void)
        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);
 
@@ -472,13 +473,13 @@ bool W_Hagar(int req)
                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:
index ab5566992a766651bad4e839bd48df141e04bdb9..fa3f48c87f554785f0828e520e9c8224e933cb68 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ HLAC,
 /* function  */ W_HLAC,
@@ -45,9 +45,10 @@ REGISTER_WEAPON(
 #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)
 {
@@ -106,7 +107,7 @@ void W_HLAC_Attack(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);
 
@@ -150,7 +151,7 @@ void W_HLAC_Attack2(void)
 
        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);
 
@@ -250,13 +251,13 @@ bool W_HLAC(int req)
                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:
index 3aa052531b3074e8dbb494a0fac0c1439b294248..2668aca2c41ecee0bd2eb0c0107532e603b7a2bb 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id     */ HMG,
 /* function     */ W_HeavyMachineGun,
@@ -37,10 +37,11 @@ REGISTER_WEAPON(
 #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()
 {
@@ -69,7 +70,7 @@ 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;
 
@@ -130,7 +131,7 @@ bool W_HeavyMachineGun(int req)
                        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;
                }
@@ -139,7 +140,7 @@ bool W_HeavyMachineGun(int req)
                        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;
                }
index 0c002bfc78aa1e727af8fb3ec4cf91383db129b5..a8d33e8704bb16937d34ec41b29612412002f8fe 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ HOOK,
 /* function  */ W_Hook,
@@ -55,7 +55,8 @@ HOOK_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
 .float hook_time_hooked;
 .float hook_time_fueldecrease;
 #endif
-#else
+#endif
+#ifdef IMPLEMENTATION
 #ifdef SVQC
 
 void spawnfunc_weapon_hook(void)
@@ -66,7 +67,7 @@ void spawnfunc_weapon_hook(void)
                remove(self);
                return;
        }
-       weapon_defaultspawnfunc(WEP_HOOK);
+       weapon_defaultspawnfunc(WEP_HOOK.m_id);
 }
 
 void W_Hook_ExplodeThink(void)
@@ -142,7 +143,7 @@ void W_Hook_Attack2(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');
 
index 56a89fd9dcf77f3bca61f0669a077d4edec2c51a..f320f711469cfb75a72daaa424bf262cafa54388 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ MACHINEGUN,
 /* function  */ W_MachineGun,
@@ -51,7 +51,8 @@ REGISTER_WEAPON(
 #ifdef SVQC
 MACHINEGUN_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
 #endif
-#else
+#endif
+#ifdef IMPLEMENTATION
 #ifdef SVQC
 
 void spawnfunc_weapon_machinegun(void)
@@ -59,10 +60,10 @@ 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(); }
 
@@ -151,7 +152,7 @@ void W_MachineGun_Attack_Frame(void)
                        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
@@ -187,7 +188,7 @@ void W_MachineGun_Attack_Auto(void)
        }
 
        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;
 
@@ -212,7 +213,7 @@ void W_MachineGun_Attack_Burst(void)
                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);
 
@@ -286,7 +287,7 @@ bool W_MachineGun(int req)
                                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);
                                }
 
@@ -294,7 +295,7 @@ bool W_MachineGun(int req)
                                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);
                                }
                        }
@@ -321,9 +322,9 @@ bool W_MachineGun(int req)
                        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;
                }
@@ -337,9 +338,9 @@ bool W_MachineGun(int req)
                        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;
                }
index 45fdb0573e5650d55e393a57e50c779d2bfc129a..25ac30e4bd9b1a9bc1df5123da0d2f1e68d6786e 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ MINE_LAYER,
 /* function  */ W_MineLayer,
@@ -54,9 +54,10 @@ void W_MineLayer_Think(void);
 .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)
 {
@@ -119,14 +120,14 @@ void W_MineLayer_Explode(void)
 
        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);
                }
@@ -146,14 +147,14 @@ void W_MineLayer_DoRemoteExplode(void)
 
        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);
                }
@@ -261,7 +262,7 @@ void W_MineLayer_Think(void)
        }
 
        // 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();
@@ -347,7 +348,7 @@ void W_MineLayer_Attack(void)
 
        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
@@ -548,10 +549,10 @@ bool W_MineLayer(int req)
                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;
index a2ac41c49a5d3bf2d7f9ebb049de87f07dd05ab5..9e4912a84bfd0fb98d43f5950d4c1e952f8c7dd1 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ MORTAR,
 /* function  */ W_Mortar,
@@ -52,10 +52,11 @@ MORTAR_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
 .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)
@@ -241,7 +242,7 @@ void W_Mortar_Attack(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');
 
@@ -290,7 +291,7 @@ void W_Mortar_Attack2(void)
        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');
 
@@ -421,13 +422,13 @@ bool W_Mortar(int req)
                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:
index 558c83c0436563784ba2091f12fe34b362b6ee66..e604b616446bbb6535da616725136bb77ef8e25f 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ PORTO,
 /* function  */ W_Porto,
@@ -36,11 +36,12 @@ PORTO_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
 .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)
 {
@@ -82,7 +83,7 @@ void W_Porto_Fail(float failhard)
                        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);
                        }
                }
index 50ccc4e96a0f02d8474ce61eae33050e863b580d..17c7ae3c2a152a1bdcd783d06b5d5c90f1fe932e 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ RIFLE,
 /* function  */ W_Rifle,
@@ -44,9 +44,10 @@ REGISTER_WEAPON(
 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(); }
 
@@ -75,12 +76,12 @@ void W_Rifle_FireBullet(float pSpread, float pDamage, float pForce, float pSolid
 
 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;
@@ -214,13 +215,13 @@ bool W_Rifle(int req)
                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:
index 42ca9185c80eacf9af2b6e9db12a21a01a7482e1..87ad16f5c67e90545c1b8e2cfecb35dc75fb6ed6 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id     */ RPC,
 /* function     */ W_RocketPropelledChainsaw,
@@ -42,9 +42,10 @@ REGISTER_WEAPON(
 #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()
 {
@@ -122,7 +123,7 @@ void W_RocketPropelledChainsaw_Attack (void)
        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
@@ -192,7 +193,7 @@ bool W_RocketPropelledChainsaw(int req)
                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:
index dc01834ec10bf9956cbaf0686490394bb1861e07..313d5defd9f6ff9baeb05932acdd69cee66d7520 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ SEEKER,
 /* function  */ W_Seeker,
@@ -81,9 +81,10 @@ SEEKER_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
 .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
@@ -276,9 +277,9 @@ void W_Seeker_Fire_Missile(vector f_diff, entity m_target)
        //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);
@@ -356,8 +357,8 @@ void W_Seeker_Fire_Flac(void)
        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;
 
@@ -416,7 +417,7 @@ void W_Seeker_Vollycontroller_Think(void) // TODO: Merge this with W_Seeker_Atta
        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;
@@ -455,7 +456,7 @@ void W_Seeker_Vollycontroller_Think(void) // TODO: Merge this with W_Seeker_Atta
 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)
@@ -477,7 +478,7 @@ void W_Seeker_Tag_Explode(void)
 {
        //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);
 }
@@ -505,7 +506,7 @@ void W_Seeker_Tag_Touch(void)
        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)
        {
@@ -676,12 +677,12 @@ bool W_Seeker(int req)
                        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;
                }
@@ -690,12 +691,12 @@ bool W_Seeker(int req)
                        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;
                }
index 17189bd4a6c29330b4d8583ac3cc6219d4f6bdf1..91961bb18dccbd14b9631e73859c6d6937b748cf 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ SHOCKWAVE,
 /* function  */ W_Shockwave,
@@ -79,7 +79,8 @@ void Net_ReadShockwaveParticle(void);
 .float sw_spread_min;
 .float sw_time;
 #endif
-#else
+#endif
+#ifdef IMPLEMENTATION
 #ifdef SVQC
 void spawnfunc_weapon_shockwave(void)
 {
@@ -87,10 +88,10 @@ 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;
@@ -178,14 +179,14 @@ void W_Shockwave_Melee_Think(void)
                                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(
@@ -375,7 +376,7 @@ void W_Shockwave_Attack(void)
                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
        );
@@ -455,7 +456,7 @@ void W_Shockwave_Attack(void)
                                        self,
                                        self,
                                        final_damage,
-                                       WEP_SHOCKWAVE,
+                                       WEP_SHOCKWAVE.m_id,
                                        head.origin,
                                        final_force
                                );
@@ -639,7 +640,7 @@ void W_Shockwave_Attack(void)
                        self,
                        self,
                        final_damage,
-                       WEP_SHOCKWAVE,
+                       WEP_SHOCKWAVE.m_id,
                        head.origin,
                        final_force
                );
@@ -647,7 +648,7 @@ void W_Shockwave_Attack(void)
                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
index 95195bd3ac632456e10a394be8c24d0b85f4a27c..d93e9dd3f9fd1627685e370801cb10f72e6b303e 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ SHOTGUN,
 /* function  */ W_Shotgun,
@@ -49,9 +49,10 @@ REGISTER_WEAPON(
 #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)
 {
@@ -62,7 +63,7 @@ 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));
 
@@ -142,11 +143,11 @@ void W_Shotgun_Melee_Think(void)
                        //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');
@@ -303,7 +304,7 @@ float W_Shotgun(float req)
                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:
@@ -317,7 +318,7 @@ float W_Shotgun(float req)
                                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
index e7477227817da1153798fc0f0a1e1767d5e667de..86fcca34681630d81b4b3da73a9a402e79674e0a 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ TUBA,
 /* function  */ W_Tuba,
@@ -51,9 +51,10 @@ float W_Tuba_MarkClientOnlyFieldsAsUsed() {
 .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)
 {
@@ -357,7 +358,7 @@ void W_Tuba_NoteOn(float hittype)
        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)
index 43ede987cef13a040df5bda4d023e66cb408da35..da94149009fc835cc1e09b6ffea1a66d42aa4c46 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ VAPORIZER,
 /* function  */ W_Vaporizer,
@@ -46,9 +46,10 @@ VAPORIZER_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
 .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)
@@ -63,7 +64,7 @@ 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);
@@ -165,9 +166,9 @@ float W_Vaporizer(float req)
 
                                        // 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),
@@ -210,7 +211,7 @@ float W_Vaporizer(float req)
                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:
@@ -218,7 +219,7 @@ float W_Vaporizer(float req)
                        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:
index 3c0d21354de46d73af552d758ab95f81bd293f10..0b0dc301397483be22d605ee17381e4a7c9d5736 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef REGISTER_WEAPON
+#ifndef IMPLEMENTATION
 REGISTER_WEAPON(
 /* WEP_##id  */ VORTEX,
 /* function  */ W_Vortex,
@@ -56,9 +56,10 @@ VORTEX_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
 
 .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) {
@@ -110,7 +111,7 @@ void W_Vortex_Attack(float issecondary)
 
        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);
@@ -214,7 +215,7 @@ bool W_Vortex(int req)
                                                                                        {
                                                                                                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
                                                                                {
@@ -272,7 +273,7 @@ bool W_Vortex(int req)
                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:
@@ -281,7 +282,7 @@ bool W_Vortex(int req)
                        {
                                // 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
index b2a85093c6ecc21a5258692ac5df1db8fa1c4ccc..d01f6f7d4d0d2f986a288f1de66b2948219ba777 100644 (file)
@@ -5,6 +5,7 @@
 #include "../common/items/all.qh"
 #include "../common/weapons/all.qh"
 #include "../common/mapinfo.qh"
+#include "../common/mutators/base.qh"
 
 ///////////////////////////////////////////////
 // Menu Source File
@@ -81,7 +82,6 @@ void m_init()
 
        // needs to be done so early because of the constants they create
        static_init();
-       CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
 
        RegisterSLCategories();
 
index 2170a83fcb3a077ab1de50531770b05c73ab756a..4a14eea7b1d12652fbb27b73dd706e11950851c0 100644 (file)
@@ -5,5 +5,6 @@
 #include "../classes.inc"
 #define IMPLEMENTATION
 #include "../classes.inc"
+#undef IMPLEMENTATION
 
 #endif
index a35fd484f37c1263172229728da7d2672520ee40..64f12478ddeb9bff3fe171e50bf8f5e2480f5aa8 100644 (file)
@@ -29,3 +29,5 @@ xonotic/util.qc
 ../common/weapons/all.qc // TODO
 
 ../warpzonelib/mathlib.qc
+
+../../mod/menu/progs.inc
index 9fa1667099b4b3ac017cde9987004d58dd082192..fcf1c04d29cda938cd5f8e3454bf1fc2150a13e7 100644 (file)
@@ -600,7 +600,7 @@ void havocbot_movetogoal()
                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;
 
@@ -614,7 +614,7 @@ void havocbot_movetogoal()
                                        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);
@@ -930,7 +930,7 @@ void havocbot_chooseenemy()
 
                // 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;
@@ -980,7 +980,7 @@ void havocbot_chooseweapon()
        // ;)
        if(g_weaponarena_weapons == WEPSET_TUBA)
        {
-               self.switchweapon = WEP_TUBA;
+               self.switchweapon = WEP_TUBA.m_id;
                return;
        }
 
@@ -989,7 +989,7 @@ void havocbot_chooseweapon()
        {
                // 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))
                        {
index f0a615a236e0a50c8f76e5dee981adf771cc5c33..c68f214d6ecad20f75bd6243e3a4cdce9bb28c39 100644 (file)
@@ -2363,7 +2363,7 @@ void PlayerPreThink (void)
 
                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));
@@ -2459,7 +2459,7 @@ void PlayerPreThink (void)
 
                // 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)
@@ -2536,7 +2536,7 @@ void PlayerPreThink (void)
 
        // 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;
index 8b4c25c1f8ec42c0aa1b0dacb84e2d9e86fb0870..9bc36c8df8098fe7c37ca22ae4977794bcd46b40 100644 (file)
@@ -322,7 +322,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp
                        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;
index 7b0a4ea98fb26a66e660b29f92940c4ab6245102..a55718d72fa55bf1343ff97cdc292c827a50d13d 100644 (file)
@@ -107,7 +107,7 @@ void GiveFrags (entity attacker, entity targ, float f, int deathtype)
                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
                }
@@ -648,7 +648,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
                                        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))
@@ -958,8 +958,8 @@ float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector in
 
        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)
@@ -1020,7 +1020,7 @@ float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector in
                                        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)
index f02e4c11b1f07ad55173652988a9cc6f92fbeaef..6f94cb3d06a0b5fb70ad2c9ad6131c4144334dc9 100644 (file)
@@ -394,7 +394,7 @@ void FireGrapplingHook (void)
 
 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)
@@ -423,14 +423,14 @@ void GrapplingHookFrame()
                        //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;
@@ -492,11 +492,11 @@ void GrappleHookInit()
        }
        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);
        }
 }
 
index 3e3682400bd2669a167fcc211ecd737ed9a222c7..dcfc19eb17e3d9440a8f84638795bdfd234d3ed1 100644 (file)
@@ -561,7 +561,6 @@ void spawnfunc___init_dedicated_server(void)
 
        // 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);
@@ -610,7 +609,6 @@ void spawnfunc_worldspawn (void)
 
        // 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);
index f038d264594b3f46a23e5a3ec1ed6f55cb2700ff..d77728215137fd0cae0754c2bd89335767a0546a 100644 (file)
@@ -515,14 +515,14 @@ float want_weapon(entity weaponinfo, float allguns) // WEAPONTODO: what still ne
                        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;
 
index a3c0d78d30310933631c53ca00809c51ddaff94a..a3dd45e51e5d3d247edbf5b914e1308d6f7ca6f8 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "t_items.qh"
 
-#include "mutators/base.qh"
+#include "mutators/events.qh"
 #include "mutators/gamemode_race.qh"
 
 #include "../common/constants.qh"
@@ -75,7 +75,6 @@ vector shotorg_adjust(vector vecs, float y_is_right, float visual);
 
 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
diff --git a/qcsrc/server/mutators/base.qc b/qcsrc/server/mutators/base.qc
deleted file mode 100644 (file)
index 2f78ec1..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-#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");
-       }
-}
diff --git a/qcsrc/server/mutators/base.qh b/qcsrc/server/mutators/base.qh
deleted file mode 100644 (file)
index c12050c..0000000
+++ /dev/null
@@ -1,569 +0,0 @@
-#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
diff --git a/qcsrc/server/mutators/events.qh b/qcsrc/server/mutators/events.qh
new file mode 100644 (file)
index 0000000..52be590
--- /dev/null
@@ -0,0 +1,480 @@
+#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
index e3e7b67dee894e5eb25831cefe6cb9b036ac5b8c..a22a17110ba5d0e25fe67f72050463af0087838b 100644 (file)
@@ -158,9 +158,9 @@ void GiveBall(entity plyr, entity ball)
        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;
 }
 
@@ -873,7 +873,7 @@ float w_nexball_weapon(float req)
        }
        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;
@@ -936,7 +936,7 @@ MUTATOR_HOOKFUNCTION(nexball_PlayerPreThink)
                        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);
 
@@ -982,7 +982,7 @@ MUTATOR_HOOKFUNCTION(nexball_SetStartItems)
 
 MUTATOR_HOOKFUNCTION(nexball_ForbidThrowing)
 {
-       if(self.weapon == WEP_MORTAR)
+       if(self.weapon == WEP_MORTAR.m_id)
                return true;
 
        return false;
@@ -991,7 +991,7 @@ MUTATOR_HOOKFUNCTION(nexball_ForbidThrowing)
 MUTATOR_HOOKFUNCTION(nexball_FilterItem)
 {
        if(self.classname == "droppedweapon")
-       if(self.weapon == WEP_MORTAR)
+       if(self.weapon == WEP_MORTAR.m_id)
                return true;
 
        return false;
index 36bf631bbd3551608130cabe1a10ff80f6e649a7..f23f42a8924dd717ab63e900f57d13be6ea0f4ff 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef MUTATOR_H
 #define MUTATOR_H
 
-#include "base.qh"
+#include "../../common/mutators/base.qh"
 #include "mutator_nades.qh"
 
 #include "../cl_client.qh"
index f5e3fa8bdceab5e0869cc97fb8bafd632464e4f5..f144899c8d86a1da4d761cb34309f0c2f1f30ffd 100644 (file)
@@ -469,7 +469,7 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_Calculate)
                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)
        {
@@ -493,7 +493,7 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_Calculate)
        // 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))
index e71f49265add057b6fb60ccbf094d7ea4fd61b53..a59bd0fe0cafbc2e2d5c2acb1910f456ac62ff24 100644 (file)
@@ -250,7 +250,7 @@ MUTATOR_HOOKFUNCTION(instagib_PlayerDamage)
                }
 
                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)
                        {
@@ -262,7 +262,7 @@ MUTATOR_HOOKFUNCTION(instagib_PlayerDamage)
                        }
                }
 
-               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)
                        {
@@ -319,13 +319,13 @@ MUTATOR_HOOKFUNCTION(instagib_FilterItem)
        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);
index 243563fa966e1e99aea718699586085b67117915..ceabcb9b2d1134d1ae4482a1d36d79f8b8f16a8e 100644 (file)
@@ -604,28 +604,28 @@ void nade_damage(entity inflictor, entity attacker, float damage, int deathtype,
        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;
@@ -925,7 +925,7 @@ MUTATOR_HOOKFUNCTION(nades_PlayerPreThink)
        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)
index d52bd09ee32c68ddd70a332ca62bd139f4b287c7..78875cb70f20227bbdb1d995cfc982522e05717c 100644 (file)
@@ -87,11 +87,11 @@ float nt_IsNewToy(float w)
 {
        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;
index ecf07cb7875ee53582e34cd478608abe664284a1..f239dbbf635d17623c2e2d20fcdb164a932a3914 100644 (file)
@@ -24,7 +24,7 @@ float NIX_CanChooseWeapon(float wpn)
        }
        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;
index a552e0114b15e159a4ca796f73251816aa3606e6..6c04b4d5452ac1ceff8c8977a5fa0cf981c0303d 100644 (file)
@@ -46,7 +46,7 @@ float ok_CheckWeaponCharge(entity ent, int wep)
 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;
 
@@ -148,9 +148,9 @@ MUTATOR_HOOKFUNCTION(ok_PlayerPreThink)
                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),
@@ -275,8 +275,8 @@ MUTATOR_HOOKFUNCTION(ok_StartItems)
 {
        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;
@@ -334,12 +334,12 @@ void ok_Initialize()
        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)
@@ -367,8 +367,8 @@ 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;
index e139865ab56395936c000fe3e28a6981d8f553a5..d0fe0a60a846ec78c2785875369ba785dbf45e24 100644 (file)
@@ -79,7 +79,7 @@
     #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"
index da723d927963bbfec2941394dd2dcbe736e9b07e..44e51828b1d2db962ede2865efad9bf77747581d 100644 (file)
@@ -1,7 +1,7 @@
 #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"
index 51b7b41e963d5eae2e10835997325f7a009d19f0..7e5aec86d37ea1a12448ffe425d1c8c6ca3e58ac 100644 (file)
@@ -117,3 +117,5 @@ weapons/weaponsystem.qc
 ../warpzonelib/mathlib.qc
 ../warpzonelib/server.qc
 ../warpzonelib/util_server.qc
+
+../../mod/server/progs.inc
index 3143699f2d7b18064466b4e3df3714850cd590c4..5b8dfd4989b84076a3d0e37ebf5c2a12fada9b69 100644 (file)
@@ -12,6 +12,7 @@
 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
 
index 4f6654a934593090f05f0dfeafd419275994df6e..2c5fb3dd8433fb44e481b3c5a9493d7fd9df2cac 100644 (file)
@@ -896,19 +896,19 @@ void vehicles_damage(entity inflictor, entity attacker, float damage, int deatht
     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;
index 89c4253a13f125d6a0e4c0d97aa6920de1c2a9db..94093438c7213336a8ae0e791c17c334c3d79eb9 100644 (file)
@@ -26,7 +26,7 @@ float client_hasweapon(entity cl, float wpn, float andammo, float complain)
        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)
@@ -55,7 +55,7 @@ float client_hasweapon(entity cl, float wpn, float andammo, float 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;
 
index d14bcfd1cfdec2d48aacdef8a572f0af9b0b0dd8..89ec52f2179f5114230addfe9eb567aa6909c55a 100644 (file)
@@ -144,7 +144,7 @@ float W_IsWeaponThrowable(float w)
                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;
index 98cbb2ba872a10794dc057693612c108163ec23e..49f6fdde73a51115762ff01f882b42cea485ee40 100644 (file)
@@ -25,7 +25,7 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector m
        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;
@@ -273,7 +273,7 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
        //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)
index d06d11cd97ad6909f25e300e7e48fe3566c78257..08568ec86e09d41d5f0c15599be5b3a1fe9d6873 100644 (file)
@@ -472,11 +472,11 @@ float weapon_prepareattack_checkammo(float secondary)
        {
                // 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
 
@@ -637,7 +637,7 @@ void weapon_thinkf(float fr, float t, void() func)
 
        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);