about summary refs log tree commit diff
path: root/src/game/server
diff options
context:
space:
mode:
authorTeetime <TeetimeTW@yahoo.de>2013-01-12 07:59:20 +0100
committerTeetime <TeetimeTW@yahoo.de>2013-01-12 07:59:20 +0100
commit90770bc12e3266cf428b66abbbd4d6bb85a5bc55 (patch)
tree6a51446a4a1ea4ca73ce61bd97bb4bad5a48c431 /src/game/server
parent198122516365d17a489cc86f205d44cc0008f99d (diff)
downloadzcatch-90770bc12e3266cf428b66abbbd4d6bb85a5bc55.tar.gz
zcatch-90770bc12e3266cf428b66abbbd4d6bb85a5bc55.zip
Refactored some things, corrected indentation etc..
Diffstat (limited to 'src/game/server')
-rw-r--r--src/game/server/entities/character.cpp61
-rw-r--r--src/game/server/entities/laser.cpp2
-rw-r--r--src/game/server/gamecontext.cpp145
-rw-r--r--src/game/server/gamecontext.h5
-rw-r--r--src/game/server/gamecontroller.cpp58
-rw-r--r--src/game/server/gamecontroller.h6
-rw-r--r--src/game/server/gamemodes/zcatch.cpp108
-rw-r--r--src/game/server/gamemodes/zcatch.h12
-rw-r--r--src/game/server/player.h3
9 files changed, 182 insertions, 218 deletions
diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp
index ac5f2f7c..a874debd 100644
--- a/src/game/server/entities/character.cpp
+++ b/src/game/server/entities/character.cpp
@@ -59,23 +59,21 @@ bool CCharacter::Spawn(CPlayer *pPlayer, vec2 Pos)
 	m_LastAction = -1;
 	
 	/*zCatch */
-	if(GameServer()->m_pController->IsZCatch() && g_Config.m_SvMode == 1)
+	switch(g_Config.m_SvMode)
 	{
+	case 1:
 		m_ActiveWeapon = WEAPON_RIFLE;
 		m_LastWeapon = WEAPON_RIFLE;
-	}
-	else if(GameServer()->m_pController->IsZCatch() && g_Config.m_SvMode == 3)
-	{
+		break;
+	case 3:
 		m_ActiveWeapon = WEAPON_HAMMER;
 		m_LastWeapon = WEAPON_HAMMER;
-	}
-	else if(GameServer()->m_pController->IsZCatch() && g_Config.m_SvMode == 4)
-	{
+		break;
+	case 4:
 		m_ActiveWeapon = WEAPON_GRENADE;
 		m_LastWeapon = WEAPON_GRENADE;
-	}
-	else
-	{
+		break;
+	default:
 		m_ActiveWeapon = WEAPON_GUN;
 		m_LastWeapon = WEAPON_HAMMER;
 	}
@@ -138,20 +136,17 @@ void CCharacter::HandleNinja()
 	if(m_ActiveWeapon != WEAPON_NINJA)
 		return;
 
-	/* zCatch */
-	if(GameServer()->m_pController->IsZCatch() == false)
+	/* zCatch - Disable for Ninja-Mode
+	if ((Server()->Tick() - m_Ninja.m_ActivationTick) > (g_pData->m_Weapons.m_Ninja.m_Duration * Server()->TickSpeed() / 1000))
 	{
-		if ((Server()->Tick() - m_Ninja.m_ActivationTick) > (g_pData->m_Weapons.m_Ninja.m_Duration * Server()->TickSpeed() / 1000))
-		{
-			// time's up, return
-			m_aWeapons[WEAPON_NINJA].m_Got = false;
-			m_ActiveWeapon = m_LastWeapon;
+		// time's up, return
+		m_aWeapons[WEAPON_NINJA].m_Got = false;
+		m_ActiveWeapon = m_LastWeapon;
 
-			SetWeapon(m_ActiveWeapon);
-			return;
-		}
+		SetWeapon(m_ActiveWeapon);
+		return;
 	}
-	/* zCatch end*/
+	*/
 	
 	// force ninja Weapon
 	SetWeapon(WEAPON_NINJA);
