From: Mario <mario.mario@y7mail.com>
Date: Fri, 25 Sep 2020 12:12:17 +0000 (+1000)
Subject: Phase out miscfunctions.qc from the server codebase, preferring more fitting location... 
X-Git-Tag: xonotic-v0.8.5~747
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=aafb3956d4321d56a6c34ccb1796b8bf6fa89458;p=xonotic%2Fxonotic-data.pk3dir.git

Phase out miscfunctions.qc from the server codebase, preferring more fitting locations for its contents
---

diff --git a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh
index 78526bc26..869860f7d 100644
--- a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh
+++ b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh
@@ -3,7 +3,6 @@
 #include <common/mutators/base.qh>
 #include <server/elimination.qh>
 #include <server/round_handler.qh>
-#include <server/miscfunctions.qh>
 #include <server/command/sv_cmd.qh>
 
 int autocvar_g_ca_point_limit;
diff --git a/qcsrc/common/gamemodes/gamemode/ctf/cl_ctf.qc b/qcsrc/common/gamemodes/gamemode/ctf/cl_ctf.qc
index 85f8e22ae..e2258c0c5 100644
--- a/qcsrc/common/gamemodes/gamemode/ctf/cl_ctf.qc
+++ b/qcsrc/common/gamemodes/gamemode/ctf/cl_ctf.qc
@@ -1,5 +1,6 @@
 #include "cl_ctf.qh"
 
+#include <common/mutators/base.qh>
 #include <client/hud/panel/modicons.qh>
 
 // CTF HUD modicon section
diff --git a/qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qh b/qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qh
index d0e13c132..9fe2f0a54 100644
--- a/qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qh
+++ b/qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qh
@@ -2,6 +2,8 @@
 
 #include "ctf.qh"
 
+#include <common/items/item/pickup.qh>
+#include <common/mutators/base.qh>
 #include <common/gamemodes/sv_rules.qh>
 
 void ctf_Initialize();
diff --git a/qcsrc/common/gamemodes/gamemode/cts/cl_cts.qc b/qcsrc/common/gamemodes/gamemode/cts/cl_cts.qc
index 27d6b868e..950ebcf15 100644
--- a/qcsrc/common/gamemodes/gamemode/cts/cl_cts.qc
+++ b/qcsrc/common/gamemodes/gamemode/cts/cl_cts.qc
@@ -1,5 +1,7 @@
 #include "cl_cts.qh"
 
+#include <common/mutators/base.qh>
+
 REGISTER_MUTATOR(cl_cts, true);
 
 MUTATOR_HOOKFUNCTION(cl_cts, HUD_Physics_showoptional)
diff --git a/qcsrc/common/gamemodes/gamemode/lms/cl_lms.qc b/qcsrc/common/gamemodes/gamemode/lms/cl_lms.qc
index 649f964f5..7be2d31bc 100644
--- a/qcsrc/common/gamemodes/gamemode/lms/cl_lms.qc
+++ b/qcsrc/common/gamemodes/gamemode/lms/cl_lms.qc
@@ -1,5 +1,7 @@
 #include "cl_lms.qh"
 
+#include <common/mutators/base.qh>
+
 REGISTER_MUTATOR(cl_lms, true);
 
 MUTATOR_HOOKFUNCTION(cl_lms, DrawInfoMessages)
diff --git a/qcsrc/common/gamemodes/gamemode/nexball/cl_nexball.qc b/qcsrc/common/gamemodes/gamemode/nexball/cl_nexball.qc
index 19b7b63ce..276995716 100644
--- a/qcsrc/common/gamemodes/gamemode/nexball/cl_nexball.qc
+++ b/qcsrc/common/gamemodes/gamemode/nexball/cl_nexball.qc
@@ -1,6 +1,7 @@
 #include "cl_nexball.qh"
 
 #include <client/hud/panel/modicons.qh>
+#include <common/mutators/base.qh>
 
 // Nexball HUD mod icon
 void HUD_Mod_NexBall(vector pos, vector mySize)
diff --git a/qcsrc/common/gamemodes/gamemode/nexball/sv_nexball.qc b/qcsrc/common/gamemodes/gamemode/nexball/sv_nexball.qc
index 156719725..1959ac424 100644
--- a/qcsrc/common/gamemodes/gamemode/nexball/sv_nexball.qc
+++ b/qcsrc/common/gamemodes/gamemode/nexball/sv_nexball.qc
@@ -6,6 +6,7 @@
 #include <server/world.qh>
 #include <common/ent_cs.qh>
 #include <common/mapobjects/triggers.qh>
+#include <common/mutators/base.qh>
 
 .entity ballcarried;
 
diff --git a/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc b/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc
index f0a0046d8..18c2cbf1f 100644
--- a/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc
+++ b/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc
@@ -1,5 +1,7 @@
 #include "onslaught.qh"
 
+#include <common/mutators/base.qh>
+
 #ifdef GAMEQC
 REGISTER_NET_LINKED(ENT_ONSCAMERA)
 #endif
diff --git a/qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qh b/qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qh
index 0800ae10f..363c0e39f 100644
--- a/qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qh
+++ b/qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qh
@@ -1,5 +1,7 @@
 #pragma once
 
+#include <common/mutators/base.qh>
+
 float autocvar_g_onslaught_point_limit;
 void ons_Initialize();
 
diff --git a/qcsrc/common/gamemodes/gamemode/race/cl_race.qc b/qcsrc/common/gamemodes/gamemode/race/cl_race.qc
index c2346a4f2..b12564b18 100644
--- a/qcsrc/common/gamemodes/gamemode/race/cl_race.qc
+++ b/qcsrc/common/gamemodes/gamemode/race/cl_race.qc
@@ -1,5 +1,7 @@
 #include "cl_race.qh"
 
+#include <common/mutators/base.qh>
+
 // Race/CTS HUD mod icons
 float crecordtime_prev; // last remembered crecordtime
 float crecordtime_change_time; // time when crecordtime last changed
diff --git a/qcsrc/common/gamemodes/gamemode/tdm/sv_tdm.qc b/qcsrc/common/gamemodes/gamemode/tdm/sv_tdm.qc
index 43a993844..1fba2215f 100644
--- a/qcsrc/common/gamemodes/gamemode/tdm/sv_tdm.qc
+++ b/qcsrc/common/gamemodes/gamemode/tdm/sv_tdm.qc
@@ -51,6 +51,16 @@ void tdm_DelayedInit(entity this)
 	}
 }
 
