]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/miscfunctions.qc
Remove even more self
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / miscfunctions.qc
index e7eed32b43c5931998ca8425ab7a784f542b350c..bcb8d02d9ab6ec23beba89330e80d7e703b99355 100644 (file)
@@ -5,7 +5,7 @@
 #include "g_hook.qh"
 #include "ipban.qh"
 #include "mutators/all.qh"
-#include "t_items.qh"
+#include "../common/t_items.qh"
 #include "weapons/accuracy.qh"
 #include "weapons/csqcprojectile.qh"
 #include "weapons/selection.qh"
@@ -13,7 +13,7 @@
 #include "../common/constants.qh"
 #include "../common/deathtypes/all.qh"
 #include "../common/mapinfo.qh"
-#include "../common/notifications.qh"
+#include "../common/notifications/all.qh"
 #include "../common/playerstats.qh"
 #include "../common/teams.qh"
 #include "../common/triggers/subs.qh"
@@ -23,6 +23,8 @@
 #include "../common/vehicles/sv_vehicles.qh"
 #include "../common/vehicles/vehicle.qh"
 #include "../common/items/all.qc"
+#include "../common/state.qh"
+#include "../common/effects/qc/globalsound.qh"
 #include "../lib/csqcmodel/sv_model.qh"
 #include "../lib/warpzone/anglestransform.qh"
 #include "../lib/warpzone/server.qh"
@@ -208,8 +210,8 @@ string NearestLocation(vector p)
     return ret;
 }
 