@@ -472,7 +467,7 @@ void CCharacter::HandleWeapons()
 
 	// ammo regen
 	int AmmoRegenTime = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Ammoregentime;
-	if(GameServer()->m_pController->IsZCatch() && m_aWeapons[m_ActiveWeapon].m_Ammo > -1)
+	if(m_aWeapons[m_ActiveWeapon].m_Ammo > -1)
 	{
 		switch(m_ActiveWeapon)
 		{
@@ -494,7 +489,7 @@ void CCharacter::HandleWeapons()
 			if ((Server()->Tick() - m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart) >= AmmoRegenTime * Server()->TickSpeed() / 1000)
 			{
 				// Add some ammo
-				m_aWeapons[m_ActiveWeapon].m_Ammo = min(m_aWeapons[m_ActiveWeapon].m_Ammo + 1, (GameServer()->m_pController->IsZCatch()) ? g_Config.m_SvGrenadeBullets : 10);
+				m_aWeapons[m_ActiveWeapon].m_Ammo = min(m_aWeapons[m_ActiveWeapon].m_Ammo + 1, g_Config.m_SvGrenadeBullets);
 				m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart = -1;
 			}
 		}
@@ -791,22 +786,14 @@ bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon)
 		return false;
 	
 	/* zCatch */
-	if(GameServer()->m_pController->IsZCatch())
-	{
-		if(From == m_pPlayer->GetCID() || Weapon == WEAPON_GAME)
-			return false;
+	if(From == m_pPlayer->GetCID() || Weapon == WEAPON_GAME)
+		return false;
 
-		if(g_Config.m_SvMode == 4 && Weapon == WEAPON_GRENADE && Dmg < g_Config.m_SvGrenadeMinDamage)
-			return false;
+	if(g_Config.m_SvMode == 4 && Weapon == WEAPON_GRENADE && Dmg < g_Config.m_SvGrenadeMinDamage)
+		return false;
 
-		m_Health = 0;
-		m_Armor = 0;
-	}
-	else
-	{
-		if(From == m_pPlayer->GetCID())
-			Dmg = max(1, Dmg/2);
-	}
+	m_Health = 0;
+	m_Armor = 0;
 	/* end zCatch */
 	
 	m_DamageTaken++;
diff --git a/src/game/server/entities/laser.cpp b/src/game/server/entities/laser.cpp
index f45a1d1d..eb1145c5 100644
--- a/src/game/server/entities/laser.cpp
+++ b/src/game/server/entities/laser.cpp
@@ -69,7 +69,7 @@ void CLaser::DoBounce()
 
 			GameServer()->CreateSound(m_Pos, SOUND_RIFLE_BOUNCE);
 
-			if(m_Bounces == 1 && g_Config.m_SvLaserjumps && GameServer()->m_pController->IsZCatch())
+			if(m_Bounces == 1 && g_Config.m_SvLaserjumps)
 				GameServer()->CreateExplosion(m_Pos, m_Owner, WEAPON_GAME, false);
 		}
 	}
diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp
index 3967f49d..7aa9c295 100644
--- a/src/game/server/gamecontext.cpp
+++ b/src/game/server/gamecontext.cpp
@@ -9,10 +9,10 @@
 #include <game/version.h>
 #include <game/collision.h>
 #include <game/gamecore.h>
-#include "gamemodes/dm.h"
+/*#include "gamemodes/dm.h"
 #include "gamemodes/tdm.h"
 #include "gamemodes/ctf.h"
-#include "gamemodes/mod.h"
+#include "gamemodes/mod.h"*/
 #include "gamemodes/zcatch.h"
 
 enum
@@ -548,62 +548,59 @@ void CGameContext::OnClientEnter(int ClientID)
 	int LeaderID = -1;
 	int StartTeam = m_pController->ClampTeam(1);
 	