+void tdm_Initialize()
+{
+	GameRules_teams(true);
+	GameRules_spawning_teams(autocvar_g_tdm_team_spawns);
+	GameRules_limit_score(autocvar_g_tdm_point_limit);
+	GameRules_limit_lead(autocvar_g_tdm_point_leadlimit);
+
+	InitializeEntity(NULL, tdm_DelayedInit, INITPRIO_GAMETYPE);
+}
+
 MUTATOR_HOOKFUNCTION(tdm, TeamBalance_CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
 {
 	M_ARGV(1, string) = "tdm_team";
diff --git a/qcsrc/common/gamemodes/gamemode/tdm/sv_tdm.qh b/qcsrc/common/gamemodes/gamemode/tdm/sv_tdm.qh
index adc6a3d6c..783655bba 100644
--- a/qcsrc/common/gamemodes/gamemode/tdm/sv_tdm.qh
+++ b/qcsrc/common/gamemodes/gamemode/tdm/sv_tdm.qh
@@ -4,19 +4,14 @@
 int autocvar_g_tdm_point_limit;
 int autocvar_g_tdm_point_leadlimit;
 bool autocvar_g_tdm_team_spawns;
-void tdm_DelayedInit(entity this);
+void tdm_Initialize();
 
 REGISTER_MUTATOR(tdm, false)
 {
     MUTATOR_STATIC();
 	MUTATOR_ONADD
 	{
-		GameRules_teams(true);
-        GameRules_spawning_teams(autocvar_g_tdm_team_spawns);
-		GameRules_limit_score(autocvar_g_tdm_point_limit);
-        GameRules_limit_lead(autocvar_g_tdm_point_leadlimit);
-
-		InitializeEntity(NULL, tdm_DelayedInit, INITPRIO_GAMETYPE);
+		tdm_Initialize();
 	}
 	return 0;
 }
diff --git a/qcsrc/common/mapobjects/misc/dynlight.qc b/qcsrc/common/mapobjects/misc/dynlight.qc
index 96d99b592..6395500d2 100644
--- a/qcsrc/common/mapobjects/misc/dynlight.qc
+++ b/qcsrc/common/mapobjects/misc/dynlight.qc
@@ -3,7 +3,6 @@
 #ifdef SVQC
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 
 const float LOOP = 1;
 
diff --git a/qcsrc/common/mapobjects/models.qc b/qcsrc/common/mapobjects/models.qc
index 6b272d1b1..9ba1dcdf6 100644
--- a/qcsrc/common/mapobjects/models.qc
+++ b/qcsrc/common/mapobjects/models.qc
@@ -3,7 +3,6 @@
 #ifdef SVQC
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include <common/net_linked.qh>
 #include "subs.qh"
 #include "triggers.qh"
diff --git a/qcsrc/common/monsters/monster/spider.qc b/qcsrc/common/monsters/monster/spider.qc
index d96544882..73518c1f9 100644
--- a/qcsrc/common/monsters/monster/spider.qc
+++ b/qcsrc/common/monsters/monster/spider.qc
@@ -1,5 +1,9 @@
 #include "spider.qh"
 
+#if defined(SVQC)
+	#include <common/mutators/base.qh>
+#endif
+
 #ifdef SVQC
 
 .float spider_slowness; // effect time of slowness inflicted by spiders
diff --git a/qcsrc/common/mutators/mutator/nix/sv_nix.qc b/qcsrc/common/mutators/mutator/nix/sv_nix.qc
index 867da41d4..0ec051a8c 100644
--- a/qcsrc/common/mutators/mutator/nix/sv_nix.qc
+++ b/qcsrc/common/mutators/mutator/nix/sv_nix.qc
@@ -1,6 +1,7 @@
 #include "sv_nix.qh"
 
 #include <server/weapons/selection.qh>
+#include <server/world.qh>
 
 //string autocvar_g_nix;
 int autocvar_g_balance_nix_ammo_cells;
diff --git a/qcsrc/common/physics/player.qc b/qcsrc/common/physics/player.qc
index 5e9460c83..319a6bf64 100644
--- a/qcsrc/common/physics/player.qc
+++ b/qcsrc/common/physics/player.qc
@@ -5,7 +5,6 @@
 #ifdef SVQC
 
 #include <server/client.qh>
-#include <server/miscfunctions.qh>
 #include <common/mapobjects/defs.qh>
 #include "../mapobjects/trigger/viewloc.qh"
 #include <server/main.qh>
diff --git a/qcsrc/common/turrets/sv_turrets.qh b/qcsrc/common/turrets/sv_turrets.qh
index 5191940b1..aec6045ae 100644
--- a/qcsrc/common/turrets/sv_turrets.qh
+++ b/qcsrc/common/turrets/sv_turrets.qh
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <server/miscfunctions.qh>
+#include "all.qh"
 
 entity turret_projectile(entity actor, Sound _snd, float _size, float _health, float _death, float _proj_type, float _cull, float _cli_anim);
 void turret_projectile_explode(entity this);
diff --git a/qcsrc/common/util.qc b/qcsrc/common/util.qc
index 4ad1d105d..b0acbee74 100644
--- a/qcsrc/common/util.qc
+++ b/qcsrc/common/util.qc
@@ -2023,4 +2023,53 @@ string playername(string thename, int teamid, bool team_colorize)
     else
         return thename;
 }
+
+float trace_hits_box_a0, trace_hits_box_a1;
+
+float trace_hits_box_1d(float end, float thmi, float thma)
+{
+    if (end == 0)
+    {
+        // just check if x is in range
+        if (0 < thmi)
+            return false;
+        if (0 > thma)
+            return false;
+    }
+    else
+    {
+        // do the trace with respect to x
+        // 0 -> end has to stay in thmi -> thma
+        trace_hits_box_a0 = max(trace_hits_box_a0, min(thmi / end, thma / end));
+        trace_hits_box_a1 = min(trace_hits_box_a1, max(thmi / end, thma / end));
+        if (trace_hits_box_a0 > trace_hits_box_a1)
+            return false;
+    }
+    return true;
+}
+
+float trace_hits_box(vector start, vector end, vector thmi, vector thma)
+{
+    end -= start;
+    thmi -= start;
+    thma -= start;
+    // now it is a trace from 0 to end
+
+    trace_hits_box_a0 = 0;
+    trace_hits_box_a1 = 1;
+
+    if (!trace_hits_box_1d(end.x, thmi.x, thma.x))
+        return false;
+    if (!trace_hits_box_1d(end.y, thmi.y, thma.y))
+        return false;
+    if (!trace_hits_box_1d(end.z, thmi.z, thma.z))
+        return false;
+
+    return true;
+}
+
+float tracebox_hits_box(vector start, vector mi, vector ma, vector end, vector thmi, vector thma)
+{
+    return trace_hits_box(start, end, thmi - ma, thma - mi);
+}
 #endif
diff --git a/qcsrc/common/util.qh b/qcsrc/common/util.qh
index 82a0f01c6..b5a4ee6df 100644
--- a/qcsrc/common/util.qh
+++ b/qcsrc/common/util.qh
@@ -244,4 +244,12 @@ float LostMovetypeFollow(entity ent);
 
 #ifdef GAMEQC
 string playername(string thename, int teamid, bool team_colorize);
+
+float trace_hits_box_1d(float end, float thmi, float thma);
+
+float trace_hits_box(vector start, vector end, vector thmi, vector thma);
+
+float tracebox_hits_box(vector start, vector mi, vector ma, vector end, vector thmi, vector thma);
+
+float tracebox_hits_box(vector start, vector mi, vector ma, vector end, vector thmi, vector thma);
 #endif
diff --git a/qcsrc/server/_mod.inc b/qcsrc/server/_mod.inc
index d6bc0528b..34ca1e2c8 100644
--- a/qcsrc/server/_mod.inc
+++ b/qcsrc/server/_mod.inc
@@ -17,7 +17,6 @@
 #include <server/main.qc>
 #include <server/mapvoting.qc>
 #include <server/matrix.qc>
-#include <server/miscfunctions.qc>
 #include <server/player.qc>
 #include <server/portals.qc>
 #include <server/race.qc>
diff --git a/qcsrc/server/_mod.qh b/qcsrc/server/_mod.qh
index e881b403d..c99753826 100644
--- a/qcsrc/server/_mod.qh
+++ b/qcsrc/server/_mod.qh
@@ -17,7 +17,6 @@
 #include <server/main.qh>
 #include <server/mapvoting.qh>
 #include <server/matrix.qh>
-#include <server/miscfunctions.qh>
 #include <server/player.qh>
 #include <server/portals.qh>
 #include <server/race.qh>
diff --git a/qcsrc/server/anticheat.qc b/qcsrc/server/anticheat.qc
index 7e8e50660..536a3b623 100644
--- a/qcsrc/server/anticheat.qc
+++ b/qcsrc/server/anticheat.qc
@@ -7,7 +7,6 @@
 #include <server/client.qh>
 #include <server/gamelog.qh>
 #include <server/main.qh>
-#include "miscfunctions.qh"
 
 #include "command/common.qh"
 #include <common/playerstats.qh>
diff --git a/qcsrc/server/bot/default/havocbot/havocbot.qc b/qcsrc/server/bot/default/havocbot/havocbot.qc
index 40a07a44c..c5a955749 100644
--- a/qcsrc/server/bot/default/havocbot/havocbot.qc
+++ b/qcsrc/server/bot/default/havocbot/havocbot.qc
@@ -8,9 +8,10 @@
 #include <common/stats.qh>
 #include <server/damage.qh>
 #include <server/items/items.qh>
-#include <server/miscfunctions.qh>
+#include <server/mutators/_mod.qh>
 #include <server/weapons/selection.qh>
 #include <server/weapons/weaponsystem.qh>
+#include <server/world.qh>
 #include "../cvars.qh"
 
 #include "../aim.qh"
diff --git a/qcsrc/server/bot/default/havocbot/roles.qc b/qcsrc/server/bot/default/havocbot/roles.qc
index 9c95fb87b..dbc55a90c 100644
--- a/qcsrc/server/bot/default/havocbot/roles.qc
+++ b/qcsrc/server/bot/default/havocbot/roles.qc
@@ -2,9 +2,9 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include <server/items/items.qh>
 #include <server/items/spawning.qh>
+#include <server/mutators/_mod.qh>
 #include <server/resources.qh>
 #include "havocbot.qh"
 
diff --git a/qcsrc/server/bot/default/navigation.qc b/qcsrc/server/bot/default/navigation.qc
index ff361388b..8a48efb0e 100644
--- a/qcsrc/server/bot/default/navigation.qc
+++ b/qcsrc/server/bot/default/navigation.qc
@@ -3,7 +3,6 @@
 #include <server/bot/api.qh>
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include "cvars.qh"
 
 #include "bot.qh"
diff --git a/qcsrc/server/bot/default/scripting.qc b/qcsrc/server/bot/default/scripting.qc
index 94c849650..bad63baa8 100644
--- a/qcsrc/server/bot/default/scripting.qc
+++ b/qcsrc/server/bot/default/scripting.qc
@@ -2,7 +2,6 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include <server/weapons/selection.qh>
 #include <server/weapons/weaponsystem.qh>
 #include "cvars.qh"
diff --git a/qcsrc/server/bot/default/waypoints.qc b/qcsrc/server/bot/default/waypoints.qc
index a9069a0b1..65da3b94c 100644
--- a/qcsrc/server/bot/default/waypoints.qc
+++ b/qcsrc/server/bot/default/waypoints.qc
@@ -3,8 +3,8 @@
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
 #include <server/items/items.qh>
-#include <server/miscfunctions.qh>
 #include <server/spawnpoints.qh>
+#include <server/weapons/tracing.qh>
 #include "cvars.qh"
 
 #include "bot.qh"
diff --git a/qcsrc/server/campaign.qc b/qcsrc/server/campaign.qc
index 3153ff111..cda65308d 100644
--- a/qcsrc/server/campaign.qc
+++ b/qcsrc/server/campaign.qc
@@ -1,11 +1,11 @@
 #include "campaign.qh"
 
+#include <common/mapinfo.qh>
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
 
 #include "cheats.qh"
 #include <server/intermission.qh>
-#include "miscfunctions.qh"
 #include "world.qh"
 
 #include "../common/campaign_common.qh"
diff --git a/qcsrc/server/chat.qc b/qcsrc/server/chat.qc
index 3362ab539..204ed1341 100644
--- a/qcsrc/server/chat.qc
+++ b/qcsrc/server/chat.qc
@@ -11,7 +11,9 @@
 #include <server/gamelog.qh>
 #include <server/main.qh>
 #include <server/mapvoting.qh>
-#include <server/miscfunctions.qh>
+#include <server/mutators/_mod.qh>
+#include <server/weapons/tracing.qh>
+#include <server/world.qh>
 
 /**
  * message "": do not say, just test flood control
diff --git a/qcsrc/server/cheats.qc b/qcsrc/server/cheats.qc
index fe1d1130a..2306abd69 100644
--- a/qcsrc/server/cheats.qc
+++ b/qcsrc/server/cheats.qc
@@ -2,7 +2,6 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include <common/effects/all.qh>
 #include <server/resources.qh>
 #include <server/main.qh>
diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc
index f2c261410..d67cd46ae 100644
--- a/qcsrc/server/client.qc
+++ b/qcsrc/server/client.qc
@@ -3,13 +3,11 @@
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
 #include <server/chat.qh>
-#include <server/miscfunctions.qh>
 #include <common/effects/all.qh>
 #include "anticheat.qh"
 #include "impulse.qh"
 #include "player.qh"
 #include "ipban.qh"
-#include "miscfunctions.qh"
 #include "portals.qh"
 #include "teamplay.qh"
 #include "spawnpoints.qh"
@@ -26,6 +24,7 @@
 #include <server/gamelog.qh>
 #include "race.qh"
 #include <server/main.qh>
+#include <server/mutators/_mod.qh>
 #include "antilag.qh"
 #include "campaign.qh"
 #include "command/common.qh"
diff --git a/qcsrc/server/clientkill.qc b/qcsrc/server/clientkill.qc
index 73ccb383d..96adde60f 100644
--- a/qcsrc/server/clientkill.qc
+++ b/qcsrc/server/clientkill.qc
@@ -4,6 +4,7 @@
 #include <common/stats.qh>
 #include <server/client.qh>
 #include <server/player.qh>
+#include <server/mutators/_mod.qh>
 
 #include "damage.qh"
 #include "teamplay.qh"
diff --git a/qcsrc/server/command/banning.qc b/qcsrc/server/command/banning.qc
index 962a8a1a8..1822f1a81 100644
--- a/qcsrc/server/command/banning.qc
+++ b/qcsrc/server/command/banning.qc
@@ -2,7 +2,6 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include <common/state.qh>
 #include <common/command/_mod.qh>
 #include "banning.qh"
diff --git a/qcsrc/server/command/cmd.qc b/qcsrc/server/command/cmd.qc
index 8ffc52b24..6426ce1a2 100644
--- a/qcsrc/server/command/cmd.qc
+++ b/qcsrc/server/command/cmd.qc
@@ -2,7 +2,6 @@
 
 #include <server/chat.qh>
 #include <server/world.qh>
-#include <server/miscfunctions.qh>
 
 #include <common/command/_mod.qh>
 
diff --git a/qcsrc/server/command/common.qc b/qcsrc/server/command/common.qc
index d67927282..710c3889f 100644
--- a/qcsrc/server/command/common.qc
+++ b/qcsrc/server/command/common.qc
@@ -2,10 +2,10 @@
 
 #include <server/chat.qh>
 #include <server/client.qh>
+#include <server/mutators/_mod.qh>
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
 #include <server/world.qh>
-#include <server/miscfunctions.qh>
 
 #include <common/command/_mod.qh>
 #include "common.qh"
diff --git a/qcsrc/server/command/getreplies.qc b/qcsrc/server/command/getreplies.qc
index 95ee35a36..17fcc2d35 100644
--- a/qcsrc/server/command/getreplies.qc
+++ b/qcsrc/server/command/getreplies.qc
@@ -4,13 +4,14 @@
 #include <common/wepent.qh>
 #include <common/stats.qh>
 #include <server/intermission.qh>
+#include <server/main.qh>
+#include <server/mutators/_mod.qh>
 #include <server/world.qh>
-#include <server/miscfunctions.qh>
 
 #include <common/command/_mod.qh>
 #include "getreplies.qh"
 
-#include "../race.qh"
+#include <server/race.qh>
 
 #include <common/constants.qh>
 #include <common/gamemodes/_mod.qh>
diff --git a/qcsrc/server/command/vote.qc b/qcsrc/server/command/vote.qc
index 0f85507fd..16b636c85 100644
--- a/qcsrc/server/command/vote.qc
+++ b/qcsrc/server/command/vote.qc
@@ -4,7 +4,6 @@
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
 #include <server/gamelog.qh>
-#include <server/miscfunctions.qh>
 
 #include <common/command/_mod.qh>
 #include "vote.qh"
@@ -13,7 +12,7 @@
 
 #include "../damage.qh"
 #include <server/intermission.qh>
-#include "../world.qh"
+#include <server/world.qh>
 #include "../teamplay.qh"
 #include "../race.qh"
 #include "../round_handler.qh"
diff --git a/qcsrc/server/compat/quake.qc b/qcsrc/server/compat/quake.qc
index d2eb785b5..23ae923b0 100644
--- a/qcsrc/server/compat/quake.qc
+++ b/qcsrc/server/compat/quake.qc
@@ -2,7 +2,6 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include <common/weapons/_all.qh>
 
 //***********************
diff --git a/qcsrc/server/compat/quake3.qc b/qcsrc/server/compat/quake3.qc
index 4bb22b13e..bda38dcf2 100644
--- a/qcsrc/server/compat/quake3.qc
+++ b/qcsrc/server/compat/quake3.qc
@@ -3,7 +3,6 @@
 #include <server/client.qh>
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include <server/items/items.qh>
 #include <server/items/spawning.qh>
 #include <server/resources.qh>
diff --git a/qcsrc/server/compat/wop.qc b/qcsrc/server/compat/wop.qc
index 4b7a6d31b..784303010 100644
--- a/qcsrc/server/compat/wop.qc
+++ b/qcsrc/server/compat/wop.qc
@@ -2,7 +2,6 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include <server/items/spawning.qh>
 #include <common/weapons/_all.qh>
 
diff --git a/qcsrc/server/damage.qc b/qcsrc/server/damage.qc
index 02a795bba..f0655a9f8 100644
--- a/qcsrc/server/damage.qc
+++ b/qcsrc/server/damage.qc
@@ -8,6 +8,7 @@
 #include <server/items/items.qh>
 #include <server/mutators/_mod.qh>
 #include <server/main.qh>
+#include <server/world.qh>
 #include "teamplay.qh"
 #include "scores.qh"
 #include "spawnpoints.qh"
diff --git a/qcsrc/server/damage.qh b/qcsrc/server/damage.qh
index 02a637ca0..60e4f0a65 100644
--- a/qcsrc/server/damage.qh
+++ b/qcsrc/server/damage.qh
@@ -6,7 +6,6 @@
     #include <common/weapons/_all.qh>
     #include <common/stats.qh>
     #include <server/items/items.qh>
-    #include <server/miscfunctions.qh>
     #include <lib/warpzone/common.qh>
     #include <common/constants.qh>
     #include <common/teams.qh>
diff --git a/qcsrc/server/hook.qc b/qcsrc/server/hook.qc
index a84a37fc3..596b542e7 100644
--- a/qcsrc/server/hook.qc
+++ b/qcsrc/server/hook.qc
@@ -4,7 +4,8 @@
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
 #include <server/damage.qh>
-#include <server/miscfunctions.qh>
+#include <server/mutators/_mod.qh>
+#include <server/world.qh>
 #include <common/effects/all.qh>
 #include "weapons/common.qh"
 #include "weapons/csqcprojectile.qh"
diff --git a/qcsrc/server/impulse.qc b/qcsrc/server/impulse.qc
index 779384d70..2d30b4c7a 100644
--- a/qcsrc/server/impulse.qc
+++ b/qcsrc/server/impulse.qc
@@ -7,6 +7,7 @@
 #include "client.qh"
 #include "clientkill.qh"
 #include "damage.qh"
+#include <server/mutators/_mod.qh>
 #include "weapons/selection.qh"
 #include "weapons/tracing.qh"
 #include "weapons/weaponsystem.qh"
diff --git a/qcsrc/server/ipban.qc b/qcsrc/server/ipban.qc
index bb19b0c70..4c386b8f3 100644
--- a/qcsrc/server/ipban.qc
+++ b/qcsrc/server/ipban.qc
@@ -2,8 +2,8 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include "autocvars.qh"
+#include <server/main.qh>
 #include "command/banning.qh"
 #include "../common/constants.qh"
 #include "../common/util.qh"
diff --git a/qcsrc/server/main.qc b/qcsrc/server/main.qc
index 0983d4621..2546362af 100644
--- a/qcsrc/server/main.qc
+++ b/qcsrc/server/main.qc
@@ -5,6 +5,7 @@
 #include "damage.qh"
 #include "world.qh"
 #include "spawnpoints.qh"
+#include <server/ipban.qh>
 #include <server/gamelog.qh>
 
 #include "bot/api.qh"
@@ -17,6 +18,7 @@
 #include <server/compat/quake3.qh>
 
 #include "../common/constants.qh"
+#include <common/command/generic.qh>
 #include "../common/deathtypes/all.qh"
 #include "../common/debug.qh"
 #include "../common/mapinfo.qh"
@@ -380,6 +382,37 @@ void WarpZone_PostInitialize_Callback()
 	delete(tracetest_ent);
 }
 
+/** engine callback */
+void URI_Get_Callback(float id, float status, string data)
+{
+	if(url_URI_Get_Callback(id, status, data))
+	{
+		// handled
+	}
+	else if (id == URI_GET_DISCARD)
+	{
+		// discard
+	}
+	else if (id >= URI_GET_CURL && id <= URI_GET_CURL_END)
+	{
+		// sv_cmd curl
+		Curl_URI_Get_Callback(id, status, data);
+	}
+	else if (id >= URI_GET_IPBAN && id <= URI_GET_IPBAN_END)
+	{
+		// 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), ".");
+	}
+}
+
 /*
 ==================
 main
diff --git a/qcsrc/server/main.qh b/qcsrc/server/main.qh
index a8c86fe2f..2fde70481 100644
--- a/qcsrc/server/main.qh
+++ b/qcsrc/server/main.qh
@@ -10,7 +10,8 @@ void remove_safely(entity e);
 
 void remove_unsafely(entity e);
 
-bool expr_evaluate(string s);
+// copies a string to a tempstring (so one can strunzone it)
+string strcat1(string s) = #115; // FRIK_FILE
 
 #ifdef PROFILING
 float client_cefc_accumulator;
diff --git a/qcsrc/server/mapvoting.qc b/qcsrc/server/mapvoting.qc
index bdd563b81..d0ade66c5 100644
--- a/qcsrc/server/mapvoting.qc
+++ b/qcsrc/server/mapvoting.qc
@@ -5,7 +5,6 @@
 #include <common/stats.qh>
 #include <server/gamelog.qh>
 #include <server/intermission.qh>
-#include <server/miscfunctions.qh>
 #include "world.qh"
 #include "command/cmd.qh"
 #include "command/getreplies.qh"
diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc
deleted file mode 100644
index d45131837..000000000
--- a/qcsrc/server/miscfunctions.qc
+++ /dev/null
@@ -1,319 +0,0 @@
-// NOTE: Please do NOT add new functions to this file! It is a dumping ground that is in the process of being cleaned up, please find a proper home for your code!
-
-#include "miscfunctions.qh"
-
-#include "antilag.qh"
-#include "command/common.qh"
-#include "client.qh"
-#include "damage.qh"
-#include "hook.qh"
-#include "world.qh"
-#include <server/gamelog.qh>
-#include "ipban.qh"
-#include <server/intermission.qh>
-#include <server/items/items.qh>
-#include <server/mutators/_mod.qh>
-#include <server/spawnpoints.qh>
-#include <server/main.qh>
-#include "mapvoting.qh"
-#include "resources.qh"
-#include <server/items/spawning.qh>
-#include "player.qh"
-#include "weapons/accuracy.qh"
-#include "weapons/common.qh"
-#include "weapons/csqcprojectile.qh"
-#include "weapons/selection.qh"
-#include "../common/command/_mod.qh"
-#include "../common/constants.qh"
-#include <common/net_linked.qh>
-#include <common/weapons/weapon/crylink.qh>
-#include "../common/deathtypes/all.qh"
-#include "../common/mapinfo.qh"
-#include "../common/notifications/all.qh"
-#include "../common/playerstats.qh"
-#include "../common/teams.qh"
-#include "../common/mapobjects/subs.qh"
-#include <common/mapobjects/trigger/hurt.qh>
-#include <common/mapobjects/target/location.qh>
-#include "../common/util.qh"
-#include "../common/turrets/sv_turrets.qh"
-#include <common/weapons/_all.qh>
-#include "../common/vehicles/sv_vehicles.qh"
-#include "../common/vehicles/vehicle.qh"
-#include "../common/items/_mod.qh"
-#include "../common/state.qh"
-#include "../common/effects/qc/globalsound.qh"
-#include "../common/wepent.qh"
-#include <common/weapons/weapon.qh>
-#include "../lib/csqcmodel/sv_model.qh"
-#include "../lib/warpzone/anglestransform.qh"
-#include "../lib/warpzone/server.qh"
-
-void crosshair_trace(entity pl)
-{
-	traceline_antilag(pl, CS(pl).cursor_trace_start, CS(pl).cursor_trace_start + normalize(CS(pl).cursor_trace_endpos - CS(pl).cursor_trace_start) * max_shot_distance, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
-}
-
-void crosshair_trace_plusvisibletriggers(entity pl)
-{
-	crosshair_trace_plusvisibletriggers__is_wz(pl, false);
-}
-
-void WarpZone_crosshair_trace_plusvisibletriggers(entity pl)
-{
-	crosshair_trace_plusvisibletriggers__is_wz(pl, true);
-}
-
-void crosshair_trace_plusvisibletriggers__is_wz(entity pl, bool is_wz)
-{
-	FOREACH_ENTITY_FLOAT(solid, SOLID_TRIGGER,
-	{
-		if(it.model != "")
-		{
-			it.solid = SOLID_BSP;
-			IL_PUSH(g_ctrace_changed, it);
-		}
-	});
-
-	if (is_wz)
-		WarpZone_crosshair_trace(pl);
-	else
-		crosshair_trace(pl);
-
-	IL_EACH(g_ctrace_changed, true, { it.solid = SOLID_TRIGGER; });
-
-	IL_CLEAR(g_ctrace_changed);
-}
-
-void WarpZone_crosshair_trace(entity pl)
-{
-	WarpZone_traceline_antilag(pl, CS(pl).cursor_trace_start, CS(pl).cursor_trace_start + normalize(CS(pl).cursor_trace_endpos - CS(pl).cursor_trace_start) * max_shot_distance, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
-}
-
-float trace_hits_box_a0, trace_hits_box_a1;
-
-float trace_hits_box_1d(float end, float thmi, float thma)
-{
-    if (end == 0)
-    {
-        // just check if x is in range
-        if (0 < thmi)
-            return false;
-        if (0 > thma)
-            return false;
-    }
-    else
-    {
-        // do the trace with respect to x
-        // 0 -> end has to stay in thmi -> thma
-        trace_hits_box_a0 = max(trace_hits_box_a0, min(thmi / end, thma / end));
-        trace_hits_box_a1 = min(trace_hits_box_a1, max(thmi / end, thma / end));
-        if (trace_hits_box_a0 > trace_hits_box_a1)
-            return false;
-    }
-    return true;
-}
-
-float trace_hits_box(vector start, vector end, vector thmi, vector thma)
-{
-    end -= start;
-    thmi -= start;
-    thma -= start;
-    // now it is a trace from 0 to end
-
-    trace_hits_box_a0 = 0;
-    trace_hits_box_a1 = 1;
-
-    if (!trace_hits_box_1d(end.x, thmi.x, thma.x))
-        return false;
-    if (!trace_hits_box_1d(end.y, thmi.y, thma.y))
-        return false;
-    if (!trace_hits_box_1d(end.z, thmi.z, thma.z))
-        return false;
-
-    return true;
-}
-
-float tracebox_hits_box(vector start, vector mi, vector ma, vector end, vector thmi, vector thma)
-{
-    return trace_hits_box(start, end, thmi - ma, thma - mi);
-}
-
-/** engine callback */
-void URI_Get_Callback(float id, float status, string data)
-{
-	if(url_URI_Get_Callback(id, status, data))
-	{
-		// handled
-	}
-	else if (id == URI_GET_DISCARD)
-	{
-		// discard
-	}
-	else if (id >= URI_GET_CURL && id <= URI_GET_CURL_END)
-	{
-		// sv_cmd curl
-		Curl_URI_Get_Callback(id, status, data);
-	}
-	else if (id >= URI_GET_IPBAN && id <= URI_GET_IPBAN_END)
-	{
-		// 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), ".");
-	}
-}
-
-string uid2name(string myuid)
-{
-	string s = db_get(ServerProgsDB, strcat("/uid2name/", myuid));
-
-	// FIXME remove this later after 0.6 release
-	// convert old style broken records to correct style
-	if(s == "")
-	{
-		s = db_get(ServerProgsDB, strcat("uid2name", myuid));
-		if(s != "")
-		{
-			db_put(ServerProgsDB, strcat("/uid2name/", myuid), s);
-			db_remove(ServerProgsDB, strcat("uid2name", myuid));
-		}
-	}
-
-	if(s == "")
-		s = "^1Unregistered Player";
-	return s;
-}
-
-bool MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundmax, float goodcontents, float badcontents, float badsurfaceflags, int attempts, float maxaboveground, float minviewdistance)
-{
-    float m = e.dphitcontentsmask;
-    e.dphitcontentsmask = goodcontents | badcontents;
-
-    vector org = boundmin;
-    vector delta = boundmax - boundmin;
-
-    vector start, end;
-    start = end = org;
-    int j; // used after the loop
-    for(j = 0; j < attempts; ++j)
-    {
-        start.x = org.x + random() * delta.x;
-        start.y = org.y + random() * delta.y;
-        start.z = org.z + random() * delta.z;
-
-        // rule 1: start inside world bounds, and outside
-        // solid, and don't start from somewhere where you can
-        // fall down to evil
-        tracebox(start, e.mins, e.maxs, start - '0 0 1' * delta.z, MOVE_NORMAL, e);
-        if (trace_fraction >= 1)
-            continue;
-        if (trace_startsolid)
-            continue;
-        if (trace_dphitcontents & badcontents)
-            continue;
-        if (trace_dphitq3surfaceflags & badsurfaceflags)
-            continue;
-
-        // rule 2: if we are too high, lower the point
-        if (trace_fraction * delta.z > maxaboveground)
-            start = trace_endpos + '0 0 1' * maxaboveground;
-        vector enddown = trace_endpos;
-
-        // rule 3: make sure we aren't outside the map. This only works
-        // for somewhat well formed maps. A good rule of thumb is that
-        // the map should have a convex outside hull.
-        // these can be traceLINES as we already verified the starting box
-        vector mstart = start + 0.5 * (e.mins + e.maxs);
-        traceline(mstart, mstart + '1 0 0' * delta.x, MOVE_NORMAL, e);
-        if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
-            continue;
-        traceline(mstart, mstart - '1 0 0' * delta.x, MOVE_NORMAL, e);
-        if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
-            continue;
-        traceline(mstart, mstart + '0 1 0' * delta.y, MOVE_NORMAL, e);
-        if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
-            continue;
-        traceline(mstart, mstart - '0 1 0' * delta.y, MOVE_NORMAL, e);
-        if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
-            continue;
-        traceline(mstart, mstart + '0 0 1' * delta.z, MOVE_NORMAL, e);
-        if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
-            continue;
-
-		// rule 4: we must "see" some spawnpoint or item
-	    entity sp = NULL;
-	    IL_EACH(g_spawnpoints, checkpvs(mstart, it),
-	    {
-	    	if((traceline(mstart, it.origin, MOVE_NORMAL, e), trace_fraction) >= 1)
-	    	{
-	    		sp = it;
-	    		break;
-	    	}
-	    });
-		if(!sp)
-		{
-			int items_checked = 0;
-			IL_EACH(g_items, checkpvs(mstart, it),
-			{
-				if((traceline(mstart, it.origin + (it.mins + it.maxs) * 0.5, MOVE_NORMAL, e), trace_fraction) >= 1)
-				{
-					sp = it;
-					break;
-				}
-
-				++items_checked;
-				if(items_checked >= attempts)
-					break; // sanity
-			});
-
-			if(!sp)
-				continue;
-		}
-
-        // find a random vector to "look at"
-        end.x = org.x + random() * delta.x;
-        end.y = org.y + random() * delta.y;
-        end.z = org.z + random() * delta.z;
-        end = start + normalize(end - start) * vlen(delta);
-
-        // rule 4: start TO end must not be too short
-        tracebox(start, e.mins, e.maxs, end, MOVE_NORMAL, e);
-        if(trace_startsolid)
-            continue;
-        if(trace_fraction < minviewdistance / vlen(delta))
-            continue;
-
-        // rule 5: don't want to look at sky
-        if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
-            continue;
-
-        // rule 6: we must not end up in trigger_hurt
-        if(tracebox_hits_trigger_hurt(start, e.mins, e.maxs, enddown))
-            continue;
-
-        break;
-    }
-
-    e.dphitcontentsmask = m;
-
-    if(j < attempts)
-    {
-        setorigin(e, start);
-        e.angles = vectoangles(end - start);
-        LOG_DEBUG("Needed ", ftos(j + 1), " attempts");
-        return true;
-    }
-    return false;
-}
-
-float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance)
-{
-	return MoveToRandomLocationWithinBounds(e, world.mins, world.maxs, goodcontents, badcontents, badsurfaceflags, attempts, maxaboveground, minviewdistance);
-}
diff --git a/qcsrc/server/miscfunctions.qh b/qcsrc/server/miscfunctions.qh
deleted file mode 100644
index ffed5b286..000000000
--- a/qcsrc/server/miscfunctions.qh
+++ /dev/null
@@ -1,49 +0,0 @@
-#pragma once
-
-#include <common/weapons/_all.qh>
-#include <common/stats.qh>
-#include <server/client.qh>
-#include <server/world.qh>
-
-#include <server/intermission.qh>
-#include <server/items/items.qh>
-
-#include <server/mutators/_mod.qh>
-
-#include <common/constants.qh>
-#include <common/mapinfo.qh>
-#include <common/turrets/all.qh>
-
-float trace_hits_box_1d(float end, float thmi, float thma);
-
-float trace_hits_box(vector start, vector end, vector thmi, vector thma);
-
-float tracebox_hits_box(vector start, vector mi, vector ma, vector end, vector thmi, vector thma);
-
-void crosshair_trace(entity pl);
-
-void crosshair_trace_plusvisibletriggers(entity pl);
-void WarpZone_crosshair_trace_plusvisibletriggers(entity pl);
-void crosshair_trace_plusvisibletriggers__is_wz(entity pl, bool is_wz);
-
-string uid2name(string myuid);
-
-bool MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundmax, float goodcontents, float badcontents, float badsurfaceflags, int attempts, float maxaboveground, float minviewdistance);
-
-float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance);
-
-float tracebox_hits_box(vector start, vector mi, vector ma, vector end, vector thmi, vector thma);
-
-void traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag);
-
-void WarpZone_crosshair_trace(entity pl);
-
-void WarpZone_traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag);
-
-#define PROJECTILE_TOUCH(e,t) MACRO_BEGIN if (WarpZone_Projectile_Touch(e,t)) return; MACRO_END
-
-// copies a string to a tempstring (so one can strunzone it)
-string strcat1(string s) = #115; // FRIK_FILE
-
-IntrusiveList g_ctrace_changed;
-STATIC_INIT(g_ctrace_changed) { g_ctrace_changed = IL_NEW(); }
diff --git a/qcsrc/server/mutators/loader.qc b/qcsrc/server/mutators/loader.qc
index f15098766..0830fb686 100644
--- a/qcsrc/server/mutators/loader.qc
+++ b/qcsrc/server/mutators/loader.qc
@@ -1,8 +1,9 @@
 #include "loader.qh"
 
