From 15588864e409e5ca95738d2451dcef1e681b8dac Mon Sep 17 00:00:00 2001
From: atheros <nexather@gmail.com>
Date: Tue, 30 Aug 2011 15:35:13 +0200
Subject: [PATCH] g_ca_spectate_enemies 0 will forbid dead ca players from
 spectating enemy players in clan arena games

---
 defaultXonotic.cfg        |  1 +
 qcsrc/server/autocvars.qh |  1 +
 qcsrc/server/cl_client.qc | 80 ++++++++++++++++++++++++++-------------
 3 files changed, 56 insertions(+), 26 deletions(-)

diff --git a/defaultXonotic.cfg b/defaultXonotic.cfg
index e9d5b285b..e7d0ed257 100644
--- a/defaultXonotic.cfg
+++ b/defaultXonotic.cfg
@@ -808,6 +808,7 @@ set g_arena_powerups 0	"enables powerups (superhealth, strength and shield), whi
 set g_ca 0 "Clan Arena: Played in rounds, once you're dead you're out! The team with survivors wins the round."
 set g_ca_point_limit 10 "point limit 10 is standard for clan arena"
 set g_ca_point_leadlimit 0
+set g_ca_spectate_enemies 1 "Allow spectating enemy player by dead player during clan arena games."
 set g_ca_warmup 10 "how long the players will have time to run around the map before the round starts"
 
 // onslaught
diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh
index ff9982333..492f01783 100644
--- a/qcsrc/server/autocvars.qh
+++ b/qcsrc/server/autocvars.qh
@@ -712,6 +712,7 @@ float autocvar_g_ca_damage2score_multiplier;
 float autocvar_g_ca_point_leadlimit;
 float autocvar_g_ca_point_limit;
 float autocvar_g_ca_round_timelimit;
+float autocvar_g_ca_spectate_enemies;
 float autocvar_g_ca_warmup;
 float autocvar_g_campaign;
 float autocvar_g_campaign_forceteam;
diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc
index f3d34bb47..a146e183c 100644
--- a/qcsrc/server/cl_client.qc
+++ b/qcsrc/server/cl_client.qc
@@ -2359,38 +2359,66 @@ float SpectateUpdate() {
 	return 1;
 }
 
-float SpectateNext() {
-	other = find(self.enemy, classname, "player");
 
-	if (!other)
+// Returns next available player to spectate if g_ca_spectate_enemies == 0
+entity CA_SpectateNext(entity start) {
+	if (start.team == self.team) {
+		return start;
+	}
+	
+	other = start;
+	// continue from current player
+	while(other && other.team != self.team) {
+		other = find(other, classname, "player");
+	}
+	
+	if (!other) {
+		// restart from begining
 		other = find(other, classname, "player");
+		while(other && other.team != self.team) {
+			other = find(other, classname, "player");
+		}
+	}
+	
+	return other;
+}
 
+float SpectateNext() {
+	other = find(self.enemy, classname, "player");
+	if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer) {
+		// CA and ca players when spectating enemies is forbidden
+		other = CA_SpectateNext(other);
+	} else {
+		// other modes and ca spectators or spectating enemies is allowed
+		if (!other)
+			other = find(other, classname, "player");
+	}
+	
 	if (other)
 		self.enemy = other;
-
+	
 	if(self.enemy.classname == "player") {
-	    if(self.enemy.vehicle)
-	    {	   
-            msg_entity = self;
-            WriteByte(MSG_ONE, SVC_SETVIEWPORT);
-            WriteEntity(MSG_ONE, self.enemy);
-            //stuffcmd(self, "set viewsize $tmpviewsize \n");
-            self.movetype = MOVETYPE_NONE;
-            accuracy_resend(self);
-	    }
-	    else 
-	    {	        
-            msg_entity = self;
-            WriteByte(MSG_ONE, SVC_SETVIEW);
-            WriteEntity(MSG_ONE, self.enemy);
-            //stuffcmd(self, "set viewsize $tmpviewsize \n");
-            self.movetype = MOVETYPE_NONE;
-            accuracy_resend(self);
-
-            if(!SpectateUpdate())
-                PutObserverInServer();
-        }
-        return 1;
+		if(self.enemy.vehicle)
+		{	   
+			msg_entity = self;
+			WriteByte(MSG_ONE, SVC_SETVIEWPORT);
+			WriteEntity(MSG_ONE, self.enemy);
+			//stuffcmd(self, "set viewsize $tmpviewsize \n");
+			self.movetype = MOVETYPE_NONE;
+			accuracy_resend(self);
+		}
+		else
+		{
+			msg_entity = self;
+			WriteByte(MSG_ONE, SVC_SETVIEW);
+			WriteEntity(MSG_ONE, self.enemy);
+			//stuffcmd(self, "set viewsize $tmpviewsize \n");
+			self.movetype = MOVETYPE_NONE;
+			accuracy_resend(self);
+			if(!SpectateUpdate())
+				PutObserverInServer();
+		}
+		return 1;
 	} else {
 		return 0;
 	}
-- 
2.39.5