-	if(m_pController->IsZCatch())
+	int Num = 0;
+
+	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
-		int Num = 0;
-		
+		if(IsClientReady(i))
+			Num++;
+	}
+	if(Num < 3)
+		m_pController->EndRound();
+
+	if(g_Config.m_SvAllowJoin == 1)
+	{
+		m_apPlayers[ClientID]->m_CaughtBy = CPlayer::ZCATCH_NOT_CAUGHT;
+		m_apPlayers[ClientID]->m_SpecExplicit = (Num < 3) ? 0 : 1;
+		StartTeam = (Num < 3) ? m_pController->ClampTeam(1) : TEAM_SPECTATORS;
+		SendBroadcast("You can join the game", ClientID);
+	}
+	else if(g_Config.m_SvAllowJoin == 2)
+	{
+		int Num2 = 0, PrevNum = 0;
+
 		for(int i = 0; i < MAX_CLIENTS; i++)
 		{
-			if(IsClientReady(i))
-				Num++;
-		}
-		if(Num < 3)
-			m_pController->EndRound();
-		
-		if(g_Config.m_SvAllowJoin == 1)
-		{
-			m_apPlayers[ClientID]->m_CaughtBy = ZCATCH_NOT_CAUGHT;
-			m_apPlayers[ClientID]->m_SpecExplicit = (Num < 3) ? 0 : 1;
-			StartTeam = (Num < 3) ? m_pController->ClampTeam(1) : TEAM_SPECTATORS;
-			SendBroadcast("You can join the game", ClientID);
-		}
-		else if(g_Config.m_SvAllowJoin == 2)
-		{
-			int Num2 = 0, PrevNum = 0;
-
-			for(int i = 0; i < MAX_CLIENTS; i++)
+			if(m_apPlayers[i])
 			{
-				if(m_apPlayers[i])
-				{
-					Num2 = 0;
-					for(int j = 0; j < MAX_CLIENTS; j++)
-						if(m_apPlayers[j] && m_apPlayers[j]->m_CaughtBy == i)
-							Num2++;
+				Num2 = 0;
+				for(int j = 0; j < MAX_CLIENTS; j++)
+					if(m_apPlayers[j] && m_apPlayers[j]->m_CaughtBy == i)
+						Num2++;
 
-					if(Num2 > PrevNum)
-					{
-						LeaderID = i;
-						PrevNum = Num2;
-		    		}
+				if(Num2 > PrevNum)
+				{
+					LeaderID = i;
+					PrevNum = Num2;
 				}
-		    }
-
-		    if(LeaderID > -1)
-			{
-				m_apPlayers[ClientID]->m_CaughtBy = LeaderID;
-				m_apPlayers[ClientID]->m_SpecExplicit = 0;
-				m_apPlayers[ClientID]->m_SpectatorID = LeaderID;
-				StartTeam = TEAM_SPECTATORS;
-			}
-			else
-			{
-				m_apPlayers[ClientID]->m_CaughtBy = ZCATCH_NOT_CAUGHT;
-				m_apPlayers[ClientID]->m_SpecExplicit = 0;
 			}
 		}
+
+		if(LeaderID > -1)
+		{
+			m_apPlayers[ClientID]->m_CaughtBy = LeaderID;
+			m_apPlayers[ClientID]->m_SpecExplicit = 0;
+			m_apPlayers[ClientID]->m_SpectatorID = LeaderID;
+			StartTeam = TEAM_SPECTATORS;
+		}
 		else
-			StartTeam = m_pController->GetAutoTeam(ClientID);
+		{
+			m_apPlayers[ClientID]->m_CaughtBy = CPlayer::ZCATCH_NOT_CAUGHT;
+			m_apPlayers[ClientID]->m_SpecExplicit = 0;
+		}
 	}
+	else
+		StartTeam = m_pController->GetAutoTeam(ClientID);
 	
 	m_apPlayers[ClientID]->SetTeamDirect(StartTeam);
 	
@@ -619,17 +616,14 @@ void CGameContext::OnClientEnter(int ClientID)
 	m_VoteUpdate = true;
 	
 	/* zCatch begin */
-   	if(m_pController->IsZCatch())
+	SendChatTarget(ClientID, "Welcome to zCatch!");
+	SendChatTarget(ClientID, "type /cmdlist to get all commands");
+	SendChatTarget(ClientID, "type /help for instructions");
+	if(g_Config.m_SvAllowJoin == 2 && LeaderID > -1)
 	{
-	    SendChatTarget(ClientID, "Welcome to zCatch!");
-	    SendChatTarget(ClientID, "type /cmdlist to get all commands");
-	    SendChatTarget(ClientID, "type /help for instructions");
-	    if(g_Config.m_SvAllowJoin == 2 && LeaderID > -1)
-	    {
-	    	char buf[128];
-	    	str_format(buf, sizeof(buf), "You will join the game when %s dies", Server()->ClientName(LeaderID));
-	    	SendChatTarget(ClientID, buf);	
-	    }
+		char buf[128];
+		str_format(buf, sizeof(buf), "You will join the game when %s dies", Server()->ClientName(LeaderID));
+		SendChatTarget(ClientID, buf);
 	}
 	/* zCatch end */
 }