+#include <common/mutators/base.qh>
+#include <common/mapinfo.qh>
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 
 STATIC_INIT_LATE(Gametype) {
     Gametype g = MapInfo_CurrentGametype();
diff --git a/qcsrc/server/pathlib/main.qc b/qcsrc/server/pathlib/main.qc
index b42e5ef68..16090e31b 100644
--- a/qcsrc/server/pathlib/main.qc
+++ b/qcsrc/server/pathlib/main.qc
@@ -2,7 +2,6 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include "pathlib.qh"
 #include "utility.qh"
 #include <common/turrets/util.qh>
diff --git a/qcsrc/server/pathlib/movenode.qc b/qcsrc/server/pathlib/movenode.qc
index 06568ae0d..65e4923ea 100644
--- a/qcsrc/server/pathlib/movenode.qc
+++ b/qcsrc/server/pathlib/movenode.qc
@@ -3,7 +3,6 @@
 #include <common/mapobjects/triggers.qh>
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include "pathlib.qh"
 #include "utility.qh"
 
diff --git a/qcsrc/server/pathlib/utility.qc b/qcsrc/server/pathlib/utility.qc
index 51d3f65c9..799cd4358 100644
--- a/qcsrc/server/pathlib/utility.qc
+++ b/qcsrc/server/pathlib/utility.qc
@@ -2,7 +2,6 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include "pathlib.qh"
 
 bool location_isok(vector point, bool waterok, bool air_isok)
diff --git a/qcsrc/server/player.qc b/qcsrc/server/player.qc
index bd73d3494..a632aab01 100644
--- a/qcsrc/server/player.qc
+++ b/qcsrc/server/player.qc
@@ -6,9 +6,9 @@
 #include "client.qh"
 #include "clientkill.qh"
 #include "damage.qh"
+#include <server/mutators/_mod.qh>
 #include "world.qh"
 #include "handicap.qh"
-#include "miscfunctions.qh"
 #include "portals.qh"
 #include "teamplay.qh"
 #include <server/main.qh>
diff --git a/qcsrc/server/race.qc b/qcsrc/server/race.qc
index 7c04ea1da..bc07efd58 100644
--- a/qcsrc/server/race.qc
+++ b/qcsrc/server/race.qc
@@ -5,8 +5,9 @@
 #include <server/damage.qh>
 #include <server/gamelog.qh>
 #include <server/intermission.qh>
+#include <server/main.qh>
+#include <server/mutators/_mod.qh>
 #include <server/world.qh>
-#include <server/miscfunctions.qh>
 #include <server/weapons/common.qh>
 #include "client.qh"
 #include "cheats.qh"
@@ -29,6 +30,27 @@
 #include <common/vehicles/sv_vehicles.qh>
 #include "../common/mutators/mutator/waypoints/waypointsprites.qh"
 
+string uid2name(string myuid)
+{
+	string s = db_get(ServerProgsDB, strcat("/uid2name/", myuid));
+
+	// FIXME remove this later after 0.6 release
+	// convert old style broken records to correct style
+	if(s == "")
+	{
+		s = db_get(ServerProgsDB, strcat("uid2name", myuid));
+		if(s != "")
+		{
+			db_put(ServerProgsDB, strcat("/uid2name/", myuid), s);
+			db_remove(ServerProgsDB, strcat("uid2name", myuid));
+		}
+	}
+
+	if(s == "")
+		s = "^1Unregistered Player";
+	return s;
+}
+
 void write_recordmarker(entity pl, float tstart, float dt)
 {
     GameLogEcho(strcat(":recordset:", ftos(pl.playerid), ":", ftos(dt)));
diff --git a/qcsrc/server/race.qh b/qcsrc/server/race.qh
index 496fd3874..9dd37a89e 100644
--- a/qcsrc/server/race.qh
+++ b/qcsrc/server/race.qh
@@ -72,4 +72,6 @@ void race_RetractPlayer(entity this);
 
 void race_InitSpectator();
 
+string uid2name(string myuid);
+
 spawnfunc(target_checkpoint);
diff --git a/qcsrc/server/resources.qc b/qcsrc/server/resources.qc
index e36eb5750..ef3dea1bf 100644
--- a/qcsrc/server/resources.qc
+++ b/qcsrc/server/resources.qc
@@ -6,7 +6,8 @@
 /// \copyright GNU GPLv2 or any later version.
 
 #include "autocvars.qh"
-#include "miscfunctions.qh"
+#include <server/mutators/_mod.qh>
+#include <server/world.qh>
 
 float GetResourceLimit(entity e, int res_type)
 {
diff --git a/qcsrc/server/round_handler.qc b/qcsrc/server/round_handler.qc
index 66da6c37c..fa970f955 100644
--- a/qcsrc/server/round_handler.qc
+++ b/qcsrc/server/round_handler.qc
@@ -1,7 +1,6 @@
 #include "round_handler.qh"
 
 #include <server/world.qh>
-#include <server/miscfunctions.qh>
 #include "campaign.qh"
 #include "command/vote.qh"
 #include <common/mapobjects/triggers.qh>
diff --git a/qcsrc/server/scores.qc b/qcsrc/server/scores.qc
index de298e220..73d03ae78 100644
--- a/qcsrc/server/scores.qc
+++ b/qcsrc/server/scores.qc
@@ -5,7 +5,6 @@
 #include "client.qh"
 #include <server/intermission.qh>
 #include <server/world.qh>
-#include <server/miscfunctions.qh>
 #include <server/mutators/_mod.qh>
 #include <server/round_handler.qh>
 #include <common/net_linked.qh>
diff --git a/qcsrc/server/scores_rules.qc b/qcsrc/server/scores_rules.qc
index 7511162aa..1ad2640ad 100644
--- a/qcsrc/server/scores_rules.qc
+++ b/qcsrc/server/scores_rules.qc
@@ -2,7 +2,6 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include "client.qh"
 #include "scores.qh"
 #include <common/gamemodes/rules.qh>
diff --git a/qcsrc/server/spawnpoints.qc b/qcsrc/server/spawnpoints.qc
index dec632f6b..4bcffe68a 100644
--- a/qcsrc/server/spawnpoints.qc
+++ b/qcsrc/server/spawnpoints.qc
@@ -2,7 +2,6 @@
 
 #include <server/mutators/_mod.qh>
 #include <server/world.qh>
-#include "miscfunctions.qh"
 #include "race.qh"
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
diff --git a/qcsrc/server/tests.qh b/qcsrc/server/tests.qh
index 7124b1895..de9b3579f 100644
--- a/qcsrc/server/tests.qh
+++ b/qcsrc/server/tests.qh
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "miscfunctions.qh"
 #include "autocvars.qh"
 #include "client.qh"
 #include "command/_mod.qh"
diff --git a/qcsrc/server/weapons/accuracy.qc b/qcsrc/server/weapons/accuracy.qc
index 2ec4fc710..e8f59f53e 100644
--- a/qcsrc/server/weapons/accuracy.qc
+++ b/qcsrc/server/weapons/accuracy.qc
@@ -9,6 +9,7 @@
 #include <common/teams.qh>
 #include <common/util.qh>
 #include <common/weapons/_all.qh>
+#include <server/world.qh>
 
 int accuracy_byte(float n, float d)
 {
diff --git a/qcsrc/server/weapons/accuracy.qh b/qcsrc/server/weapons/accuracy.qh
index d1665b2bd..396de1bdb 100644
--- a/qcsrc/server/weapons/accuracy.qh
+++ b/qcsrc/server/weapons/accuracy.qh
@@ -2,7 +2,6 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 
 .bool cvar_cl_accuracy_data_share;
 REPLICATE(cvar_cl_accuracy_data_share, bool, "cl_accuracy_data_share");
diff --git a/qcsrc/server/weapons/common.qc b/qcsrc/server/weapons/common.qc
index a1a5ad964..2539b7d3b 100644
--- a/qcsrc/server/weapons/common.qc
+++ b/qcsrc/server/weapons/common.qc
@@ -5,7 +5,7 @@
 #include <common/stats.qh>
 #include <server/damage.qh>
 #include <server/items/items.qh>
-#include <server/miscfunctions.qh>
+#include <server/mutators/_mod.qh>
 #include <common/constants.qh>
 #include <common/net_linked.qh>
 #include <common/deathtypes/all.qh>
diff --git a/qcsrc/server/weapons/common.qh b/qcsrc/server/weapons/common.qh
index c8e3eb533..77f707d0a 100644
--- a/qcsrc/server/weapons/common.qh
+++ b/qcsrc/server/weapons/common.qh
@@ -21,6 +21,8 @@ bool WarpZone_Projectile_Touch_ImpactFilter_Callback(entity this, entity toucher
 
 .entity realowner;
 
+#define PROJECTILE_TOUCH(e,t) MACRO_BEGIN if (WarpZone_Projectile_Touch(e,t)) return; MACRO_END
+
 #define PROJECTILE_MAKETRIGGER(e) (e).solid = SOLID_CORPSE; (e).dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE
 // when doing this, hagar can go through clones
 // #define PROJECTILE_MAKETRIGGER(e) (e).solid = SOLID_BBOX
diff --git a/qcsrc/server/weapons/csqcprojectile.qc b/qcsrc/server/weapons/csqcprojectile.qc
index 758cd51ab..27a376ec7 100644
--- a/qcsrc/server/weapons/csqcprojectile.qc
+++ b/qcsrc/server/weapons/csqcprojectile.qc
@@ -3,7 +3,6 @@
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
 #include <server/items/items.qh>
-#include <server/miscfunctions.qh>
 
 #include "../command/common.qh"
 
diff --git a/qcsrc/server/weapons/hitplot.qc b/qcsrc/server/weapons/hitplot.qc
index 2d56b783f..45642f298 100644
--- a/qcsrc/server/weapons/hitplot.qc
+++ b/qcsrc/server/weapons/hitplot.qc
@@ -4,7 +4,6 @@
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
 #include <server/world.qh>
-#include <server/miscfunctions.qh>
 #include "../antilag.qh"
 #include <common/weapons/_all.qh>
 #include <common/state.qh>
diff --git a/qcsrc/server/weapons/selection.qh b/qcsrc/server/weapons/selection.qh
index 03c203f4e..01c05d3fb 100644
--- a/qcsrc/server/weapons/selection.qh
+++ b/qcsrc/server/weapons/selection.qh
@@ -2,7 +2,6 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 
 .int selectweapon; // last selected weapon of the player
 
diff --git a/qcsrc/server/weapons/spawning.qc b/qcsrc/server/weapons/spawning.qc
index 63bc865e2..f555a6ea7 100644
--- a/qcsrc/server/weapons/spawning.qc
+++ b/qcsrc/server/weapons/spawning.qc
@@ -5,6 +5,7 @@
 #include <server/mutators/_mod.qh>
 #include <server/items/items.qh>
 #include <server/items/spawning.qh>
+#include <server/world.qh>
 #include <common/weapons/_all.qh>
 
 .bool m_isreplaced; ///< Holds whether the weapon has been replaced.
diff --git a/qcsrc/server/weapons/spawning.qh b/qcsrc/server/weapons/spawning.qh
index eb40bfc40..e0f1a61a9 100644
--- a/qcsrc/server/weapons/spawning.qh
+++ b/qcsrc/server/weapons/spawning.qh
@@ -2,7 +2,6 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 
 string W_Apply_Weaponreplace(string in);
 
diff --git a/qcsrc/server/weapons/throwing.qc b/qcsrc/server/weapons/throwing.qc
index 2408adbf1..1a92f3991 100644
--- a/qcsrc/server/weapons/throwing.qc
+++ b/qcsrc/server/weapons/throwing.qc
@@ -6,6 +6,7 @@
 #include <server/mutators/_mod.qh>
 #include <server/items/items.qh>
 #include "../damage.qh"
+#include <server/world.qh>
 #include <common/items/item.qh>
 #include <common/mapinfo.qh>
 #include <common/notifications/all.qh>
diff --git a/qcsrc/server/weapons/throwing.qh b/qcsrc/server/weapons/throwing.qh
index 8ebd4080c..22adc649b 100644
--- a/qcsrc/server/weapons/throwing.qh
+++ b/qcsrc/server/weapons/throwing.qh
@@ -2,7 +2,6 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 
 .float savenextthink;
 void thrown_wep_think(entity this);
diff --git a/qcsrc/server/weapons/tracing.qc b/qcsrc/server/weapons/tracing.qc
index 3e8382652..b82095a69 100644
--- a/qcsrc/server/weapons/tracing.qc
+++ b/qcsrc/server/weapons/tracing.qc
@@ -9,7 +9,8 @@
 
 #include "../damage.qh"
 #include <server/main.qh>
-#include "../antilag.qh"
+#include <server/mutators/_mod.qh>
+#include <server/antilag.qh>
 
 #include <common/constants.qh>
 #include <common/net_linked.qh>
@@ -499,3 +500,44 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo
 {
 	fireBullet_antilag(this, weaponentity, start, dir, spread, max_solid_penetration, damage, headshot_multiplier, force, dtype, tracer_effect, true);
 }
+
+void crosshair_trace(entity pl)
+{
+	traceline_antilag(pl, CS(pl).cursor_trace_start, CS(pl).cursor_trace_start + normalize(CS(pl).cursor_trace_endpos - CS(pl).cursor_trace_start) * max_shot_distance, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
+}
+
+void crosshair_trace_plusvisibletriggers(entity pl)
+{
+	crosshair_trace_plusvisibletriggers__is_wz(pl, false);
+}
+
+void WarpZone_crosshair_trace_plusvisibletriggers(entity pl)
+{
+	crosshair_trace_plusvisibletriggers__is_wz(pl, true);
+}
+
+void crosshair_trace_plusvisibletriggers__is_wz(entity pl, bool is_wz)
+{
+	FOREACH_ENTITY_FLOAT(solid, SOLID_TRIGGER,
+	{
+		if(it.model != "")
+		{
+			it.solid = SOLID_BSP;
+			IL_PUSH(g_ctrace_changed, it);
+		}
+	});
+
+	if (is_wz)
+		WarpZone_crosshair_trace(pl);
+	else
+		crosshair_trace(pl);
+
+	IL_EACH(g_ctrace_changed, true, { it.solid = SOLID_TRIGGER; });
+
+	IL_CLEAR(g_ctrace_changed);
+}
+
+void WarpZone_crosshair_trace(entity pl)
+{
+	WarpZone_traceline_antilag(pl, CS(pl).cursor_trace_start, CS(pl).cursor_trace_start + normalize(CS(pl).cursor_trace_endpos - CS(pl).cursor_trace_start) * max_shot_distance, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
+}
diff --git a/qcsrc/server/weapons/tracing.qh b/qcsrc/server/weapons/tracing.qh
index 67246859c..9c5a77c8d 100644
--- a/qcsrc/server/weapons/tracing.qh
+++ b/qcsrc/server/weapons/tracing.qh
@@ -2,7 +2,6 @@
 
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 
 vector w_shotorg;
 vector w_shotdir;
@@ -82,3 +81,18 @@ entity fireBullet_last_hit;
 void fireBullet_trace_callback(vector start, vector hit, vector end);
 void fireBullet_antilag(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float headshot_multiplier, float force, float dtype, entity tracer_effect, bool do_antilag);
 void fireBullet(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float headshot_multiplier, float force, float dtype, entity tracer_effect);
+
+void crosshair_trace(entity pl);
+
+void crosshair_trace_plusvisibletriggers(entity pl);
+void WarpZone_crosshair_trace_plusvisibletriggers(entity pl);
+void crosshair_trace_plusvisibletriggers__is_wz(entity pl, bool is_wz);
+
+void traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag);
+
+void WarpZone_crosshair_trace(entity pl);
+
+void WarpZone_traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag);
+
+IntrusiveList g_ctrace_changed;
+STATIC_INIT(g_ctrace_changed) { g_ctrace_changed = IL_NEW(); }
diff --git a/qcsrc/server/weapons/weaponstats.qc b/qcsrc/server/weapons/weaponstats.qc
index 02ba234ea..f774cb056 100644
--- a/qcsrc/server/weapons/weaponstats.qc
+++ b/qcsrc/server/weapons/weaponstats.qc
@@ -3,7 +3,6 @@
 #include <server/intermission.qh>
 #include <common/weapons/_all.qh>
 #include <common/stats.qh>
-#include <server/miscfunctions.qh>
 #include "../world.qh"
 
 #include <common/weapons/_all.qh>
diff --git a/qcsrc/server/weapons/weaponsystem.qh b/qcsrc/server/weapons/weaponsystem.qh
index d1223c6d5..284c1efc6 100644
--- a/qcsrc/server/weapons/weaponsystem.qh
+++ b/qcsrc/server/weapons/weaponsystem.qh
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <server/miscfunctions.qh>
+#include <common/weapons/all.qh>
 
 #define INDEPENDENT_ATTACK_FINISHED 1
 
diff --git a/qcsrc/server/world.qc b/qcsrc/server/world.qc
index 4c51fe064..88890fc2f 100644
--- a/qcsrc/server/world.qc
+++ b/qcsrc/server/world.qc
@@ -40,6 +40,7 @@
 #include "../common/stats.qh"
 #include "../common/teams.qh"
 #include <common/mapobjects/triggers.qh>
+#include <common/mapobjects/trigger/hurt.qh>
 #include "../common/mapobjects/trigger/secret.qh"
 #include "../common/mapobjects/target/music.qh"
 #include "../common/util.qh"
@@ -1019,6 +1020,133 @@ spawnfunc(light)
 	delete(this);
 }
 
+bool MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundmax, float goodcontents, float badcontents, float badsurfaceflags, int attempts, float maxaboveground, float minviewdistance)
+{
+    float m = e.dphitcontentsmask;
+    e.dphitcontentsmask = goodcontents | badcontents;
+
+    vector org = boundmin;
+    vector delta = boundmax - boundmin;
+
+    vector start, end;
+    start = end = org;
+    int j; // used after the loop
+    for(j = 0; j < attempts; ++j)
+    {
+        start.x = org.x + random() * delta.x;
+        start.y = org.y + random() * delta.y;
+        start.z = org.z + random() * delta.z;
+
+        // rule 1: start inside world bounds, and outside
+        // solid, and don't start from somewhere where you can
+        // fall down to evil
+        tracebox(start, e.mins, e.maxs, start - '0 0 1' * delta.z, MOVE_NORMAL, e);
+        if (trace_fraction >= 1)
+            continue;
+        if (trace_startsolid)
+            continue;
+        if (trace_dphitcontents & badcontents)
+            continue;
+        if (trace_dphitq3surfaceflags & badsurfaceflags)
+            continue;
+
+        // rule 2: if we are too high, lower the point
+        if (trace_fraction * delta.z > maxaboveground)
+            start = trace_endpos + '0 0 1' * maxaboveground;
+        vector enddown = trace_endpos;
+
+        // rule 3: make sure we aren't outside the map. This only works
+        // for somewhat well formed maps. A good rule of thumb is that
+        // the map should have a convex outside hull.
+        // these can be traceLINES as we already verified the starting box
+        vector mstart = start + 0.5 * (e.mins + e.maxs);
+        traceline(mstart, mstart + '1 0 0' * delta.x, MOVE_NORMAL, e);
+        if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
+            continue;
+        traceline(mstart, mstart - '1 0 0' * delta.x, MOVE_NORMAL, e);
+        if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
+            continue;
+        traceline(mstart, mstart + '0 1 0' * delta.y, MOVE_NORMAL, e);
+        if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
+            continue;
+        traceline(mstart, mstart - '0 1 0' * delta.y, MOVE_NORMAL, e);
+        if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
+            continue;
+        traceline(mstart, mstart + '0 0 1' * delta.z, MOVE_NORMAL, e);
+        if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
+            continue;
+
+		// rule 4: we must "see" some spawnpoint or item
+	    entity sp = NULL;
+	    IL_EACH(g_spawnpoints, checkpvs(mstart, it),
+	    {
+	    	if((traceline(mstart, it.origin, MOVE_NORMAL, e), trace_fraction) >= 1)
+	    	{
+	    		sp = it;
+	    		break;
+	    	}
+	    });
+		if(!sp)
+		{
+			int items_checked = 0;
+			IL_EACH(g_items, checkpvs(mstart, it),
+			{
+				if((traceline(mstart, it.origin + (it.mins + it.maxs) * 0.5, MOVE_NORMAL, e), trace_fraction) >= 1)
+				{
+					sp = it;
+					break;
+				}
+
+				++items_checked;
+				if(items_checked >= attempts)
+					break; // sanity
+			});
+
+			if(!sp)
+				continue;
+		}
+
+        // find a random vector to "look at"
+        end.x = org.x + random() * delta.x;
+        end.y = org.y + random() * delta.y;
+        end.z = org.z + random() * delta.z;
+        end = start + normalize(end - start) * vlen(delta);
+
+        // rule 4: start TO end must not be too short
+        tracebox(start, e.mins, e.maxs, end, MOVE_NORMAL, e);
+        if(trace_startsolid)
+            continue;
+        if(trace_fraction < minviewdistance / vlen(delta))
+            continue;
+
+        // rule 5: don't want to look at sky
+        if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
+            continue;
+
+        // rule 6: we must not end up in trigger_hurt
+        if(tracebox_hits_trigger_hurt(start, e.mins, e.maxs, enddown))
+            continue;
+
+        break;
+    }
+
+    e.dphitcontentsmask = m;
+
+    if(j < attempts)
+    {
+        setorigin(e, start);
+        e.angles = vectoangles(end - start);
+        LOG_DEBUG("Needed ", ftos(j + 1), " attempts");
+        return true;
+    }
+    return false;
+}
+
+float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance)
+{
+	return MoveToRandomLocationWithinBounds(e, world.mins, world.maxs, goodcontents, badcontents, badsurfaceflags, attempts, maxaboveground, minviewdistance);
+}
+
 /*
 ===============================================================================
 
diff --git a/qcsrc/server/world.qh b/qcsrc/server/world.qh
index 706c931c8..f89d645c4 100644
--- a/qcsrc/server/world.qh
+++ b/qcsrc/server/world.qh
@@ -117,6 +117,11 @@ void SetWinners(.float field, float value);
 void ReadyRestart();
 
 void DumpStats(float final);
+
+bool MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundmax, float goodcontents, float badcontents, float badsurfaceflags, int attempts, float maxaboveground, float minviewdistance);
+
+float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance);
+
 void CheckRules_World();
 float RedirectionThink();