-string formatmessage(string msg)
-{SELFPARAM();
+string formatmessage(entity this, string msg)
+{
        float p, p1, p2;
        float n;
        vector cursor;
@@ -221,12 +223,12 @@ string formatmessage(string msg)
        n = 7;
 
        ammoitems = "batteries";
-       if(self.items & ITEM_Plasma.m_itemid) ammoitems = ITEM_Plasma.m_name;
-       if(self.items & ITEM_Cells.m_itemid) ammoitems = ITEM_Cells.m_name;
-       if(self.items & ITEM_Rockets.m_itemid) ammoitems = ITEM_Rockets.m_name;
-       if(self.items & ITEM_Shells.m_itemid) ammoitems = ITEM_Shells.m_name;
+       if(this.items & ITEM_Plasma.m_itemid) ammoitems = ITEM_Plasma.m_name;
+       if(this.items & ITEM_Cells.m_itemid) ammoitems = ITEM_Cells.m_name;
+       if(this.items & ITEM_Rockets.m_itemid) ammoitems = ITEM_Rockets.m_name;
+       if(this.items & ITEM_Shells.m_itemid) ammoitems = ITEM_Shells.m_name;
 
-       WarpZone_crosshair_trace(self);
+       WarpZone_crosshair_trace(this);
        cursor = trace_endpos;
        cursor_ent = trace_ent;
 
@@ -235,8 +237,8 @@ string formatmessage(string msg)
                        break; // too many replacements
 
                n = n - 1;
-               p1 = strstr(msg, "%", p); // NOTE: this destroys msg as it's a tempstring!
-               p2 = strstr(msg, "\\", p); // NOTE: this destroys msg as it's a tempstring!
+               p1 = strstrofs(msg, "%", p); // NOTE: this destroys msg as it's a tempstring!
+               p2 = strstrofs(msg, "\\", p); // NOTE: this destroys msg as it's a tempstring!
 
                if (p1 < 0)
                        p1 = p2;
@@ -257,21 +259,21 @@ string formatmessage(string msg)
                        case "%": replacement = "%"; break;
                        case "\\":replacement = "\\"; break;
                        case "n": replacement = "\n"; break;
-                       case "a": replacement = ftos(floor(self.armorvalue)); break;
-                       case "h": replacement = ftos(floor(self.health)); break;
-                       case "l": replacement = NearestLocation(self.origin); break;
+                       case "a": replacement = ftos(floor(this.armorvalue)); break;
+                       case "h": replacement = ftos(floor(this.health)); break;
+                       case "l": replacement = NearestLocation(this.origin); break;
                        case "y": replacement = NearestLocation(cursor); break;
-                       case "d": replacement = NearestLocation(self.death_origin); break;
-                       case "w": replacement = WEP_NAME(((!self.weapon) ? (!self.switchweapon ? self.cnt : self.switchweapon) : self.weapon)); break;
+                       case "d": replacement = NearestLocation(this.death_origin); break;
+                       case "w": replacement = ((PS(this).m_weapon == WEP_Null) ? ((PS(this).m_switchweapon == WEP_Null) ? Weapons_from(this.cnt) : PS(this).m_switchweapon) : PS(this).m_weapon).m_name; break;
                        case "W": replacement = ammoitems; break;
                        case "x": replacement = ((cursor_ent.netname == "" || !cursor_ent) ? "nothing" : cursor_ent.netname); break;
-                       case "s": replacement = ftos(vlen(self.velocity - self.velocity_z * '0 0 1')); break;
-                       case "S": replacement = ftos(vlen(self.velocity)); break;
+                       case "s": replacement = ftos(vlen(this.velocity - this.velocity_z * '0 0 1')); break;
+                       case "S": replacement = ftos(vlen(this.velocity)); break;
                        case "t": replacement = seconds_tostring(ceil(max(0, autocvar_timelimit * 60 + game_starttime - time))); break;
                        case "T": replacement = seconds_tostring(floor(time - game_starttime)); break;
                        default:
                        {
-                               MUTATOR_CALLHOOK(FormatMessage, escape, replacement, msg);
+                               MUTATOR_CALLHOOK(FormatMessage, this, escape, replacement, msg);
                                escape = format_escape;
                                replacement = format_replacement;
                                break;
@@ -374,8 +376,42 @@ string W_FixWeaponOrder_ForceComplete_AndBuildImpulseList(string wo)
        self.weaponorder_byimpulse = strzone(W_FixWeaponOrder_BuildImpulseList(o));
        return o;
 }
-void GetCvars(float f)
-{SELFPARAM();
+
+REPLICATE(autoswitch, bool, "cl_autoswitch");
+
+REPLICATE(cvar_cl_allow_uid2name, bool, "cl_allow_uid2name");
+
+REPLICATE(cvar_cl_autoscreenshot, int, "cl_autoscreenshot");
+
+REPLICATE(cvar_cl_autotaunt, float, "cl_autotaunt");
+
+REPLICATE(cvar_cl_clippedspectating, bool, "cl_clippedspectating");
+
+REPLICATE(cvar_cl_handicap, float, "cl_handicap");
+
+REPLICATE(cvar_cl_jetpack_jump, bool, "cl_jetpack_jump");
+
+REPLICATE(cvar_cl_movement_track_canjump, bool, "cl_movement_track_canjump");
+
+REPLICATE(cvar_cl_newusekeysupported, bool, "cl_newusekeysupported");
+
+REPLICATE(cvar_cl_noantilag, bool, "cl_noantilag");
+
+REPLICATE(cvar_cl_physics, string, "cl_physics");
+
+REPLICATE(cvar_cl_voice_directional, int, "cl_voice_directional");
+
+REPLICATE(cvar_cl_voice_directional_taunt_attenuation, float, "cl_voice_directional_taunt_attenuation");
+
+REPLICATE(cvar_cl_weaponimpulsemode, int, "cl_weaponimpulsemode");
+
+REPLICATE(cvar_g_xonoticversion, string, "g_xonoticversion");
+
+/**
+ * @param f -1: cleanup, 0: request, 1: receive
+ */
+void GetCvars(entity this, int f)
+{
        string s = string_null;
 
        if (f > 0)
@@ -389,13 +425,6 @@ void GetCvars(float f)
 
        ReplicateVars(this, s, f);
 
-       GetCvars_handleFloat(s, f, autoswitch, "cl_autoswitch");
-       GetCvars_handleFloat(s, f, cvar_cl_autoscreenshot, "cl_autoscreenshot");
-       GetCvars_handleFloat(s, f, cvar_cl_jetpack_jump, "cl_jetpack_jump");
-       GetCvars_handleString(s, f, cvar_g_xonoticversion, "g_xonoticversion");
-       GetCvars_handleString(s, f, cvar_cl_physics, "cl_physics");
-       GetCvars_handleFloat(s, f, cvar_cl_handicap, "cl_handicap");
-       GetCvars_handleFloat(s, f, cvar_cl_clippedspectating, "cl_clippedspectating");
        GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriority, "cl_weaponpriority", W_FixWeaponOrder_ForceComplete_AndBuildImpulseList);
        GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[0], "cl_weaponpriority0", W_FixWeaponOrder_AllowIncomplete);
        GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[1], "cl_weaponpriority1", W_FixWeaponOrder_AllowIncomplete);
@@ -407,23 +436,14 @@ void GetCvars(float f)
        GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[7], "cl_weaponpriority7", W_FixWeaponOrder_AllowIncomplete);
        GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[8], "cl_weaponpriority8", W_FixWeaponOrder_AllowIncomplete);
        GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[9], "cl_weaponpriority9", W_FixWeaponOrder_AllowIncomplete);