@@ -974,34 +968,18 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
 		// Switch team on given client and kill/respawn him
 		if(m_pController->CanJoinTeam(pMsg->m_Team, ClientID))
 		{
-			if(m_pController->CanChangeTeam(pPlayer, pMsg->m_Team) && !m_pController->IsZCatch()) //zCatch
+			if(m_pController->CanChangeTeam(pPlayer, pMsg->m_Team))
 			{
 				pPlayer->m_LastSetTeam = Server()->Tick();
-				if(pPlayer->GetTeam() == TEAM_SPECTATORS || pMsg->m_Team == TEAM_SPECTATORS)
-					m_VoteUpdate = true;
 				pPlayer->SetTeam(pMsg->m_Team);
-				(void)m_pController->CheckTeamBalance();
-				pPlayer->m_TeamChangeTick = Server()->Tick();
 			}
-			/* begin zCatch */
-			else if(m_pController->IsZCatch())
-			{	
-				if(pPlayer->m_CaughtBy >= 0)
-				{
-					char buf[256];
-					str_format(buf, sizeof(buf), "You will join automatically when \"%s\" dies.", Server()->ClientName(pPlayer->m_CaughtBy));
-					SendChatTarget(ClientID, buf);
-					return;
-				}
-				else if(pPlayer->m_CaughtBy == ZCATCH_NOT_CAUGHT)
-				{
-					pPlayer->m_LastSetTeam = Server()->Tick();
-					pPlayer->SetTeam(pMsg->m_Team);
-				}
-			}
-            /* end zCatch */
 			else
-				SendBroadcast("Teams must be balanced, please join other team", ClientID);
+			{
+				char aBuf[256];
+				str_format(aBuf, sizeof(aBuf), "You will join automatically when \"%s\" dies.", Server()->ClientName(pPlayer->m_CaughtBy));
+				SendChatTarget(ClientID, aBuf);
+				return;
+			}
 		}
 		else
 		{
@@ -1774,7 +1752,7 @@ void CGameContext::OnInit(/*class IKernel *pKernel*/)
 	//players = new CPlayer[MAX_CLIENTS];
 
 	// select gametype
-	if(str_comp(g_Config.m_SvGametype, "mod") == 0)
+	/*if(str_comp(g_Config.m_SvGametype, "mod") == 0)
 		m_pController = new CGameControllerMOD(this);
 	else if(str_comp(g_Config.m_SvGametype, "ctf") == 0)
 		m_pController = new CGameControllerCTF(this);
@@ -1783,7 +1761,8 @@ void CGameContext::OnInit(/*class IKernel *pKernel*/)
 	else if(str_comp_nocase(g_Config.m_SvGametype, "zcatch") == 0)
 		m_pController = new CGameController_zCatch(this);
 	else
-		m_pController = new CGameControllerDM(this);
+		m_pController = new CGameControllerDM(this);*/
+	m_pController = new CGameController_zCatch(this);
 
 	// setup core world
 	//for(int i = 0; i < MAX_CLIENTS; i++)
diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h
index 8dca1fbe..47a831d1 100644
--- a/src/game/server/gamecontext.h
+++ b/src/game/server/gamecontext.h
@@ -143,11 +143,6 @@ public:
 		CHAT_BLUE=1
 	};
 	
