From a363319214d4de35856f9c9c55be57294727b6f1 Mon Sep 17 00:00:00 2001
From: Mario <mario@smbclan.net>
Date: Thu, 15 Oct 2015 00:56:31 +1000
Subject: [PATCH] Clean up a bunch of gamemode specific code

---
 .../common/gamemodes/gamemode/nexball/nexball.qc  |  8 ++++++++
 qcsrc/server/cl_player.qc                         |  8 ++++++++
 qcsrc/server/mutators/events.qh                   |  5 +++++
 qcsrc/server/mutators/gamemode_ctf.qc             |  8 ++++++++
 qcsrc/server/mutators/gamemode_keepaway.qc        |  8 ++++++++
 qcsrc/server/mutators/gamemode_keyhunt.qc         |  6 ++++++
 qcsrc/server/mutators/mutator_nades.qc            | 15 +++++++++------
 7 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc
index decb4c7dec..959ec857de 100644
--- a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc
+++ b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc
@@ -1029,6 +1029,14 @@ MUTATOR_HOOKFUNCTION(nb, WantWeapon)
 	return true;
 }
 
+MUTATOR_HOOKFUNCTION(nb, DropSpecialItems)
+{
+	if(frag_target.ballcarried)
+		DropBall(frag_target.ballcarried, frag_target.origin, frag_target.velocity);
+
+	return false;
+}
+
 REGISTER_MUTATOR(nb, g_nexball)
 {
 	ActivateTeamplay();
diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc
index 1b770121e8..9ab358635b 100644
--- a/qcsrc/server/cl_player.qc
+++ b/qcsrc/server/cl_player.qc
@@ -26,6 +26,14 @@
 
 #include "../common/animdecide.qh"
 
+void Drop_Special_Items(entity player)
+{
+	// called when the player has become stuck or frozen
+	// so objective items aren't stuck with the player
+
+	MUTATOR_CALLHOOK(DropSpecialItems, player);
+}
+
 void CopyBody_Think(void)
 {SELFPARAM();
 	if(self.CopyBody_nextthink && time > self.CopyBody_nextthink)
diff --git a/qcsrc/server/mutators/events.qh b/qcsrc/server/mutators/events.qh
index a9f8b8a999..1af9a9fbf5 100644
--- a/qcsrc/server/mutators/events.qh
+++ b/qcsrc/server/mutators/events.qh
@@ -760,4 +760,9 @@ MUTATOR_HOOKABLE(GetPlayerStatus, EV_GetPlayerStatus);
     /**/ o(string, ret_string) \
     /**/
 MUTATOR_HOOKABLE(SetWeaponArena, EV_SetWeaponArena);
+
+#define EV_DropSpecialItems(i, o) \
+    /**/ i(entity, frag_target) \
+    /**/
+MUTATOR_HOOKABLE(DropSpecialItems, EV_DropSpecialItems);
 #endif
diff --git a/qcsrc/server/mutators/gamemode_ctf.qc b/qcsrc/server/mutators/gamemode_ctf.qc
index 2814a4e4e3..016f9bd47a 100644
--- a/qcsrc/server/mutators/gamemode_ctf.qc
+++ b/qcsrc/server/mutators/gamemode_ctf.qc
@@ -2373,6 +2373,14 @@ MUTATOR_HOOKFUNCTION(ctf, SV_ParseClientCommand)
 	return false;
 }
 
+MUTATOR_HOOKFUNCTION(ctf, DropSpecialItems)
+{
+	if(frag_target.flagcarried)
+		ctf_Handle_Throw(frag_target, world, DROP_THROW);
+
+	return false;
+}
+
 
 // ==========
 // Spawnfuncs
diff --git a/qcsrc/server/mutators/gamemode_keepaway.qc b/qcsrc/server/mutators/gamemode_keepaway.qc
index ca1f241d65..61289b58f4 100644
--- a/qcsrc/server/mutators/gamemode_keepaway.qc
+++ b/qcsrc/server/mutators/gamemode_keepaway.qc
@@ -406,6 +406,14 @@ MUTATOR_HOOKFUNCTION(ka, HavocBot_ChooseRole)
 	return true;
 }
 
+MUTATOR_HOOKFUNCTION(ka, DropSpecialItems)
+{
+	if(frag_target.ballcarried)
+		ka_DropEvent(frag_target);
+
+	return false;
+}
+
 
 // ==============
 // Initialization
diff --git a/qcsrc/server/mutators/gamemode_keyhunt.qc b/qcsrc/server/mutators/gamemode_keyhunt.qc
index 71a65c6b59..4893bf13e5 100644
--- a/qcsrc/server/mutators/gamemode_keyhunt.qc
+++ b/qcsrc/server/mutators/gamemode_keyhunt.qc
@@ -1320,6 +1320,12 @@ MUTATOR_HOOKFUNCTION(kh, HavocBot_ChooseRole)
 	return true;
 }
 
+MUTATOR_HOOKFUNCTION(kh, DropSpecialItems)
+{
+	kh_Key_DropAll(frag_target, false);
+	return false;
+}
+
 REGISTER_MUTATOR(kh, g_keyhunt)
 {
 	ActivateTeamplay();
diff --git a/qcsrc/server/mutators/mutator_nades.qc b/qcsrc/server/mutators/mutator_nades.qc
index fc1f1d1e7b..45cc4f9c4c 100644
--- a/qcsrc/server/mutators/mutator_nades.qc
+++ b/qcsrc/server/mutators/mutator_nades.qc
@@ -243,13 +243,8 @@ void nade_ice_freeze(entity freezefield, entity frost_target, float freeze_time)
 	frost_target.frozen_by = freezefield.realowner;
 	Send_Effect(EFFECT_ELECTRO_IMPACT, frost_target.origin, '0 0 0', 1);
 	Freeze(frost_target, 1/freeze_time, 3, false);
-	if(frost_target.ballcarried)
-	if(g_keepaway) { ka_DropEvent(frost_target); }
-	else { DropBall(frost_target.ballcarried, frost_target.origin, frost_target.velocity);}
-	if(frost_target.flagcarried) { ctf_Handle_Throw(frost_target, world, DROP_THROW); }
-	if(frost_target.nade) { toss_nade(frost_target, '0 0 0', time + 0.05); }
 
-	kh_Key_DropAll(frost_target, false);
+	Drop_Special_Items(frost_target);
 }
 
 void nade_ice_think()
@@ -1160,6 +1155,14 @@ MUTATOR_HOOKFUNCTION(nades, MonsterDies)
 	return false;
 }
 
+MUTATOR_HOOKFUNCTION(nades, DropSpecialItems)
+{
+	if(frag_target.nade)
+		toss_nade(frag_target, '0 0 0', time + 0.05);
+
+	return false;
+}
+
 bool nades_RemovePlayer()
 {SELFPARAM();
 	nades_Clear(self);
-- 
2.39.5