-       GetCvars_handleFloat(s, f, cvar_cl_weaponimpulsemode, "cl_weaponimpulsemode");
-       GetCvars_handleFloat(s, f, cvar_cl_autotaunt, "cl_autotaunt");
-       GetCvars_handleFloat(s, f, cvar_cl_noantilag, "cl_noantilag");
-       GetCvars_handleFloat(s, f, cvar_cl_voice_directional, "cl_voice_directional");
-       GetCvars_handleFloat(s, f, cvar_cl_voice_directional_taunt_attenuation, "cl_voice_directional_taunt_attenuation");
-
-       GetCvars_handleFloatOnce(s, f, cvar_cl_gunalign, "cl_gunalign");
-       GetCvars_handleFloat(s, f, cvar_cl_allow_uid2name, "cl_allow_uid2name");
+
        GetCvars_handleFloat(s, f, cvar_cl_allow_uidtracking, "cl_allow_uidtracking");
-       GetCvars_handleFloat(s, f, cvar_cl_movement_track_canjump, "cl_movement_track_canjump");
-       GetCvars_handleFloat(s, f, cvar_cl_newusekeysupported, "cl_newusekeysupported");
 
        // fixup of switchweapon (needed for LMS or when spectating is disabled, as PutClientInServer comes too early)
        if (f > 0)
        {
                if (s == "cl_weaponpriority")
-                       self.switchweapon = w_getbestweapon(self);
+                       if (PS(self)) PS(self).m_switchweapon = w_getbestweapon(self);
                if (s == "cl_allow_uidtracking")
                        PlayerStats_GameReport_AddPlayer(self);
        }