-	enum
-	{
-		ZCATCH_NOT_CAUGHT = -1,
-	}; 
-	
 	struct CMutes
 	{
 		char m_IP[NETADDR_MAXSTRSIZE];
diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp
index 58c4d9f0..7001ca32 100644
--- a/src/game/server/gamecontroller.cpp
+++ b/src/game/server/gamecontroller.cpp
@@ -136,35 +136,30 @@ bool IGameController::OnEntity(int Index, vec2 Pos)
 		m_aaSpawnPoints[1][m_aNumSpawnPoints[1]++] = Pos;
 	else if(Index == ENTITY_SPAWN_BLUE)
 		m_aaSpawnPoints[2][m_aNumSpawnPoints[2]++] = Pos;
-	/* zCatch */
-   	else if(!GameServer()->m_pController->IsZCatch())
-    	{
-        if(Index == ENTITY_ARMOR_1)
-            Type = POWERUP_ARMOR;
-        else if(Index == ENTITY_HEALTH_1)
-            Type = POWERUP_HEALTH;
-        else if(Index == ENTITY_WEAPON_SHOTGUN)
-        {
-            Type = POWERUP_WEAPON;
-            SubType = WEAPON_SHOTGUN;
-        }
-        else if(Index == ENTITY_WEAPON_GRENADE)
-        {
-            Type = POWERUP_WEAPON;
-            SubType = WEAPON_GRENADE;
-        }
-        else if(Index == ENTITY_WEAPON_RIFLE)
-        {
-            Type = POWERUP_WEAPON;
-            SubType = WEAPON_RIFLE;
-        }
-        else if(Index == ENTITY_POWERUP_NINJA && g_Config.m_SvPowerups)
-        {
-            Type = POWERUP_NINJA;
-            SubType = WEAPON_NINJA;
-        }
-    }
-    /* end zCatch*/
+	else if(Index == ENTITY_ARMOR_1)
+		Type = POWERUP_ARMOR;
+	else if(Index == ENTITY_HEALTH_1)
+		Type = POWERUP_HEALTH;
+	else if(Index == ENTITY_WEAPON_SHOTGUN)
+	{
+		Type = POWERUP_WEAPON;
+		SubType = WEAPON_SHOTGUN;
+	}
+	else if(Index == ENTITY_WEAPON_GRENADE)
+	{
+		Type = POWERUP_WEAPON;
+		SubType = WEAPON_GRENADE;
+	}
+	else if(Index == ENTITY_WEAPON_RIFLE)
+	{
+		Type = POWERUP_WEAPON;
+		SubType = WEAPON_RIFLE;
+	}
+	else if(Index == ENTITY_POWERUP_NINJA && g_Config.m_SvPowerups)
+	{
+		Type = POWERUP_NINJA;
+		SubType = WEAPON_NINJA;
+	}
 
 	if(Type != -1)
 	{
@@ -176,11 +171,6 @@ bool IGameController::OnEntity(int Index, vec2 Pos)
 	return false;
 }
 
-bool IGameController::IsZCatch()
-{
-	return false;
-}
-
 void IGameController::EndRound()
 {
 	if(m_Warmup) // game can't end when we are running warmup
diff --git a/src/game/server/gamecontroller.h b/src/game/server/gamecontroller.h
index 1be24509..fbf6ae79 100644
--- a/src/game/server/gamecontroller.h
+++ b/src/game/server/gamecontroller.h
@@ -12,13 +12,13 @@
 */
 class IGameController
 {
+protected:
 	vec2 m_aaSpawnPoints[3][64];
 	int m_aNumSpawnPoints[3];
 
 	class CGameContext *m_pGameServer;
 	class IServer *m_pServer;
 
-protected:
 	CGameContext *GameServer() const { return m_pGameServer; }
 	IServer *Server() const { return m_pServer; }
 
@@ -138,12 +138,10 @@ public:
 	virtual int GetAutoTeam(int NotThisID);
 	virtual bool CanJoinTeam(int Team, int NotThisID);
 	bool CheckTeamBalance();
-	bool CanChangeTeam(CPlayer *pPplayer, int JoinTeam);
+	virtual bool CanChangeTeam(CPlayer *pPlayer, int JoinTeam);
 	int ClampTeam(int Team);
 
 	virtual void PostReset();
-	
-	virtual bool IsZCatch();
 };
 
 #endif
diff --git a/src/game/server/gamemodes/zcatch.cpp b/src/game/server/gamemodes/zcatch.cpp
index 2a94e7ac..393f4511 100644
--- a/src/game/server/gamemodes/zcatch.cpp
+++ b/src/game/server/gamemodes/zcatch.cpp
@@ -1,13 +1,16 @@
 /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
 /* If you are missing that file, acquire a complete release at teeworlds.com.                */
-/* zCatch by erd and Teetime */
+/* zCatch by erd and Teetime                                                                 */
 
 #include <engine/shared/config.h>
 #include <game/server/gamecontext.h>
+#include <game/server/gamecontroller.h>
+#include <game/server/entities/character.h>
+#include <game/server/player.h>
 #include "zcatch.h"
 
-CGameController_zCatch::CGameController_zCatch(class CGameContext *pGameServer) 
-: IGameController(pGameServer)
+CGameController_zCatch::CGameController_zCatch(class CGameContext *pGameServer) :
+		IGameController(pGameServer)
 {
 	m_pGameType = "zCatch";
 	m_OldMode = g_Config.m_SvMode;
@@ -25,14 +28,9 @@ void CGameController_zCatch::Tick()
 	}
 }
 
-bool CGameController_zCatch::IsZCatch()
-{
-	return true;
-}
-
 void CGameController_zCatch::DoWincheck()
 {
-	int Players = 0, Players_Spec = 0, Players_SpecExplicit = 0;	
+	int Players = 0, Players_Spec = 0, Players_SpecExplicit = 0;
 
 	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
@@ -50,7 +48,7 @@ void CGameController_zCatch::DoWincheck()
 	{
 		//Do nothing
 	}
-	else if((Players - Players_Spec == 1) && (Players != Players_Spec) && (Players - Players_SpecExplicit != 1)) 
+	else if((Players - Players_Spec == 1) && (Players != Players_Spec) && (Players - Players_SpecExplicit != 1))
 	{
 		for(int i = 0; i < MAX_CLIENTS; i++)
 		{
@@ -65,12 +63,12 @@ void CGameController_zCatch::DoWincheck()
 
 int CGameController_zCatch::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int WeaponID)
 {
-	int VictimID =  pVictim->GetPlayer()->GetCID();
-	char aBuf[256];
-	if(pKiller !=  pVictim->GetPlayer())
+	int VictimID = pVictim->GetPlayer()->GetCID();
+
+	if(pKiller != pVictim->GetPlayer())
 	{
 		pKiller->m_Kills++;
-		pVictim->GetPlayer()->m_Deaths++; 
+		pVictim->GetPlayer()->m_Deaths++;
 
 		pKiller->m_Score++;
 
@@ -83,6 +81,7 @@ int CGameController_zCatch::OnCharacterDeath(class CCharacter *pVictim, class CP
 			if(pVictim->GetPlayer()->m_PlayerWantToFollowCatcher)
 				pVictim->GetPlayer()->m_SpectatorID = pKiller->GetCID(); // Let the victim follow his catcher
 
+			char aBuf[256];
 			str_format(aBuf, sizeof(aBuf), "Caught by \"%s\". You will join the game automatically when \"%s\" dies.", Server()->ClientName(pKiller->GetCID()), Server()->ClientName(pKiller->GetCID()));
 			GameServer()->SendChatTarget(VictimID, aBuf);
 		}
@@ -94,15 +93,15 @@ int CGameController_zCatch::OnCharacterDeath(class CCharacter *pVictim, class CP
 			pVictim->GetPlayer()->m_Score -= g_Config.m_SvKillPenalty;
 	}
 
-	for(int i=0; i < MAX_CLIENTS; i++)
+	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
 		if(GameServer()->m_apPlayers[i])
 		{
 			if(GameServer()->m_apPlayers[i]->m_CaughtBy == VictimID)
 			{
-				GameServer()->m_apPlayers[i]->m_CaughtBy = ZCATCH_NOT_CAUGHT;
+				GameServer()->m_apPlayers[i]->m_CaughtBy = CPlayer::ZCATCH_NOT_CAUGHT;
 				GameServer()->m_apPlayers[i]->SetTeamDirect(GameServer()->m_pController->ClampTeam(1));
-				
+
 				if(pKiller != pVictim->GetPlayer())
 					pKiller->m_Score++;
 			}
@@ -142,11 +141,11 @@ void CGameController_zCatch::StartRound()
 	m_aTeamscore[TEAM_BLUE] = 0;
 	m_ForceBalanced = false;
 	Server()->DemoRecorder_HandleAutoStart();
-	for(int i=0; i<MAX_CLIENTS; i++)
+	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
 		if(GameServer()->m_apPlayers[i])
-		{		
-			GameServer()->m_apPlayers[i]->m_CaughtBy = ZCATCH_NOT_CAUGHT;
+		{
+			GameServer()->m_apPlayers[i]->m_CaughtBy = CPlayer::ZCATCH_NOT_CAUGHT;
 			GameServer()->m_apPlayers[i]->m_Kills = 0;
 			GameServer()->m_apPlayers[i]->m_Deaths = 0;
 			GameServer()->m_apPlayers[i]->m_TicksSpec = 0;
@@ -167,27 +166,27 @@ void CGameController_zCatch::OnCharacterSpawn(class CCharacter *pChr)
 
 	// give default weapons
 	switch(g_Config.m_SvMode)
-		{
-			case 1: /* Instagib - Only Riffle */
-				pChr->GiveWeapon(WEAPON_RIFLE, -1);
-				break;
-			case 2: /* All Weapons */
-				pChr->GiveWeapon(WEAPON_HAMMER, -1);
-				pChr->GiveWeapon(WEAPON_GUN, 6);
-				pChr->GiveWeapon(WEAPON_GRENADE, 6);
-				pChr->GiveWeapon(WEAPON_SHOTGUN, 6);
-				pChr->GiveWeapon(WEAPON_RIFLE, 6);
-				break;
-			case 3: /* Hammer */
-				pChr->GiveWeapon(WEAPON_HAMMER, -1);
-				break;
-			case 4: /* Grenade */
-				pChr->GiveWeapon(WEAPON_GRENADE, g_Config.m_SvGrenadeBullets);
-				break;
-			case 5: /* Ninja */
-				pChr->GiveNinja();
-				break;
-		}
+	{
+	case 1: /* Instagib - Only Riffle */
+		pChr->GiveWeapon(WEAPON_RIFLE, -1);
+		break;
+	case 2: /* All Weapons */
+		pChr->GiveWeapon(WEAPON_HAMMER, -1);
+		pChr->GiveWeapon(WEAPON_GUN, 6);
+		pChr->GiveWeapon(WEAPON_GRENADE, 6);
+		pChr->GiveWeapon(WEAPON_SHOTGUN, 6);
+		pChr->GiveWeapon(WEAPON_RIFLE, 6);
+		break;
+	case 3: /* Hammer */
+		pChr->GiveWeapon(WEAPON_HAMMER, -1);
+		break;
+	case 4: /* Grenade */
+		pChr->GiveWeapon(WEAPON_GRENADE, g_Config.m_SvGrenadeBullets);
+		break;
+	case 5: /* Ninja */
+		pChr->GiveNinja();
+		break;
+	}
 
 	//Update color of spawning tees
 	OnPlayerInfoChange(pChr->GetPlayer());
@@ -203,18 +202,18 @@ void CGameController_zCatch::EndRound()
 			if(GameServer()->m_apPlayers[i]->m_SpecExplicit == 0)
 			{
 				GameServer()->m_apPlayers[i]->SetTeamDirect(GameServer()->m_pController->ClampTeam(1));
-				
+
 				char aBuf[128];
 				str_format(aBuf, sizeof(aBuf), "Kills: %d | Deaths: %d", GameServer()->m_apPlayers[i]->m_Kills, GameServer()->m_apPlayers[i]->m_Deaths);
 				GameServer()->SendChatTarget(i, aBuf);
 
 				if(GameServer()->m_apPlayers[i]->m_TicksSpec != 0 || GameServer()->m_apPlayers[i]->m_TicksIngame != 0)
 				{
-					double TimeInSpec = (GameServer()->m_apPlayers[i]->m_TicksSpec*100.0) / (GameServer()->m_apPlayers[i]->m_TicksIngame + GameServer()->m_apPlayers[i]->m_TicksSpec);
-					str_format(aBuf, sizeof(aBuf), "Spec: %.2f%% | Ingame: %.2f%%", (double)TimeInSpec, (double)(100.0 - TimeInSpec));
+					double TimeInSpec = (GameServer()->m_apPlayers[i]->m_TicksSpec * 100.0) / (GameServer()->m_apPlayers[i]->m_TicksIngame + GameServer()->m_apPlayers[i]->m_TicksSpec);
+					str_format(aBuf, sizeof(aBuf), "Spec: %.2f%% | Ingame: %.2f%%", (double) TimeInSpec, (double) (100.0 - TimeInSpec));
 					GameServer()->SendChatTarget(i, aBuf);
 				}
-				GameServer()->m_apPlayers[i]->m_CaughtBy = ZCATCH_NOT_CAUGHT; //Set all players in server as non-caught
+				GameServer()->m_apPlayers[i]->m_CaughtBy = CPlayer::ZCATCH_NOT_CAUGHT; //Set all players in server as non-caught
 			}
 		}
 	}
@@ -226,3 +225,22 @@ void CGameController_zCatch::EndRound()
 	m_GameOverTick = Server()->Tick();
 	m_SuddenDeath = 0;
 }
+
+bool CGameController_zCatch::CanChangeTeam(CPlayer *pPlayer, int JoinTeam)
+{
+	if(pPlayer->m_CaughtBy >= 0)
+		return false;
+	return true;
+}
+
+bool CGameController_zCatch::OnEntity(int Index, vec2 Pos)
+{
+	if(Index == ENTITY_SPAWN)
+		m_aaSpawnPoints[0][m_aNumSpawnPoints[0]++] = Pos;
+	else if(Index == ENTITY_SPAWN_RED)
+		m_aaSpawnPoints[1][m_aNumSpawnPoints[1]++] = Pos;
+	else if(Index == ENTITY_SPAWN_BLUE)
+		m_aaSpawnPoints[2][m_aNumSpawnPoints[2]++] = Pos;
+
+	return false;
+}
diff --git a/src/game/server/gamemodes/zcatch.h b/src/game/server/gamemodes/zcatch.h
index cb01ff8b..4f110a03 100644
--- a/src/game/server/gamemodes/zcatch.h
+++ b/src/game/server/gamemodes/zcatch.h
@@ -1,13 +1,13 @@
 /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
 /* If you are missing that file, acquire a complete release at teeworlds.com.                */
-/* zCatch by erd and Teetime */
+/* zCatch by erd and Teetime                                                                 */
 
 #ifndef GAME_SERVER_GAMEMODES_ZCATCH_H
 #define GAME_SERVER_GAMEMODES_ZCATCH_H
 
 #include <game/server/gamecontroller.h>
 
-class CGameController_zCatch : public IGameController
+class CGameController_zCatch: public IGameController
 {
 	int m_OldMode;
 
@@ -15,17 +15,13 @@ public:
 	CGameController_zCatch(class CGameContext *pGameServer);
 	virtual void Tick();
 	virtual void DoWincheck();
-	virtual bool IsZCatch();
-
-	enum
-	{
-		ZCATCH_NOT_CAUGHT = -1,
-	}; 
 
 	virtual void StartRound();
 	virtual void OnCharacterSpawn(class CCharacter *pChr);
 	virtual void OnPlayerInfoChange(class CPlayer *pP);
 	virtual int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int WeaponID);
+	virtual bool OnEntity(int Index, vec2 Pos);
+	virtual bool CanChangeTeam(CPlayer *pPlayer, int JoinTeam);
 	virtual void EndRound();
 };
 
diff --git a/src/game/server/player.h b/src/game/server/player.h
index 6bd39370..3c15212f 100644
--- a/src/game/server/player.h
+++ b/src/game/server/player.h
@@ -97,7 +97,8 @@ public:
 		int m_Max;
 	} m_Latency;
 	
-		//zCatch:
+	//zCatch:
+	enum { ZCATCH_NOT_CAUGHT = -1 };
 	int m_CaughtBy;
 	int m_SpecExplicit;
 	int m_Deaths;