@@ -444,7 +464,7 @@ string playername(entity p)
 
 float want_weapon(entity weaponinfo, float allguns) // WEAPONTODO: what still needs done?
 {
-       int i = weaponinfo.weapon;
+       int i = weaponinfo.m_id;
        int d = 0;
        bool allow_mutatorblocked = false;
 
@@ -487,8 +507,7 @@ float want_weapon(entity weaponinfo, float allguns) // WEAPONTODO: what still ne
 
 void readplayerstartcvars()
 {
-       entity e;
-       float i, j, t;
+       float i, t;
        string s;
 
        // initialize starting values for players
@@ -524,24 +543,20 @@ void readplayerstartcvars()
        {
                g_weaponarena = 1;
                g_weaponarena_list = "All Weapons";
-               for (j = WEP_FIRST; j <= WEP_LAST; ++j)
-               {
-                       e = Weapons_from(j);
-                       if (!(e.spawnflags & WEP_FLAG_MUTATORBLOCKED))
-                               g_weaponarena_weapons |= (e.m_wepset);
-               }
+               FOREACH(Weapons, it != WEP_Null, LAMBDA(
+                       if(!(it.spawnflags & WEP_FLAG_MUTATORBLOCKED))
+                               g_weaponarena_weapons |= (it.m_wepset);
+               ));
        }
        else if (s == "most")
        {
                g_weaponarena = 1;
                g_weaponarena_list = "Most Weapons";
-               for (j = WEP_FIRST; j <= WEP_LAST; ++j)
-               {
-                       e = Weapons_from(j);
-                       if (!(e.spawnflags & WEP_FLAG_MUTATORBLOCKED))
-                               if (e.spawnflags & WEP_FLAG_NORMAL)
-                                       g_weaponarena_weapons |= (e.m_wepset);
-               }
+               FOREACH(Weapons, it != WEP_Null, LAMBDA(
+                       if(!(it.spawnflags & WEP_FLAG_MUTATORBLOCKED))
+                               if(it.spawnflags & WEP_FLAG_NORMAL)
+                                       g_weaponarena_weapons |= (it.m_wepset);
+               ));
        }
        else if (s == "none")
        {
@@ -556,20 +571,14 @@ void readplayerstartcvars()
                for (i = 0; i < t; ++i)
                {
                        s = argv(i);
-                       for (j = WEP_FIRST; j <= WEP_LAST; ++j)
-                       {
-                               e = Weapons_from(j);
-                               if (e.netname == s)
+                       FOREACH(Weapons, it != WEP_Null, LAMBDA(
+                               if(it.netname == s)
                                {
-                                       g_weaponarena_weapons |= (e.m_wepset);
-                                       g_weaponarena_list = strcat(g_weaponarena_list, e.m_name, " & ");
+                                       g_weaponarena_weapons |= (it.m_wepset);
+                                       g_weaponarena_list = strcat(g_weaponarena_list, it.m_name, " & ");
                                        break;
                                }
-                       }
-                       if (j > WEP_LAST)
-                       {
-                               LOG_INFO("The weapon mutator list contains an unknown weapon ", s, ". Skipped.\n");
-                       }
+                       ));
                }
                g_weaponarena_list = strzone(substring(g_weaponarena_list, 0, strlen(g_weaponarena_list) - 3));
        }
@@ -588,18 +597,16 @@ void readplayerstartcvars()
        }
        else
        {
-               for (i = WEP_FIRST; i <= WEP_LAST; ++i)
-               {
-                       e = Weapons_from(i);
-                       int w = want_weapon(e, false);
-                       WepSet s = e.m_wepset;
+               FOREACH(Weapons, it != WEP_Null, LAMBDA(
+                       int w = want_weapon(it, false);
+                       WepSet s = it.m_wepset;
                        if(w & 1)
                                start_weapons |= s;
                        if(w & 2)
                                start_weapons_default |= s;
                        if(w & 4)
                                start_weapons_defaultmask |= s;
-               }
+               ));
        }
 
        if(!cvar("g_use_ammunition"))
@@ -651,18 +658,16 @@ void readplayerstartcvars()
                        warmup_start_weapons = '0 0 0';
                        warmup_start_weapons_default = '0 0 0';
                        warmup_start_weapons_defaultmask = '0 0 0';
-                       for (i = WEP_FIRST; i <= WEP_LAST; ++i)
-                       {
-                               e = Weapons_from(i);
-                               int w = want_weapon(e, g_warmup_allguns);
-                               WepSet s = (e.m_wepset);
+                       FOREACH(Weapons, it != WEP_Null, LAMBDA(
+                               int w = want_weapon(it, g_warmup_allguns);
+                               WepSet s = (it.m_wepset);
                                if(w & 1)
                                        warmup_start_weapons |= s;
                                if(w & 2)
                                        warmup_start_weapons_default |= s;
                                if(w & 4)
                                        warmup_start_weapons_defaultmask |= s;
-                       }
+                       ));
                }
        }
 
@@ -681,13 +686,10 @@ void readplayerstartcvars()
        WepSet precache_weapons = start_weapons;
        if (g_warmup_allguns != 1)
                precache_weapons |= warmup_start_weapons;
-       for (i = WEP_FIRST; i <= WEP_LAST; ++i)
-       {
-               e = Weapons_from(i);
-               if(precache_weapons & (e.m_wepset)) {
-                       e.wr_init(e);
-               }
-       }
+       FOREACH(Weapons, it != WEP_Null, LAMBDA(
+               if(precache_weapons & (it.m_wepset))
+                       it.wr_init(it);
+       ));
 
        start_ammo_shells = max(0, start_ammo_shells);
        start_ammo_nails = max(0, start_ammo_nails);
@@ -735,36 +737,24 @@ void precache_playermodel(string m)
 }
 void precache_all_playermodels(string pattern)
 {
-       float globhandle, i, n;
-       string f;
-
-       globhandle = search_begin(pattern, true, false);
-       if (globhandle < 0)
-               return;
-       n = search_getsize(globhandle);
-       for (i = 0; i < n; ++i)
+       int globhandle = search_begin(pattern, true, false);
+       if (globhandle < 0) return;
+       int n = search_getsize(globhandle);
+       for (int i = 0; i < n; ++i)
        {
-               //print(search_getfilename(globhandle, i), "\n");
-               f = search_getfilename(globhandle, i);
-               precache_playermodel(f);
+               string s = search_getfilename(globhandle, i);
+               precache_playermodel(s);
        }
        search_end(globhandle);
 }
 
 void precache_playermodels(string s)
 {
-       if(s != "")
-       {
-               int n = tokenize_console(s);
-               precache_playermodel(argv(0));
-
-               for (int i = 1; i < n; ++i)
-                       precache_model(argv(i));
-       }
+       FOREACH_WORD(s, true, LAMBDA(precache_playermodel(it)));
 }
 
 void precache()
-{SELFPARAM();
+{
     // gamemode related things
 
     // Precache all player models if desired
@@ -861,7 +851,7 @@ void remove_safely(entity e)
     builtin_remove(e);
 }
 
-void InitializeEntity(entity e, void() func, float order)
+void InitializeEntity(entity e, void(entity this) func, float order)
 {
     entity prev, cur;
 
@@ -895,7 +885,7 @@ void InitializeEntity(entity e, void() func, float order)
     }
 }
 void InitializeEntitiesRun()
-{SELFPARAM();
+{
     entity startoflist = initialize_entity_first;
     initialize_entity_first = NULL;
     remove = remove_except_protected;
@@ -909,7 +899,7 @@ void InitializeEntitiesRun()
         e.initialize_entity_order = 0;
        entity next = e.initialize_entity_next;
         e.initialize_entity_next = NULL;
-        var void() func = e.initialize_entity;
+        var void(entity this) func = e.initialize_entity;
         e.initialize_entity = func_null;
         if (e.classname == "initialize_entity")
         {
@@ -920,7 +910,7 @@ void InitializeEntitiesRun()
         //dprint("Delayed initialization: ", e.classname, "\n");
         if (func)
         {
-               WITH(entity, self, e, func());
+               WITHSELF(e, func(e));
         }
         else
         {
@@ -968,44 +958,25 @@ void EliminatedPlayers_Init(float(entity) isEliminated_func)
 }
 
 
-void adaptor_think2touch()
-{SELFPARAM();
-    entity o;
-    o = other;
-    other = world;
-    self.touch();
-    other = o;
-}
 
-void adaptor_think2use()
-{SELFPARAM();
-    entity o, a;
-    o = other;
-    a = activator;
-    activator = world;
-    other = world;
-    self.use();
-    other = o;
-    activator = a;
-}
 
-void adaptor_think2use_hittype_splash() // for timed projectile detonation
-{SELFPARAM();
-       if(!(self.flags & FL_ONGROUND)) // if onground, we ARE touching something, but HITTYPE_SPLASH is to be networked if the damage causing projectile is not touching ANYTHING
-               self.projectiledeathtype |= HITTYPE_SPLASH;
-       adaptor_think2use();
+void adaptor_think2use_hittype_splash(entity this) // for timed projectile detonation
+{
+       if(!(IS_ONGROUND(this))) // if onground, we ARE touching something, but HITTYPE_SPLASH is to be networked if the damage causing projectile is not touching ANYTHING
+               this.projectiledeathtype |= HITTYPE_SPLASH;
+       WITHSELF(this, adaptor_think2use(this));
 }
 
 // deferred dropping
-void DropToFloor_Handler()
-{SELFPARAM();
-    builtin_droptofloor();
-    self.dropped_origin = self.origin;
+void DropToFloor_Handler(entity this)
+{
+    WITHSELF(this, builtin_droptofloor());
+    this.dropped_origin = this.origin;
 }
 
-void droptofloor()
-{SELFPARAM();
-    InitializeEntity(self, DropToFloor_Handler, INITPRIO_DROPTOFLOOR);
+void droptofloor(entity this)
+{
+    InitializeEntity(this, DropToFloor_Handler, INITPRIO_DROPTOFLOOR);
 }
 
 
@@ -1059,8 +1030,8 @@ float tracebox_hits_box(vector start, vector mi, vector ma, vector end, vector t
     return trace_hits_box(start, end, thmi - ma, thma - mi);
 }
 
-float SUB_NoImpactCheck()
-{SELFPARAM();
+bool SUB_NoImpactCheck(entity this, entity toucher)
+{
        // zero hitcontents = this is not the real impact, but either the
        // mirror-impact of something hitting the projectile instead of the
        // projectile hitting the something, or a touchareagrid one. Neither of
@@ -1068,17 +1039,17 @@ float SUB_NoImpactCheck()
        if(trace_dphitcontents == 0)
        {
                //dprint("A hit happened with zero hit contents... DEBUG THIS, this should never happen for projectiles! Projectile will self-destruct.\n");
-               LOG_TRACEF("A hit from a projectile happened with no hit contents! DEBUG THIS, this should never happen for projectiles! Profectile will self-destruct. (edict: %d, classname: %s, origin: %s)\n", num_for_edict(self), self.classname, vtos(self.origin));
-               checkclient();
+               LOG_TRACEF("A hit from a projectile happened with no hit contents! DEBUG THIS, this should never happen for projectiles! Profectile will self-destruct. (edict: %d, classname: %s, origin: %s)\n", etof(this), this.classname, vtos(this.origin));
+               WITHSELF(this, checkclient());
        }
     if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
-        return 1;
-    if (other == world && self.size != '0 0 0')
+        return true;
+    if (toucher == world && this.size != '0 0 0')
     {
         vector tic;
-        tic = self.velocity * sys_frametime;
-        tic = tic + normalize(tic) * vlen(self.maxs - self.mins);
-        traceline(self.origin - tic, self.origin + tic, MOVE_NORMAL, self);
+        tic = this.velocity * sys_frametime;
+        tic = tic + normalize(tic) * vlen(this.maxs - this.mins);
+        traceline(this.origin - tic, this.origin + tic, MOVE_NORMAL, this);
         if (trace_fraction >= 1)
         {
             LOG_TRACE("Odd... did not hit...?\n");
@@ -1086,37 +1057,37 @@ float SUB_NoImpactCheck()
         else if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
         {
             LOG_TRACE("Detected and prevented the sky-grapple bug.\n");
-            return 1;
+            return true;
         }
     }
 
-    return 0;
+    return false;
 }
 
-#define SUB_OwnerCheck() (other && (other == self.owner))
+#define SUB_OwnerCheck(ent,oth) ((oth) && ((oth) == (ent).owner))
 
 void W_Crylink_Dequeue(entity e);
-float WarpZone_Projectile_Touch_ImpactFilter_Callback()
-{SELFPARAM();
-       if(SUB_OwnerCheck())
+bool WarpZone_Projectile_Touch_ImpactFilter_Callback(entity this, entity toucher)
+{
+       if(SUB_OwnerCheck(this, toucher))
                return true;
-       if(SUB_NoImpactCheck())
+       if(SUB_NoImpactCheck(this, toucher))
        {
-               if(self.classname == "nade")
+               if(this.classname == "nade")
                        return false; // no checks here
-               else if(self.classname == "grapplinghook")
-                       RemoveGrapplingHook(self.realowner);
-               else if(self.classname == "spike")
+               else if(this.classname == "grapplinghook")
+                       RemoveGrapplingHook(this.realowner);
+               else if(this.classname == "spike")
                {
-                       W_Crylink_Dequeue(self);
-                       remove(self);
+                       W_Crylink_Dequeue(this);
+                       remove(this);
                }
                else
-                       remove(self);
+                       remove(this);
                return true;
        }
        if(trace_ent && trace_ent.solid > SOLID_TRIGGER)
-               UpdateCSQCProjectile(self);
+               UpdateCSQCProjectile(this);
        return false;
 }
 
@@ -1141,6 +1112,10 @@ void URI_Get_Callback(float id, float status, string data)
                // online ban list
                OnlineBanList_URI_Get_Callback(id, status, data);
        }
+       else if (MUTATOR_CALLHOOK(URI_GetCallback, id, status, data))
+       {
+               // handled by a mutator
+       }
        else
        {
                LOG_INFO("Received HTTP request data for an invalid id ", ftos(id), ".\n");
@@ -1414,7 +1389,8 @@ float LostMovetypeFollow(entity ent)
        return 0;
 }
 
-float isPushable(entity e)
+.bool pushable;
+bool isPushable(entity e)
 {
        if(e.pushable)
                return true;
@@ -1426,9 +1402,6 @@ float isPushable(entity e)
        {
                case "body":
                case "droppedweapon":
-               case "keepawayball":
-               case "nexball_basketball":
-               case "nexball_football":
                        return true;
                case "bullet": // antilagged bullets can't hit this either
                        return false;