about summary refs log tree commit diff
path: root/src/game/server
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2010-05-29 07:25:38 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2010-05-29 07:25:38 +0000
commit72c06a258940696093f255fb1061beb58e1cdd0b (patch)
tree36b9a7712eec2d4f07837eab9c38ef1c5af85319 /src/game/server
parente56feb597bc743677633432f77513b02907fd169 (diff)
downloadzcatch-72c06a258940696093f255fb1061beb58e1cdd0b.tar.gz
zcatch-72c06a258940696093f255fb1061beb58e1cdd0b.zip
copied refactor to trunk
Diffstat (limited to 'src/game/server')
-rw-r--r--src/game/server/entities/character.cpp964
-rw-r--r--src/game/server/entities/character.h133
-rw-r--r--src/game/server/entities/character.hpp134
-rw-r--r--src/game/server/entities/laser.cpp130
-rw-r--r--src/game/server/entities/laser.h28
-rw-r--r--src/game/server/entities/laser.hpp31
-rw-r--r--src/game/server/entities/pickup.cpp180
-rw-r--r--src/game/server/entities/pickup.h23
-rw-r--r--src/game/server/entities/pickup.hpp24
-rw-r--r--src/game/server/entities/projectile.cpp145
-rw-r--r--src/game/server/entities/projectile.h30
-rw-r--r--src/game/server/entities/projectile.hpp37
-rw-r--r--src/game/server/entity.cpp49
-rw-r--r--src/game/server/entity.h (renamed from src/game/server/entity.hpp)92
-rw-r--r--src/game/server/eventhandler.cpp54
-rw-r--r--src/game/server/eventhandler.h30
-rw-r--r--src/game/server/eventhandler.hpp25
-rw-r--r--src/game/server/gamecontext.cpp1036
-rw-r--r--src/game/server/gamecontext.h168
-rw-r--r--src/game/server/gamecontext.hpp105
-rw-r--r--src/game/server/gamecontroller.cpp641
-rw-r--r--src/game/server/gamecontroller.h145
-rw-r--r--src/game/server/gamecontroller.hpp136
-rw-r--r--src/game/server/gamemodes/ctf.cpp252
-rw-r--r--src/game/server/gamemodes/ctf.h38
-rw-r--r--src/game/server/gamemodes/ctf.hpp36
-rw-r--r--src/game/server/gamemodes/dm.cpp15
-rw-r--r--src/game/server/gamemodes/dm.h11
-rw-r--r--src/game/server/gamemodes/dm.hpp10
-rw-r--r--src/game/server/gamemodes/mod.cpp19
-rw-r--r--src/game/server/gamemodes/mod.h14
-rw-r--r--src/game/server/gamemodes/mod.hpp13
-rw-r--r--src/game/server/gamemodes/tdm.cpp33
-rw-r--r--src/game/server/gamemodes/tdm.h13
-rw-r--r--src/game/server/gamemodes/tdm.hpp12
-rw-r--r--src/game/server/gameworld.cpp233
-rw-r--r--src/game/server/gameworld.h (renamed from src/game/server/gameworld.hpp)68
-rw-r--r--src/game/server/hooks.cpp599
-rw-r--r--src/game/server/player.cpp220
-rw-r--r--src/game/server/player.h89
-rw-r--r--src/game/server/player.hpp75
41 files changed, 3124 insertions, 2966 deletions
diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp
index 8ba91a80..839088dd 100644
--- a/src/game/server/entities/character.cpp
+++ b/src/game/server/entities/character.cpp
@@ -1,838 +1,820 @@
 #include <new>
-#include <engine/e_server_interface.h>
-#include <engine/e_config.h>
-#include <game/server/gamecontext.hpp>
-#include <game/mapitems.hpp>
+#include <engine/shared/config.h>
+#include <game/server/gamecontext.h>
+#include <game/mapitems.h>
 
-#include "character.hpp"
-#include "laser.hpp"
-#include "projectile.hpp"
+#include "character.h"
+#include "laser.h"
+#include "projectile.h"
 
-struct INPUT_COUNT
+//input count
+struct CInputCount
 {
-	int presses;
-	int releases;
+	int m_Presses;
+	int m_Releases;
 };
 
-static INPUT_COUNT count_input(int prev, int cur)
+CInputCount CountInput(int Prev, int Cur)
 {
-	INPUT_COUNT c = {0,0};
-	prev &= INPUT_STATE_MASK;
-	cur &= INPUT_STATE_MASK;
-	int i = prev;
-	while(i != cur)
+	CInputCount c = {0, 0};
+	Prev &= INPUT_STATE_MASK;
+	Cur &= INPUT_STATE_MASK;
+	int i = Prev;
+	
+	while(i != Cur)
 	{
 		i = (i+1)&INPUT_STATE_MASK;
 		if(i&1)
-			c.presses++;
+			c.m_Presses++;
 		else
-			c.releases++;
+			c.m_Releases++;
 	}
 
 	return c;
 }
 
 
-MACRO_ALLOC_POOL_ID_IMPL(CHARACTER, MAX_CLIENTS)
+MACRO_ALLOC_POOL_ID_IMPL(CCharacter, MAX_CLIENTS)
 
-// player
-CHARACTER::CHARACTER()
-: ENTITY(NETOBJTYPE_CHARACTER)
+// Character, "physical" player's part
+CCharacter::CCharacter(CGameWorld *pWorld)
+: CEntity(pWorld, NETOBJTYPE_CHARACTER)
 {
-	proximity_radius = phys_size;
+	m_ProximityRadius = g_CharPhysSize;
+	m_Health = 0;
+	m_Armor = 0;
 }
 
-void CHARACTER::reset()
+void CCharacter::Reset()
 {
-	destroy();
+	Destroy();
 }
 
-bool CHARACTER::spawn(PLAYER *player, vec2 pos, int team)
+bool CCharacter::Spawn(CPlayer *pPlayer, vec2 Pos)
 {
-	player_state = PLAYERSTATE_UNKNOWN;
-	emote_stop = -1;
-	last_action = -1;
-	active_weapon = WEAPON_GUN;
-	last_weapon = WEAPON_HAMMER;
-	queued_weapon = -1;
+	m_PlayerState = PLAYERSTATE_UNKNOWN;
+	m_EmoteStop = -1;
+	m_LastAction = -1;
+	m_ActiveWeapon = WEAPON_GUN;
+	m_LastWeapon = WEAPON_HAMMER;
+	m_QueuedWeapon = -1;
 	
-	//clear();
-	this->player = player;
-	this->pos = pos;
-	this->team = team;
+	m_pPlayer = pPlayer;
+	m_Pos = Pos;
 	
-	core.reset();
-	core.world = &game.world.core;
-	core.pos = pos;
-	game.world.core.characters[player->client_id] = &core;
-
-	reckoning_tick = 0;
-	mem_zero(&sendcore, sizeof(sendcore));
-	mem_zero(&reckoningcore, sizeof(reckoningcore));
+	m_Core.Reset();
+	m_Core.Init(&GameServer()->m_World.m_Core, GameServer()->Collision());
+	m_Core.m_Pos = m_Pos;
+	GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = &m_Core;
+
+	m_ReckoningTick = 0;
+	mem_zero(&m_SendCore, sizeof(m_SendCore));
+	mem_zero(&m_ReckoningCore, sizeof(m_ReckoningCore));
 	
-	game.world.insert_entity(this);
-	alive = true;
-	player->force_balanced = false;
+	GameServer()->m_World.InsertEntity(this);
+	m_Alive = true;
 
-	game.controller->on_character_spawn(this);
+	GameServer()->m_pController->OnCharacterSpawn(this);
 
 	return true;
 }
 
-void CHARACTER::destroy()
+void CCharacter::Destroy()
 {
-	game.world.core.characters[player->client_id] = 0;
-	alive = false;
+	GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = 0;
+	m_Alive = false;
 }
 
-void CHARACTER::set_weapon(int w)
+void CCharacter::SetWeapon(int W)
 {
-	if(w == active_weapon)
+	if(W == m_ActiveWeapon)
 		return;
 		
-	last_weapon = active_weapon;
-	queued_weapon = -1;
-	active_weapon = w;
-	if(active_weapon < 0 || active_weapon >= NUM_WEAPONS)
-		active_weapon = 0;
+	m_LastWeapon = m_ActiveWeapon;
+	m_QueuedWeapon = -1;
+	m_ActiveWeapon = W;
+	GameServer()->CreateSound(m_Pos, SOUND_WEAPON_SWITCH);
 	
-	game.create_sound(pos, SOUND_WEAPON_SWITCH);
+	if(m_ActiveWeapon < 0 || m_ActiveWeapon >= NUM_WEAPONS)
+		m_ActiveWeapon = 0;
 }
 
-bool CHARACTER::is_grounded()
+bool CCharacter::IsGrounded()
 {
-	if(col_check_point((int)(pos.x+phys_size/2), (int)(pos.y+phys_size/2+5)))
+	if(GameServer()->Collision()->CheckPoint(m_Pos.x+g_CharPhysSize/2, m_Pos.y+g_CharPhysSize/2+5))
 		return true;
-	if(col_check_point((int)(pos.x-phys_size/2), (int)(pos.y+phys_size/2+5)))
+	if(GameServer()->Collision()->CheckPoint(m_Pos.x-g_CharPhysSize/2, m_Pos.y+g_CharPhysSize/2+5))
 		return true;
 	return false;
 }
 
 
-int CHARACTER::handle_ninja()
+void CCharacter::HandleNinja()
 {
-	if(active_weapon != WEAPON_NINJA)
-		return 0;
+	if(m_ActiveWeapon != WEAPON_NINJA)
+		return;
 	
-	vec2 direction = normalize(vec2(latest_input.target_x, latest_input.target_y));
+	vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY));
 
-	if ((server_tick() - ninja.activationtick) > (data->weapons.ninja.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
-		weapons[WEAPON_NINJA].got = false;
-		active_weapon = last_weapon;
-		if(active_weapon == WEAPON_NINJA)
-			active_weapon = WEAPON_GUN;
-		set_weapon(active_weapon);
-		return 0;
+		m_aWeapons[WEAPON_NINJA].m_Got = false;
+		m_ActiveWeapon = m_LastWeapon;
+		if(m_ActiveWeapon == WEAPON_NINJA)
+			m_ActiveWeapon = WEAPON_GUN;
+			
+		SetWeapon(m_ActiveWeapon);
+		return;
 	}
 	
-	// force ninja weapon
-	set_weapon(WEAPON_NINJA);
+	// force ninja Weapon
+	SetWeapon(WEAPON_NINJA);
 
-	ninja.currentmovetime--;
+	m_Ninja.m_CurrentMoveTime--;
 
-	if (ninja.currentmovetime == 0)
+	if (m_Ninja.m_CurrentMoveTime == 0)
 	{
-		// reset player velocity
-		core.vel *= 0.2f;
-		//return MODIFIER_RETURNFLAGS_OVERRIDEWEAPON;
+		// reset velocity
+		m_Core.m_Vel *= 0.2f;
 	}
 
-	if (ninja.currentmovetime > 0)
+	if (m_Ninja.m_CurrentMoveTime > 0)
 	{
-		// Set player velocity
-		core.vel = ninja.activationdir * data->weapons.ninja.velocity;
-		vec2 oldpos = pos;
-		move_box(&core.pos, &core.vel, vec2(phys_size, phys_size), 0.0f);
+		// Set velocity
+		m_Core.m_Vel = m_Ninja.m_ActivationDir * g_pData->m_Weapons.m_Ninja.m_Velocity;
+		vec2 OldPos = m_Pos;
+		GameServer()->Collision()->MoveBox(&m_Core.m_Pos, &m_Core.m_Vel, vec2(g_CharPhysSize, g_CharPhysSize), 0.f);
+		
 		// reset velocity so the client doesn't predict stuff
-		core.vel = vec2(0.0f,0.0f);
-		if ((ninja.currentmovetime % 2) == 0)
-		{
-			//create_smoke(pos);
-		}
+		m_Core.m_Vel = vec2(0.f, 0.f);
 
-		// check if we hit anything along the way
+		// check if we Hit anything along the way
 		{
-			CHARACTER *ents[64];
-			vec2 dir = pos - oldpos;
-			float radius = phys_size * 2.0f; //length(dir * 0.5f);
-			vec2 center = oldpos + dir * 0.5f;
-			int num = game.world.find_entities(center, radius, (ENTITY**)ents, 64, NETOBJTYPE_CHARACTER);
+			CCharacter *aEnts[64];
+			vec2 Dir = m_Pos - OldPos;
+			float Radius = g_CharPhysSize * 2.0f;
+			vec2 Center = OldPos + Dir * 0.5f;
+			int Num = GameServer()->m_World.FindEntities(Center, Radius, (CEntity**)aEnts, 64, NETOBJTYPE_CHARACTER);
 
-			for (int i = 0; i < num; i++)
+			for (int i = 0; i < Num; ++i)
 			{
-				// Check if entity is a player
-				if (ents[i] == this)
+				if (aEnts[i] == this)
 					continue;
-				// make sure we haven't hit this object before
-				bool balreadyhit = false;
-				for (int j = 0; j < numobjectshit; j++)
+					
+				// make sure we haven't Hit this object before
+				bool bAlreadyHit = false;
+				for (int j = 0; j < m_NumObjectsHit; j++)
 				{
-					if (hitobjects[j] == ents[i])
-						balreadyhit = true;
+					if (m_apHitObjects[j] == aEnts[i])
+						bAlreadyHit = true;
 				}
-				if (balreadyhit)
+				if (bAlreadyHit)
 					continue;
 
 				// check so we are sufficiently close
-				if (distance(ents[i]->pos, pos) > (phys_size * 2.0f))
+				if (distance(aEnts[i]->m_Pos, m_Pos) > (g_CharPhysSize * 2.0f))
 					continue;
 
-				// hit a player, give him damage and stuffs...
-				game.create_sound(ents[i]->pos, SOUND_NINJA_HIT);
+				// Hit a player, give him damage and stuffs...
+				GameServer()->CreateSound(aEnts[i]->m_Pos, SOUND_NINJA_HIT);
 				// set his velocity to fast upward (for now)
-				if(numobjectshit < 10)
-					hitobjects[numobjectshit++] = ents[i];
+				if(m_NumObjectsHit < 10)
+					m_apHitObjects[m_NumObjectsHit++] = aEnts[i];
 					
-				ents[i]->take_damage(vec2(0,10.0f), data->weapons.ninja.base->damage, player->client_id,WEAPON_NINJA);
+				aEnts[i]->TakeDamage(vec2(0, 10.0f), g_pData->m_Weapons.m_Ninja.m_pBase->m_Damage, m_pPlayer->GetCID(), WEAPON_NINJA);
 			}
 		}
-		return 0;
+		
+		return;
 	}
 
-	return 0;
+	return;
 }
 
 
-void CHARACTER::do_weaponswitch()
+void CCharacter::DoWeaponSwitch()
 {
-	if(reload_timer != 0) // make sure we have reloaded
-		return;
-		
-	if(queued_weapon == -1) // check for a queued weapon
+	// make sure we can switch
+	if(m_ReloadTimer != 0 || m_QueuedWeapon == -1 || m_aWeapons[WEAPON_NINJA].m_Got)
 		return;
 
-	if(weapons[WEAPON_NINJA].got) // if we have ninja, no weapon selection is possible
-		return;
-
-	// switch weapon
-	set_weapon(queued_weapon);
+	// switch Weapon
+	SetWeapon(m_QueuedWeapon);
 }
 
-void CHARACTER::handle_weaponswitch()
+void CCharacter::HandleWeaponSwitch()
 {
-	int wanted_weapon = active_weapon;
-	if(queued_weapon != -1)
-		wanted_weapon = queued_weapon;
+	int WantedWeapon = m_ActiveWeapon;
+	if(m_QueuedWeapon != -1)
+		WantedWeapon = m_QueuedWeapon;
 	
-	// select weapon
-	int next = count_input(latest_previnput.next_weapon, latest_input.next_weapon).presses;
-	int prev = count_input(latest_previnput.prev_weapon, latest_input.prev_weapon).presses;
+	// select Weapon
+	int Next = CountInput(m_LatestPrevInput.m_NextWeapon, m_LatestInput.m_NextWeapon).m_Presses;
+	int Prev = CountInput(m_LatestPrevInput.m_PrevWeapon, m_LatestInput.m_PrevWeapon).m_Presses;
 
-	if(next < 128) // make sure we only try sane stuff
+	if(Next < 128) // make sure we only try sane stuff
 	{
-		while(next) // next weapon selection
+		while(Next) // Next Weapon selection
 		{
-			wanted_weapon = (wanted_weapon+1)%NUM_WEAPONS;
-			if(weapons[wanted_weapon].got)
-				next--;
+			WantedWeapon = (WantedWeapon+1)%NUM_WEAPONS;
+			if(m_aWeapons[WantedWeapon].m_Got)
+				Next--;
 		}
 	}
 
-	if(prev < 128) // make sure we only try sane stuff
+	if(Prev < 128) // make sure we only try sane stuff
 	{
-		while(prev) // prev weapon selection
+		while(Prev) // Prev Weapon selection
 		{
-			wanted_weapon = (wanted_weapon-1)<0?NUM_WEAPONS-1:wanted_weapon-1;
-			if(weapons[wanted_weapon].got)
-				prev--;
+			WantedWeapon = (WantedWeapon-1)<0?NUM_WEAPONS-1:WantedWeapon-1;
+			if(m_aWeapons[WantedWeapon].m_Got)
+				Prev--;
 		}
 	}
 
-	// direct weapon selection
-	if(latest_input.wanted_weapon)
-		wanted_weapon = input.wanted_weapon-1;
+	// Direct Weapon selection
+	if(m_LatestInput.m_WantedWeapon)
+		WantedWeapon = m_Input.m_WantedWeapon-1;
 
 	// check for insane values
-	if(wanted_weapon >= 0 && wanted_weapon < NUM_WEAPONS && wanted_weapon != active_weapon && weapons[wanted_weapon].got)
-		queued_weapon = wanted_weapon;
+	if(WantedWeapon >= 0 && WantedWeapon < NUM_WEAPONS && WantedWeapon != m_ActiveWeapon && m_aWeapons[WantedWeapon].m_Got)
+		m_QueuedWeapon = WantedWeapon;
 	
-	do_weaponswitch();
+	DoWeaponSwitch();
 }
 
-void CHARACTER::fire_weapon()
+void CCharacter::FireWeapon()
 {
-	if(reload_timer != 0)
+	if(m_ReloadTimer != 0)
 		return;
 		
-	do_weaponswitch();
+	DoWeaponSwitch();
+	vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY));
 	
-	vec2 direction = normalize(vec2(latest_input.target_x, latest_input.target_y));
-	
-	bool fullauto = false;
-	if(active_weapon == WEAPON_GRENADE || active_weapon == WEAPON_SHOTGUN || active_weapon == WEAPON_RIFLE)
-		fullauto = true;
+	bool FullAuto = false;
+	if(m_ActiveWeapon == WEAPON_GRENADE || m_ActiveWeapon == WEAPON_SHOTGUN || m_ActiveWeapon == WEAPON_RIFLE)
+		FullAuto = true;
 
 
 	// check if we gonna fire
-	bool will_fire = false;
-	if(count_input(latest_previnput.fire, latest_input.fire).presses) will_fire = true;
-	if(fullauto && (latest_input.fire&1) && weapons[active_weapon].ammo) will_fire = true;
-	if(!will_fire)
+	bool WillFire = false;
+	if(CountInput(m_LatestPrevInput.m_Fire, m_LatestInput.m_Fire).m_Presses)
+		WillFire = true;
+		
+	if(FullAuto && (m_LatestInput.m_Fire&1) && m_aWeapons[m_ActiveWeapon].m_Ammo)
+		WillFire = true;
+		
+	if(!WillFire)
 		return;
 		
 	// check for ammo
-	if(!weapons[active_weapon].ammo)
+	if(!m_aWeapons[m_ActiveWeapon].m_Ammo)
 	{
 		// 125ms is a magical limit of how fast a human can click
-		reload_timer = 125 * server_tickspeed() / 1000;;
-		game.create_sound(pos, SOUND_WEAPON_NOAMMO);
+		m_ReloadTimer = 125 * Server()->TickSpeed() / 1000;
+		GameServer()->CreateSound(m_Pos, SOUND_WEAPON_NOAMMO);
 		return;
 	}
 	
-	vec2 projectile_startpos = pos+direction*phys_size*0.75f;
+	vec2 ProjStartPos = m_Pos+Direction*g_CharPhysSize*0.75f;
 	
-	switch(active_weapon)
+	switch(m_ActiveWeapon)
 	{
 		case WEAPON_HAMMER:
 		{
-			// reset objects hit
-			numobjectshit = 0;
-			game.create_sound(pos, SOUND_HAMMER_FIRE);
+			// reset objects Hit
+			m_NumObjectsHit = 0;
+			GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE);
 			
-			CHARACTER *ents[64];
-			int hits = 0;
-			int num = game.world.find_entities(pos+direction*phys_size*0.75f, phys_size*0.5f, (ENTITY**)ents, 64, NETOBJTYPE_CHARACTER);
+			CCharacter *aEnts[64];
+			int Hits = 0;
+			int Num = GameServer()->m_World.FindEntities(ProjStartPos, g_CharPhysSize*0.5f, (CEntity**)aEnts, 
+			64, NETOBJTYPE_CHARACTER);
 
-			for (int i = 0; i < num; i++)
+			for (int i = 0; i < Num; ++i)
 			{
-				CHARACTER *target = ents[i];
-				if (target == this)
+				CCharacter *Target = aEnts[i];
+				
+				//for race mod or any other mod, which needs hammer hits through the wall remove second condition
+				if ((Target == this) || GameServer()->Collision()->IntersectLine(ProjStartPos, Target->m_Pos, NULL, NULL))
 					continue;
-					
-				// hit a player, give him damage and stuffs...
-				vec2 fdir = normalize(ents[i]->pos - pos);
 
 				// set his velocity to fast upward (for now)
-				game.create_hammerhit(pos);
-				ents[i]->take_damage(vec2(0,-1.0f), data->weapons.hammer.base->damage, player->client_id, active_weapon);
-				vec2 dir;
-				if (length(target->pos - pos) > 0.0f)
-					dir = normalize(target->pos - pos);
+				GameServer()->CreateHammerHit(m_Pos);
+				aEnts[i]->TakeDamage(vec2(0.f, -1.f), g_pData->m_Weapons.m_Hammer.m_pBase->m_Damage, m_pPlayer->GetCID(), m_ActiveWeapon);
+				
+				vec2 Dir;
+				if (length(Target->m_Pos - m_Pos) > 0.0f)
+					Dir = normalize(Target->m_Pos - m_Pos);
 				else
-					dir = vec2(0,-1);
+					Dir = vec2(0.f, -1.f);
 					
-				target->core.vel += normalize(dir + vec2(0,-1.1f)) * 10.0f;
-				hits++;
+				Target->m_Core.m_Vel += normalize(Dir + vec2(0.f, -1.1f)) * 10.0f;
+				Hits++;
 			}
 			
-			// if we hit anything, we have to wait for the reload
-			if(hits)
-				reload_timer = server_tickspeed()/3;
+			// if we Hit anything, we have to wait for the reload
+			if(Hits)
+				m_ReloadTimer = Server()->TickSpeed()/3;
 			
 		} break;
 
 		case WEAPON_GUN:
 		{
-			PROJECTILE *proj = new PROJECTILE(WEAPON_GUN,
-				player->client_id,
-				projectile_startpos,
-				direction,
-				(int)(server_tickspeed()*tuning.gun_lifetime),
+			CProjectile *Proj = new CProjectile(GameWorld(), WEAPON_GUN,
+				m_pPlayer->GetCID(),
+				ProjStartPos,
+				Direction,
+				(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GunLifetime),
 				1, 0, 0, -1, WEAPON_GUN);
 				
-			// pack the projectile and send it to the client directly
-			NETOBJ_PROJECTILE p;
-			proj->fill_info(&p);
+			// pack the Projectile and send it to the client Directly
+			CNetObj_Projectile p;
+			Proj->FillInfo(&p);
 			
-			msg_pack_start(NETMSGTYPE_SV_EXTRAPROJECTILE, 0);
-			msg_pack_int(1);
-			for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
-				msg_pack_int(((int *)&p)[i]);
-			msg_pack_end();
-			server_send_msg(player->client_id);
-							
-			game.create_sound(pos, SOUND_GUN_FIRE);
+			CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
+			Msg.AddInt(1);
+			for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
+				Msg.AddInt(((int *)&p)[i]);
+				
+			Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID());
+	
+			GameServer()->CreateSound(m_Pos, SOUND_GUN_FIRE);
 		} break;
 		
 		case WEAPON_SHOTGUN:
 		{
-			int shotspread = 2;
+			int ShotSpread = 2;
 
-			msg_pack_start(NETMSGTYPE_SV_EXTRAPROJECTILE, 0);
-			msg_pack_int(shotspread*2+1);
+			CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
+			Msg.AddInt(ShotSpread*2+1);
 			
-			for(int i = -shotspread; i <= shotspread; i++)
+			for(int i = -ShotSpread; i <= ShotSpread; ++i)
 			{
-				float spreading[] = {-0.185f, -0.070f, 0, 0.070f, 0.185f};
-				float a = get_angle(direction);
-				a += spreading[i+2];
-				float v = 1-(abs(i)/(float)shotspread);
-				float speed = mix((float)tuning.shotgun_speeddiff, 1.0f, v);
-				PROJECTILE *proj = new PROJECTILE(WEAPON_SHOTGUN,
-					player->client_id,
-					projectile_startpos,
-					vec2(cosf(a), sinf(a))*speed,
-					(int)(server_tickspeed()*tuning.shotgun_lifetime),
+				float Spreading[] = {-0.185f, -0.070f, 0, 0.070f, 0.185f};
+				float a = GetAngle(Direction);
+				a += Spreading[i+2];
+				float v = 1-(absolute(i)/(float)ShotSpread);
+				float Speed = mix((float)GameServer()->Tuning()->m_ShotgunSpeeddiff, 1.0f, v);
+				CProjectile *Proj = new CProjectile(GameWorld(), WEAPON_SHOTGUN,
+					m_pPlayer->GetCID(),
+					ProjStartPos,
+					vec2(cosf(a), sinf(a))*Speed,
+					(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_ShotgunLifetime),
 					1, 0, 0, -1, WEAPON_SHOTGUN);
 					
-				// pack the projectile and send it to the client directly
-				NETOBJ_PROJECTILE p;
-				proj->fill_info(&p);
+				// pack the Projectile and send it to the client Directly
+				CNetObj_Projectile p;
+				Proj->FillInfo(&p);
 				
-				for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
-					msg_pack_int(((int *)&p)[i]);
+				for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
+					Msg.AddInt(((int *)&p)[i]);
 			}
 
-			msg_pack_end();
-			server_send_msg(player->client_id);					
+			Server()->SendMsg(&Msg, 0,m_pPlayer->GetCID());					
 			
-			game.create_sound(pos, SOUND_SHOTGUN_FIRE);
+			GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE);
 		} break;
 
 		case WEAPON_GRENADE:
 		{
-			PROJECTILE *proj = new PROJECTILE(WEAPON_GRENADE,
-				player->client_id,
-				projectile_startpos,
-				direction,
-				(int)(server_tickspeed()*tuning.grenade_lifetime),
-				1, PROJECTILE::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);
-
-			// pack the projectile and send it to the client directly
-			NETOBJ_PROJECTILE p;
-			proj->fill_info(&p);
+			CProjectile *Proj = new CProjectile(GameWorld(), WEAPON_GRENADE,
+				m_pPlayer->GetCID(),
+				ProjStartPos,
+				Direction,
+				(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GrenadeLifetime),
+				1, true, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);
+
+			// pack the Projectile and send it to the client Directly
+			CNetObj_Projectile p;
+			Proj->FillInfo(&p);
+			
+			CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
+			Msg.AddInt(1);
+			for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
+				Msg.AddInt(((int *)&p)[i]);
+			Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID());
 			
-			msg_pack_start(NETMSGTYPE_SV_EXTRAPROJECTILE, 0);
-			msg_pack_int(1);
-			for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
-				msg_pack_int(((int *)&p)[i]);
-			msg_pack_end();
-			server_send_msg(player->client_id);
-
-			game.create_sound(pos, SOUND_GRENADE_FIRE);
+			GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE);
 		} break;
 		
 		case WEAPON_RIFLE:
 		{
-			new LASER(pos, direction, tuning.laser_reach, player->client_id);
-			game.create_sound(pos, SOUND_RIFLE_FIRE);
+			new CLaser(GameWorld(), m_Pos, Direction, GameServer()->Tuning()->m_LaserReach, m_pPlayer->GetCID());
+			GameServer()->CreateSound(m_Pos, SOUND_RIFLE_FIRE);
 		} break;
 		
 		case WEAPON_NINJA:
 		{
-			attack_tick = server_tick();
-			ninja.activationdir = direction;
-			ninja.currentmovetime = data->weapons.ninja.movetime * server_tickspeed() / 1000;
-
-			//reload_timer = data->weapons.ninja.base->firedelay * server_tickspeed() / 1000 + server_tick();
+			// reset Hit objects
+			m_NumObjectsHit = 0;
 			
-			// reset hit objects
-			numobjectshit = 0;
+			m_AttackTick = Server()->Tick();
+			m_Ninja.m_ActivationDir = Direction;
+			m_Ninja.m_CurrentMoveTime = g_pData->m_Weapons.m_Ninja.m_Movetime * Server()->TickSpeed() / 1000;
 
-			game.create_sound(pos, SOUND_NINJA_FIRE);
-			
+			GameServer()->CreateSound(m_Pos, SOUND_NINJA_FIRE);
 		} break;
 		
 	}
-
-	if(weapons[active_weapon].ammo > 0) // -1 == unlimited
-		weapons[active_weapon].ammo--;
-	attack_tick = server_tick();
-	if(!reload_timer)
-		reload_timer = data->weapons.id[active_weapon].firedelay * server_tickspeed() / 1000;
+	
+	m_AttackTick = Server()->Tick();
+	
+	if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0) // -1 == unlimited
+		m_aWeapons[m_ActiveWeapon].m_Ammo--;
+	
+	if(!m_ReloadTimer)
+		m_ReloadTimer = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Firedelay * Server()->TickSpeed() / 1000;
 }
 
-int CHARACTER::handle_weapons()
+void CCharacter::HandleWeapons()
 {
-	vec2 direction = normalize(vec2(latest_input.target_x, latest_input.target_y));
-
-	/*
-	if(config.dbg_stress)
-	{
-		for(int i = 0; i < NUM_WEAPONS; i++)
-		{
-			weapons[i].got = true;
-			weapons[i].ammo = 10;
-		}
-
-		if(reload_timer) // twice as fast reload
-			reload_timer--;
-	} */
-
-	//if(active_weapon == WEAPON_NINJA)
-	handle_ninja();
-
+	//ninja
+	HandleNinja();
+	
+	vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY));
 
 	// check reload timer
-	if(reload_timer)
+	if(m_ReloadTimer)
 	{
-		reload_timer--;
-		return 0;
+		m_ReloadTimer--;
+		return;
 	}
-	
-	/*
-	if (active_weapon == WEAPON_NINJA)
-	{
-		// don't update other weapons while ninja is active
-		return handle_ninja();
-	}*/
 
-	// fire weapon, if wanted
-	fire_weapon();
+	// fire Weapon, if wanted
+	FireWeapon();
 
 	// ammo regen
-	int ammoregentime = data->weapons.id[active_weapon].ammoregentime;
-	if(ammoregentime)
+	int AmmoRegenTime = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Ammoregentime;
+	if(AmmoRegenTime)
 	{
 		// If equipped and not active, regen ammo?
-		if (reload_timer <= 0)
+		if (m_ReloadTimer <= 0)
 		{
-			if (weapons[active_weapon].ammoregenstart < 0)
-				weapons[active_weapon].ammoregenstart = server_tick();
+			if (m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart < 0)
+				m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart = Server()->Tick();
 
-			if ((server_tick() - weapons[active_weapon].ammoregenstart) >= ammoregentime * server_tickspeed() / 1000)
+			if ((Server()->Tick() - m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart) >= AmmoRegenTime * Server()->TickSpeed() / 1000)
 			{
 				// Add some ammo
-				weapons[active_weapon].ammo = min(weapons[active_weapon].ammo + 1, 10);
-				weapons[active_weapon].ammoregenstart = -1;
+				m_aWeapons[m_ActiveWeapon].m_Ammo = min(m_aWeapons[m_ActiveWeapon].m_Ammo + 1, 10);
+				m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart = -1;
 			}
 		}
 		else
 		{
-			weapons[active_weapon].ammoregenstart = -1;
+			m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart = -1;
 		}
 	}
 	
-	return 0;
+	return;
+}
+
+bool CCharacter::GiveWeapon(int Weapon, int Ammo)
+{
+	if(m_aWeapons[Weapon].m_Ammo < g_pData->m_Weapons.m_aId[Weapon].m_Maxammo || !m_aWeapons[Weapon].m_Got)
+	{	
+		m_aWeapons[Weapon].m_Got = true;
+		m_aWeapons[Weapon].m_Ammo = min(g_pData->m_Weapons.m_aId[Weapon].m_Maxammo, Ammo);
+		return true;
+	}
+	return false;
+}
+
+void CCharacter::GiveNinja()
+{
+	m_Ninja.m_ActivationTick = Server()->Tick();
+	m_aWeapons[WEAPON_NINJA].m_Got = true;
+	m_aWeapons[WEAPON_NINJA].m_Ammo = -1;
+	m_LastWeapon = m_ActiveWeapon;
+	m_ActiveWeapon = WEAPON_NINJA;
+	
+	GameServer()->CreateSound(m_Pos, SOUND_PICKUP_NINJA);
 }
 
-void CHARACTER::on_predicted_input(NETOBJ_PLAYER_INPUT *new_input)
+void CCharacter::SetEmote(int Emote, int Tick)
+{
+	m_EmoteType = Emote;
+	m_EmoteStop = Tick;
+}
+
+void CCharacter::OnPredictedInput(CNetObj_PlayerInput *pNewInput)
 {
 	// check for changes
-	if(mem_comp(&input, new_input, sizeof(NETOBJ_PLAYER_INPUT)) != 0)
-		last_action = server_tick();
+	if(mem_comp(&m_Input, pNewInput, sizeof(CNetObj_PlayerInput)) != 0)
+		m_LastAction = Server()->Tick();
 		
 	// copy new input
-	mem_copy(&input, new_input, sizeof(input));
-	num_inputs++;
+	mem_copy(&m_Input, pNewInput, sizeof(m_Input));
+	m_NumInputs++;
 	
 	// or are not allowed to aim in the center
-	if(input.target_x == 0 && input.target_y == 0)
-		input.target_y = -1;	
+	if(m_Input.m_TargetX == 0 && m_Input.m_TargetY == 0)
+		m_Input.m_TargetY = -1;	
 }
 
-void CHARACTER::on_direct_input(NETOBJ_PLAYER_INPUT *new_input)
+void CCharacter::OnDirectInput(CNetObj_PlayerInput *pNewInput)
 {
-	mem_copy(&latest_previnput, &latest_input, sizeof(latest_input));
-	mem_copy(&latest_input, new_input, sizeof(latest_input));
+	mem_copy(&m_LatestPrevInput, &m_LatestInput, sizeof(m_LatestInput));
+	mem_copy(&m_LatestInput, pNewInput, sizeof(m_LatestInput));
 	
-	if(num_inputs > 2 && team != -1)
+	if(m_NumInputs > 2 && m_pPlayer->GetTeam() != -1)
 	{
-		handle_weaponswitch();
-		fire_weapon();
+		HandleWeaponSwitch();
+		FireWeapon();
 	}
 	
-	mem_copy(&latest_previnput, &latest_input, sizeof(latest_input));
+	mem_copy(&m_LatestPrevInput, &m_LatestInput, sizeof(m_LatestInput));
 }
 
-void CHARACTER::tick()
+void CCharacter::Tick()
 {
-	if(player->force_balanced)
+	if(m_pPlayer->m_ForceBalanced)
 	{
-		char buf[128];
-		str_format(buf, sizeof(buf), "You were moved to %s due to team balancing", game.controller->get_team_name(team));
-		game.send_broadcast(buf, player->client_id);
+		char Buf[128];
+		str_format(Buf, sizeof(Buf), "You were moved to %s due to team balancing", GameServer()->m_pController->GetTeamName(m_pPlayer->GetTeam()));
+		GameServer()->SendBroadcast(Buf, m_pPlayer->GetCID());
 		
-		player->force_balanced = false;
+		m_pPlayer->m_ForceBalanced = false;
 	}
 
-	//player_core core;
-	//core.pos = pos;
-	//core.jumped = jumped;
-	core.input = input;
-	core.tick(true);
+	m_Core.m_Input = m_Input;
+	m_Core.Tick(true);
 	
-	float phys_size = 28.0f;
 	// handle death-tiles
-	if(col_get((int)(pos.x+phys_size/3), (int)(pos.y-phys_size/3))&COLFLAG_DEATH ||
-			col_get((int)(pos.x+phys_size/3), (int)(pos.y+phys_size/3))&COLFLAG_DEATH ||
-			col_get((int)(pos.x-phys_size/3), (int)(pos.y-phys_size/3))&COLFLAG_DEATH ||
-			col_get((int)(pos.x-phys_size/3), (int)(pos.y+phys_size/3))&COLFLAG_DEATH)
+	if(GameServer()->Collision()->GetCollisionAt(m_Pos.x+g_CharPhysSize/3.f, m_Pos.y-g_CharPhysSize/3.f)&CCollision::COLFLAG_DEATH ||
+		GameServer()->Collision()->GetCollisionAt(m_Pos.x+g_CharPhysSize/3.f, m_Pos.y+g_CharPhysSize/3.f)&CCollision::COLFLAG_DEATH ||
+		GameServer()->Collision()->GetCollisionAt(m_Pos.x-g_CharPhysSize/3.f, m_Pos.y-g_CharPhysSize/3.f)&CCollision::COLFLAG_DEATH ||
+		GameServer()->Collision()->GetCollisionAt(m_Pos.x-g_CharPhysSize/3.f, m_Pos.y+g_CharPhysSize/3.f)&CCollision::COLFLAG_DEATH)
 	{
-		die(player->client_id, WEAPON_WORLD);
+		Die(m_pPlayer->GetCID(), WEAPON_WORLD);
 	}
 
-	// handle weapons
-	handle_weapons();
+	// handle Weapons
+	HandleWeapons();
 
-	player_state = input.player_state;
+	m_PlayerState = m_Input.m_PlayerState;
 
 	// Previnput
-	previnput = input;
+	m_PrevInput = m_Input;
 	return;
 }
 
-void CHARACTER::tick_defered()
+void CCharacter::TickDefered()
 {
 	// advance the dummy
 	{
-		WORLD_CORE tempworld;
-		reckoningcore.world = &tempworld;
-		reckoningcore.tick(false);
-		reckoningcore.move();
-		reckoningcore.quantize();
+		CWorldCore TempWorld;
+		m_ReckoningCore.Init(&TempWorld, GameServer()->Collision());
+		m_ReckoningCore.Tick(false);
+		m_ReckoningCore.Move();
+		m_ReckoningCore.Quantize();
 	}
 	
-	//lastsentcore;
-	/*if(!dead)
-	{*/
-		vec2 start_pos = core.pos;
-		vec2 start_vel = core.vel;
-		bool stuck_before = test_box(core.pos, vec2(28.0f, 28.0f));
-		
-		core.move();
-		bool stuck_after_move = test_box(core.pos, vec2(28.0f, 28.0f));
-		core.quantize();
-		bool stuck_after_quant = test_box(core.pos, vec2(28.0f, 28.0f));
-		pos = core.pos;
-		
-		if(!stuck_before && (stuck_after_move || stuck_after_quant))
-		{
-			dbg_msg("player", "STUCK!!! %d %d %d %f %f %f %f %x %x %x %x", 
-				stuck_before,
-				stuck_after_move,
-				stuck_after_quant,
-				start_pos.x, start_pos.y,
-				start_vel.x, start_vel.y,
-				*((unsigned *)&start_pos.x), *((unsigned *)&start_pos.y),
-				*((unsigned *)&start_vel.x), *((unsigned *)&start_vel.y));
-		}
+	//lastsentcore
+	vec2 StartPos = m_Core.m_Pos;
+	vec2 StartVel = m_Core.m_Vel;
+	bool StuckBefore = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f));
+	
+	m_Core.Move();
+	bool StuckAfterMove = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f));
+	m_Core.Quantize();
+	bool StuckAfterQuant = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f));
+	m_Pos = m_Core.m_Pos;
+	
+	if(!StuckBefore && (StuckAfterMove || StuckAfterQuant))
+	{
+		dbg_msg("char_core", "STUCK!!! %d %d %d %f %f %f %f %x %x %x %x", 
+			StuckBefore,
+			StuckAfterMove,
+			StuckAfterQuant,
+			StartPos.x, StartPos.y,
+			StartVel.x, StartVel.y,
+			*((unsigned *)&StartPos.x), *((unsigned *)&StartPos.y),
+			*((unsigned *)&StartVel.x), *((unsigned *)&StartVel.y));
+	}
 
-		int events = core.triggered_events;
-		int mask = cmask_all_except_one(player->client_id);
-		
-		if(events&COREEVENT_GROUND_JUMP) game.create_sound(pos, SOUND_PLAYER_JUMP, mask);
-		
-		//if(events&COREEVENT_HOOK_LAUNCH) snd_play_random(CHN_WORLD, SOUND_HOOK_LOOP, 1.0f, pos);
-		if(events&COREEVENT_HOOK_ATTACH_PLAYER) game.create_sound(pos, SOUND_HOOK_ATTACH_PLAYER, cmask_all());
-		if(events&COREEVENT_HOOK_ATTACH_GROUND) game.create_sound(pos, SOUND_HOOK_ATTACH_GROUND, mask);
-		if(events&COREEVENT_HOOK_HIT_NOHOOK) game.create_sound(pos, SOUND_HOOK_NOATTACH, mask);
-		//if(events&COREEVENT_HOOK_RETRACT) snd_play_random(CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, pos);
-	//}
-	
-	if(team == -1)
+	int Events = m_Core.m_TriggeredEvents;
+	int Mask = CmaskAllExceptOne(m_pPlayer->GetCID());
+	
+	if(Events&COREEVENT_GROUND_JUMP) GameServer()->CreateSound(m_Pos, SOUND_PLAYER_JUMP, Mask);
+	
+	if(Events&COREEVENT_HOOK_ATTACH_PLAYER) GameServer()->CreateSound(m_Pos, SOUND_HOOK_ATTACH_PLAYER, CmaskAll());
+	if(Events&COREEVENT_HOOK_ATTACH_GROUND) GameServer()->CreateSound(m_Pos, SOUND_HOOK_ATTACH_GROUND, Mask);
+	if(Events&COREEVENT_HOOK_HIT_NOHOOK) GameServer()->CreateSound(m_Pos, SOUND_HOOK_NOATTACH, Mask);
+
+	
+	if(m_pPlayer->GetTeam() == -1)
 	{
-		pos.x = input.target_x;
-		pos.y = input.target_y;
+		m_Pos.x = m_Input.m_TargetX;
+		m_Pos.y = m_Input.m_TargetY;
 	}
 	
-	// update the sendcore if needed
+	// update the m_SendCore if needed
 	{
-		NETOBJ_CHARACTER predicted;
-		NETOBJ_CHARACTER current;
-		mem_zero(&predicted, sizeof(predicted));
-		mem_zero(&current, sizeof(current));
-		reckoningcore.write(&predicted);
-		core.write(&current);
+		CNetObj_Character Predicted;
+		CNetObj_Character Current;
+		mem_zero(&Predicted, sizeof(Predicted));
+		mem_zero(&Current, sizeof(Current));
+		m_ReckoningCore.Write(&Predicted);
+		m_Core.Write(&Current);
 
 		// only allow dead reackoning for a top of 3 seconds
-		if(reckoning_tick+server_tickspeed()*3 < server_tick() || mem_comp(&predicted, &current, sizeof(NETOBJ_CHARACTER)) != 0)
+		if(m_ReckoningTick+Server()->TickSpeed()*3 < Server()->Tick() || mem_comp(&Predicted, &Current, sizeof(CNetObj_Character)) != 0)
 		{
-			reckoning_tick = server_tick();
-			sendcore = core;
-			reckoningcore = core;
+			m_ReckoningTick = Server()->Tick();
+			m_SendCore = m_Core;
+			m_ReckoningCore = m_Core;
 		}
 	}
 }
 
-bool CHARACTER::increase_health(int amount)
+bool CCharacter::IncreaseHealth(int Amount)
 {
-	if(health >= 10)
+	if(m_Health >= 10)
 		return false;
-	health = clamp(health+amount, 0, 10);
+	m_Health = clamp(m_Health+Amount, 0, 10);
 	return true;
 }
 
-bool CHARACTER::increase_armor(int amount)
+bool CCharacter::IncreaseArmor(int Amount)
 {
-	if(armor >= 10)
+	if(m_Armor >= 10)
 		return false;
-	armor = clamp(armor+amount, 0, 10);
+	m_Armor = clamp(m_Armor+Amount, 0, 10);
 	return true;
 }
 
-void CHARACTER::die(int killer, int weapon)
+void CCharacter::Die(int Killer, int Weapon)
 {
-	/*if (dead || team == -1)
-		return;*/
-	int mode_special = game.controller->on_character_death(this, game.players[killer], weapon);
+	int ModeSpecial = GameServer()->m_pController->OnCharacterDeath(this, GameServer()->m_apPlayers[Killer], Weapon);
 
 	dbg_msg("game", "kill killer='%d:%s' victim='%d:%s' weapon=%d special=%d",
-		killer, server_clientname(killer),
-		player->client_id, server_clientname(player->client_id), weapon, mode_special);
+		Killer, Server()->ClientName(Killer),
+		m_pPlayer->GetCID(), Server()->ClientName(m_pPlayer->GetCID()), Weapon, ModeSpecial);
 
 	// send the kill message
-	NETMSG_SV_KILLMSG msg;
-	msg.killer = killer;
-	msg.victim = player->client_id;
-	msg.weapon = weapon;
-	msg.mode_special = mode_special;
-	msg.pack(MSGFLAG_VITAL);
-	server_send_msg(-1);
+	CNetMsg_Sv_KillMsg Msg;
+	Msg.m_Killer = Killer;
+	Msg.m_Victim = m_pPlayer->GetCID();
+	Msg.m_Weapon = Weapon;
+	Msg.m_ModeSpecial = ModeSpecial;
+	Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, -1);
 
 	// a nice sound
-	game.create_sound(pos, SOUND_PLAYER_DIE);
-
-	// set dead state
-	// TODO: do stuff here
-	/*
-	die_pos = pos;
-	dead = true;
-	*/
+	GameServer()->CreateSound(m_Pos, SOUND_PLAYER_DIE);
 	
 	// this is for auto respawn after 3 secs
-	player->die_tick = server_tick();
+	m_pPlayer->m_DieTick = Server()->Tick();
 	
-	alive = false;
-	game.world.remove_entity(this);
-	game.world.core.characters[player->client_id] = 0;
-	game.create_death(pos, player->client_id);
+	m_Alive = false;
+	GameServer()->m_World.RemoveEntity(this);
+	GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = 0;
+	GameServer()->CreateDeath(m_Pos, m_pPlayer->GetCID());
 	
 	// we got to wait 0.5 secs before respawning
-	player->respawn_tick = server_tick()+server_tickspeed()/2;
+	m_pPlayer->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2;
 }
 
-bool CHARACTER::take_damage(vec2 force, int dmg, int from, int weapon)
+bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon)
 {
-	core.vel += force;
+	m_Core.m_Vel += Force;
 	
-	if(game.controller->is_friendly_fire(player->client_id, from) && !config.sv_teamdamage)
+	if(GameServer()->m_pController->IsFriendlyFire(m_pPlayer->GetCID(), From) && !g_Config.m_SvTeamdamage)
 		return false;
 
-	// player only inflicts half damage on self
-	if(from == player->client_id)
-		dmg = max(1, dmg/2);
+	// m_pPlayer only inflicts half damage on self
+	if(From == m_pPlayer->GetCID())
+		Dmg = max(1, Dmg/2);
 
-	damage_taken++;
+	m_DamageTaken++;
 
 	// create healthmod indicator
-	if(server_tick() < damage_taken_tick+25)
+	if(Server()->Tick() < m_DamageTakenTick+25)
 	{
 		// make sure that the damage indicators doesn't group together
-		game.create_damageind(pos, damage_taken*0.25f, dmg);
+		GameServer()->CreateDamageInd(m_Pos, m_DamageTaken*0.25f, Dmg);
 	}
 	else
 	{
-		damage_taken = 0;
-		game.create_damageind(pos, 0, dmg);
+		m_DamageTaken = 0;
+		GameServer()->CreateDamageInd(m_Pos, 0, Dmg);
 	}
 
-	if(dmg)
+	if(Dmg)
 	{
-		if(armor)
+		if(m_Armor)
 		{
-			if(dmg > 1)
+			if(Dmg > 1)
 			{
-				health--;
-				dmg--;
+				m_Health--;
+				Dmg--;
 			}
 			
-			if(dmg > armor)
+			if(Dmg > m_Armor)
 			{
-				dmg -= armor;
-				armor = 0;
+				Dmg -= m_Armor;
+				m_Armor = 0;
 			}
 			else
 			{
-				armor -= dmg;
-				dmg = 0;
+				m_Armor -= Dmg;
+				Dmg = 0;
 			}
 		}
 		
-		health -= dmg;
+		m_Health -= Dmg;
 	}
 
-	damage_taken_tick = server_tick();
+	m_DamageTakenTick = Server()->Tick();
 
-	// do damage hit sound
-	if(from >= 0 && from != player->client_id && game.players[from])
-		game.create_sound(game.players[from]->view_pos, SOUND_HIT, cmask_one(from));
+	// do damage Hit sound
+	if(From >= 0 && From != m_pPlayer->GetCID() && GameServer()->m_apPlayers[From])
+		GameServer()->CreateSound(GameServer()->m_apPlayers[From]->m_ViewPos, SOUND_HIT, CmaskOne(From));
 
 	// check for death
-	if(health <= 0)
+	if(m_Health <= 0)
 	{
-		die(from, weapon);
+		Die(From, Weapon);
 		
 		// set attacker's face to happy (taunt!)
-		if (from >= 0 && from != player->client_id && game.players[from])
+		if (From >= 0 && From != m_pPlayer->GetCID() && GameServer()->m_apPlayers[From])
 		{
-			CHARACTER *chr = game.players[from]->get_character();
-			if (chr)
+			CCharacter *pChr = GameServer()->m_apPlayers[From]->GetCharacter();
+			if (pChr)
 			{
-				chr->emote_type = EMOTE_HAPPY;
-				chr->emote_stop = server_tick() + server_tickspeed();
+				pChr->m_EmoteType = EMOTE_HAPPY;
+				pChr->m_EmoteStop = Server()->Tick() + Server()->TickSpeed();
 			}
 		}
 	
 		return false;
 	}
 
-	if (dmg > 2)
-		game.create_sound(pos, SOUND_PLAYER_PAIN_LONG);
+	if (Dmg > 2)
+		GameServer()->CreateSound(m_Pos, SOUND_PLAYER_PAIN_LONG);
 	else
-		game.create_sound(pos, SOUND_PLAYER_PAIN_SHORT);
+		GameServer()->CreateSound(m_Pos, SOUND_PLAYER_PAIN_SHORT);
 
-	emote_type = EMOTE_PAIN;
-	emote_stop = server_tick() + 500 * server_tickspeed() / 1000;
+	m_EmoteType = EMOTE_PAIN;
+	m_EmoteStop = Server()->Tick() + 500 * Server()->TickSpeed() / 1000;
 
-	// spawn blood?
 	return true;
 }
 
-void CHARACTER::snap(int snapping_client)
+void CCharacter::Snap(int SnappingClient)
 {
-	if(networkclipped(snapping_client))
+	if(NetworkClipped(SnappingClient))
 		return;
 	
-	NETOBJ_CHARACTER *character = (NETOBJ_CHARACTER *)snap_new_item(NETOBJTYPE_CHARACTER, player->client_id, sizeof(NETOBJ_CHARACTER));
+	CNetObj_Character *Character = static_cast<CNetObj_Character *>(Server()->SnapNewItem(NETOBJTYPE_CHARACTER, m_pPlayer->GetCID(), sizeof(CNetObj_Character)));
 	
-	// write down the core
-	if(game.world.paused)
+	// write down the m_Core
+	if(GameServer()->m_World.m_Paused)
 	{
 		// no dead reckoning when paused because the client doesn't know
 		// how far to perform the reckoning
-		character->tick = 0;
-		core.write(character);
+		Character->m_Tick = 0;
+		m_Core.Write(Character);
 	}
 	else
 	{
-		character->tick = reckoning_tick;
-		sendcore.write(character);
+		Character->m_Tick = m_ReckoningTick;
+		m_SendCore.Write(Character);
 	}
 	
 	// set emote
-	if (emote_stop < server_tick())
+	if (m_EmoteStop < Server()->Tick())
 	{
-		emote_type = EMOTE_NORMAL;
-		emote_stop = -1;
+		m_EmoteType = EMOTE_NORMAL;
+		m_EmoteStop = -1;
 	}
 
-	character->emote = emote_type;
+	Character->m_Emote = m_EmoteType;
 
-	character->ammocount = 0;
-	character->health = 0;
-	character->armor = 0;
+	Character->m_AmmoCount = 0;
+	Character->m_Health = 0;
+	Character->m_Armor = 0;
 	
-	character->weapon = active_weapon;
-	character->attacktick = attack_tick;
+	Character->m_Weapon = m_ActiveWeapon;
+	Character->m_AttackTick = m_AttackTick;
 
-	character->direction = input.direction;
+	Character->m_Direction = m_Input.m_Direction;
 
-	if(player->client_id == snapping_client)
+	if(m_pPlayer->GetCID() == SnappingClient)
 	{
-		character->health = health;
-		character->armor = armor;
-		if(weapons[active_weapon].ammo > 0)
-			character->ammocount = weapons[active_weapon].ammo;
+		Character->m_Health = m_Health;
+		Character->m_Armor = m_Armor;
+		if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0)
+			Character->m_AmmoCount = m_aWeapons[m_ActiveWeapon].m_Ammo;
 	}
 
-	if (character->emote == EMOTE_NORMAL)
+	if (Character->m_Emote == EMOTE_NORMAL)
 	{
-		if(250 - ((server_tick() - last_action)%(250)) < 5)
-			character->emote = EMOTE_BLINK;
+		if(250 - ((Server()->Tick() - m_LastAction)%(250)) < 5)
+			Character->m_Emote = EMOTE_BLINK;
 	}
 
-	character->player_state = player_state;
+	Character->m_PlayerState = m_PlayerState;
 }
diff --git a/src/game/server/entities/character.h b/src/game/server/entities/character.h
new file mode 100644
index 00000000..30c6586f
--- /dev/null
+++ b/src/game/server/entities/character.h
@@ -0,0 +1,133 @@
+#ifndef GAME_SERVER_ENTITIES_CHARACTER_H
+#define GAME_SERVER_ENTITIES_CHARACTER_H
+
+#include <game/server/entity.h>
+#include <game/generated/server_data.h>
+#include <game/generated/protocol.h>
+
+#include <game/gamecore.h>
+
+//character's size
+const int g_CharPhysSize = 28;
+
+enum
+{
+	WEAPON_GAME = -3, // team switching etc
+	WEAPON_SELF = -2, // console kill command
+	WEAPON_WORLD = -1, // death tiles etc
+};
+
+class CCharacter : public CEntity
+{
+	MACRO_ALLOC_POOL_ID()
+	
+public:
+	CCharacter(CGameWorld *pWorld);
+	
+	virtual void Reset();
+	virtual void Destroy();
+	virtual void Tick();
+	virtual void TickDefered();
+	virtual void Snap(int SnappingClient);
+		
+	bool IsGrounded();
+	
+	void SetWeapon(int W);
+	void HandleWeaponSwitch();
+	void DoWeaponSwitch();
+	
+	void HandleWeapons();
+	void HandleNinja();
+
+	void OnPredictedInput(CNetObj_PlayerInput *pNewInput);
+	void OnDirectInput(CNetObj_PlayerInput *pNewInput);
+	void FireWeapon();
+
+	void Die(int Killer, int Weapon);
+	bool TakeDamage(vec2 Force, int Dmg, int From, int Weapon);	
+
+	bool Spawn(class CPlayer *pPlayer, vec2 Pos);
+	bool Remove();
+	
+	bool IncreaseHealth(int Amount);
+	bool IncreaseArmor(int Amount);
+	
+	bool GiveWeapon(int Weapon, int Ammo);
+	void GiveNinja();
+	
+	void SetEmote(int Emote, int Tick);
+	
+	const bool IsAlive() { return m_Alive; }
+	class CPlayer *GetPlayer() { return m_pPlayer; }
+	
+private:
+	// player controlling this character
+	class CPlayer *m_pPlayer;
+	
+	bool m_Alive;
+
+	// weapon info
+	CEntity *m_apHitObjects[10];
+	int m_NumObjectsHit;
+	
+	struct WeaponStat
+	{
+		int m_AmmoRegenStart;
+		int m_Ammo;
+		int m_Ammocost;
+		bool m_Got;
+		
+	} m_aWeapons[NUM_WEAPONS];
+	
+	int m_ActiveWeapon;
+	int m_LastWeapon;
+	int m_QueuedWeapon;
+	
+	int m_ReloadTimer;
+	int m_AttackTick;
+	
+	int m_DamageTaken;
+
+	int m_EmoteType;
+	int m_EmoteStop;
+	
+	// last tick that the player took any action ie some input
+	int m_LastAction;
+
+	// these are non-heldback inputs
+	CNetObj_PlayerInput m_LatestPrevInput;
+	CNetObj_PlayerInput m_LatestInput;
+
+	// input	
+	CNetObj_PlayerInput m_PrevInput;
+	CNetObj_PlayerInput m_Input;
+	int m_NumInputs;
+	int m_Jumped;
+	
+	int m_DamageTakenTick;
+
+	int m_Health;
+	int m_Armor;
+
+	// ninja
+	struct
+	{
+		vec2 m_ActivationDir;
+		int m_ActivationTick;
+		int m_CurrentMoveTime;
+		
+	} m_Ninja;
+
+	int m_PlayerState;// if the client is chatting, accessing a menu or so
+
+	// the player core for the physics	
+	CCharacterCore m_Core;
+	
+	// info for dead reckoning
+	int m_ReckoningTick; // tick that we are performing dead reckoning From
+	CCharacterCore m_SendCore; // core that we should send
+	CCharacterCore m_ReckoningCore; // the dead reckoning core
+
+};
+
+#endif
diff --git a/src/game/server/entities/character.hpp b/src/game/server/entities/character.hpp
deleted file mode 100644
index bd2f7afe..00000000
--- a/src/game/server/entities/character.hpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-
-#ifndef GAME_SERVER_ENTITY_CHARACTER_H
-#define GAME_SERVER_ENTITY_CHARACTER_H
-
-#include <game/server/entity.hpp>
-#include <game/generated/gs_data.hpp>
-#include <game/generated/g_protocol.hpp>
-
-#include <game/gamecore.hpp>
-
-enum
-{
-	WEAPON_GAME = -3, // team switching etc
-	WEAPON_SELF = -2, // console kill command
-	WEAPON_WORLD = -1, // death tiles etc
-};
-
-class CHARACTER : public ENTITY
-{
-	MACRO_ALLOC_POOL_ID()
-public:
-	// player controlling this character
-	class PLAYER *player;
-	
-	bool alive;
-
-	// weapon info
-	ENTITY *hitobjects[10];
-	int numobjectshit;
-	struct WEAPONSTAT
-	{
-		int ammoregenstart;
-		int ammo;
-		int ammocost;
-		bool got;
-	} weapons[NUM_WEAPONS];
-	
-	int active_weapon;
-	int last_weapon;
-	int queued_weapon;
-	
-	int reload_timer;
-	int attack_tick;
-	
-	int damage_taken;
-
-	int emote_type;
-	int emote_stop;
-
-	// TODO: clean this up
-	char skin_name[64];
-	int use_custom_color;
-	int color_body;
-	int color_feet;
-	
-	int last_action; // last tick that the player took any action ie some input
-
-	// these are non-heldback inputs
-	NETOBJ_PLAYER_INPUT latest_previnput;
-	NETOBJ_PLAYER_INPUT latest_input;
-
-	// input	
-	NETOBJ_PLAYER_INPUT previnput;
-	NETOBJ_PLAYER_INPUT input;
-	int num_inputs;
-	int jumped;
-	
-	int damage_taken_tick;
-
-	int health;
-	int armor;
-
-	// ninja
-	struct
-	{
-		vec2 activationdir;
-		int activationtick;
-		int currentmovetime;
-	} ninja;
-
-	//
-	//int score;
-	int team;
-	int player_state; // if the client is chatting, accessing a menu or so
-
-	// the player core for the physics	
-	CHARACTER_CORE core;
-	
-	// info for dead reckoning
-	int reckoning_tick; // tick that we are performing dead reckoning from
-	CHARACTER_CORE sendcore; // core that we should send
-	CHARACTER_CORE reckoningcore; // the dead reckoning core
-
-	//
-	CHARACTER();
-	
-	virtual void reset();
-	virtual void destroy();
-		
-	bool is_grounded();
-	
-	void set_weapon(int w);
-	
-	void handle_weaponswitch();
-	void do_weaponswitch();
-	
-	int handle_weapons();
-	int handle_ninja();
-
-	void on_predicted_input(NETOBJ_PLAYER_INPUT *new_input);
-	void on_direct_input(NETOBJ_PLAYER_INPUT *new_input);
-	void fire_weapon();
-
-	void die(int killer, int weapon);
-
-	bool take_damage(vec2 force, int dmg, int from, int weapon);	
-
-	
-	bool spawn(PLAYER *player, vec2 pos, int team);
-	//bool init_tryspawn(int team);
-	bool remove();
-
-	static const int phys_size = 28;
-
-	virtual void tick();
-	virtual void tick_defered();
-	virtual void snap(int snapping_client);
-	
-	bool increase_health(int amount);
-	bool increase_armor(int amount);
-};
-
-#endif
diff --git a/src/game/server/entities/laser.cpp b/src/game/server/entities/laser.cpp
index 2c6fa0ff..6bc26074 100644
--- a/src/game/server/entities/laser.cpp
+++ b/src/game/server/entities/laser.cpp
@@ -1,115 +1,105 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-#include <engine/e_server_interface.h>
-#include <game/generated/g_protocol.hpp>
-#include <game/server/gamecontext.hpp>
-#include "laser.hpp"
+// copyright (c) 2007 magnus auvinen, see licence.txt for more info
+#include <game/generated/protocol.h>
+#include <game/server/gamecontext.h>
+#include "laser.h"
 
-//////////////////////////////////////////////////
-// laser
-//////////////////////////////////////////////////
-LASER::LASER(vec2 pos, vec2 direction, float start_energy, int owner)
-: ENTITY(NETOBJTYPE_LASER)
+CLaser::CLaser(CGameWorld *pGameWorld, vec2 Pos, vec2 Direction, float StartEnergy, int Owner)
+: CEntity(pGameWorld, NETOBJTYPE_LASER)
 {
-	this->pos = pos;
-	this->owner = owner;
-	energy = start_energy;
-	dir = direction;
-	bounces = 0;
-	do_bounce();
-	
-	game.world.insert_entity(this);
+	m_Pos = Pos;
+	m_Owner = Owner;
+	m_Energy = StartEnergy;
+	m_Dir = Direction;
+	m_Bounces = 0;
+	m_EvalTick = 0;
+	GameWorld()->InsertEntity(this);
+	DoBounce();
 }
 
 
-bool LASER::hit_character(vec2 from, vec2 to)
+bool CLaser::HitCharacter(vec2 From, vec2 To)
 {
-	vec2 at;
-	CHARACTER *owner_char = game.get_player_char(owner);
-	CHARACTER *hit = game.world.intersect_character(pos, to, 0.0f, at, owner_char);
-	if(!hit)
+	vec2 At;
+	CCharacter *OwnerChar = GameServer()->GetPlayerChar(m_Owner);
+	CCharacter *Hit = GameServer()->m_World.IntersectCharacter(m_Pos, To, 0.f, At, OwnerChar);
+	if(!Hit)
 		return false;
 
-	this->from = from;
-	pos = at;
-	energy = -1;		
-	hit->take_damage(vec2(0,0), tuning.laser_damage, owner, WEAPON_RIFLE);
+	m_From = From;
+	m_Pos = At;
+	m_Energy = -1;		
+	Hit->TakeDamage(vec2(0.f, 0.f), GameServer()->Tuning()->m_LaserDamage, m_Owner, WEAPON_RIFLE);
 	return true;
 }
 
-void LASER::do_bounce()
+void CLaser::DoBounce()
 {
-	eval_tick = server_tick();
+	m_EvalTick = Server()->Tick();
 	
-	if(energy < 0)
+	if(m_Energy < 0)
 	{
-		//dbg_msg("laser", "%d removed", server_tick());
-		game.world.destroy_entity(this);
+		GameServer()->m_World.DestroyEntity(this);
 		return;
 	}
 	
-	vec2 to = pos + dir*energy;
-	vec2 org_to = to;
+	vec2 To = m_Pos + m_Dir * m_Energy;
+	vec2 OrgTo = To;
 	
-	if(col_intersect_line(pos, to, 0x0, &to))
+	if(GameServer()->Collision()->IntersectLine(m_Pos, To, 0x0, &To))
 	{
-		if(!hit_character(pos, to))
+		if(!HitCharacter(m_Pos, To))
 		{
 			// intersected
-			from = pos;
-			pos = to;
+			m_From = m_Pos;
+			m_Pos = To;
 
-			vec2 temp_pos = pos;
-			vec2 temp_dir = dir*4.0f;
+			vec2 TempPos = m_Pos;
+			vec2 TempDir = m_Dir * 4.0f;
 			
-			move_point(&temp_pos, &temp_dir, 1.0f, 0);
-			pos = temp_pos;
-			dir = normalize(temp_dir);
+			GameServer()->Collision()->MovePoint(&TempPos, &TempDir, 1.0f, 0);
+			m_Pos = TempPos;
+			m_Dir = normalize(TempDir);
 			
-			energy -= distance(from, pos) + tuning.laser_bounce_cost;
-			bounces++;
+			m_Energy -= distance(m_From, m_Pos) + GameServer()->Tuning()->m_LaserBounceCost;
+			m_Bounces++;
 			
-			if(bounces > tuning.laser_bounce_num)
-				energy = -1;
+			if(m_Bounces > GameServer()->Tuning()->m_LaserBounceNum)
+				m_Energy = -1;
 				
-			game.create_sound(pos, SOUND_RIFLE_BOUNCE);
+			GameServer()->CreateSound(m_Pos, SOUND_RIFLE_BOUNCE);
 		}
 	}
 	else
 	{
-		if(!hit_character(pos, to))
+		if(!HitCharacter(m_Pos, To))
 		{
-			from = pos;
-			pos = to;
-			energy = -1;
+			m_From = m_Pos;
+			m_Pos = To;
+			m_Energy = -1;
 		}
 	}
-		
-	//dbg_msg("laser", "%d done %f %f %f %f", server_tick(), from.x, from.y, pos.x, pos.y);
 }
 	
-void LASER::reset()
+void CLaser::Reset()
 {
-	game.world.destroy_entity(this);
+	GameServer()->m_World.DestroyEntity(this);
 }
 
-void LASER::tick()
+void CLaser::Tick()
 {
-	if(server_tick() > eval_tick+(server_tickspeed()*tuning.laser_bounce_delay)/1000.0f)
-	{
-		do_bounce();
-	}
-
+	if(Server()->Tick() > m_EvalTick+(Server()->TickSpeed()*GameServer()->Tuning()->m_LaserBounceDelay)/1000.0f)
+		DoBounce();
 }
 
-void LASER::snap(int snapping_client)
+void CLaser::Snap(int SnappingClient)
 {
-	if(networkclipped(snapping_client))
+	if(NetworkClipped(SnappingClient))
 		return;
 
-	NETOBJ_LASER *obj = (NETOBJ_LASER *)snap_new_item(NETOBJTYPE_LASER, id, sizeof(NETOBJ_LASER));
-	obj->x = (int)pos.x;
-	obj->y = (int)pos.y;
-	obj->from_x = (int)from.x;
-	obj->from_y = (int)from.y;
-	obj->start_tick = eval_tick;
+	CNetObj_Laser *pObj = static_cast<CNetObj_Laser *>(Server()->SnapNewItem(NETOBJTYPE_LASER, m_Id, sizeof(CNetObj_Laser)));
+	pObj->m_X = (int)m_Pos.x;
+	pObj->m_Y = (int)m_Pos.y;
+	pObj->m_FromX = (int)m_From.x;
+	pObj->m_FromY = (int)m_From.y;
+	pObj->m_StartTick = m_EvalTick;
 }
diff --git a/src/game/server/entities/laser.h b/src/game/server/entities/laser.h
new file mode 100644
index 00000000..040cfb4c
--- /dev/null
+++ b/src/game/server/entities/laser.h
@@ -0,0 +1,28 @@
+#ifndef GAME_SERVER_ENTITIES_LASER_H
+#define GAME_SERVER_ENTITIES_LASER_H
+
+#include <game/server/entity.h>
+
+class CLaser : public CEntity
+{
+public:
+	CLaser(CGameWorld *pGameWorld, vec2 Pos, vec2 Direction, float StartEnergy, int Owner);
+	
+	virtual void Reset();
+	virtual void Tick();
+	virtual void Snap(int SnappingClient);
+	
+protected:
+	bool HitCharacter(vec2 From, vec2 To);
+	void DoBounce();
+	
+private:
+	vec2 m_From;
+	vec2 m_Dir;
+	float m_Energy;
+	int m_Bounces;
+	int m_EvalTick;
+	int m_Owner;
+};
+
+#endif
diff --git a/src/game/server/entities/laser.hpp b/src/game/server/entities/laser.hpp
deleted file mode 100644
index aa4c2284..00000000
--- a/src/game/server/entities/laser.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-
-#ifndef GAME_SERVER_ENTITY_LASER_H
-#define GAME_SERVER_ENTITY_LASER_H
-
-#include <game/server/entity.hpp>
-
-class CHARACTER;
-
-class LASER : public ENTITY
-{
-	vec2 from;
-	vec2 dir;
-	float energy;
-	int bounces;
-	int eval_tick;
-	int owner;
-	
-	bool hit_character(vec2 from, vec2 to);
-	void do_bounce();
-	
-public:
-	
-	LASER(vec2 pos, vec2 direction, float start_energy, int owner);
-	
-	virtual void reset();
-	virtual void tick();
-	virtual void snap(int snapping_client);
-};
-
-#endif
diff --git a/src/game/server/entities/pickup.cpp b/src/game/server/entities/pickup.cpp
index 436282cc..9798e2c3 100644
--- a/src/game/server/entities/pickup.cpp
+++ b/src/game/server/entities/pickup.cpp
@@ -1,143 +1,129 @@
-#include <engine/e_server_interface.h>
-#include <game/generated/g_protocol.hpp>
-#include <game/server/gamecontext.hpp>
-#include "pickup.hpp"
+#include <game/generated/protocol.h>
+#include <game/server/gamecontext.h>
+#include "pickup.h"
 
-//////////////////////////////////////////////////
-// pickup
-//////////////////////////////////////////////////
-PICKUP::PICKUP(int _type, int _subtype)
-: ENTITY(NETOBJTYPE_PICKUP)
+CPickup::CPickup(CGameWorld *pGameWorld, int Type, int SubType)
+: CEntity(pGameWorld, NETOBJTYPE_PICKUP)
 {
-	type = _type;
-	subtype = _subtype;
-	proximity_radius = phys_size;
+	m_Type = Type;
+	m_Subtype = SubType;
+	m_ProximityRadius = PickupPhysSize;
 
-	reset();
-
-	// TODO: should this be done here?
-	game.world.insert_entity(this);
+	Reset();
+	
+	GameWorld()->InsertEntity(this);
 }
 
-void PICKUP::reset()
+void CPickup::Reset()
 {
-	if (data->pickups[type].spawndelay > 0)
-		spawntick = server_tick() + server_tickspeed() * data->pickups[type].spawndelay;
+	if (g_pData->m_aPickups[m_Type].m_Spawndelay > 0)
+		m_SpawnTick = Server()->Tick() + Server()->TickSpeed() * g_pData->m_aPickups[m_Type].m_Spawndelay;
 	else
-		spawntick = -1;
+		m_SpawnTick = -1;
 }
 
-void PICKUP::tick()
+void CPickup::Tick()
 {
 	// wait for respawn
-	if(spawntick > 0)
+	if(m_SpawnTick > 0)
 	{
-		if(server_tick() > spawntick)
+		if(Server()->Tick() > m_SpawnTick)
 		{
 			// respawn
-			spawntick = -1;
+			m_SpawnTick = -1;
 
-			if(type == POWERUP_WEAPON)
-				game.create_sound(pos, SOUND_WEAPON_SPAWN);
+			if(m_Type == POWERUP_WEAPON)
+				GameServer()->CreateSound(m_Pos, SOUND_WEAPON_SPAWN);
 		}
 		else
 			return;
 	}
 	// Check if a player intersected us
-	CHARACTER *chr = game.world.closest_character(pos, 20.0f, 0);
-	if(chr)
+	CCharacter *pChr = GameServer()->m_World.ClosestCharacter(m_Pos, 20.0f, 0);
+	if(pChr && pChr->IsAlive())
 	{
 		// player picked us up, is someone was hooking us, let them go
-		int respawntime = -1;
-		switch (type)
+		int RespawnTime = -1;
+		switch (m_Type)
 		{
-		case POWERUP_HEALTH:
-			if(chr->increase_health(1))
-			{
-				game.create_sound(pos, SOUND_PICKUP_HEALTH);
-				respawntime = data->pickups[type].respawntime;
-			}
-			break;
-		case POWERUP_ARMOR:
-			if(chr->increase_armor(1))
-			{
-				game.create_sound(pos, SOUND_PICKUP_ARMOR);
-				respawntime = data->pickups[type].respawntime;
-			}
-			break;
+			case POWERUP_HEALTH:
+				if(pChr->IncreaseHealth(1))
+				{
+					GameServer()->CreateSound(m_Pos, SOUND_PICKUP_HEALTH);
+					RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
+				}
+				break;
+				
+			case POWERUP_ARMOR:
+				if(pChr->IncreaseArmor(1))
+				{
+					GameServer()->CreateSound(m_Pos, SOUND_PICKUP_ARMOR);
+					RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
+				}
+				break;
 
-		case POWERUP_WEAPON:
-			if(subtype >= 0 && subtype < NUM_WEAPONS)
-			{
-				if(chr->weapons[subtype].ammo < data->weapons.id[subtype].maxammo || !chr->weapons[subtype].got)
+			case POWERUP_WEAPON:
+				if(m_Subtype >= 0 && m_Subtype < NUM_WEAPONS)
 				{
-					chr->weapons[subtype].got = true;
-					chr->weapons[subtype].ammo = min(data->weapons.id[subtype].maxammo, chr->weapons[subtype].ammo + 10);
-					respawntime = data->pickups[type].respawntime;
+					if(pChr->GiveWeapon(m_Subtype, 10))
+					{
+						RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
 
-					// TODO: data compiler should take care of stuff like this
-					if(subtype == WEAPON_GRENADE)
-						game.create_sound(pos, SOUND_PICKUP_GRENADE);
-					else if(subtype == WEAPON_SHOTGUN)
-						game.create_sound(pos, SOUND_PICKUP_SHOTGUN);
-					else if(subtype == WEAPON_RIFLE)
-						game.create_sound(pos, SOUND_PICKUP_SHOTGUN);
+						if(m_Subtype == WEAPON_GRENADE)
+							GameServer()->CreateSound(m_Pos, SOUND_PICKUP_GRENADE);
+						else if(m_Subtype == WEAPON_SHOTGUN)
+							GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN);
+						else if(m_Subtype == WEAPON_RIFLE)
+							GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN);
 
-					if(chr->player)
-                    	game.send_weapon_pickup(chr->player->client_id, subtype);
+						if(pChr->GetPlayer())
+							GameServer()->SendWeaponPickup(pChr->GetPlayer()->GetCID(), m_Subtype);
+					}
 				}
-			}
-			break;
-		case POWERUP_NINJA:
-			{
-				// activate ninja on target player
-				chr->ninja.activationtick = server_tick();
-				chr->weapons[WEAPON_NINJA].got = true;
-				chr->weapons[WEAPON_NINJA].ammo = -1;
-				chr->last_weapon = chr->active_weapon;
-				chr->active_weapon = WEAPON_NINJA;
-				respawntime = data->pickups[type].respawntime;
-				game.create_sound(pos, SOUND_PICKUP_NINJA);
-
-				// loop through all players, setting their emotes
-				ENTITY *ents[64];
-				int num = game.world.find_entities(vec2(0, 0), 1000000, ents, 64, NETOBJTYPE_CHARACTER);
-				for (int i = 0; i < num; i++)
+				break;
+				
+			case POWERUP_NINJA:
 				{
-					CHARACTER *c = (CHARACTER *)ents[i];
-					if (c != chr)
+					// activate ninja on target player
+					pChr->GiveNinja();
+					RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
+
+					// loop through all players, setting their emotes
+					CEntity *apEnts[64];
+					int Num = GameServer()->m_World.FindEntities(vec2(0, 0), 1000000, apEnts, 64, NETOBJTYPE_CHARACTER);
+					
+					for (int i = 0; i < Num; ++i)
 					{
-						c->emote_type = EMOTE_SURPRISE;
-						c->emote_stop = server_tick() + server_tickspeed();
+						CCharacter *pC = static_cast<CCharacter *>(apEnts[i]);
+						if (pC != pChr)
+							pC->SetEmote(EMOTE_SURPRISE, Server()->Tick() + Server()->TickSpeed());
 					}
-				}
 
-				chr->emote_type = EMOTE_ANGRY;
-				chr->emote_stop = server_tick() + 1200 * server_tickspeed() / 1000;
+					pChr->SetEmote(EMOTE_ANGRY, Server()->Tick() + 1200 * Server()->TickSpeed() / 1000);
+					break;
+				}
 				
+			default:
 				break;
-			}
-		default:
-			break;
 		};
 
-		if(respawntime >= 0)
+		if(RespawnTime >= 0)
 		{
 			dbg_msg("game", "pickup player='%d:%s' item=%d/%d",
-				chr->player->client_id, server_clientname(chr->player->client_id), type, subtype);
-			spawntick = server_tick() + server_tickspeed() * respawntime;
+				pChr->GetPlayer()->GetCID(), Server()->ClientName(pChr->GetPlayer()->GetCID()), m_Type, m_Subtype);
+			m_SpawnTick = Server()->Tick() + Server()->TickSpeed() * RespawnTime;
 		}
 	}
 }
 
-void PICKUP::snap(int snapping_client)
+void CPickup::Snap(int SnappingClient)
 {
-	if(spawntick != -1)
+	if(m_SpawnTick != -1 || NetworkClipped(SnappingClient))
 		return;
 
-	NETOBJ_PICKUP *up = (NETOBJ_PICKUP *)snap_new_item(NETOBJTYPE_PICKUP, id, sizeof(NETOBJ_PICKUP));
-	up->x = (int)pos.x;
-	up->y = (int)pos.y;
-	up->type = type; // TODO: two diffrent types? what gives?
-	up->subtype = subtype;
+	CNetObj_Pickup *pP = static_cast<CNetObj_Pickup *>(Server()->SnapNewItem(NETOBJTYPE_PICKUP, m_Id, sizeof(CNetObj_Pickup)));
+	pP->m_X = (int)m_Pos.x;
+	pP->m_Y = (int)m_Pos.y;
+	pP->m_Type = m_Type;
+	pP->m_Subtype = m_Subtype;
 }
diff --git a/src/game/server/entities/pickup.h b/src/game/server/entities/pickup.h
new file mode 100644
index 00000000..c076464c
--- /dev/null
+++ b/src/game/server/entities/pickup.h
@@ -0,0 +1,23 @@
+#ifndef GAME_SERVER_ENTITIES_PICKUP_H
+#define GAME_SERVER_ENTITIES_PICKUP_H
+
+#include <game/server/entity.h>
+
+const int PickupPhysSize = 14;
+
+class CPickup : public CEntity
+{
+public:
+	CPickup(CGameWorld *pGameWorld, int Type, int SubType = 0);
+	
+	virtual void Reset();
+	virtual void Tick();
+	virtual void Snap(int SnappingClient);
+	
+private:
+	int m_Type;
+	int m_Subtype;
+	int m_SpawnTick;
+};
+
+#endif
diff --git a/src/game/server/entities/pickup.hpp b/src/game/server/entities/pickup.hpp
deleted file mode 100644
index cd480d92..00000000
--- a/src/game/server/entities/pickup.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-
-#ifndef GAME_SERVER_ENTITY_PICKUP_H
-#define GAME_SERVER_ENTITY_PICKUP_H
-
-#include <game/server/entity.hpp>
-
-// TODO: move to seperate file
-class PICKUP : public ENTITY
-{
-public:
-	static const int phys_size = 14;
-	
-	int type;
-	int subtype; // weapon type for instance?
-	int spawntick;
-	PICKUP(int _type, int _subtype = 0);
-	
-	virtual void reset();
-	virtual void tick();
-	virtual void snap(int snapping_client);
-};
-
-#endif
diff --git a/src/game/server/entities/projectile.cpp b/src/game/server/entities/projectile.cpp
index 2a8de766..18652ba1 100644
--- a/src/game/server/entities/projectile.cpp
+++ b/src/game/server/entities/projectile.cpp
@@ -1,105 +1,102 @@
-#include <engine/e_server_interface.h>
-#include <game/generated/g_protocol.hpp>
-#include <game/server/gamecontext.hpp>
-#include "projectile.hpp"
+#include <game/generated/protocol.h>
+#include <game/server/gamecontext.h>
+#include "projectile.h"
 
-
-//////////////////////////////////////////////////
-// projectile
-//////////////////////////////////////////////////
-PROJECTILE::PROJECTILE(int type, int owner, vec2 pos, vec2 dir, int span,
-	int damage, int flags, float force, int sound_impact, int weapon)
-: ENTITY(NETOBJTYPE_PROJECTILE)
+CProjectile::CProjectile(CGameWorld *pGameWorld, int Type, int Owner, vec2 Pos, vec2 Dir, int Span,
+		int Damage, bool Explosive, float Force, int SoundImpact, int Weapon)
+: CEntity(pGameWorld, NETOBJTYPE_PROJECTILE)
 {
-	this->type = type;
-	this->pos = pos;
-	this->direction = dir;
-	this->lifespan = span;
-	this->owner = owner;
-	this->flags = flags;
-	this->force = force;
-	this->damage = damage;
-	this->sound_impact = sound_impact;
-	this->weapon = weapon;
-	this->bounce = 0;
-	this->start_tick = server_tick();
-	game.world.insert_entity(this);
+	m_Type = Type;
+	m_Pos = Pos;
+	m_Direction = Dir;
+	m_LifeSpan = Span;
+	m_Owner = Owner;
+	m_Force = Force;
+	m_Damage = Damage;
+	m_SoundImpact = SoundImpact;
+	m_Weapon = Weapon;
+	m_StartTick = Server()->Tick();
+	m_Explosive = Explosive;
+
+	GameWorld()->InsertEntity(this);
 }
 
-void PROJECTILE::reset()
+void CProjectile::Reset()
 {
-	game.world.destroy_entity(this);
+	GameServer()->m_World.DestroyEntity(this);
 }
 
-vec2 PROJECTILE::get_pos(float time)
+vec2 CProjectile::GetPos(float Time)
 {
-	float curvature = 0;
-	float speed = 0;
-	if(type == WEAPON_GRENADE)
-	{
-		curvature = tuning.grenade_curvature;
-		speed = tuning.grenade_speed;
-	}
-	else if(type == WEAPON_SHOTGUN)
-	{
-		curvature = tuning.shotgun_curvature;
-		speed = tuning.shotgun_speed;
-	}
-	else if(type == WEAPON_GUN)
+	float Curvature = 0;
+	float Speed = 0;
+	
+	switch(m_Type)
 	{
-		curvature = tuning.gun_curvature;
-		speed = tuning.gun_speed;
+		case WEAPON_GRENADE:
+			Curvature = GameServer()->Tuning()->m_GrenadeCurvature;
+			Speed = GameServer()->Tuning()->m_GrenadeSpeed;
+			break;
+			
+		case WEAPON_SHOTGUN:
+			Curvature = GameServer()->Tuning()->m_ShotgunCurvature;
+			Speed = GameServer()->Tuning()->m_ShotgunSpeed;
+			break;
+			
+		case WEAPON_GUN:
+			Curvature = GameServer()->Tuning()->m_GunCurvature;
+			Speed = GameServer()->Tuning()->m_GunSpeed;
+			break;
 	}
 	
-	return calc_pos(pos, direction, curvature, speed, time);
+	return CalcPos(m_Pos, m_Direction, Curvature, Speed, Time);
 }
 
 
-void PROJECTILE::tick()
+void CProjectile::Tick()
 {
-	
-	float pt = (server_tick()-start_tick-1)/(float)server_tickspeed();
-	float ct = (server_tick()-start_tick)/(float)server_tickspeed();
-	vec2 prevpos = get_pos(pt);
-	vec2 curpos = get_pos(ct);
+	float Pt = (Server()->Tick()-m_StartTick-1)/(float)Server()->TickSpeed();
+	float Ct = (Server()->Tick()-m_StartTick)/(float)Server()->TickSpeed();
+	vec2 PrevPos = GetPos(Pt);
+	vec2 CurPos = GetPos(Ct);
+	int Collide = GameServer()->Collision()->IntersectLine(PrevPos, CurPos, &CurPos, 0);
+	CCharacter *OwnerChar = GameServer()->GetPlayerChar(m_Owner);
+	CCharacter *TargetChr = GameServer()->m_World.IntersectCharacter(PrevPos, CurPos, 6.0f, CurPos, OwnerChar);
 
-	lifespan--;
+	m_LifeSpan--;
 	
-	int collide = col_intersect_line(prevpos, curpos, &curpos, 0);
-	//int collide = col_check_point((int)curpos.x, (int)curpos.y);
-	CHARACTER *ownerchar = game.get_player_char(owner);
-	CHARACTER *targetchr = game.world.intersect_character(prevpos, curpos, 6.0f, curpos, ownerchar);
-	if(targetchr || collide || lifespan < 0)
+	if(TargetChr || Collide || m_LifeSpan < 0)
 	{
-		if(lifespan >= 0 || weapon == WEAPON_GRENADE)
-			game.create_sound(curpos, sound_impact);
+		if(m_LifeSpan >= 0 || m_Weapon == WEAPON_GRENADE)
+			GameServer()->CreateSound(CurPos, m_SoundImpact);
 
-		if(flags & PROJECTILE_FLAGS_EXPLODE)
-			game.create_explosion(curpos, owner, weapon, false);
-		else if(targetchr)
-			targetchr->take_damage(direction * max(0.001f, force), damage, owner, weapon);
+		if(m_Explosive)
+			GameServer()->CreateExplosion(CurPos, m_Owner, m_Weapon, false);
+			
+		else if(TargetChr)
+			TargetChr->TakeDamage(m_Direction * max(0.001f, m_Force), m_Damage, m_Owner, m_Weapon);
 
-		game.world.destroy_entity(this);
+		GameServer()->m_World.DestroyEntity(this);
 	}
 }
 
-void PROJECTILE::fill_info(NETOBJ_PROJECTILE *proj)
+void CProjectile::FillInfo(CNetObj_Projectile *pProj)
 {
-	proj->x = (int)pos.x;
-	proj->y = (int)pos.y;
-	proj->vx = (int)(direction.x*100.0f);
-	proj->vy = (int)(direction.y*100.0f);
-	proj->start_tick = start_tick;
-	proj->type = type;
+	pProj->m_X = (int)m_Pos.x;
+	pProj->m_Y = (int)m_Pos.y;
+	pProj->m_VelX = (int)(m_Direction.x*100.0f);
+	pProj->m_VelY = (int)(m_Direction.y*100.0f);
+	pProj->m_StartTick = m_StartTick;
+	pProj->m_Type = m_Type;
 }
 
-void PROJECTILE::snap(int snapping_client)
+void CProjectile::Snap(int SnappingClient)
 {
-	float ct = (server_tick()-start_tick)/(float)server_tickspeed();
+	float Ct = (Server()->Tick()-m_StartTick)/(float)Server()->TickSpeed();
 	
-	if(networkclipped(snapping_client, get_pos(ct)))
+	if(NetworkClipped(SnappingClient, GetPos(Ct)))
 		return;
 
-	NETOBJ_PROJECTILE *proj = (NETOBJ_PROJECTILE *)snap_new_item(NETOBJTYPE_PROJECTILE, id, sizeof(NETOBJ_PROJECTILE));
-	fill_info(proj);
+	CNetObj_Projectile *pProj = static_cast<CNetObj_Projectile *>(Server()->SnapNewItem(NETOBJTYPE_PROJECTILE, m_Id, sizeof(CNetObj_Projectile)));
+	FillInfo(pProj);
 }
diff --git a/src/game/server/entities/projectile.h b/src/game/server/entities/projectile.h
new file mode 100644
index 00000000..87f4f6c3
--- /dev/null
+++ b/src/game/server/entities/projectile.h
@@ -0,0 +1,30 @@
+#ifndef GAME_SERVER_ENTITIES_PROJECTILE_H
+#define GAME_SERVER_ENTITIES_PROJECTILE_H
+
+class CProjectile : public CEntity
+{
+public:
+	CProjectile(CGameWorld *pGameWorld, int Type, int Owner, vec2 Pos, vec2 Dir, int Span,
+		int Damage, bool Explosive, float Force, int SoundImpact, int Weapon);
+
+	vec2 GetPos(float Time);
+	void FillInfo(CNetObj_Projectile *pProj);
+
+	virtual void Reset();
+	virtual void Tick();
+	virtual void Snap(int SnappingClient);
+	
+private:
+	vec2 m_Direction;
+	int m_LifeSpan;
+	int m_Owner;
+	int m_Type;
+	int m_Damage;
+	int m_SoundImpact;
+	int m_Weapon;
+	float m_Force;
+	int m_StartTick;
+	bool m_Explosive;
+};
+
+#endif
diff --git a/src/game/server/entities/projectile.hpp b/src/game/server/entities/projectile.hpp
deleted file mode 100644
index a5c3b88f..00000000
--- a/src/game/server/entities/projectile.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-
-#ifndef GAME_SERVER_ENTITY_PROJECTILE_H
-#define GAME_SERVER_ENTITY_PROJECTILE_H
-
-class PROJECTILE : public ENTITY
-{
-public:
-	enum
-	{
-		PROJECTILE_FLAGS_EXPLODE = 1 << 0,
-	};
-	
-	vec2 direction;
-	int lifespan;
-	int owner;
-	int type;
-	int flags;
-	int damage;
-	int sound_impact;
-	int weapon;
-	int bounce;
-	float force;
-	int start_tick;
-	
-	PROJECTILE(int type, int owner, vec2 pos, vec2 vel, int span,
-		int damage, int flags, float force, int sound_impact, int weapon);
-
-	vec2 get_pos(float time);
-	void fill_info(NETOBJ_PROJECTILE *proj);
-
-	virtual void reset();
-	virtual void tick();
-	virtual void snap(int snapping_client);
-};
-
-#endif
diff --git a/src/game/server/entity.cpp b/src/game/server/entity.cpp
index 8e3345ab..d17c3fab 100644
--- a/src/game/server/entity.cpp
+++ b/src/game/server/entity.cpp
@@ -1,49 +1,50 @@
 
-#include <engine/e_server_interface.h>
-#include "entity.hpp"
-#include "gamecontext.hpp"
+#include "entity.h"
+#include "gamecontext.h"
 
 //////////////////////////////////////////////////
 // Entity
 //////////////////////////////////////////////////
-ENTITY::ENTITY(int objtype)
+CEntity::CEntity(CGameWorld *pGameWorld, int ObjType)
 {
-	this->objtype = objtype;
-	pos = vec2(0,0);
-	proximity_radius = 0;
+	m_pGameWorld = pGameWorld;
+	
+	m_Objtype = ObjType;
+	m_Pos = vec2(0,0);
+	m_ProximityRadius = 0;
 
-	marked_for_destroy = false;	
-	id = snap_new_id();
+	m_MarkedForDestroy = false;	
+	m_Id = Server()->SnapNewID();
 
-	next_entity = 0;
-	prev_entity = 0;
-	prev_type_entity = 0;
-	next_type_entity = 0;
+	m_pNextEntity = 0;
+	m_pPrevEntity = 0;
+	m_pPrevTypeEntity = 0;
+	m_pNextTypeEntity = 0;
 }
 
-ENTITY::~ENTITY()
+CEntity::~CEntity()
 {
-	game.world.remove_entity(this);
-	snap_free_id(id);
+	GameWorld()->RemoveEntity(this);
+	Server()->SnapFreeID(m_Id);
 }
 
-int ENTITY::networkclipped(int snapping_client)
+int CEntity::NetworkClipped(int SnappingClient)
 {
-	return networkclipped(snapping_client, pos);
+	return NetworkClipped(SnappingClient, m_Pos);
 }
 
-int ENTITY::networkclipped(int snapping_client, vec2 check_pos)
+int CEntity::NetworkClipped(int SnappingClient, vec2 CheckPos)
 {
-	if(snapping_client == -1)
+	if(SnappingClient == -1)
 		return 0;
 	
-	float dx = game.players[snapping_client]->view_pos.x-check_pos.x;
-	float dy = game.players[snapping_client]->view_pos.y-check_pos.y;
+	float dx = GameServer()->m_apPlayers[SnappingClient]->m_ViewPos.x-CheckPos.x;
+	float dy = GameServer()->m_apPlayers[SnappingClient]->m_ViewPos.y-CheckPos.y;
 	
-	if(fabs(dx) > 1000.0f || fabs(dy) > 800.0f)
+	if(absolute(dx) > 1000.0f || absolute(dy) > 800.0f)
 		return 1;
 	
-	if(distance(game.players[snapping_client]->view_pos, check_pos) > 1100.0f)
+	if(distance(GameServer()->m_apPlayers[SnappingClient]->m_ViewPos, CheckPos) > 1100.0f)
 		return 1;
 	return 0;
 }
diff --git a/src/game/server/entity.hpp b/src/game/server/entity.h
index debe57b6..b7fd3d94 100644
--- a/src/game/server/entity.hpp
+++ b/src/game/server/entity.h
@@ -2,101 +2,109 @@
 #define GAME_SERVER_ENTITY_H
 
 #include <new>
-#include <base/vmath.hpp>
+#include <base/vmath.h>
+#include <game/server/gameworld.h>
 
 #define MACRO_ALLOC_HEAP() \
 	public: \
-	void *operator new(size_t size) \
+	void *operator new(size_t Size) \
 	{ \
-		void *p = mem_alloc(size, 1); \
+		void *p = mem_alloc(Size, 1); \
 		/*dbg_msg("", "++ %p %d", p, size);*/ \
-		mem_zero(p, size); \
+		mem_zero(p, Size); \
 		return p; \
 	} \
-	void operator delete(void *p) \
+	void operator delete(void *pPtr) \
 	{ \
 		/*dbg_msg("", "-- %p", p);*/ \
-		mem_free(p); \
+		mem_free(pPtr); \
 	} \
 	private:
 
 #define MACRO_ALLOC_POOL_ID() \
 	public: \
-	void *operator new(size_t size, int id); \
+	void *operator new(size_t Size, int id); \
 	void operator delete(void *p); \
 	private:
 	
-#define MACRO_ALLOC_POOL_ID_IMPL(POOLTYPE, poolsize) \
-	static char pool_data_##POOLTYPE[poolsize][sizeof(POOLTYPE)] = {{0}}; \
-	static int pool_used_##POOLTYPE[poolsize] = {0}; \
-	void *POOLTYPE::operator new(size_t size, int id) \
+#define MACRO_ALLOC_POOL_ID_IMPL(POOLTYPE, PoolSize) \
+	static char ms_PoolData##POOLTYPE[PoolSize][sizeof(POOLTYPE)] = {{0}}; \
+	static int ms_PoolUsed##POOLTYPE[PoolSize] = {0}; \
+	void *POOLTYPE::operator new(size_t Size, int id) \
 	{ \
-		dbg_assert(sizeof(POOLTYPE) == size, "size error"); \
-		dbg_assert(!pool_used_##POOLTYPE[id], "already used"); \
+		dbg_assert(sizeof(POOLTYPE) == Size, "size error"); \
+		dbg_assert(!ms_PoolUsed##POOLTYPE[id], "already used"); \
 		/*dbg_msg("pool", "++ %s %d", #POOLTYPE, id);*/ \
-		pool_used_##POOLTYPE[id] = 1; \
-		mem_zero(pool_data_##POOLTYPE[id], size); \
-		return pool_data_##POOLTYPE[id]; \
+		ms_PoolUsed##POOLTYPE[id] = 1; \
+		mem_zero(ms_PoolData##POOLTYPE[id], Size); \
+		return ms_PoolData##POOLTYPE[id]; \
 	} \
 	void POOLTYPE::operator delete(void *p) \
 	{ \
-		int id = (POOLTYPE*)p - (POOLTYPE*)pool_data_##POOLTYPE; \
-		dbg_assert(pool_used_##POOLTYPE[id], "not used"); \
+		int id = (POOLTYPE*)p - (POOLTYPE*)ms_PoolData##POOLTYPE; \
+		dbg_assert(ms_PoolUsed##POOLTYPE[id], "not used"); \
 		/*dbg_msg("pool", "-- %s %d", #POOLTYPE, id);*/ \
-		pool_used_##POOLTYPE[id] = 0; \
-		mem_zero(pool_data_##POOLTYPE[id], sizeof(POOLTYPE)); \
+		ms_PoolUsed##POOLTYPE[id] = 0; \
+		mem_zero(ms_PoolData##POOLTYPE[id], sizeof(POOLTYPE)); \
 	}
 	
 /*
 	Class: Entity
 		Basic entity class.
 */
-class ENTITY
+class CEntity
 {
 	MACRO_ALLOC_HEAP()
 private:
-	friend class GAMEWORLD; // thy these?
-	ENTITY *prev_entity;
-	ENTITY *next_entity;
+	friend class CGameWorld; // thy these?
+	CEntity *m_pPrevEntity;
+	CEntity *m_pNextEntity;
 
-	ENTITY *prev_type_entity;
-	ENTITY *next_type_entity;
+	CEntity *m_pPrevTypeEntity;
+	CEntity *m_pNextTypeEntity;
+	
+	class CGameWorld *m_pGameWorld;
 protected:
-	bool marked_for_destroy;
-	int id;
-	int objtype;
+	bool m_MarkedForDestroy;
+	int m_Id;
+	int m_Objtype;
 public:
-	ENTITY(int objtype);
-	virtual ~ENTITY();
+	CEntity(CGameWorld *pGameWorld, int Objtype);
+	virtual ~CEntity();
+	
+	class CGameWorld *GameWorld() { return m_pGameWorld; }
+	class CGameContext *GameServer() { return GameWorld()->GameServer(); }
+	class IServer *Server() { return GameWorld()->Server(); }
+	
 	
-	ENTITY *typenext() { return next_type_entity; }
-	ENTITY *typeprev() { return prev_type_entity; }
+	CEntity *TypeNext() { return m_pNextTypeEntity; }
+	CEntity *TypePrev() { return m_pPrevTypeEntity; }
 
 	/*
 		Function: destroy
 			Destorys the entity.
 	*/
-	virtual void destroy() { delete this; }
+	virtual void Destroy() { delete this; }
 		
 	/*
 		Function: reset
 			Called when the game resets the map. Puts the entity
 			back to it's starting state or perhaps destroys it.
 	*/
-	virtual void reset() {}
+	virtual void Reset() {}
 	
 	/*
 		Function: tick
 			Called progress the entity to the next tick. Updates
 			and moves the entity to it's new state and position.
 	*/
-	virtual void tick() {}
+	virtual void Tick() {}
 
 	/*
 		Function: tick_defered
 			Called after all entities tick() function has been called.
 	*/
-	virtual void tick_defered() {}
+	virtual void TickDefered() {}
 	
 	/*
 		Function: snap
@@ -109,7 +117,7 @@ public:
 				snapshot of everything in the game for demo
 				recording.
 	*/
-	virtual void snap(int snapping_client) {}
+	virtual void Snap(int SnappingClient) {}
 	
 	/*
 		Function: networkclipped(int snapping_client)
@@ -125,21 +133,21 @@ public:
 		Returns:
 			Non-zero if the entity doesn't have to be in the snapshot.
 	*/
-	int networkclipped(int snapping_client);
-	int networkclipped(int snapping_client, vec2 check_pos);
+	int NetworkClipped(int SnappingClient);
+	int NetworkClipped(int SnappingClient, vec2 CheckPos);
 		
 
 	/*
 		Variable: proximity_radius
 			Contains the physical size of the entity.
 	*/
-	float proximity_radius;
+	float m_ProximityRadius;
 	
 	/*
 		Variable: pos
 			Contains the current posititon of the entity.
 	*/
-	vec2 pos;
+	vec2 m_Pos;
 };
 
 #endif
diff --git a/src/game/server/eventhandler.cpp b/src/game/server/eventhandler.cpp
index 761eaf2c..48b6689e 100644
--- a/src/game/server/eventhandler.cpp
+++ b/src/game/server/eventhandler.cpp
@@ -1,48 +1,54 @@
-#include "eventhandler.hpp"
-#include "gamecontext.hpp"
+#include "eventhandler.h"
+#include "gamecontext.h"
 
 //////////////////////////////////////////////////
 // Event handler
 //////////////////////////////////////////////////
-EVENTHANDLER::EVENTHANDLER()
+CEventHandler::CEventHandler()
 {
-	clear();
+	m_pGameServer = 0;
+	Clear();
 }
 
-void *EVENTHANDLER::create(int type, int size, int mask)
+void CEventHandler::SetGameServer(CGameContext *pGameServer)
 {
-	if(num_events == MAX_EVENTS)
+	m_pGameServer = pGameServer;
+}
+
+void *CEventHandler::Create(int Type, int Size, int Mask)
+{
+	if(m_NumEvents == MAX_EVENTS)
 		return 0;
-	if(current_offset+size >= MAX_DATASIZE)
+	if(m_CurrentOffset+Size >= MAX_DATASIZE)
 		return 0;
 
-	void *p = &data[current_offset];
-	offsets[num_events] = current_offset;
-	types[num_events] = type;
-	sizes[num_events] = size;
-	client_masks[num_events] = mask;
-	current_offset += size;
-	num_events++;
+	void *p = &m_aData[m_CurrentOffset];
+	m_aOffsets[m_NumEvents] = m_CurrentOffset;
+	m_aTypes[m_NumEvents] = Type;
+	m_aSizes[m_NumEvents] = Size;
+	m_aClientMasks[m_NumEvents] = Mask;
+	m_CurrentOffset += Size;
+	m_NumEvents++;
 	return p;
 }
 
-void EVENTHANDLER::clear()
+void CEventHandler::Clear()
 {
-	num_events = 0;
-	current_offset = 0;
+	m_NumEvents = 0;
+	m_CurrentOffset = 0;
 }
 
-void EVENTHANDLER::snap(int snapping_client)
+void CEventHandler::Snap(int SnappingClient)
 {
-	for(int i = 0; i < num_events; i++)
+	for(int i = 0; i < m_NumEvents; i++)
 	{
-		if(snapping_client == -1 || cmask_is_set(client_masks[i], snapping_client))
+		if(SnappingClient == -1 || CmaskIsSet(m_aClientMasks[i], SnappingClient))
 		{
-			NETEVENT_COMMON *ev = (NETEVENT_COMMON *)&data[offsets[i]];
-			if(snapping_client == -1 || distance(game.players[snapping_client]->view_pos, vec2(ev->x, ev->y)) < 1500.0f)
+			NETEVENT_COMMON *ev = (NETEVENT_COMMON *)&m_aData[m_aOffsets[i]];
+			if(SnappingClient == -1 || distance(GameServer()->m_apPlayers[SnappingClient]->m_ViewPos, vec2(ev->m_X, ev->m_Y)) < 1500.0f)
 			{
-				void *d = snap_new_item(types[i], i, sizes[i]);
-				mem_copy(d, &data[offsets[i]], sizes[i]);
+				void *d = GameServer()->Server()->SnapNewItem(m_aTypes[i], i, m_aSizes[i]);
+				mem_copy(d, &m_aData[m_aOffsets[i]], m_aSizes[i]);
 			}
 		}
 	}
diff --git a/src/game/server/eventhandler.h b/src/game/server/eventhandler.h
new file mode 100644
index 00000000..3833efe0
--- /dev/null
+++ b/src/game/server/eventhandler.h
@@ -0,0 +1,30 @@
+#ifndef GAME_SERVER_EVENTHANDLER_H
+#define GAME_SERVER_EVENTHANDLER_H
+
+//
+class CEventHandler
+{
+	static const int MAX_EVENTS = 128;
+	static const int MAX_DATASIZE = 128*64;
+
+	int m_aTypes[MAX_EVENTS];  // TODO: remove some of these arrays
+	int m_aOffsets[MAX_EVENTS];
+	int m_aSizes[MAX_EVENTS];
+	int m_aClientMasks[MAX_EVENTS];
+	char m_aData[MAX_DATASIZE];
+	
+	class CGameContext *m_pGameServer;
+	
+	int m_CurrentOffset;
+	int m_NumEvents;
+public:
+	CGameContext *GameServer() const { return m_pGameServer; }
+	void SetGameServer(CGameContext *pGameServer);
+	
+	CEventHandler();
+	void *Create(int Type, int Size, int Mask = -1);
+	void Clear();
+	void Snap(int SnappingClient);
+};
+
+#endif
diff --git a/src/game/server/eventhandler.hpp b/src/game/server/eventhandler.hpp
deleted file mode 100644
index 4d513154..00000000
--- a/src/game/server/eventhandler.hpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef GAME_SERVER_EVENTHANDLER_H
-#define GAME_SERVER_EVENTHANDLER_H
-
-//
-class EVENTHANDLER
-{
-	static const int MAX_EVENTS = 128;
-	static const int MAX_DATASIZE = 128*64;
-
-	int types[MAX_EVENTS];  // TODO: remove some of these arrays
-	int offsets[MAX_EVENTS];
-	int sizes[MAX_EVENTS];
-	int client_masks[MAX_EVENTS];
-	char data[MAX_DATASIZE];
-	
-	int current_offset;
-	int num_events;
-public:
-	EVENTHANDLER();
-	void *create(int type, int size, int mask = -1);
-	void clear();
-	void snap(int snapping_client);
-};
-
-#endif
diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp
index 736d437f..795bb65f 100644
--- a/src/game/server/gamecontext.cpp
+++ b/src/game/server/gamecontext.cpp
@@ -1,99 +1,143 @@
-#include <string.h>
 #include <new>
-#include <engine/e_server_interface.h>
-#include "gamecontext.hpp"
+#include <base/math.h>
+#include <engine/shared/config.h>
+#include <engine/map.h>
+#include <engine/console.h>
+#include "gamecontext.h"
+#include <game/version.h>
+#include <game/collision.h>
+#include <game/gamecore.h>
+#include "gamemodes/dm.h"
+#include "gamemodes/tdm.h"
+#include "gamemodes/ctf.h"
+#include "gamemodes/mod.h"
 
-GAMECONTEXT game;
+enum
+{
+	RESET,
+	NO_RESET
+};
 
-GAMECONTEXT::GAMECONTEXT()
+void CGameContext::Construct(int Resetting)
 {
+	m_Resetting = 0;
+	m_pServer = 0;
+	
 	for(int i = 0; i < MAX_CLIENTS; i++)
-		players[i] = 0;
+		m_apPlayers[i] = 0;
 	
-	controller = 0;
-	vote_closetime = 0;
+	m_pController = 0;
+	m_VoteCloseTime = 0;
+	m_pVoteOptionFirst = 0;
+	m_pVoteOptionLast = 0;
+
+	if(Resetting==NO_RESET)
+		m_pVoteOptionHeap = new CHeap();
+}
+
+CGameContext::CGameContext(int Resetting)
+{
+	Construct(Resetting);
+}
+
+CGameContext::CGameContext()
+{
+	Construct(NO_RESET);
 }
 
-GAMECONTEXT::~GAMECONTEXT()
+CGameContext::~CGameContext()
 {
 	for(int i = 0; i < MAX_CLIENTS; i++)
-		delete players[i];
+		delete m_apPlayers[i];
+	if(!m_Resetting)
+		delete m_pVoteOptionHeap;
 }
 
-void GAMECONTEXT::clear()
+void CGameContext::Clear()
 {
-	this->~GAMECONTEXT();
+	CHeap *pVoteOptionHeap = m_pVoteOptionHeap;
+	CVoteOption *pVoteOptionFirst = m_pVoteOptionFirst;
+	CVoteOption *pVoteOptionLast = m_pVoteOptionLast;
+	CTuningParams Tuning = m_Tuning;
+
+	m_Resetting = true;
+	this->~CGameContext();
 	mem_zero(this, sizeof(*this));
-	new (this) GAMECONTEXT();
+	new (this) CGameContext(RESET);
+
+	m_pVoteOptionHeap = pVoteOptionHeap;
+	m_pVoteOptionFirst = pVoteOptionFirst;
+	m_pVoteOptionLast = pVoteOptionLast;
+	m_Tuning = Tuning;
 }
 
 
-class CHARACTER *GAMECONTEXT::get_player_char(int client_id)
+class CCharacter *CGameContext::GetPlayerChar(int ClientId)
 {
-	if(client_id < 0 || client_id >= MAX_CLIENTS || !players[client_id])
+	if(ClientId < 0 || ClientId >= MAX_CLIENTS || !m_apPlayers[ClientId])
 		return 0;
-	return players[client_id]->get_character();
+	return m_apPlayers[ClientId]->GetCharacter();
 }
 
-void GAMECONTEXT::create_damageind(vec2 p, float angle, int amount)
+void CGameContext::CreateDamageInd(vec2 p, float Angle, int Amount)
 {
-	float a = 3 * 3.14159f / 2 + angle;
+	float a = 3 * 3.14159f / 2 + Angle;
 	//float a = get_angle(dir);
 	float s = a-pi/3;
 	float e = a+pi/3;
-	for(int i = 0; i < amount; i++)
+	for(int i = 0; i < Amount; i++)
 	{
-		float f = mix(s, e, float(i+1)/float(amount+2));
-		NETEVENT_DAMAGEIND *ev = (NETEVENT_DAMAGEIND *)events.create(NETEVENTTYPE_DAMAGEIND, sizeof(NETEVENT_DAMAGEIND));
+		float f = mix(s, e, float(i+1)/float(Amount+2));
+		NETEVENT_DAMAGEIND *ev = (NETEVENT_DAMAGEIND *)m_Events.Create(NETEVENTTYPE_DAMAGEIND, sizeof(NETEVENT_DAMAGEIND));
 		if(ev)
 		{
-			ev->x = (int)p.x;
-			ev->y = (int)p.y;
-			ev->angle = (int)(f*256.0f);
+			ev->m_X = (int)p.x;
+			ev->m_Y = (int)p.y;
+			ev->m_Angle = (int)(f*256.0f);
 		}
 	}
 }
 
-void GAMECONTEXT::create_hammerhit(vec2 p)
+void CGameContext::CreateHammerHit(vec2 p)
 {
 	// create the event
-	NETEVENT_HAMMERHIT *ev = (NETEVENT_HAMMERHIT *)events.create(NETEVENTTYPE_HAMMERHIT, sizeof(NETEVENT_HAMMERHIT));
+	NETEVENT_HAMMERHIT *ev = (NETEVENT_HAMMERHIT *)m_Events.Create(NETEVENTTYPE_HAMMERHIT, sizeof(NETEVENT_HAMMERHIT));
 	if(ev)
 	{
-		ev->x = (int)p.x;
-		ev->y = (int)p.y;
+		ev->m_X = (int)p.x;
+		ev->m_Y = (int)p.y;
 	}
 }
 
 
-void GAMECONTEXT::create_explosion(vec2 p, int owner, int weapon, bool bnodamage)
+void CGameContext::CreateExplosion(vec2 p, int Owner, int Weapon, bool NoDamage)
 {
 	// create the event
-	NETEVENT_EXPLOSION *ev = (NETEVENT_EXPLOSION *)events.create(NETEVENTTYPE_EXPLOSION, sizeof(NETEVENT_EXPLOSION));
+	NETEVENT_EXPLOSION *ev = (NETEVENT_EXPLOSION *)m_Events.Create(NETEVENTTYPE_EXPLOSION, sizeof(NETEVENT_EXPLOSION));
 	if(ev)
 	{
-		ev->x = (int)p.x;
-		ev->y = (int)p.y;
+		ev->m_X = (int)p.x;
+		ev->m_Y = (int)p.y;
 	}
 
-	if (!bnodamage)
+	if (!NoDamage)
 	{
 		// deal damage
-		CHARACTER *ents[64];
-		float radius = 135.0f;
-		float innerradius = 48.0f;
-		int num = game.world.find_entities(p, radius, (ENTITY**)ents, 64, NETOBJTYPE_CHARACTER);
-		for(int i = 0; i < num; i++)
+		CCharacter *apEnts[64];
+		float Radius = 135.0f;
+		float InnerRadius = 48.0f;
+		int Num = m_World.FindEntities(p, Radius, (CEntity**)apEnts, 64, NETOBJTYPE_CHARACTER);
+		for(int i = 0; i < Num; i++)
 		{
-			vec2 diff = ents[i]->pos - p;
-			vec2 forcedir(0,1);
-			float l = length(diff);
+			vec2 Diff = apEnts[i]->m_Pos - p;
+			vec2 ForceDir(0,1);
+			float l = length(Diff);
 			if(l)
-				forcedir = normalize(diff);
-			l = 1-clamp((l-innerradius)/(radius-innerradius), 0.0f, 1.0f);
-			float dmg = 6 * l;
-			if((int)dmg)
-				ents[i]->take_damage(forcedir*dmg*2, (int)dmg, owner, weapon);
+				ForceDir = normalize(Diff);
+			l = 1-clamp((l-InnerRadius)/(Radius-InnerRadius), 0.0f, 1.0f);
+			float Dmg = 6 * l;
+			if((int)Dmg)
+				apEnts[i]->TakeDamage(ForceDir*Dmg*2, (int)Dmg, Owner, Weapon);
 		}
 	}
 }
@@ -110,273 +154,893 @@ void create_smoke(vec2 p)
 	}
 }*/
 
-void GAMECONTEXT::create_playerspawn(vec2 p)
+void CGameContext::CreatePlayerSpawn(vec2 p)
 {
 	// create the event
-	NETEVENT_SPAWN *ev = (NETEVENT_SPAWN *)events.create(NETEVENTTYPE_SPAWN, sizeof(NETEVENT_SPAWN));
+	NETEVENT_SPAWN *ev = (NETEVENT_SPAWN *)m_Events.Create(NETEVENTTYPE_SPAWN, sizeof(NETEVENT_SPAWN));
 	if(ev)
 	{
-		ev->x = (int)p.x;
-		ev->y = (int)p.y;
+		ev->m_X = (int)p.x;
+		ev->m_Y = (int)p.y;
 	}
 }
 
-void GAMECONTEXT::create_death(vec2 p, int cid)
+void CGameContext::CreateDeath(vec2 p, int ClientId)
 {
 	// create the event
-	NETEVENT_DEATH *ev = (NETEVENT_DEATH *)events.create(NETEVENTTYPE_DEATH, sizeof(NETEVENT_DEATH));
+	NETEVENT_DEATH *ev = (NETEVENT_DEATH *)m_Events.Create(NETEVENTTYPE_DEATH, sizeof(NETEVENT_DEATH));
 	if(ev)
 	{
-		ev->x = (int)p.x;
-		ev->y = (int)p.y;
-		ev->cid = cid;
+		ev->m_X = (int)p.x;
+		ev->m_Y = (int)p.y;
+		ev->m_ClientId = ClientId;
 	}
 }
 
-void GAMECONTEXT::create_sound(vec2 pos, int sound, int mask)
+void CGameContext::CreateSound(vec2 Pos, int Sound, int Mask)
 {
-	if (sound < 0)
+	if (Sound < 0)
 		return;
 
 	// create a sound
-	NETEVENT_SOUNDWORLD *ev = (NETEVENT_SOUNDWORLD *)events.create(NETEVENTTYPE_SOUNDWORLD, sizeof(NETEVENT_SOUNDWORLD), mask);
+	NETEVENT_SOUNDWORLD *ev = (NETEVENT_SOUNDWORLD *)m_Events.Create(NETEVENTTYPE_SOUNDWORLD, sizeof(NETEVENT_SOUNDWORLD), Mask);
 	if(ev)
 	{
-		ev->x = (int)pos.x;
-		ev->y = (int)pos.y;
-		ev->soundid = sound;
+		ev->m_X = (int)Pos.x;
+		ev->m_Y = (int)Pos.y;
+		ev->m_SoundId = Sound;
 	}
 }
 
-void GAMECONTEXT::create_sound_global(int sound, int target)
+void CGameContext::CreateSoundGlobal(int Sound, int Target)
 {
-	if (sound < 0)
+	if (Sound < 0)
 		return;
 
-	NETMSG_SV_SOUNDGLOBAL msg;
-	msg.soundid = sound;
-	msg.pack(MSGFLAG_VITAL);
-	server_send_msg(target);
+	CNetMsg_Sv_SoundGlobal Msg;
+	Msg.m_Soundid = Sound;
+	Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, Target);
 }
 
 
-void GAMECONTEXT::send_chat_target(int to, const char *text)
+void CGameContext::SendChatTarget(int To, const char *pText)
 {
-	NETMSG_SV_CHAT msg;
-	msg.team = 0;
-	msg.cid = -1;
-	msg.message = text;
-	msg.pack(MSGFLAG_VITAL);
-	server_send_msg(to);
+	CNetMsg_Sv_Chat Msg;
+	Msg.m_Team = 0;
+	Msg.m_Cid = -1;
+	Msg.m_pMessage = pText;
+	Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, To);
 }
 
 
-void GAMECONTEXT::send_chat(int chatter_cid, int team, const char *text)
+void CGameContext::SendChat(int ChatterClientId, int Team, const char *pText)
 {
-	if(chatter_cid >= 0 && chatter_cid < MAX_CLIENTS)
-		dbg_msg("chat", "%d:%d:%s: %s", chatter_cid, team, server_clientname(chatter_cid), text);
+	if(ChatterClientId >= 0 && ChatterClientId < MAX_CLIENTS)
+		dbg_msg("chat", "%d:%d:%s: %s", ChatterClientId, Team, Server()->ClientName(ChatterClientId), pText);
 	else
-		dbg_msg("chat", "*** %s", text);
+		dbg_msg("chat", "*** %s", pText);
 
-	if(team == CHAT_ALL)
+	if(Team == CHAT_ALL)
 	{
-		NETMSG_SV_CHAT msg;
-		msg.team = 0;
-		msg.cid = chatter_cid;
-		msg.message = text;
-		msg.pack(MSGFLAG_VITAL);
-		server_send_msg(-1);
+		CNetMsg_Sv_Chat Msg;
+		Msg.m_Team = 0;
+		Msg.m_Cid = ChatterClientId;
+		Msg.m_pMessage = pText;
+		Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, -1);
 	}
 	else
 	{
-		NETMSG_SV_CHAT msg;
-		msg.team = 1;
-		msg.cid = chatter_cid;
-		msg.message = text;
+		CNetMsg_Sv_Chat Msg;
+		Msg.m_Team = 1;
+		Msg.m_Cid = ChatterClientId;
+		Msg.m_pMessage = pText;
 		
 		// pack one for the recording only
-		msg.pack(MSGFLAG_VITAL|MSGFLAG_NOSEND);
-		server_send_msg(-1);
+		Server()->SendPackMsg(&Msg, MSGFLAG_VITAL|MSGFLAG_NOSEND, -1);
 
 		// send to the clients
-		msg.pack(MSGFLAG_VITAL|MSGFLAG_NORECORD);
 		for(int i = 0; i < MAX_CLIENTS; i++)
 		{
-			if(game.players[i] && game.players[i]->team == team)
-				server_send_msg(i);
+			if(m_apPlayers[i] && m_apPlayers[i]->GetTeam() == Team)
+				Server()->SendPackMsg(&Msg, MSGFLAG_VITAL|MSGFLAG_NORECORD, i);
 		}
 	}
 }
 
-void GAMECONTEXT::send_emoticon(int cid, int emoticon)
+void CGameContext::SendEmoticon(int ClientId, int Emoticon)
 {
-	NETMSG_SV_EMOTICON msg;
-	msg.cid = cid;
-	msg.emoticon = emoticon;
-	msg.pack(MSGFLAG_VITAL);
-	server_send_msg(-1);
+	CNetMsg_Sv_Emoticon Msg;
+	Msg.m_Cid = ClientId;
+	Msg.m_Emoticon = Emoticon;
+	Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, -1);
 }
 
-void GAMECONTEXT::send_weapon_pickup(int cid, int weapon)
+void CGameContext::SendWeaponPickup(int ClientId, int Weapon)
 {
-	NETMSG_SV_WEAPONPICKUP msg;
-	msg.weapon = weapon;
-	msg.pack(MSGFLAG_VITAL);
-	server_send_msg(cid);
+	CNetMsg_Sv_WeaponPickup Msg;
+	Msg.m_Weapon = Weapon;
+	Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientId);
 }
 
 
-void GAMECONTEXT::send_broadcast(const char *text, int cid)
+void CGameContext::SendBroadcast(const char *pText, int ClientId)
 {
-	NETMSG_SV_BROADCAST msg;
-	msg.message = text;
-	msg.pack(MSGFLAG_VITAL);
-	server_send_msg(cid);
+	CNetMsg_Sv_Broadcast Msg;
+	Msg.m_pMessage = pText;
+	Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientId);
 }
 
 // 
-void GAMECONTEXT::start_vote(const char *desc, const char *command)
+void CGameContext::StartVote(const char *pDesc, const char *pCommand)
 {
 	// check if a vote is already running
-	if(vote_closetime)
+	if(m_VoteCloseTime)
 		return;
 
 	// reset votes
-	vote_enforce = VOTE_ENFORCE_UNKNOWN;
+	m_VoteEnforce = VOTE_ENFORCE_UNKNOWN;
 	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
-		if(players[i])
-			players[i]->vote = 0;
+		if(m_apPlayers[i])
+		{
+			m_apPlayers[i]->m_Vote = 0;
+			m_apPlayers[i]->m_VotePos = 0;
+		}
 	}
 	
 	// start vote
-	vote_closetime = time_get() + time_freq()*25;
-	str_copy(vote_description, desc, sizeof(vote_description));
-	str_copy(vote_command, command, sizeof(vote_description));
-	send_vote_set(-1);
-	send_vote_status(-1);
+	m_VoteCloseTime = time_get() + time_freq()*25;
+	str_copy(m_aVoteDescription, pDesc, sizeof(m_aVoteDescription));
+	str_copy(m_aVoteCommand, pCommand, sizeof(m_aVoteCommand));
+	SendVoteSet(-1);
+	m_VoteUpdate = true;
 }
 
 
-void GAMECONTEXT::end_vote()
+void CGameContext::EndVote()
 {
-	vote_closetime = 0;
-	send_vote_set(-1);
+	m_VoteCloseTime = 0;
+	SendVoteSet(-1);
 }
 
-void GAMECONTEXT::send_vote_set(int cid)
+void CGameContext::SendVoteSet(int ClientId)
 {
-	NETMSG_SV_VOTE_SET msg;
-	if(vote_closetime)
+	CNetMsg_Sv_VoteSet Msg;
+	if(m_VoteCloseTime)
 	{
-		msg.timeout = (vote_closetime-time_get())/time_freq();
-		msg.description = vote_description;
-		msg.command = vote_command;
+		Msg.m_Timeout = (m_VoteCloseTime-time_get())/time_freq();
+		Msg.m_pDescription = m_aVoteDescription;
+		Msg.m_pCommand = "";
 	}
 	else
 	{
-		msg.timeout = 0;
-		msg.description = "";
-		msg.command = "";
+		Msg.m_Timeout = 0;
+		Msg.m_pDescription = "";
+		Msg.m_pCommand = "";
 	}
-	msg.pack(MSGFLAG_VITAL);
-	server_send_msg(cid);
+	Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientId);
 }
 
-void GAMECONTEXT::send_vote_status(int cid)
+void CGameContext::SendVoteStatus(int ClientId, int Total, int Yes, int No)
 {
-	NETMSG_SV_VOTE_STATUS msg = {0};
-	for(int i = 0; i < MAX_CLIENTS; i++)
+	CNetMsg_Sv_VoteStatus Msg = {0};
+	Msg.m_Total = Total;
+	Msg.m_Yes = Yes;
+	Msg.m_No = No;
+	Msg.m_Pass = Total - (Yes+No);
+
+	Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientId);
+	
+}
+
+void CGameContext::AbortVoteKickOnDisconnect(int ClientId)
+{
+	if(m_VoteCloseTime && !str_comp_num(m_aVoteCommand, "kick ", 5) && str_toint(&m_aVoteCommand[5]) == ClientId)
+		m_VoteCloseTime = -1;
+}
+
+
+void CGameContext::CheckPureTuning()
+{
+	// might not be created yet during start up
+	if(!m_pController)
+		return;
+	
+	if(	str_comp(m_pController->m_pGameType, "DM")==0 ||
+		str_comp(m_pController->m_pGameType, "TDM")==0 ||
+		str_comp(m_pController->m_pGameType, "CTF")==0)
 	{
-		if(players[i])
+		CTuningParams p;
+		if(mem_comp(&p, &m_Tuning, sizeof(p)) != 0)
 		{
-			msg.total++;
-			if(players[i]->vote > 0)
-				msg.yes++;
-			else if(players[i]->vote < 0)
-				msg.no++;
-			else
-				msg.pass++;
+			dbg_msg("server", "resetting tuning due to pure server");
+			m_Tuning = p;
 		}
 	}	
-
-	msg.pack(MSGFLAG_VITAL);
-	server_send_msg(cid);
-	
 }
 
-void GAMECONTEXT::abort_vote_kick_on_disconnect(int client_id)
+void CGameContext::SendTuningParams(int Cid)
 {
-	if(vote_closetime && !strncmp(vote_command, "kick ", 5) && atoi(&vote_command[5]) == client_id)
-		vote_closetime = -1;
+	CheckPureTuning();
+	
+	CMsgPacker Msg(NETMSGTYPE_SV_TUNEPARAMS);
+	int *pParams = (int *)&m_Tuning;
+	for(unsigned i = 0; i < sizeof(m_Tuning)/sizeof(int); i++)
+		Msg.AddInt(pParams[i]);
+	Server()->SendMsg(&Msg, MSGFLAG_VITAL, Cid);
 }
 
-void GAMECONTEXT::tick()
+void CGameContext::OnTick()
 {
-	world.core.tuning = tuning;
-	world.tick();
+	// check tuning
+	CheckPureTuning();
+
+	// copy tuning
+	m_World.m_Core.m_Tuning = m_Tuning;
+	m_World.Tick();
 
 	//if(world.paused) // make sure that the game object always updates
-	controller->tick();
+	m_pController->Tick();
 		
 	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
-		if(players[i])
-			players[i]->tick();
+		if(m_apPlayers[i])
+			m_apPlayers[i]->Tick();
 	}
 	
 	// update voting
-	if(vote_closetime)
+	if(m_VoteCloseTime)
 	{
 		// abort the kick-vote on player-leave
-		if(vote_closetime == -1)
+		if(m_VoteCloseTime == -1)
 		{
-			send_chat(-1, GAMECONTEXT::CHAT_ALL, "Vote aborted");
-			end_vote();
+			SendChat(-1, CGameContext::CHAT_ALL, "Vote aborted");
+			EndVote();
 		}
 		else
 		{
-			// count votes
-			int total = 0, yes = 0, no = 0;
-			for(int i = 0; i < MAX_CLIENTS; i++)
+			int Total = 0, Yes = 0, No = 0;
+			if(m_VoteUpdate)
 			{
-				if(players[i])
+				// count votes
+				char aaBuf[MAX_CLIENTS][64] = {{0}};
+				for(int i = 0; i < MAX_CLIENTS; i++)
+					if(m_apPlayers[i])
+						Server()->GetClientIP(i, aaBuf[i], 64);
+				bool aVoteChecked[MAX_CLIENTS] = {0};
+				for(int i = 0; i < MAX_CLIENTS; i++)
 				{
-					total++;
-					if(players[i]->vote > 0)
-						yes++;
-					else if(players[i]->vote < 0)
-						no++;
+					if(!m_apPlayers[i] || m_apPlayers[i]->GetTeam() == -1 || aVoteChecked[i])	// don't count in votes by spectators
+						continue;
+					
+					int ActVote = m_apPlayers[i]->m_Vote;
+					int ActVotePos = m_apPlayers[i]->m_VotePos;
+					
+					// check for more players with the same ip (only use the vote of the one who voted first)
+					for(int j = i+1; j < MAX_CLIENTS; ++j)
+					{
+						if(!m_apPlayers[j] || aVoteChecked[j] || str_comp(aaBuf[j], aaBuf[i]))
+							continue;
+
+						aVoteChecked[j] = true;
+						if(m_apPlayers[j]->m_Vote && (!ActVote || ActVotePos > m_apPlayers[j]->m_VotePos))
+						{
+							ActVote = m_apPlayers[j]->m_Vote;
+							ActVotePos = m_apPlayers[j]->m_VotePos;
+						}
+					}
+
+					Total++;
+					if(ActVote > 0)
+						Yes++;
+					else if(ActVote < 0)
+						No++;
 				}
+
+				if(Yes >= Total/2+1)
+					m_VoteEnforce = VOTE_ENFORCE_YES;
+				else if(No >= Total/2+1 || Yes+No == Total)
+					m_VoteEnforce = VOTE_ENFORCE_NO;
 			}
+			
+			if(m_VoteEnforce == VOTE_ENFORCE_YES)
+			{
+				Console()->ExecuteLine(m_aVoteCommand);
+				EndVote();
+				SendChat(-1, CGameContext::CHAT_ALL, "Vote passed");
+			
+				if(m_apPlayers[m_VoteCreator])
+					m_apPlayers[m_VoteCreator]->m_Last_VoteCall = 0;
+			}
+			else if(m_VoteEnforce == VOTE_ENFORCE_NO || time_get() > m_VoteCloseTime)
+			{
+				EndVote();
+				SendChat(-1, CGameContext::CHAT_ALL, "Vote failed");
+			}
+			else if(m_VoteUpdate)
+			{
+				m_VoteUpdate = false;
+				SendVoteStatus(-1, Total, Yes, No);
+			}
+		}
+	}
+	
+
+#ifdef CONF_DEBUG
+	if(g_Config.m_DbgDummies)
+	{
+		for(int i = 0; i < g_Config.m_DbgDummies ; i++)
+		{
+			CNetObj_PlayerInput Input = {0};
+			Input.m_Direction = (i&1)?-1:1;
+			m_apPlayers[MAX_CLIENTS-i-1]->OnPredictedInput(&Input);
+		}
+	}
+#endif	
+}
+
+// Server hooks
+void CGameContext::OnClientDirectInput(int ClientID, void *pInput)
+{
+	if(!m_World.m_Paused)
+		m_apPlayers[ClientID]->OnDirectInput((CNetObj_PlayerInput *)pInput);
+}
+
+void CGameContext::OnClientPredictedInput(int ClientID, void *pInput)
+{
+	if(!m_World.m_Paused)
+		m_apPlayers[ClientID]->OnPredictedInput((CNetObj_PlayerInput *)pInput);
+}
+
+void CGameContext::OnClientEnter(int ClientId)
+{
+	//world.insert_entity(&players[client_id]);
+	m_apPlayers[ClientId]->Respawn();
+	dbg_msg("game", "join player='%d:%s'", ClientId, Server()->ClientName(ClientId));
+
+
+	char aBuf[512];
+	str_format(aBuf, sizeof(aBuf), "%s entered and joined the %s", Server()->ClientName(ClientId), m_pController->GetTeamName(m_apPlayers[ClientId]->GetTeam()));
+	SendChat(-1, CGameContext::CHAT_ALL, aBuf); 
+
+	dbg_msg("game", "team_join player='%d:%s' team=%d", ClientId, Server()->ClientName(ClientId), m_apPlayers[ClientId]->GetTeam());
+
+	m_VoteUpdate = true;
+}
+
+void CGameContext::OnClientConnected(int ClientId)
+{
+	// Check which team the player should be on
+	const int StartTeam = g_Config.m_SvTournamentMode ? -1 : m_pController->GetAutoTeam(ClientId);
+
+	m_apPlayers[ClientId] = new(ClientId) CPlayer(this, ClientId, StartTeam);
+	//players[client_id].init(client_id);
+	//players[client_id].client_id = client_id;
+	
+	(void)m_pController->CheckTeamBalance();
+
+#ifdef CONF_DEBUG
+	if(g_Config.m_DbgDummies)
+	{
+		if(ClientId >= MAX_CLIENTS-g_Config.m_DbgDummies)
+			return;
+	}
+#endif
+
+	// send active vote
+	if(m_VoteCloseTime)
+		SendVoteSet(ClientId);
+
+	// send motd
+	CNetMsg_Sv_Motd Msg;
+	Msg.m_pMessage = g_Config.m_SvMotd;
+	Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientId);
+}
+
+void CGameContext::OnClientDrop(int ClientId)
+{
+	AbortVoteKickOnDisconnect(ClientId);
+	m_apPlayers[ClientId]->OnDisconnect();
+	delete m_apPlayers[ClientId];
+	m_apPlayers[ClientId] = 0;
+	
+	(void)m_pController->CheckTeamBalance();
+	m_VoteUpdate = true;
+}
+
+void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
+{
+	void *pRawMsg = m_NetObjHandler.SecureUnpackMsg(MsgId, pUnpacker);
+	CPlayer *p = m_apPlayers[ClientId];
+	
+	if(!pRawMsg)
+	{
+		dbg_msg("server", "dropped weird message '%s' (%d), failed on '%s'", m_NetObjHandler.GetMsgName(MsgId), MsgId, m_NetObjHandler.FailedMsgOn());
+		return;
+	}
+	
+	if(MsgId == NETMSGTYPE_CL_SAY)
+	{
+		CNetMsg_Cl_Say *pMsg = (CNetMsg_Cl_Say *)pRawMsg;
+		int Team = pMsg->m_Team;
+		if(Team)
+			Team = p->GetTeam();
+		else
+			Team = CGameContext::CHAT_ALL;
+		
+		if(g_Config.m_SvSpamprotection && p->m_Last_Chat && p->m_Last_Chat+Server()->TickSpeed() > Server()->Tick())
+			return;
+		
+		p->m_Last_Chat = Server()->Tick();
+
+		// check for invalid chars
+		unsigned char *pMessage = (unsigned char *)pMsg->m_pMessage;
+		while (*pMessage)
+		{
+			if(*pMessage < 32)
+				*pMessage = ' ';
+			pMessage++;
+		}
+		
+		SendChat(ClientId, Team, pMsg->m_pMessage);
+	}
+	else if(MsgId == NETMSGTYPE_CL_CALLVOTE)
+	{
+		if(g_Config.m_SvSpamprotection && p->m_Last_VoteTry && p->m_Last_VoteTry+Server()->TickSpeed()*3 > Server()->Tick())
+			return;
+
+		int64 Now = Server()->Tick();
+		p->m_Last_VoteTry = Now;
+		if(m_VoteCloseTime)
+		{
+			SendChatTarget(ClientId, "Wait for current vote to end before calling a new one.");
+			return;
+		}
 		
-			if(vote_enforce == VOTE_ENFORCE_YES || yes >= total/2+1)
+		int Timeleft = p->m_Last_VoteCall + Server()->TickSpeed()*60 - Now;
+		if(p->m_Last_VoteCall && Timeleft > 0)
+		{
+			char aChatmsg[512] = {0};
+			str_format(aChatmsg, sizeof(aChatmsg), "You must wait %d seconds before making another vote", (Timeleft/Server()->TickSpeed())+1);
+			SendChatTarget(ClientId, aChatmsg);
+			return;
+		}
+		
+		char aChatmsg[512] = {0};
+		char aDesc[512] = {0};
+		char aCmd[512] = {0};
+		CNetMsg_Cl_CallVote *pMsg = (CNetMsg_Cl_CallVote *)pRawMsg;
+		if(str_comp_nocase(pMsg->m_Type, "option") == 0)
+		{
+			CVoteOption *pOption = m_pVoteOptionFirst;
+			while(pOption)
 			{
-				console_execute_line(vote_command);
-				end_vote();
-				send_chat(-1, GAMECONTEXT::CHAT_ALL, "Vote passed");
+				if(str_comp_nocase(pMsg->m_Value, pOption->m_aCommand) == 0)
+				{
+					str_format(aChatmsg, sizeof(aChatmsg), "%s called vote to change server option '%s'", Server()->ClientName(ClientId), pOption->m_aCommand);
+					str_format(aDesc, sizeof(aDesc), "%s", pOption->m_aCommand);
+					str_format(aCmd, sizeof(aCmd), "%s", pOption->m_aCommand);
+					break;
+				}
+
+				pOption = pOption->m_pNext;
+			}
 			
-				if(players[vote_creator])
-					players[vote_creator]->last_votecall = 0;
+			if(!pOption)
+			{
+				str_format(aChatmsg, sizeof(aChatmsg), "'%s' isn't an option on this server", pMsg->m_Value);
+				SendChatTarget(ClientId, aChatmsg);
+				return;
 			}
-			else if(vote_enforce == VOTE_ENFORCE_NO || time_get() > vote_closetime || no >= total/2+1 || yes+no == total)
+		}
+		else if(str_comp_nocase(pMsg->m_Type, "kick") == 0)
+		{
+			if(!g_Config.m_SvVoteKick)
 			{
-				end_vote();
-				send_chat(-1, GAMECONTEXT::CHAT_ALL, "Vote failed");
+				SendChatTarget(ClientId, "Server does not allow voting to kick players");
+				return;
 			}
+			
+			int KickId = str_toint(pMsg->m_Value);
+			if(KickId < 0 || KickId >= MAX_CLIENTS || !m_apPlayers[KickId])
+			{
+				SendChatTarget(ClientId, "Invalid client id to kick");
+				return;
+			}
+			
+			str_format(aChatmsg, sizeof(aChatmsg), "%s called for vote to kick '%s'", Server()->ClientName(ClientId), Server()->ClientName(KickId));
+			str_format(aDesc, sizeof(aDesc), "Kick '%s'", Server()->ClientName(KickId));
+			if (!g_Config.m_SvVoteKickBantime)
+				str_format(aCmd, sizeof(aCmd), "kick %d", KickId);
+			else
+			{
+				char aBuf[64] = {0};
+				Server()->GetClientIP(KickId, aBuf, sizeof(aBuf));
+				str_format(aCmd, sizeof(aCmd), "ban %s %d", aBuf, g_Config.m_SvVoteKickBantime);
+			}
+		}
+		
+		if(aCmd[0])
+		{
+			SendChat(-1, CGameContext::CHAT_ALL, aChatmsg);
+			StartVote(aDesc, aCmd);
+			p->m_Vote = 1;
+			p->m_VotePos = m_VotePos = 1;
+			m_VoteCreator = ClientId;
+			p->m_Last_VoteCall = Now;
+		}
+	}
+	else if(MsgId == NETMSGTYPE_CL_VOTE)
+	{
+		if(!m_VoteCloseTime)
+			return;
+
+		if(p->m_Vote == 0)
+		{
+			CNetMsg_Cl_Vote *pMsg = (CNetMsg_Cl_Vote *)pRawMsg;
+			if(!pMsg->m_Vote)
+				return;
+
+			p->m_Vote = pMsg->m_Vote;
+			p->m_VotePos = ++m_VotePos;
+			m_VoteUpdate = true;
 		}
 	}
+	else if (MsgId == NETMSGTYPE_CL_SETTEAM && !m_World.m_Paused)
+	{
+		CNetMsg_Cl_SetTeam *pMsg = (CNetMsg_Cl_SetTeam *)pRawMsg;
+		
+		if(p->GetTeam() == pMsg->m_Team || (g_Config.m_SvSpamprotection && p->m_Last_SetTeam && p->m_Last_SetTeam+Server()->TickSpeed()*3 > Server()->Tick()))
+			return;
+
+		// Switch team on given client and kill/respawn him
+		if(m_pController->CanJoinTeam(pMsg->m_Team, ClientId))
+		{
+			if(m_pController->CanChangeTeam(p, pMsg->m_Team))
+			{
+				p->m_Last_SetTeam = Server()->Tick();
+				if(p->GetTeam() == -1 || pMsg->m_Team == -1)
+					m_VoteUpdate = true;
+				p->SetTeam(pMsg->m_Team);
+				(void)m_pController->CheckTeamBalance();
+			}
+			else
+				SendBroadcast("Teams must be balanced, please join other team", ClientId);
+		}
+		else
+		{
+			char aBuf[128];
+			str_format(aBuf, sizeof(aBuf), "Only %d active players are allowed", g_Config.m_SvMaxClients-g_Config.m_SvSpectatorSlots);
+			SendBroadcast(aBuf, ClientId);
+		}
+	}
+	else if (MsgId == NETMSGTYPE_CL_CHANGEINFO || MsgId == NETMSGTYPE_CL_STARTINFO)
+	{
+		CNetMsg_Cl_ChangeInfo *pMsg = (CNetMsg_Cl_ChangeInfo *)pRawMsg;
+		
+		if(g_Config.m_SvSpamprotection && p->m_Last_ChangeInfo && p->m_Last_ChangeInfo+Server()->TickSpeed()*5 > Server()->Tick())
+			return;
+			
+		p->m_Last_ChangeInfo = Server()->Tick();
+		
+		p->m_TeeInfos.m_UseCustomColor = pMsg->m_UseCustomColor;
+		p->m_TeeInfos.m_ColorBody = pMsg->m_ColorBody;
+		p->m_TeeInfos.m_ColorFeet = pMsg->m_ColorFeet;
+
+		// check for invalid chars
+		unsigned char *pName = (unsigned char *)pMsg->m_pName;
+		while (*pName)
+		{
+			if(*pName < 32)
+				*pName = ' ';
+			pName++;
+		}
+
+		// copy old name
+		char aOldName[MAX_NAME_LENGTH];
+		str_copy(aOldName, Server()->ClientName(ClientId), MAX_NAME_LENGTH);
+		
+		Server()->SetClientName(ClientId, pMsg->m_pName);
+		if(MsgId == NETMSGTYPE_CL_CHANGEINFO && str_comp(aOldName, Server()->ClientName(ClientId)) != 0)
+		{
+			char aChatText[256];
+			str_format(aChatText, sizeof(aChatText), "%s changed name to %s", aOldName, Server()->ClientName(ClientId));
+			SendChat(-1, CGameContext::CHAT_ALL, aChatText);
+		}
+		
+		// set skin
+		str_copy(p->m_TeeInfos.m_SkinName, pMsg->m_pSkin, sizeof(p->m_TeeInfos.m_SkinName));
+		
+		m_pController->OnPlayerInfoChange(p);
+		
+		if(MsgId == NETMSGTYPE_CL_STARTINFO)
+		{
+			// send vote options
+			CNetMsg_Sv_VoteClearOptions ClearMsg;
+			Server()->SendPackMsg(&ClearMsg, MSGFLAG_VITAL, ClientId);
+			CVoteOption *pCurrent = m_pVoteOptionFirst;
+			while(pCurrent)
+			{
+				CNetMsg_Sv_VoteOption OptionMsg;
+				OptionMsg.m_pCommand = pCurrent->m_aCommand;
+				Server()->SendPackMsg(&OptionMsg, MSGFLAG_VITAL, ClientId);
+				pCurrent = pCurrent->m_pNext;
+			}
+			
+			// send tuning parameters to client
+			SendTuningParams(ClientId);
+
+			//
+			CNetMsg_Sv_ReadyToEnter m;
+			Server()->SendPackMsg(&m, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientId);
+		}
+	}
+	else if (MsgId == NETMSGTYPE_CL_EMOTICON && !m_World.m_Paused)
+	{
+		CNetMsg_Cl_Emoticon *pMsg = (CNetMsg_Cl_Emoticon *)pRawMsg;
+		
+		if(g_Config.m_SvSpamprotection && p->m_Last_Emote && p->m_Last_Emote+Server()->TickSpeed()*3 > Server()->Tick())
+			return;
+			
+		p->m_Last_Emote = Server()->Tick();
+		
+		SendEmoticon(ClientId, pMsg->m_Emoticon);
+	}
+	else if (MsgId == NETMSGTYPE_CL_KILL && !m_World.m_Paused)
+	{
+		if(p->m_Last_Kill && p->m_Last_Kill+Server()->TickSpeed()*3 > Server()->Tick())
+			return;
+		
+		p->m_Last_Kill = Server()->Tick();
+		p->KillCharacter(WEAPON_SELF);
+		p->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()*3;
+	}
+}
+
+void CGameContext::ConTuneParam(IConsole::IResult *pResult, void *pUserData)
+{
+	CGameContext *pSelf = (CGameContext *)pUserData;
+	const char *pParamName = pResult->GetString(0);
+	float NewValue = pResult->GetFloat(1);
+
+	if(pSelf->Tuning()->Set(pParamName, NewValue))
+	{
+		dbg_msg("tuning", "%s changed to %.2f", pParamName, NewValue);
+		pSelf->SendTuningParams(-1);
+	}
+	else
+		dbg_msg("tuning", "No such tuning parameter");
+}
+
+void CGameContext::ConTuneReset(IConsole::IResult *pResult, void *pUserData)
+{
+	CGameContext *pSelf = (CGameContext *)pUserData;
+	CTuningParams p;
+	*pSelf->Tuning() = p;
+	pSelf->SendTuningParams(-1);
+	dbg_msg("tuning", "Tuning reset");
+}
+
+void CGameContext::ConTuneDump(IConsole::IResult *pResult, void *pUserData)
+{
+	CGameContext *pSelf = (CGameContext *)pUserData;
+	for(int i = 0; i < pSelf->Tuning()->Num(); i++)
+	{
+		float v;
+		pSelf->Tuning()->Get(i, &v);
+		dbg_msg("tuning", "%s %.2f", pSelf->Tuning()->m_apNames[i], v);
+	}
+}
+
+void CGameContext::ConChangeMap(IConsole::IResult *pResult, void *pUserData)
+{
+	CGameContext *pSelf = (CGameContext *)pUserData;
+	pSelf->m_pController->ChangeMap(pResult->GetString(0));
+}
+
+void CGameContext::ConRestart(IConsole::IResult *pResult, void *pUserData)
+{
+	CGameContext *pSelf = (CGameContext *)pUserData;
+	if(pResult->NumArguments())
+		pSelf->m_pController->DoWarmup(pResult->GetInteger(0));
+	else
+		pSelf->m_pController->StartRound();
+}
+
+void CGameContext::ConBroadcast(IConsole::IResult *pResult, void *pUserData)
+{
+	CGameContext *pSelf = (CGameContext *)pUserData;
+	pSelf->SendBroadcast(pResult->GetString(0), -1);
+}
+
+void CGameContext::ConSay(IConsole::IResult *pResult, void *pUserData)
+{
+	CGameContext *pSelf = (CGameContext *)pUserData;
+	pSelf->SendChat(-1, CGameContext::CHAT_ALL, pResult->GetString(0));
+}
+
+void CGameContext::ConSetTeam(IConsole::IResult *pResult, void *pUserData)
+{
+	CGameContext *pSelf = (CGameContext *)pUserData;
+	int ClientId = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
+	int Team = clamp(pResult->GetInteger(1), -1, 1);
+	
+	dbg_msg("", "%d %d", ClientId, Team);
+	
+	if(!pSelf->m_apPlayers[ClientId])
+		return;
+	
+	pSelf->m_apPlayers[ClientId]->SetTeam(Team);
+	(void)pSelf->m_pController->CheckTeamBalance();
+}
+
+void CGameContext::ConAddVote(IConsole::IResult *pResult, void *pUserData)
+{
+	CGameContext *pSelf = (CGameContext *)pUserData;
+	int Len = str_length(pResult->GetString(0));
+	
+	CGameContext::CVoteOption *pOption = (CGameContext::CVoteOption *)pSelf->m_pVoteOptionHeap->Allocate(sizeof(CGameContext::CVoteOption) + Len);
+	pOption->m_pNext = 0;
+	pOption->m_pPrev = pSelf->m_pVoteOptionLast;
+	if(pOption->m_pPrev)
+		pOption->m_pPrev->m_pNext = pOption;
+	pSelf->m_pVoteOptionLast = pOption;
+	if(!pSelf->m_pVoteOptionFirst)
+		pSelf->m_pVoteOptionFirst = pOption;
+	
+	mem_copy(pOption->m_aCommand, pResult->GetString(0), Len+1);
+	dbg_msg("server", "added option '%s'", pOption->m_aCommand);
+
+	CNetMsg_Sv_VoteOption OptionMsg;
+	OptionMsg.m_pCommand = pOption->m_aCommand;
+	pSelf->Server()->SendPackMsg(&OptionMsg, MSGFLAG_VITAL, -1);
+}
+
+void CGameContext::ConVote(IConsole::IResult *pResult, void *pUserData)
+{
+	CGameContext *pSelf = (CGameContext *)pUserData;
+	if(str_comp_nocase(pResult->GetString(0), "yes") == 0)
+		pSelf->m_VoteEnforce = CGameContext::VOTE_ENFORCE_YES;
+	else if(str_comp_nocase(pResult->GetString(0), "no") == 0)
+		pSelf->m_VoteEnforce = CGameContext::VOTE_ENFORCE_NO;
+	dbg_msg("server", "forcing vote %s", pResult->GetString(0));
+}
+
+void CGameContext::ConchainSpecialMotdupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
+{
+	pfnCallback(pResult, pCallbackUserData);
+	if(pResult->NumArguments())
+	{
+		CNetMsg_Sv_Motd Msg;
+		Msg.m_pMessage = g_Config.m_SvMotd;
+		CGameContext *pSelf = (CGameContext *)pUserData;
+		for(int i = 0; i < MAX_CLIENTS; ++i)
+			if(pSelf->m_apPlayers[i])
+				pSelf->Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, i);
+	}
+}
+
+void CGameContext::OnConsoleInit()
+{
+	m_pServer = Kernel()->RequestInterface<IServer>();
+	m_pConsole = Kernel()->RequestInterface<IConsole>();
+
+	Console()->Register("tune", "si", CFGFLAG_SERVER, ConTuneParam, this, "");
+	Console()->Register("tune_reset", "", CFGFLAG_SERVER, ConTuneReset, this, "");
+	Console()->Register("tune_dump", "", CFGFLAG_SERVER, ConTuneDump, this, "");
+
+	Console()->Register("change_map", "r", CFGFLAG_SERVER, ConChangeMap, this, "");
+	Console()->Register("restart", "?i", CFGFLAG_SERVER, ConRestart, this, "");
+	Console()->Register("broadcast", "r", CFGFLAG_SERVER, ConBroadcast, this, "");
+	Console()->Register("say", "r", CFGFLAG_SERVER, ConSay, this, "");
+	Console()->Register("set_team", "ii", CFGFLAG_SERVER, ConSetTeam, this, "");
+
+	Console()->Register("addvote", "r", CFGFLAG_SERVER, ConAddVote, this, "");
+	Console()->Register("vote", "r", CFGFLAG_SERVER, ConVote, this, "");
+
+	Console()->Chain("sv_motd", ConchainSpecialMotdupdate, this);
+}
+
+void CGameContext::OnInit(/*class IKernel *pKernel*/)
+{
+	m_pServer = Kernel()->RequestInterface<IServer>();
+	m_pConsole = Kernel()->RequestInterface<IConsole>();
+	m_World.SetGameServer(this);
+	m_Events.SetGameServer(this);
+	
+	//if(!data) // only load once
+		//data = load_data_from_memory(internal_data);
+		
+	for(int i = 0; i < NUM_NETOBJTYPES; i++)
+		Server()->SnapSetStaticsize(i, m_NetObjHandler.GetObjSize(i));
+
+	m_Layers.Init(Kernel());
+	m_Collision.Init(&m_Layers);
+
+	// reset everything here
+	//world = new GAMEWORLD;
+	//players = new CPlayer[MAX_CLIENTS];
+
+	// select gametype
+	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);
+	else if(str_comp(g_Config.m_SvGametype, "tdm") == 0)
+		m_pController = new CGameControllerTDM(this);
+	else
+		m_pController = new CGameControllerDM(this);
+
+	// setup core world
+	//for(int i = 0; i < MAX_CLIENTS; i++)
+	//	game.players[i].core.world = &game.world.core;
+
+	// create all entities from the game layer
+	CMapItemLayerTilemap *pTileMap = m_Layers.GameLayer();
+	CTile *pTiles = (CTile *)Kernel()->RequestInterface<IMap>()->GetData(pTileMap->m_Data);
+	
+	
+	
+	
+	/*
+	num_spawn_points[0] = 0;
+	num_spawn_points[1] = 0;
+	num_spawn_points[2] = 0;
+	*/
+	
+	for(int y = 0; y < pTileMap->m_Height; y++)
+	{
+		for(int x = 0; x < pTileMap->m_Width; x++)
+		{
+			int Index = pTiles[y*pTileMap->m_Width+x].m_Index;
+			
+			if(Index >= ENTITY_OFFSET)
+			{
+				vec2 Pos(x*32.0f+16.0f, y*32.0f+16.0f);
+				m_pController->OnEntity(Index-ENTITY_OFFSET, Pos);
+			}
+		}
+	}
+
+	//game.world.insert_entity(game.Controller);
+
+#ifdef CONF_DEBUG
+	if(g_Config.m_DbgDummies)
+	{
+		for(int i = 0; i < g_Config.m_DbgDummies ; i++)
+		{
+			OnClientConnected(MAX_CLIENTS-i-1);
+		}
+	}
+#endif
+}
+
+void CGameContext::OnShutdown()
+{
+	delete m_pController;
+	m_pController = 0;
+	Clear();
 }
 
-void GAMECONTEXT::snap(int client_id)
+void CGameContext::OnSnap(int ClientId)
 {
-	world.snap(client_id);
-	controller->snap(client_id);
-	events.snap(client_id);
+	m_World.Snap(ClientId);
+	m_pController->Snap(ClientId);
+	m_Events.Snap(ClientId);
 	
 	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
-		if(players[i])
-			players[i]->snap(client_id);
+		if(m_apPlayers[i])
+			m_apPlayers[i]->Snap(ClientId);
 	}
 }
+void CGameContext::OnPreSnap() {}
+void CGameContext::OnPostSnap()
+{
+	m_Events.Clear();
+}
+
+const char *CGameContext::Version() { return GAME_VERSION; }
+const char *CGameContext::NetVersion() { return GAME_NETVERSION; }
+
+IGameServer *CreateGameServer() { return new CGameContext; }
diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h
new file mode 100644
index 00000000..d55203e7
--- /dev/null
+++ b/src/game/server/gamecontext.h
@@ -0,0 +1,168 @@
+#ifndef GAME_SERVER_GAMECONTEXT_H
+#define GAME_SERVER_GAMECONTEXT_H
+
+#include <engine/server.h>
+#include <engine/console.h>
+#include <engine/shared/memheap.h>
+
+#include <game/layers.h>
+
+#include "eventhandler.h"
+#include "gamecontroller.h"
+#include "gameworld.h"
+#include "player.h"
+
+/*
+	Tick
+		Game Context (CGameContext::tick)
+			Game World (GAMEWORLD::tick)
+				Reset world if requested (GAMEWORLD::reset)
+				All entities in the world (ENTITY::tick)
+				All entities in the world (ENTITY::tick_defered)
+				Remove entities marked for deletion (GAMEWORLD::remove_entities)
+			Game Controller (GAMECONTROLLER::tick)
+			All players (CPlayer::tick)
+			
+
+	Snap
+		Game Context (CGameContext::snap)
+			Game World (GAMEWORLD::snap)
+				All entities in the world (ENTITY::snap)
+			Game Controller (GAMECONTROLLER::snap)
+			Events handler (EVENT_HANDLER::snap)
+			All players (CPlayer::snap)
+
+*/
+class CGameContext : public IGameServer
+{
+	IServer *m_pServer;
+	class IConsole *m_pConsole;
+	CLayers m_Layers;
+	CCollision m_Collision;
+	CNetObjHandler m_NetObjHandler;
+	CTuningParams m_Tuning;
+
+	static void ConTuneParam(IConsole::IResult *pResult, void *pUserData);
+	static void ConTuneReset(IConsole::IResult *pResult, void *pUserData);
+	static void ConTuneDump(IConsole::IResult *pResult, void *pUserData);
+	static void ConChangeMap(IConsole::IResult *pResult, void *pUserData);
+	static void ConRestart(IConsole::IResult *pResult, void *pUserData);
+	static void ConBroadcast(IConsole::IResult *pResult, void *pUserData);
+	static void ConSay(IConsole::IResult *pResult, void *pUserData);
+	static void ConSetTeam(IConsole::IResult *pResult, void *pUserData);
+	static void ConAddVote(IConsole::IResult *pResult, void *pUserData);
+	static void ConVote(IConsole::IResult *pResult, void *pUserData);
+	static void ConchainSpecialMotdupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
+	
+	CGameContext(int Resetting);
+	void Construct(int Resetting);
+
+	bool m_Resetting;
+public:
+	IServer *Server() const { return m_pServer; }
+	class IConsole *Console() { return m_pConsole; }
+	CCollision *Collision() { return &m_Collision; }
+	CTuningParams *Tuning() { return &m_Tuning; }
+
+	CGameContext();
+	~CGameContext();
+	
+	void Clear();
+	
+	CEventHandler m_Events;
+	CPlayer *m_apPlayers[MAX_CLIENTS];
+
+	IGameController *m_pController;
+	CGameWorld m_World;
+	
+	// helper functions
+	class CCharacter *GetPlayerChar(int ClientId);
+	
+	// voting
+	void StartVote(const char *pDesc, const char *pCommand);
+	void EndVote();
+	void SendVoteSet(int ClientId);
+	void SendVoteStatus(int ClientId, int Total, int Yes, int No);
+	void AbortVoteKickOnDisconnect(int ClientId);
+	
+	int m_VoteCreator;
+	int64 m_VoteCloseTime;
+	bool m_VoteUpdate;
+	int m_VotePos;
+	char m_aVoteDescription[512];
+	char m_aVoteCommand[512];
+	int m_VoteEnforce;
+	enum
+	{
+		VOTE_ENFORCE_UNKNOWN=0,
+		VOTE_ENFORCE_NO,
+		VOTE_ENFORCE_YES,
+	};
+	struct CVoteOption
+	{
+		CVoteOption *m_pNext;
+		CVoteOption *m_pPrev;
+		char m_aCommand[1];
+	};
+	CHeap *m_pVoteOptionHeap;
+	CVoteOption *m_pVoteOptionFirst;
+	CVoteOption *m_pVoteOptionLast;
+
+	// helper functions
+	void CreateDamageInd(vec2 Pos, float AngleMod, int Amount);
+	void CreateExplosion(vec2 Pos, int Owner, int Weapon, bool NoDamage);
+	void CreateSmoke(vec2 Pos);
+	void CreateHammerHit(vec2 Pos);
+	void CreatePlayerSpawn(vec2 Pos);
+	void CreateDeath(vec2 Pos, int Who);
+	void CreateSound(vec2 Pos, int Sound, int Mask=-1);
+	void CreateSoundGlobal(int Sound, int Target=-1);	
+
+
+	enum
+	{
+		CHAT_ALL=-2,
+		CHAT_SPEC=-1,
+		CHAT_RED=0,
+		CHAT_BLUE=1
+	};
+
+	// network
+	void SendChatTarget(int To, const char *pText);
+	void SendChat(int ClientId, int Team, const char *pText);
+	void SendEmoticon(int ClientId, int Emoticon);
+	void SendWeaponPickup(int ClientId, int Weapon);
+	void SendBroadcast(const char *pText, int ClientId);
+	
+	
+	//
+	void CheckPureTuning();
+	void SendTuningParams(int ClientId);
+	
+	// engine events
+	virtual void OnInit();
+	virtual void OnConsoleInit();
+	virtual void OnShutdown();
+	
+	virtual void OnTick();
+	virtual void OnPreSnap();
+	virtual void OnSnap(int ClientId);
+	virtual void OnPostSnap();
+	
+	virtual void OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId);
+
+	virtual void OnClientConnected(int ClientId);
+	virtual void OnClientEnter(int ClientId);
+	virtual void OnClientDrop(int ClientId);
+	virtual void OnClientDirectInput(int ClientId, void *pInput);
+	virtual void OnClientPredictedInput(int ClientId, void *pInput);
+
+	virtual const char *Version();
+	virtual const char *NetVersion();
+};
+
+inline int CmaskAll() { return -1; }
+inline int CmaskOne(int ClientId) { return 1<<ClientId; }
+inline int CmaskAllExceptOne(int ClientId) { return 0x7fffffff^CmaskOne(ClientId); }
+inline bool CmaskIsSet(int Mask, int ClientId) { return (Mask&CmaskOne(ClientId)) != 0; }
+#endif
diff --git a/src/game/server/gamecontext.hpp b/src/game/server/gamecontext.hpp
deleted file mode 100644
index bea087cb..00000000
--- a/src/game/server/gamecontext.hpp
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef GAME_SERVER_GAMECONTEXT_H
-#define GAME_SERVER_GAMECONTEXT_H
-
-#include "eventhandler.hpp"
-#include "gamecontroller.hpp"
-#include "gameworld.hpp"
-#include "player.hpp"
-
-/*
-	Tick
-		Game Context (GAMECONTEXT::tick)
-			Game World (GAMEWORLD::tick)
-				Reset world if requested (GAMEWORLD::reset)
-				All entities in the world (ENTITY::tick)
-				All entities in the world (ENTITY::tick_defered)
-				Remove entities marked for deletion (GAMEWORLD::remove_entities)
-			Game Controller (GAMECONTROLLER::tick)
-			All players (PLAYER::tick)
-			
-
-	Snap
-		Game Context (GAMECONTEXT::snap)
-			Game World (GAMEWORLD::snap)
-				All entities in the world (ENTITY::snap)
-			Game Controller (GAMECONTROLLER::snap)
-			Events handler (EVENT_HANDLER::snap)
-			All players (PLAYER::snap)
-
-*/
-class GAMECONTEXT
-{
-public:
-	GAMECONTEXT();
-	~GAMECONTEXT();
-	
-	void clear();
-	
-	EVENTHANDLER events;
-	PLAYER *players[MAX_CLIENTS];
-	
-	GAMECONTROLLER *controller;
-	GAMEWORLD world;
-
-	void tick();
-	void snap(int client_id);
-	
-	// helper functions
-	class CHARACTER *get_player_char(int client_id);
-	
-	// voting
-	void start_vote(const char *desc, const char *command);
-	void end_vote();
-	void send_vote_set(int cid);
-	void send_vote_status(int cid);
-	void abort_vote_kick_on_disconnect(int client_id);
-	int vote_creator;
-	int64 vote_closetime;
-	char vote_description[512];
-	char vote_command[512];
-	int vote_enforce;
-	enum
-	{
-		VOTE_ENFORCE_UNKNOWN=0,
-		VOTE_ENFORCE_NO,
-		VOTE_ENFORCE_YES,
-	};
-
-	// helper functions
-	void create_damageind(vec2 p, float angle_mod, int amount);
-	void create_explosion(vec2 p, int owner, int weapon, bool bnodamage);
-	void create_smoke(vec2 p);
-	void create_hammerhit(vec2 p);
-	void create_playerspawn(vec2 p);
-	void create_death(vec2 p, int who);
-	void create_sound(vec2 pos, int sound, int mask=-1);
-	void create_sound_global(int sound, int target=-1);	
-
-
-	enum
-	{
-		CHAT_ALL=-2,
-		CHAT_SPEC=-1,
-		CHAT_RED=0,
-		CHAT_BLUE=1
-	};
-
-	// network
-	void send_chat_target(int to, const char *text);
-	void send_chat(int cid, int team, const char *text);
-	void send_emoticon(int cid, int emoticon);
-	void send_weapon_pickup(int cid, int weapon);
-	void send_broadcast(const char *text, int cid);
-
-};
-
-extern GAMECONTEXT game;
-
-// MISC stuff, move to a better place later on
-
-extern TUNING_PARAMS tuning;
-inline int cmask_all() { return -1; }
-inline int cmask_one(int cid) { return 1<<cid; }
-inline int cmask_all_except_one(int cid) { return 0x7fffffff^cmask_one(cid); }
-inline bool cmask_is_set(int mask, int cid) { return (mask&cmask_one(cid)) != 0; }
-#endif
diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp
index cdbace8e..a822f7ca 100644
--- a/src/game/server/gamecontroller.cpp
+++ b/src/game/server/gamecontroller.cpp
@@ -1,607 +1,614 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-#include <string.h>
-#include <engine/e_config.h>
-#include <engine/e_server_interface.h>
-#include <game/mapitems.hpp>
+// copyright (c) 2007 magnus auvinen, see licence.txt for more info
+#include <engine/shared/config.h>
+#include <game/mapitems.h>
 
-#include <game/generated/g_protocol.hpp>
+#include <game/generated/protocol.h>
 
-#include "entities/pickup.hpp"
-#include "gamecontroller.hpp"
-#include "gamecontext.hpp"
+#include "entities/pickup.h"
+#include "gamecontroller.h"
+#include "gamecontext.h"
 
 
-
-GAMECONTROLLER::GAMECONTROLLER()
+IGameController::IGameController(class CGameContext *pGameServer)
 {
-	gametype = "unknown";
+	m_pGameServer = pGameServer;
+	m_pServer = m_pGameServer->Server();
+	m_pGameType = "unknown";
 	
 	//
-	do_warmup(config.sv_warmup);
-	game_over_tick = -1;
-	sudden_death = 0;
-	round_start_tick = server_tick();
-	round_count = 0;
-	game_flags = 0;
-	teamscore[0] = 0;
-	teamscore[1] = 0;
-	map_wish[0] = 0;
-	
-	unbalanced_tick = -1;
-	force_balanced = false;
-	
-	num_spawn_points[0] = 0;
-	num_spawn_points[1] = 0;
-	num_spawn_points[2] = 0;
+	DoWarmup(g_Config.m_SvWarmup);
+	m_GameOverTick = -1;
+	m_SuddenDeath = 0;
+	m_RoundStartTick = Server()->Tick();
+	m_RoundCount = 0;
+	m_GameFlags = 0;
+	m_aTeamscore[0] = 0;
+	m_aTeamscore[1] = 0;
+	m_aMapWish[0] = 0;
+	
+	m_UnbalancedTick = -1;
+	m_ForceBalanced = false;
+	
+	m_aNumSpawnPoints[0] = 0;
+	m_aNumSpawnPoints[1] = 0;
+	m_aNumSpawnPoints[2] = 0;
 }
 
-GAMECONTROLLER::~GAMECONTROLLER()
+IGameController::~IGameController()
 {
 }
 
-float GAMECONTROLLER::evaluate_spawn_pos(SPAWNEVAL *eval, vec2 pos)
+float IGameController::EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos)
 {
-	float score = 0.0f;
-	CHARACTER *c = (CHARACTER *)game.world.find_first(NETOBJTYPE_CHARACTER);
-	for(; c; c = (CHARACTER *)c->typenext())
+	float Score = 0.0f;
+	CCharacter *pC = static_cast<CCharacter *>(GameServer()->m_World.FindFirst(NETOBJTYPE_CHARACTER));
+	for(; pC; pC = (CCharacter *)pC->TypeNext())
 	{
 		// team mates are not as dangerous as enemies
-		float scoremod = 1.0f;
-		if(eval->friendly_team != -1 && c->team == eval->friendly_team)
-			scoremod = 0.5f;
+		float Scoremod = 1.0f;
+		if(pEval->m_FriendlyTeam != -1 && pC->GetPlayer()->GetTeam() == pEval->m_FriendlyTeam)
+			Scoremod = 0.5f;
 			
-		float d = distance(pos, c->pos);
+		float d = distance(Pos, pC->m_Pos);
 		if(d == 0)
-			score += 1000000000.0f;
+			Score += 1000000000.0f;
 		else
-			score += 1.0f/d;
+			Score += 1.0f/d;
 	}
 	
-	return score;
+	return Score;
 }
 
-void GAMECONTROLLER::evaluate_spawn_type(SPAWNEVAL *eval, int t)
+void IGameController::EvaluateSpawnType(CSpawnEval *pEval, int T)
 {
 	// get spawn point
-	for(int i  = 0; i < num_spawn_points[t]; i++)
+	for(int i  = 0; i < m_aNumSpawnPoints[T]; i++)
 	{
-		vec2 p = spawn_points[t][i];
-		float s = evaluate_spawn_pos(eval, p);
-		if(!eval->got || eval->score > s)
+		vec2 P = m_aaSpawnPoints[T][i];
+		float S = EvaluateSpawnPos(pEval, P);
+		if(!pEval->m_Got || pEval->m_Score > S)
 		{
-			eval->got = true;
-			eval->score = s;
-			eval->pos = p;
+			pEval->m_Got = true;
+			pEval->m_Score = S;
+			pEval->m_Pos = P;
 		}
 	}
 }
 
-bool GAMECONTROLLER::can_spawn(PLAYER *player, vec2 *out_pos)
+bool IGameController::CanSpawn(CPlayer *pPlayer, vec2 *pOutPos)
 {
-	SPAWNEVAL eval;
+	CSpawnEval Eval;
 	
 	// spectators can't spawn
-	if(player->team == -1)
+	if(pPlayer->GetTeam() == -1)
 		return false;
 	
-	if(is_teamplay())
+	if(IsTeamplay())
 	{
-		eval.friendly_team = player->team;
+		Eval.m_FriendlyTeam = pPlayer->GetTeam();
 		
 		// try first try own team spawn, then normal spawn and then enemy
-		evaluate_spawn_type(&eval, 1+(player->team&1));
-		if(!eval.got)
+		EvaluateSpawnType(&Eval, 1+(pPlayer->GetTeam()&1));
+		if(!Eval.m_Got)
 		{
-			evaluate_spawn_type(&eval, 0);
-			if(!eval.got)
-				evaluate_spawn_type(&eval, 1+((player->team+1)&1));
+			EvaluateSpawnType(&Eval, 0);
+			if(!Eval.m_Got)
+				EvaluateSpawnType(&Eval, 1+((pPlayer->GetTeam()+1)&1));
 		}
 	}
 	else
 	{
-		evaluate_spawn_type(&eval, 0);
-		evaluate_spawn_type(&eval, 1);
-		evaluate_spawn_type(&eval, 2);
+		EvaluateSpawnType(&Eval, 0);
+		EvaluateSpawnType(&Eval, 1);
+		EvaluateSpawnType(&Eval, 2);
 	}
 	
-	*out_pos = eval.pos;
-	return eval.got;
+	*pOutPos = Eval.m_Pos;
+	return Eval.m_Got;
 }
 
 
-bool GAMECONTROLLER::on_entity(int index, vec2 pos)
+bool IGameController::OnEntity(int Index, vec2 Pos)
 {
-	int type = -1;
-	int subtype = 0;
+	int Type = -1;
+	int SubType = 0;
 	
-	if(index == ENTITY_SPAWN)
-		spawn_points[0][num_spawn_points[0]++] = pos;
-	else if(index == ENTITY_SPAWN_RED)
-		spawn_points[1][num_spawn_points[1]++] = pos;
-	else if(index == ENTITY_SPAWN_BLUE)
-		spawn_points[2][num_spawn_points[2]++] = pos;
-	else if(index == ENTITY_ARMOR_1)
-		type = POWERUP_ARMOR;
-	else if(index == ENTITY_HEALTH_1)
-		type = POWERUP_HEALTH;
-	else if(index == ENTITY_WEAPON_SHOTGUN)
+	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;
+	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;
+		Type = POWERUP_WEAPON;
+		SubType = WEAPON_SHOTGUN;
 	}
-	else if(index == ENTITY_WEAPON_GRENADE)
+	else if(Index == ENTITY_WEAPON_GRENADE)
 	{
-		type = POWERUP_WEAPON;
-		subtype = WEAPON_GRENADE;
+		Type = POWERUP_WEAPON;
+		SubType = WEAPON_GRENADE;
 	}
-	else if(index == ENTITY_WEAPON_RIFLE)
+	else if(Index == ENTITY_WEAPON_RIFLE)
 	{
-		type = POWERUP_WEAPON;
-		subtype = WEAPON_RIFLE;
+		Type = POWERUP_WEAPON;
+		SubType = WEAPON_RIFLE;
 	}
-	else if(index == ENTITY_POWERUP_NINJA && config.sv_powerups)
+	else if(Index == ENTITY_POWERUP_NINJA && g_Config.m_SvPowerups)
 	{
-		type = POWERUP_NINJA;
-		subtype = WEAPON_NINJA;
+		Type = POWERUP_NINJA;
+		SubType = WEAPON_NINJA;
 	}
 	
-	if(type != -1)
+	if(Type != -1)
 	{
-		PICKUP *pickup = new PICKUP(type, subtype);
-		pickup->pos = pos;
+		CPickup *pPickup = new CPickup(&GameServer()->m_World, Type, SubType);
+		pPickup->m_Pos = Pos;
 		return true;
 	}
 
 	return false;
 }
 
-void GAMECONTROLLER::endround()
+void IGameController::EndRound()
 {
-	if(warmup) // game can't end when we are running warmup
+	if(m_Warmup) // game can't end when we are running warmup
 		return;
 		
-	game.world.paused = true;
-	game_over_tick = server_tick();
-	sudden_death = 0;
+	GameServer()->m_World.m_Paused = true;
+	m_GameOverTick = Server()->Tick();
+	m_SuddenDeath = 0;
 }
 
-void GAMECONTROLLER::resetgame()
+void IGameController::ResetGame()
 {
-	game.world.reset_requested = true;
+	GameServer()->m_World.m_ResetRequested = true;
 }
 
-const char *GAMECONTROLLER::get_team_name(int team)
+const char *IGameController::GetTeamName(int Team)
 {
-	if(is_teamplay())
+	if(IsTeamplay())
 	{
-		if(team == 0)
+		if(Team == 0)
 			return "red team";
-		else if(team == 1)
+		else if(Team == 1)
 			return "blue team";
 	}
 	else
 	{
-		if(team == 0)
+		if(Team == 0)
 			return "game";
 	}
 	
 	return "spectators";
 }
 
-static bool is_separator(char c) { return c == ';' || c == ' ' || c == ',' || c == '\t'; }
+static bool IsSeparator(char c) { return c == ';' || c == ' ' || c == ',' || c == '\t'; }
 
-void GAMECONTROLLER::startround()
+void IGameController::StartRound()
 {
-	resetgame();
-	
-	round_start_tick = server_tick();
-	sudden_death = 0;
-	game_over_tick = -1;
-	game.world.paused = false;
-	teamscore[0] = 0;
-	teamscore[1] = 0;
-	unbalanced_tick = -1;
-	force_balanced = false;
-	dbg_msg("game","start round type='%s' teamplay='%d'", gametype, game_flags&GAMEFLAG_TEAMS);
+	ResetGame();
+	
+	m_RoundStartTick = Server()->Tick();
+	m_SuddenDeath = 0;
+	m_GameOverTick = -1;
+	GameServer()->m_World.m_Paused = false;
+	m_aTeamscore[0] = 0;
+	m_aTeamscore[1] = 0;
+	m_ForceBalanced = false;
+	dbg_msg("game","start round type='%s' teamplay='%d'", m_pGameType, m_GameFlags&GAMEFLAG_TEAMS);
 }
 
-void GAMECONTROLLER::change_map(const char *to_map)
+void IGameController::ChangeMap(const char *pToMap)
 {
-	str_copy(map_wish, to_map, sizeof(map_wish));
-	endround();
+	str_copy(m_aMapWish, pToMap, sizeof(m_aMapWish));
+	EndRound();
 }
 
-void GAMECONTROLLER::cyclemap()
+void IGameController::CycleMap()
 {
-	if(map_wish[0] != 0)
+	if(m_aMapWish[0] != 0)
 	{
-		dbg_msg("game", "rotating map to %s", map_wish);
-		str_copy(config.sv_map, map_wish, sizeof(config.sv_map));
-		map_wish[0] = 0;
-		round_count = 0;
+		dbg_msg("game", "rotating map to %s", m_aMapWish);
+		str_copy(g_Config.m_SvMap, m_aMapWish, sizeof(g_Config.m_SvMap));
+		m_aMapWish[0] = 0;
+		m_RoundCount = 0;
 		return;
 	}
-	if(!strlen(config.sv_maprotation))
+	if(!str_length(g_Config.m_SvMaprotation))
 		return;
 
-	if(round_count < config.sv_rounds_per_map-1)
+	if(m_RoundCount < g_Config.m_SvRoundsPerMap-1)
 		return;
 		
 	// handle maprotation
-	const char *map_rotation = config.sv_maprotation;
-	const char *current_map = config.sv_map;
+	const char *pMapRotation = g_Config.m_SvMaprotation;
+	const char *pCurrentMap = g_Config.m_SvMap;
 	
-	int current_map_len = strlen(current_map);
-	const char *next_map = map_rotation;
-	while(*next_map)
+	int CurrentMapLen = str_length(pCurrentMap);
+	const char *pNextMap = pMapRotation;
+	while(*pNextMap)
 	{
-		int wordlen = 0;
-		while(next_map[wordlen] && !is_separator(next_map[wordlen]))
-			wordlen++;
+		int WordLen = 0;
+		while(pNextMap[WordLen] && !IsSeparator(pNextMap[WordLen]))
+			WordLen++;
 		
-		if(wordlen == current_map_len && strncmp(next_map, current_map, current_map_len) == 0)
+		if(WordLen == CurrentMapLen && str_comp_num(pNextMap, pCurrentMap, CurrentMapLen) == 0)
 		{
 			// map found
-			next_map += current_map_len;
-			while(*next_map && is_separator(*next_map))
-				next_map++;
+			pNextMap += CurrentMapLen;
+			while(*pNextMap && IsSeparator(*pNextMap))
+				pNextMap++;
 				
 			break;
 		}
 		
-		next_map++;
+		pNextMap++;
 	}
 	
 	// restart rotation
-	if(next_map[0] == 0)
-		next_map = map_rotation;
+	if(pNextMap[0] == 0)
+		pNextMap = pMapRotation;
 
 	// cut out the next map	
-	char buf[512];
+	char Buf[512];
 	for(int i = 0; i < 512; i++)
 	{
-		buf[i] = next_map[i];
-		if(is_separator(next_map[i]) || next_map[i] == 0)
+		Buf[i] = pNextMap[i];
+		if(IsSeparator(pNextMap[i]) || pNextMap[i] == 0)
 		{
-			buf[i] = 0;
+			Buf[i] = 0;
 			break;
 		}
 	}
 	
 	// skip spaces
 	int i = 0;
-	while(is_separator(buf[i]))
+	while(IsSeparator(Buf[i]))
 		i++;
 	
-	round_count = 0;
+	m_RoundCount = 0;
 	
-	dbg_msg("game", "rotating map to %s", &buf[i]);
-	str_copy(config.sv_map, &buf[i], sizeof(config.sv_map));
+	dbg_msg("game", "rotating map to %s", &Buf[i]);
+	str_copy(g_Config.m_SvMap, &Buf[i], sizeof(g_Config.m_SvMap));
 }
 
-void GAMECONTROLLER::post_reset()
+void IGameController::PostReset()
 {
 	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
-		if(game.players[i])
+		if(GameServer()->m_apPlayers[i])
 		{
-			game.players[i]->respawn();
-			game.players[i]->score = 0;
+			GameServer()->m_apPlayers[i]->Respawn();
+			GameServer()->m_apPlayers[i]->m_Score = 0;
 		}
 	}
 }
 	
-void GAMECONTROLLER::on_player_info_change(class PLAYER *p)
+void IGameController::OnPlayerInfoChange(class CPlayer *pP)
 {
-	const int team_colors[2] = {65387, 10223467};
-	if(is_teamplay())
+	const int aTeamColors[2] = {65387, 10223467};
+	if(IsTeamplay())
 	{
-		if(p->team >= 0 || p->team <= 1)
+		if(pP->GetTeam() >= 0 || pP->GetTeam() <= 1)
 		{
-			p->use_custom_color = 1;
-			p->color_body = team_colors[p->team];
-			p->color_feet = team_colors[p->team];
+			pP->m_TeeInfos.m_UseCustomColor = 1;
+			pP->m_TeeInfos.m_ColorBody = aTeamColors[pP->GetTeam()];
+			pP->m_TeeInfos.m_ColorFeet = aTeamColors[pP->GetTeam()];
 		}
 	}
 }
 
 
-int GAMECONTROLLER::on_character_death(class CHARACTER *victim, class PLAYER *killer, int weapon)
+int IGameController::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon)
 {
 	// do scoreing
-	if(!killer)
+	if(!pKiller)
 		return 0;
-	if(killer == victim->player)
-		victim->player->score--; // suicide
+	if(pKiller == pVictim->GetPlayer())
+		pVictim->GetPlayer()->m_Score--; // suicide
 	else
 	{
-		if(is_teamplay() && victim->team == killer->team)
-			killer->score--; // teamkill
+		if(IsTeamplay() && pVictim->GetPlayer()->GetTeam() == pKiller->GetTeam())
+			pKiller->m_Score--; // teamkill
 		else
-			killer->score++; // normal kill
+			pKiller->m_Score++; // normal kill
 	}
 	return 0;
 }
 
-void GAMECONTROLLER::on_character_spawn(class CHARACTER *chr)
+void IGameController::OnCharacterSpawn(class CCharacter *pChr)
 {
 	// default health
-	chr->health = 10;
+	pChr->IncreaseHealth(10);
 	
 	// give default weapons
-	chr->weapons[WEAPON_HAMMER].got = 1;
-	chr->weapons[WEAPON_HAMMER].ammo = -1;
-	chr->weapons[WEAPON_GUN].got = 1;
-	chr->weapons[WEAPON_GUN].ammo = 10;
+	pChr->GiveWeapon(WEAPON_HAMMER, -1);
+	pChr->GiveWeapon(WEAPON_GUN, 10);
 }
 
-void GAMECONTROLLER::do_warmup(int seconds)
+void IGameController::DoWarmup(int Seconds)
 {
-	warmup = seconds*server_tickspeed();
+	if(Seconds < 0)
+		m_Warmup = 0;
+	else
+		m_Warmup = Seconds*Server()->TickSpeed();
 }
 
-bool GAMECONTROLLER::is_friendly_fire(int cid1, int cid2)
+bool IGameController::IsFriendlyFire(int Cid1, int Cid2)
 {
-	if(cid1 == cid2)
+	if(Cid1 == Cid2)
 		return false;
 	
-	if(is_teamplay())
+	if(IsTeamplay())
 	{
-		if(!game.players[cid1] || !game.players[cid2])
+		if(!GameServer()->m_apPlayers[Cid1] || !GameServer()->m_apPlayers[Cid2])
 			return false;
 			
-		if(game.players[cid1]->team == game.players[cid2]->team)
+		if(GameServer()->m_apPlayers[Cid1]->GetTeam() == GameServer()->m_apPlayers[Cid2]->GetTeam())
 			return true;
 	}
 	
 	return false;
 }
 
-bool GAMECONTROLLER::is_force_balanced()
+bool IGameController::IsForceBalanced()
 {
-	if(force_balanced)
+	if(m_ForceBalanced)
 	{
-		force_balanced = false;
+		m_ForceBalanced = false;
 		return true;
 	}
 	else
 		return false;
 }
 
-void GAMECONTROLLER::tick()
+bool IGameController::CanBeMovedOnBalance(int Cid)
+{
+	return true;
+}
+
+void IGameController::Tick()
 {
 	// do warmup
-	if(warmup)
+	if(m_Warmup)
 	{
-		warmup--;
-		if(!warmup)
-			startround();
+		m_Warmup--;
+		if(!m_Warmup)
+			StartRound();
 	}
 	
-	if(game_over_tick != -1)
+	if(m_GameOverTick != -1)
 	{
 		// game over.. wait for restart
-		if(server_tick() > game_over_tick+server_tickspeed()*10)
+		if(Server()->Tick() > m_GameOverTick+Server()->TickSpeed()*10)
 		{
-			cyclemap();
-			startround();
-			round_count++;
+			CycleMap();
+			StartRound();
+			m_RoundCount++;
 		}
 	}
 	
 	// do team-balancing
-	if (is_teamplay() && unbalanced_tick != -1 && server_tick() > unbalanced_tick+config.sv_teambalance_time*server_tickspeed()*60)
+	if (IsTeamplay() && m_UnbalancedTick != -1 && Server()->Tick() > m_UnbalancedTick+g_Config.m_SvTeambalanceTime*Server()->TickSpeed()*60)
 	{
 		dbg_msg("game", "Balancing teams");
 		
-		int t[2] = {0,0};
-		int tscore[2] = {0,0};
+		int aT[2] = {0,0};
+		int aTScore[2] = {0,0};
 		for(int i = 0; i < MAX_CLIENTS; i++)
 		{
-			if(game.players[i] && game.players[i]->team != -1)
+			if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != -1)
 			{
-				t[game.players[i]->team]++;
-				tscore[game.players[i]->team]+=game.players[i]->score;
+				aT[GameServer()->m_apPlayers[i]->GetTeam()]++;
+				aTScore[GameServer()->m_apPlayers[i]->GetTeam()] += GameServer()->m_apPlayers[i]->m_Score;
 			}
 		}
 		
 		// are teams unbalanced?
-		if(abs(t[0]-t[1]) >= 2)
+		if(absolute(aT[0]-aT[1]) >= 2)
 		{
-			int m = (t[0] > t[1]) ? 0 : 1;
-			int num_balance = abs(t[0]-t[1]) / 2;
+			int M = (aT[0] > aT[1]) ? 0 : 1;
+			int NumBalance = absolute(aT[0]-aT[1]) / 2;
 			
 			do
 			{
-				PLAYER *p = 0;
-				int pd = tscore[m];
+				CPlayer *pP = 0;
+				int PD = aTScore[M];
 				for(int i = 0; i < MAX_CLIENTS; i++)
 				{
-					if(!game.players[i])
+					if(!GameServer()->m_apPlayers[i])
+						continue;
+					if(!CanBeMovedOnBalance(i))
 						continue;
-					
 					// remember the player who would cause lowest score-difference
-					if(game.players[i]->team == m && (!p || abs((tscore[m^1]+game.players[i]->score) - (tscore[m]-game.players[i]->score)) < pd))
+					if(GameServer()->m_apPlayers[i]->GetTeam() == M && (!pP || absolute((aTScore[M^1]+GameServer()->m_apPlayers[i]->m_Score) - (aTScore[M]-GameServer()->m_apPlayers[i]->m_Score)) < PD))
 					{
-						p = game.players[i];
-						pd = abs((tscore[m^1]+p->score) - (tscore[m]-p->score));
+						pP = GameServer()->m_apPlayers[i];
+						PD = absolute((aTScore[M^1]+pP->m_Score) - (aTScore[M]-pP->m_Score));
 					}
 				}
 				
 				// move the player to other team without losing his score
 				// TODO: change in player::set_team needed: player won't lose score on team-change
-				int score_before = p->score;
-				p->set_team(m^1);
-				p->score = score_before;
+				int ScoreBefore = pP->m_Score;
+				pP->SetTeam(M^1);
+				pP->m_Score = ScoreBefore;
 				
-				p->respawn();
-				p->force_balanced = true;
-			} while (--num_balance);
+				pP->Respawn();
+				pP->m_ForceBalanced = true;
+			} while (--NumBalance);
 			
-			force_balanced = true;
+			m_ForceBalanced = true;
 		}
-		unbalanced_tick = -1;
+		m_UnbalancedTick = -1;
 	}
 	
 	// update browse info
-	int prog = -1;
-	if(config.sv_timelimit > 0)
-		prog = max(prog, (server_tick()-round_start_tick) * 100 / (config.sv_timelimit*server_tickspeed()*60));
+	int Prog = -1;
+	if(g_Config.m_SvTimelimit > 0)
+		Prog = max(Prog, (Server()->Tick()-m_RoundStartTick) * 100 / (g_Config.m_SvTimelimit*Server()->TickSpeed()*60));
 
-	if(config.sv_scorelimit)
+	if(g_Config.m_SvScorelimit)
 	{
-		if(is_teamplay())
+		if(IsTeamplay())
 		{
-			prog = max(prog, (teamscore[0]*100)/config.sv_scorelimit);
-			prog = max(prog, (teamscore[1]*100)/config.sv_scorelimit);
+			Prog = max(Prog, (m_aTeamscore[0]*100)/g_Config.m_SvScorelimit);
+			Prog = max(Prog, (m_aTeamscore[1]*100)/g_Config.m_SvScorelimit);
 		}
 		else
 		{
 			for(int i = 0; i < MAX_CLIENTS; i++)
 			{
-				if(game.players[i])
-					prog = max(prog, (game.players[i]->score*100)/config.sv_scorelimit);
+				if(GameServer()->m_apPlayers[i])
+					Prog = max(Prog, (GameServer()->m_apPlayers[i]->m_Score*100)/g_Config.m_SvScorelimit);
 			}
 		}
 	}
 
-	if(warmup)
-		prog = -1;
+	if(m_Warmup)
+		Prog = -1;
 		
-	server_setbrowseinfo(gametype, prog);
+	Server()->SetBrowseInfo(m_pGameType, Prog);
 }
 
 
-bool GAMECONTROLLER::is_teamplay() const
+bool IGameController::IsTeamplay() const
 {
-	return game_flags&GAMEFLAG_TEAMS;
+	return m_GameFlags&GAMEFLAG_TEAMS;
 }
 
-void GAMECONTROLLER::snap(int snapping_client)
+void IGameController::Snap(int SnappingClient)
 {
-	NETOBJ_GAME *gameobj = (NETOBJ_GAME *)snap_new_item(NETOBJTYPE_GAME, 0, sizeof(NETOBJ_GAME));
-	gameobj->paused = game.world.paused;
-	gameobj->game_over = game_over_tick==-1?0:1;
-	gameobj->sudden_death = sudden_death;
+	CNetObj_Game *pGameObj = (CNetObj_Game *)Server()->SnapNewItem(NETOBJTYPE_GAME, 0, sizeof(CNetObj_Game));
+	pGameObj->m_Paused = GameServer()->m_World.m_Paused;
+	pGameObj->m_GameOver = m_GameOverTick==-1?0:1;
+	pGameObj->m_SuddenDeath = m_SuddenDeath;
 	
-	gameobj->score_limit = config.sv_scorelimit;
-	gameobj->time_limit = config.sv_timelimit;
-	gameobj->round_start_tick = round_start_tick;
-	gameobj->flags = game_flags;
+	pGameObj->m_ScoreLimit = g_Config.m_SvScorelimit;
+	pGameObj->m_TimeLimit = g_Config.m_SvTimelimit;
+	pGameObj->m_RoundStartTick = m_RoundStartTick;
+	pGameObj->m_Flags = m_GameFlags;
 	
-	gameobj->warmup = warmup;
+	pGameObj->m_Warmup = m_Warmup;
 	
-	gameobj->round_num = (strlen(config.sv_maprotation) && config.sv_rounds_per_map) ? config.sv_rounds_per_map : 0;
-	gameobj->round_current = round_count+1;
+	pGameObj->m_RoundNum = (str_length(g_Config.m_SvMaprotation) && g_Config.m_SvRoundsPerMap) ? g_Config.m_SvRoundsPerMap : 0;
+	pGameObj->m_RoundCurrent = m_RoundCount+1;
 	
 	
-	if(snapping_client == -1)
+	if(SnappingClient == -1)
 	{
 		// we are recording a demo, just set the scores
-		gameobj->teamscore_red = teamscore[0];
-		gameobj->teamscore_blue = teamscore[1];
+		pGameObj->m_TeamscoreRed = m_aTeamscore[0];
+		pGameObj->m_TeamscoreBlue = m_aTeamscore[1];
 	}
 	else
 	{
 		// TODO: this little hack should be removed
-		gameobj->teamscore_red = is_teamplay() ? teamscore[0] : game.players[snapping_client]->score;
-		gameobj->teamscore_blue = teamscore[1];
+		pGameObj->m_TeamscoreRed = IsTeamplay() ? m_aTeamscore[0] : GameServer()->m_apPlayers[SnappingClient]->m_Score;
+		pGameObj->m_TeamscoreBlue = m_aTeamscore[1];
 	}
 }
 
-int GAMECONTROLLER::get_auto_team(int notthisid)
+int IGameController::GetAutoTeam(int Notthisid)
 {
 	// this will force the auto balancer to work overtime aswell
-	if(config.dbg_stress)
+	if(g_Config.m_DbgStress)
 		return 0;
 	
-	int numplayers[2] = {0,0};
+	int aNumplayers[2] = {0,0};
 	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
-		if(game.players[i] && i != notthisid)
+		if(GameServer()->m_apPlayers[i] && i != Notthisid)
 		{
-			if(game.players[i]->team == 0 || game.players[i]->team == 1)
-				numplayers[game.players[i]->team]++;
+			if(GameServer()->m_apPlayers[i]->GetTeam() == 0 || GameServer()->m_apPlayers[i]->GetTeam() == 1)
+				aNumplayers[GameServer()->m_apPlayers[i]->GetTeam()]++;
 		}
 	}
 
-	int team = 0;
-	if(is_teamplay())
-		team = numplayers[0] > numplayers[1] ? 1 : 0;
+	int Team = 0;
+	if(IsTeamplay())
+		Team = aNumplayers[0] > aNumplayers[1] ? 1 : 0;
 		
-	if(can_join_team(team, notthisid))
-		return team;
+	if(CanJoinTeam(Team, Notthisid))
+		return Team;
 	return -1;
 }
 
-bool GAMECONTROLLER::can_join_team(int team, int notthisid)
+bool IGameController::CanJoinTeam(int Team, int Notthisid)
 {
-	(void)team;
-	int numplayers[2] = {0,0};
+	if(Team == -1)
+		return true;
+
+	int aNumplayers[2] = {0,0};
 	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
-		if(game.players[i] && i != notthisid)
+		if(GameServer()->m_apPlayers[i] && i != Notthisid)
 		{
-			if(game.players[i]->team >= 0 || game.players[i]->team == 1)
-				numplayers[game.players[i]->team]++;
+			if(GameServer()->m_apPlayers[i]->GetTeam() >= 0 || GameServer()->m_apPlayers[i]->GetTeam() == 1)
+				aNumplayers[GameServer()->m_apPlayers[i]->GetTeam()]++;
 		}
 	}
 	
-	return (numplayers[0] + numplayers[1]) < config.sv_max_clients-config.sv_spectator_slots;
+	return (aNumplayers[0] + aNumplayers[1]) < g_Config.m_SvMaxClients-g_Config.m_SvSpectatorSlots;
 }
 
-bool GAMECONTROLLER::check_team_balance()
+bool IGameController::CheckTeamBalance()
 {
-	if(!is_teamplay() || !config.sv_teambalance_time)
+	if(!IsTeamplay() || !g_Config.m_SvTeambalanceTime)
 		return true;
 	
-	int t[2] = {0, 0};
+	int aT[2] = {0, 0};
 	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
-		PLAYER *p = game.players[i];
-		if(p && p->team != -1)
-			t[p->team]++;
+		CPlayer *pP = GameServer()->m_apPlayers[i];
+		if(pP && pP->GetTeam() != -1)
+			aT[pP->GetTeam()]++;
 	}
 	
-	if(abs(t[0]-t[1]) >= 2)
+	if(absolute(aT[0]-aT[1]) >= 2)
 	{
-		dbg_msg("game", "Team is NOT balanced (red=%d blue=%d)", t[0], t[1]);
-		if (game.controller->unbalanced_tick == -1)
-			game.controller->unbalanced_tick = server_tick();
+		dbg_msg("game", "Team is NOT balanced (red=%d blue=%d)", aT[0], aT[1]);
+		if(GameServer()->m_pController->m_UnbalancedTick == -1)
+			GameServer()->m_pController->m_UnbalancedTick = Server()->Tick();
 		return false;
 	}
 	else
 	{
-		dbg_msg("game", "Team is balanced (red=%d blue=%d)", t[0], t[1]);
-		game.controller->unbalanced_tick = -1;
+		dbg_msg("game", "Team is balanced (red=%d blue=%d)", aT[0], aT[1]);
+		GameServer()->m_pController->m_UnbalancedTick = -1;
 		return true;
 	}
 }
 
-bool GAMECONTROLLER::can_change_team(PLAYER *pplayer, int jointeam)
+bool IGameController::CanChangeTeam(CPlayer *pPlayer, int JoinTeam)
 {
-	int t[2] = {0, 0};
+	int aT[2] = {0, 0};
 	
-	if (!is_teamplay() || jointeam == -1 || !config.sv_teambalance_time)
+	if (!IsTeamplay() || JoinTeam == -1 || !g_Config.m_SvTeambalanceTime)
 		return true;
 	
 	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
-		PLAYER *p = game.players[i];
-		if(p && p->team != -1)
-			t[p->team]++;
+		CPlayer *pP = GameServer()->m_apPlayers[i];
+		if(pP && pP->GetTeam() != -1)
+			aT[pP->GetTeam()]++;
 	}
 	
 	// simulate what would happen if changed team
-	t[jointeam]++;
-	if (pplayer->team != -1)
-		t[jointeam^1]--;
+	aT[JoinTeam]++;
+	if (pPlayer->GetTeam() != -1)
+		aT[JoinTeam^1]--;
 	
 	// there is a player-difference of at least 2
-	if(abs(t[0]-t[1]) >= 2)
+	if(absolute(aT[0]-aT[1]) >= 2)
 	{
 		// player wants to join team with less players
-		if ((t[0] < t[1] && jointeam == 0) || (t[0] > t[1] && jointeam == 1))
+		if ((aT[0] < aT[1] && JoinTeam == 0) || (aT[0] > aT[1] && JoinTeam == 1))
 			return true;
 		else
 			return false;
@@ -610,62 +617,60 @@ bool GAMECONTROLLER::can_change_team(PLAYER *pplayer, int jointeam)
 		return true;
 }
 
-void GAMECONTROLLER::do_player_score_wincheck()
+void IGameController::DoPlayerScoreWincheck()
 {
-	if(game_over_tick == -1  && !warmup)
+	if(m_GameOverTick == -1  && !m_Warmup)
 	{
 		// gather some stats
-		int topscore = 0;
-		int topscore_count = 0;
+		int Topscore = 0;
+		int TopscoreCount = 0;
 		for(int i = 0; i < MAX_CLIENTS; i++)
 		{
-			if(game.players[i])
+			if(GameServer()->m_apPlayers[i])
 			{
-				if(game.players[i]->score > topscore)
+				if(GameServer()->m_apPlayers[i]->m_Score > Topscore)
 				{
-					topscore = game.players[i]->score;
-					topscore_count = 1;
+					Topscore = GameServer()->m_apPlayers[i]->m_Score;
+					TopscoreCount = 1;
 				}
-				else if(game.players[i]->score == topscore)
-					topscore_count++;
+				else if(GameServer()->m_apPlayers[i]->m_Score == Topscore)
+					TopscoreCount++;
 			}
 		}
 		
 		// check score win condition
-		if((config.sv_scorelimit > 0 && topscore >= config.sv_scorelimit) ||
-			(config.sv_timelimit > 0 && (server_tick()-round_start_tick) >= config.sv_timelimit*server_tickspeed()*60))
+		if((g_Config.m_SvScorelimit > 0 && Topscore >= g_Config.m_SvScorelimit) ||
+			(g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_RoundStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60))
 		{
-			if(topscore_count == 1)
-				endround();
+			if(TopscoreCount == 1)
+				EndRound();
 			else
-				sudden_death = 1;
+				m_SuddenDeath = 1;
 		}
 	}
 }
 
-void GAMECONTROLLER::do_team_score_wincheck()
+void IGameController::DoTeamScoreWincheck()
 {
-	if(game_over_tick == -1 && !warmup)
+	if(m_GameOverTick == -1 && !m_Warmup)
 	{
 		// check score win condition
-		if((config.sv_scorelimit > 0 && (teamscore[0] >= config.sv_scorelimit || teamscore[1] >= config.sv_scorelimit)) ||
-			(config.sv_timelimit > 0 && (server_tick()-round_start_tick) >= config.sv_timelimit*server_tickspeed()*60))
+		if((g_Config.m_SvScorelimit > 0 && (m_aTeamscore[0] >= g_Config.m_SvScorelimit || m_aTeamscore[1] >= g_Config.m_SvScorelimit)) ||
+			(g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_RoundStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60))
 		{
-			if(teamscore[0] != teamscore[1])
-				endround();
+			if(m_aTeamscore[0] != m_aTeamscore[1])
+				EndRound();
 			else
-				sudden_death = 1;
+				m_SuddenDeath = 1;
 		}
 	}
 }
 
-int GAMECONTROLLER::clampteam(int team)
+int IGameController::ClampTeam(int Team)
 {
-	if(team < 0) // spectator
+	if(Team < 0) // spectator
 		return -1;
-	if(is_teamplay())
-		return team&1;
+	if(IsTeamplay())
+		return Team&1;
 	return  0;
 }
-
-GAMECONTROLLER *gamecontroller = 0;
diff --git a/src/game/server/gamecontroller.h b/src/game/server/gamecontroller.h
new file mode 100644
index 00000000..0624dcab
--- /dev/null
+++ b/src/game/server/gamecontroller.h
@@ -0,0 +1,145 @@
+#ifndef GAME_SERVER_GAMECONTROLLER_H
+#define GAME_SERVER_GAMECONTROLLER_H
+
+#include <base/vmath.h>
+
+/*
+	Class: Game Controller
+		Controls the main game logic. Keeping track of team and player score,
+		winning conditions and specific game logic.
+*/
+class IGameController
+{
+	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; }
+
+	struct CSpawnEval
+	{
+		CSpawnEval()
+		{
+			m_Got = false;
+			m_FriendlyTeam = -1;
+			m_Pos = vec2(100,100);
+		}
+			
+		vec2 m_Pos;
+		bool m_Got;
+		int m_FriendlyTeam;
+		float m_Score;
+	};
+
+	float EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos);
+	void EvaluateSpawnType(CSpawnEval *pEval, int Type);
+	bool EvaluateSpawn(class CPlayer *pP, vec2 *pPos);
+
+	void CycleMap();
+	void ResetGame();
+	
+	char m_aMapWish[128];
+
+	
+	int m_RoundStartTick;
+	int m_GameOverTick;
+	int m_SuddenDeath;
+	
+	int m_aTeamscore[2];
+	
+	int m_Warmup;
+	int m_RoundCount;
+	
+	int m_GameFlags;
+	int m_UnbalancedTick;
+	bool m_ForceBalanced;
+	
+public:
+	const char *m_pGameType;
+
+	bool IsTeamplay() const;
+	
+	IGameController(class CGameContext *pGameServer);
+	virtual ~IGameController();
+
+	void DoTeamScoreWincheck();
+	void DoPlayerScoreWincheck();
+	
+	void DoWarmup(int Seconds);
+	
+	void StartRound();
+	void EndRound();
+	void ChangeMap(const char *pToMap);
+	
+	bool IsFriendlyFire(int Cid1, int Cid2);
+	
+	bool IsForceBalanced();
+
+	/*
+	
+	*/	
+	virtual bool CanBeMovedOnBalance(int Cid);
+
+	virtual void Tick();
+	
+	virtual void Snap(int SnappingClient);
+	
+	/*
+		Function: on_entity
+			Called when the map is loaded to process an entity
+			in the map.
+			
+		Arguments:
+			index - Entity index.
+			pos - Where the entity is located in the world.
+			
+		Returns:
+			bool?
+	*/
+	virtual bool OnEntity(int Index, vec2 Pos);
+	
+	/*
+		Function: on_CCharacter_spawn
+			Called when a CCharacter spawns into the game world.
+			
+		Arguments:
+			chr - The CCharacter that was spawned.
+	*/
+	virtual void OnCharacterSpawn(class CCharacter *pChr);
+	
+	/*
+		Function: on_CCharacter_death
+			Called when a CCharacter in the world dies.
+			
+		Arguments:
+			victim - The CCharacter that died.
+			killer - The player that killed it.
+			weapon - What weapon that killed it. Can be -1 for undefined
+				weapon when switching team or player suicides.
+	*/
+	virtual int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
+
+
+	virtual void OnPlayerInfoChange(class CPlayer *pP);
+
+	//
+	virtual bool CanSpawn(class CPlayer *pP, vec2 *pPos);
+
+	/*
+	
+	*/	
+	virtual const char *GetTeamName(int Team);
+	virtual int GetAutoTeam(int NotThisId);
+	virtual bool CanJoinTeam(int Team, int NotThisId);
+	bool CheckTeamBalance();
+	bool CanChangeTeam(CPlayer *pPplayer, int JoinTeam);
+	int ClampTeam(int Team);
+
+	virtual void PostReset();
+};
+
+#endif
diff --git a/src/game/server/gamecontroller.hpp b/src/game/server/gamecontroller.hpp
deleted file mode 100644
index 26b8a81f..00000000
--- a/src/game/server/gamecontroller.hpp
+++ /dev/null
@@ -1,136 +0,0 @@
-#ifndef GAME_SERVER_GAMECONTROLLER_H
-#define GAME_SERVER_GAMECONTROLLER_H
-
-#include <base/vmath.hpp>
-
-/*
-	Class: Game Controller
-		Controls the main game logic. Keeping track of team and player score,
-		winning conditions and specific game logic.
-*/
-class GAMECONTROLLER
-{
-	vec2 spawn_points[3][64];
-	int num_spawn_points[3];
-protected:
-	struct SPAWNEVAL
-	{
-		SPAWNEVAL()
-		{
-			got = false;
-			friendly_team = -1;
-			pos = vec2(100,100);
-		}
-			
-		vec2 pos;
-		bool got;
-		int friendly_team;
-		float score;
-	};
-
-	float evaluate_spawn_pos(SPAWNEVAL *eval, vec2 pos);
-	void evaluate_spawn_type(SPAWNEVAL *eval, int type);
-	bool evaluate_spawn(class PLAYER *p, vec2 *pos);
-
-	void cyclemap();
-	void resetgame();
-	
-	char map_wish[128];
-
-	
-	int round_start_tick;
-	int game_over_tick;
-	int sudden_death;
-	
-	int teamscore[2];
-	
-	int warmup;
-	int round_count;
-	
-	int game_flags;
-	int unbalanced_tick;
-	bool force_balanced;
-	
-public:
-	const char *gametype;
-
-	bool is_teamplay() const;
-	
-	GAMECONTROLLER();
-	virtual ~GAMECONTROLLER();
-
-	void do_team_score_wincheck();
-	void do_player_score_wincheck();
-	
-	void do_warmup(int seconds);
-	
-	void startround();
-	void endround();
-	void change_map(const char *to_map);
-	
-	bool is_friendly_fire(int cid1, int cid2);
-	
-	bool is_force_balanced();
-
-	/*
-	
-	*/	
-	virtual void tick();
-	
-	virtual void snap(int snapping_client);
-	
-	/*
-		Function: on_entity
-			Called when the map is loaded to process an entity
-			in the map.
-			
-		Arguments:
-			index - Entity index.
-			pos - Where the entity is located in the world.
-			
-		Returns:
-			bool?
-	*/
-	virtual bool on_entity(int index, vec2 pos);
-	
-	/*
-		Function: on_character_spawn
-			Called when a character spawns into the game world.
-			
-		Arguments:
-			chr - The character that was spawned.
-	*/
-	virtual void on_character_spawn(class CHARACTER *chr);
-	
-	/*
-		Function: on_character_death
-			Called when a character in the world dies.
-			
-		Arguments:
-			victim - The character that died.
-			killer - The player that killed it.
-			weapon - What weapon that killed it. Can be -1 for undefined
-				weapon when switching team or player suicides.
-	*/
-	virtual int on_character_death(class CHARACTER *victim, class PLAYER *killer, int weapon);
-
-
-	virtual void on_player_info_change(class PLAYER *p);
-
-	//
-	virtual bool can_spawn(class PLAYER *p, vec2 *pos);
-
-	/*
-	
-	*/	
-	virtual const char *get_team_name(int team);
-	virtual int get_auto_team(int notthisid);
-	virtual bool can_join_team(int team, int notthisid);
-	bool check_team_balance();
-	bool can_change_team(PLAYER *pplayer, int jointeam);
-	int clampteam(int team);
-
-	virtual void post_reset();
-};
-
-#endif
diff --git a/src/game/server/gamemodes/ctf.cpp b/src/game/server/gamemodes/ctf.cpp
index b2146b51..3da88342 100644
--- a/src/game/server/gamemodes/ctf.cpp
+++ b/src/game/server/gamemodes/ctf.cpp
@@ -1,188 +1,205 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-#include <engine/e_server_interface.h>
-#include <game/mapitems.hpp>
-#include <game/server/entities/character.hpp>
-#include <game/server/player.hpp>
-#include <game/server/gamecontext.hpp>
-#include "ctf.hpp"
+// copyright (c) 2007 magnus auvinen, see licence.txt for more info
+#include <game/mapitems.h>
+#include <game/server/entities/character.h>
+#include <game/server/player.h>
+#include <game/server/gamecontext.h>
+#include "ctf.h"
 
-GAMECONTROLLER_CTF::GAMECONTROLLER_CTF()
+CGameControllerCTF::CGameControllerCTF(class CGameContext *pGameServer)
+: IGameController(pGameServer)
 {
-	flags[0] = 0;
-	flags[1] = 0;
-	gametype = "CTF";
-	game_flags = GAMEFLAG_TEAMS|GAMEFLAG_FLAGS;
+	m_apFlags[0] = 0;
+	m_apFlags[1] = 0;
+	m_pGameType = "CTF";
+	m_GameFlags = GAMEFLAG_TEAMS|GAMEFLAG_FLAGS;
 }
 
-bool GAMECONTROLLER_CTF::on_entity(int index, vec2 pos)
+bool CGameControllerCTF::OnEntity(int Index, vec2 Pos)
 {
-	if(GAMECONTROLLER::on_entity(index, pos))
+	if(IGameController::OnEntity(Index, Pos))
 		return true;
 	
-	int team = -1;
-	if(index == ENTITY_FLAGSTAND_RED) team = 0;
-	if(index == ENTITY_FLAGSTAND_BLUE) team = 1;
-	if(team == -1)
+	int Team = -1;
+	if(Index == ENTITY_FLAGSTAND_RED) Team = 0;
+	if(Index == ENTITY_FLAGSTAND_BLUE) Team = 1;
+	if(Team == -1)
 		return false;
 		
-	FLAG *f = new FLAG(team);
-	f->stand_pos = pos;
-	f->pos = pos;
-	flags[team] = f;
+	CFlag *F = new CFlag(&GameServer()->m_World, Team);
+	F->m_StandPos = Pos;
+	F->m_Pos = Pos;
+	m_apFlags[Team] = F;
+	GameServer()->m_World.InsertEntity(F);
 	return true;
 }
 
-int GAMECONTROLLER_CTF::on_character_death(class CHARACTER *victim, class PLAYER *killer, int weaponid)
+int CGameControllerCTF::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int WeaponID)
 {
-	GAMECONTROLLER::on_character_death(victim, killer, weaponid);
-	int had_flag = 0;
+	IGameController::OnCharacterDeath(pVictim, pKiller, WeaponID);
+	int HadFlag = 0;
 	
 	// drop flags
-	for(int fi = 0; fi < 2; fi++)
+	for(int i = 0; i < 2; i++)
 	{
-		FLAG *f = flags[fi];
-		if(f && killer && f->carrying_character == killer->get_character())
-			had_flag |= 2;
-		if(f && f->carrying_character == victim)
+		CFlag *F = m_apFlags[i];
+		if(F && pKiller && pKiller->GetCharacter() && F->m_pCarryingCCharacter == pKiller->GetCharacter())
+			HadFlag |= 2;
+		if(F && F->m_pCarryingCCharacter == pVictim)
 		{
-			game.create_sound_global(SOUND_CTF_DROP);
-			f->drop_tick = server_tick();
-			f->carrying_character = 0;
-			f->vel = vec2(0,0);
+			GameServer()->CreateSoundGlobal(SOUND_CTF_DROP);
+			F->m_DropTick = Server()->Tick();
+			F->m_pCarryingCCharacter = 0;
+			F->m_Vel = vec2(0,0);
 			
-			if(killer && killer->team != victim->team)
-				killer->score++;
+			if(pKiller && pKiller->GetTeam() != pVictim->GetPlayer()->GetTeam())
+				pKiller->m_Score++;
 				
-			had_flag |= 1;
+			HadFlag |= 1;
 		}
 	}
 	
-	return had_flag;
+	return HadFlag;
+}
+
+bool CGameControllerCTF::CanBeMovedOnBalance(int Cid)
+{
+	CCharacter* Character = GameServer()->m_apPlayers[Cid]->GetCharacter();
+	if(Character)
+	{
+		for(int fi = 0; fi < 2; fi++)
+		{
+			CFlag *F = m_apFlags[fi];
+			if(F->m_pCarryingCCharacter == Character)
+				return false;
+		}
+	}
+	return true;
 }
 
-void GAMECONTROLLER_CTF::tick()
+void CGameControllerCTF::Tick()
 {
-	GAMECONTROLLER::tick();
+	IGameController::Tick();
 
-	do_team_score_wincheck();
+	DoTeamScoreWincheck();
 	
 	for(int fi = 0; fi < 2; fi++)
 	{
-		FLAG *f = flags[fi];
+		CFlag *F = m_apFlags[fi];
 		
-		if(!f)
+		if(!F)
 			continue;
 		
 		// flag hits death-tile, reset it
-		if(col_get((int)f->pos.x, (int)f->pos.y)&COLFLAG_DEATH)
+		if(GameServer()->Collision()->GetCollisionAt(F->m_Pos.x, F->m_Pos.y)&CCollision::COLFLAG_DEATH)
 		{
-			game.create_sound_global(SOUND_CTF_RETURN);
-			f->reset();
+			GameServer()->CreateSoundGlobal(SOUND_CTF_RETURN);
+			F->Reset();
 			continue;
 		}
 		
 		//
-		if(f->carrying_character)
+		if(F->m_pCarryingCCharacter)
 		{
 			// update flag position
-			f->pos = f->carrying_character->pos;
+			F->m_Pos = F->m_pCarryingCCharacter->m_Pos;
 			
-			if(flags[fi^1] && flags[fi^1]->at_stand)
+			if(m_apFlags[fi^1] && m_apFlags[fi^1]->m_AtStand)
 			{
-				if(distance(f->pos, flags[fi^1]->pos) < 32)
+				if(distance(F->m_Pos, m_apFlags[fi^1]->m_Pos) < 32)
 				{
 					// CAPTURE! \o/
-					teamscore[fi^1] += 100;
-					f->carrying_character->player->score += 5;
+					m_aTeamscore[fi^1] += 100;
+					F->m_pCarryingCCharacter->GetPlayer()->m_Score += 5;
 
 					dbg_msg("game", "flag_capture player='%d:%s'",
-						f->carrying_character->player->client_id,
-						server_clientname(f->carrying_character->player->client_id));
+						F->m_pCarryingCCharacter->GetPlayer()->GetCID(),
+						Server()->ClientName(F->m_pCarryingCCharacter->GetPlayer()->GetCID()));
 
-					char buf[512];
-					float capture_time = (server_tick() - f->grab_tick)/(float)server_tickspeed();
-					if(capture_time <= 60)
+					char Buf[512];
+					float CaptureTime = (Server()->Tick() - F->m_GrabTick)/(float)Server()->TickSpeed();
+					if(CaptureTime <= 60)
 					{
-						str_format(buf, sizeof(buf), "the %s flag was captured by %s (%d.%s%d seconds)", fi ? "blue" : "red", server_clientname(f->carrying_character->player->client_id), (int)capture_time%60, ((int)(capture_time*100)%100)<10?"0":"", (int)(capture_time*100)%100);
+						str_format(Buf, sizeof(Buf), "The %s flag was captured by %s (%d.%s%d seconds)", fi ? "blue" : "red", Server()->ClientName(F->m_pCarryingCCharacter->GetPlayer()->GetCID()), (int)CaptureTime%60, ((int)(CaptureTime*100)%100)<10?"0":"", (int)(CaptureTime*100)%100);
 					}
 					else
 					{
-						str_format(buf, sizeof(buf), "the %s flag was captured by %s", fi ? "blue" : "red", server_clientname(f->carrying_character->player->client_id));
+						str_format(Buf, sizeof(Buf), "The %s flag was captured by %s", fi ? "blue" : "red", Server()->ClientName(F->m_pCarryingCCharacter->GetPlayer()->GetCID()));
 					}
-					game.send_chat(-1, -2, buf);
+					GameServer()->SendChat(-1, -2, Buf);
 					for(int i = 0; i < 2; i++)
-						flags[i]->reset();
+						m_apFlags[i]->Reset();
 					
-					game.create_sound_global(SOUND_CTF_CAPTURE);
+					GameServer()->CreateSoundGlobal(SOUND_CTF_CAPTURE);
 				}
-			}			
+			}
 		}
 		else
 		{
-			CHARACTER *close_characters[MAX_CLIENTS];
-			int num = game.world.find_entities(f->pos, 32.0f, (ENTITY**)close_characters, MAX_CLIENTS, NETOBJTYPE_CHARACTER);
-			for(int i = 0; i < num; i++)
+			CCharacter *apCloseCCharacters[MAX_CLIENTS];
+			int Num = GameServer()->m_World.FindEntities(F->m_Pos, 32.0f, (CEntity**)apCloseCCharacters, MAX_CLIENTS, NETOBJTYPE_CHARACTER);
+			for(int i = 0; i < Num; i++)
 			{
-				if(!close_characters[i]->alive || close_characters[i]->player->team == -1 || col_intersect_line(f->pos, close_characters[i]->pos, NULL, NULL))
+				if(!apCloseCCharacters[i]->IsAlive() || apCloseCCharacters[i]->GetPlayer()->GetTeam() == -1 || GameServer()->Collision()->IntersectLine(F->m_Pos, apCloseCCharacters[i]->m_Pos, NULL, NULL))
 					continue;
 				
-				if(close_characters[i]->team == f->team)
+				if(apCloseCCharacters[i]->GetPlayer()->GetTeam() == F->m_Team)
 				{
 					// return the flag
-					if(!f->at_stand)
+					if(!F->m_AtStand)
 					{
-						CHARACTER *chr = close_characters[i];
-						chr->player->score += 1;
+						CCharacter *pChr = apCloseCCharacters[i];
+						pChr->GetPlayer()->m_Score += 1;
 
 						dbg_msg("game", "flag_return player='%d:%s'",
-							chr->player->client_id,
-							server_clientname(chr->player->client_id));
+							pChr->GetPlayer()->GetCID(),
+							Server()->ClientName(pChr->GetPlayer()->GetCID()));
 
-						game.create_sound_global(SOUND_CTF_RETURN);
-						f->reset();
+						GameServer()->CreateSoundGlobal(SOUND_CTF_RETURN);
+						F->Reset();
 					}
 				}
 				else
 				{
 					// take the flag
-					if(f->at_stand)
+					if(F->m_AtStand)
 					{
-						teamscore[fi^1]++;
-						f->grab_tick = server_tick();
+						m_aTeamscore[fi^1]++;
+						F->m_GrabTick = Server()->Tick();
 					}
-					f->at_stand = 0;
-					f->carrying_character = close_characters[i];
-					f->carrying_character->player->score += 1;
+					
+					F->m_AtStand = 0;
+					F->m_pCarryingCCharacter = apCloseCCharacters[i];
+					F->m_pCarryingCCharacter->GetPlayer()->m_Score += 1;
 
 					dbg_msg("game", "flag_grab player='%d:%s'",
-						f->carrying_character->player->client_id,
-						server_clientname(f->carrying_character->player->client_id));
+						F->m_pCarryingCCharacter->GetPlayer()->GetCID(),
+						Server()->ClientName(F->m_pCarryingCCharacter->GetPlayer()->GetCID()));
 					
 					for(int c = 0; c < MAX_CLIENTS; c++)
 					{
-						if(!game.players[c])
+						if(!GameServer()->m_apPlayers[c])
 							continue;
 							
-						if(game.players[c]->team == fi)
-							game.create_sound_global(SOUND_CTF_GRAB_EN, game.players[c]->client_id);
+						if(GameServer()->m_apPlayers[c]->GetTeam() == fi)
+							GameServer()->CreateSoundGlobal(SOUND_CTF_GRAB_EN, GameServer()->m_apPlayers[c]->GetCID());
 						else
-							game.create_sound_global(SOUND_CTF_GRAB_PL, game.players[c]->client_id);
+							GameServer()->CreateSoundGlobal(SOUND_CTF_GRAB_PL, GameServer()->m_apPlayers[c]->GetCID());
 					}
 					break;
 				}
 			}
 			
-			if(!f->carrying_character && !f->at_stand)
+			if(!F->m_pCarryingCCharacter && !F->m_AtStand)
 			{
-				if(server_tick() > f->drop_tick + server_tickspeed()*30)
+				if(Server()->Tick() > F->m_DropTick + Server()->TickSpeed()*30)
 				{
-					game.create_sound_global(SOUND_CTF_RETURN);
-					f->reset();
+					GameServer()->CreateSoundGlobal(SOUND_CTF_RETURN);
+					F->Reset();
 				}
 				else
 				{
-					f->vel.y += game.world.core.tuning.gravity;
-					move_box(&f->pos, &f->vel, vec2(f->phys_size, f->phys_size), 0.5f);
+					F->m_Vel.y += GameServer()->m_World.m_Core.m_Tuning.m_Gravity;
+					GameServer()->Collision()->MoveBox(&F->m_Pos, &F->m_Vel, vec2(F->m_PhysSize, F->m_PhysSize), 0.5f);
 				}
 			}
 		}
@@ -190,39 +207,36 @@ void GAMECONTROLLER_CTF::tick()
 }
 
 // Flag
-FLAG::FLAG(int _team)
-: ENTITY(NETOBJTYPE_FLAG)
+CFlag::CFlag(CGameWorld *pGameWorld, int Team)
+: CEntity(pGameWorld, NETOBJTYPE_FLAG)
 {
-	team = _team;
-	proximity_radius = phys_size;
-	carrying_character = 0x0;
-	grab_tick = 0;
-	
-	reset();
+	m_Team = Team;
+	m_ProximityRadius = m_PhysSize;
+	m_pCarryingCCharacter = 0x0;
+	m_GrabTick = 0;
 	
-	// TODO: should this be done here?
-	game.world.insert_entity(this);
+	Reset();
 }
 
-void FLAG::reset()
+void CFlag::Reset()
 {
-	carrying_character = 0x0;
-	at_stand = 1;
-	pos = stand_pos;
-	vel = vec2(0,0);
-	grab_tick = 0;
+	m_pCarryingCCharacter = 0x0;
+	m_AtStand = 1;
+	m_Pos = m_StandPos;
+	m_Vel = vec2(0,0);
+	m_GrabTick = 0;
 }
 
-void FLAG::snap(int snapping_client)
+void CFlag::Snap(int SnappingClient)
 {
-	NETOBJ_FLAG *flag = (NETOBJ_FLAG *)snap_new_item(NETOBJTYPE_FLAG, team, sizeof(NETOBJ_FLAG));
-	flag->x = (int)pos.x;
-	flag->y = (int)pos.y;
-	flag->team = team;
-	flag->carried_by = -1;
+	CNetObj_Flag *pFlag = (CNetObj_Flag *)Server()->SnapNewItem(NETOBJTYPE_FLAG, m_Team, sizeof(CNetObj_Flag));
+	pFlag->m_X = (int)m_Pos.x;
+	pFlag->m_Y = (int)m_Pos.y;
+	pFlag->m_Team = m_Team;
+	pFlag->m_CarriedBy = -1;
 	
-	if(at_stand)
-		flag->carried_by = -2;
-	else if(carrying_character && carrying_character->player)
-		flag->carried_by = carrying_character->player->client_id;
+	if(m_AtStand)
+		pFlag->m_CarriedBy = -2;
+	else if(m_pCarryingCCharacter && m_pCarryingCCharacter->GetPlayer())
+		pFlag->m_CarriedBy = m_pCarryingCCharacter->GetPlayer()->GetCID();
 }
diff --git a/src/game/server/gamemodes/ctf.h b/src/game/server/gamemodes/ctf.h
new file mode 100644
index 00000000..b86ad688
--- /dev/null
+++ b/src/game/server/gamemodes/ctf.h
@@ -0,0 +1,38 @@
+#ifndef GAME_SERVER_GAMEMODES_CTF_H
+#define GAME_SERVER_GAMEMODES_CTF_H
+#include <game/server/gamecontroller.h>
+#include <game/server/entity.h>
+
+class CGameControllerCTF : public IGameController
+{
+public:
+	class CFlag *m_apFlags[2];
+	
+	CGameControllerCTF(class CGameContext *pGameServer);
+	virtual bool CanBeMovedOnBalance(int Cid);
+	virtual void Tick();
+	
+	virtual bool OnEntity(int Index, vec2 Pos);
+	virtual int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
+};
+
+// TODO: move to seperate file
+class CFlag : public CEntity
+{
+public:
+	static const int m_PhysSize = 14;
+	CCharacter *m_pCarryingCCharacter;
+	vec2 m_Vel;
+	vec2 m_StandPos;
+	
+	int m_Team;
+	int m_AtStand;
+	int m_DropTick;
+	int m_GrabTick;
+	
+	CFlag(CGameWorld *pGameWorld, int Team);
+
+	virtual void Reset();
+	virtual void Snap(int SnappingClient);
+};
+#endif
diff --git a/src/game/server/gamemodes/ctf.hpp b/src/game/server/gamemodes/ctf.hpp
deleted file mode 100644
index 67a098a4..00000000
--- a/src/game/server/gamemodes/ctf.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-
-#include <game/server/gamecontroller.hpp>
-#include <game/server/entity.hpp>
-
-class GAMECONTROLLER_CTF : public GAMECONTROLLER
-{
-public:
-	class FLAG *flags[2];
-	
-	GAMECONTROLLER_CTF();
-	virtual void tick();
-	
-	virtual bool on_entity(int index, vec2 pos);
-	virtual int on_character_death(class CHARACTER *victim, class PLAYER *killer, int weapon);
-};
-
-// TODO: move to seperate file
-class FLAG : public ENTITY
-{
-public:
-	static const int phys_size = 14;
-	CHARACTER *carrying_character;
-	vec2 vel;
-	vec2 stand_pos;
-	
-	int team;
-	int at_stand;
-	int drop_tick;
-	int grab_tick;
-	
-	FLAG(int _team);
-
-	virtual void reset();
-	virtual void snap(int snapping_client);
-};
diff --git a/src/game/server/gamemodes/dm.cpp b/src/game/server/gamemodes/dm.cpp
index 15c0b987..173ef5fd 100644
--- a/src/game/server/gamemodes/dm.cpp
+++ b/src/game/server/gamemodes/dm.cpp
@@ -1,14 +1,15 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-#include "dm.hpp"
+// copyright (c) 2007 magnus auvinen, see licence.txt for more info
+#include "dm.h"
 
 
-GAMECONTROLLER_DM::GAMECONTROLLER_DM()
+CGameControllerDM::CGameControllerDM(class CGameContext *pGameServer)
+: IGameController(pGameServer)
 {
-	gametype = "DM";
+	m_pGameType = "DM";
 }
 
-void GAMECONTROLLER_DM::tick()
+void CGameControllerDM::Tick()
 {
-	do_player_score_wincheck();
-	GAMECONTROLLER::tick();
+	DoPlayerScoreWincheck();
+	IGameController::Tick();
 }
diff --git a/src/game/server/gamemodes/dm.h b/src/game/server/gamemodes/dm.h
new file mode 100644
index 00000000..f2854680
--- /dev/null
+++ b/src/game/server/gamemodes/dm.h
@@ -0,0 +1,11 @@
+#ifndef GAME_SERVER_GAMEMODES_DM_H
+#define GAME_SERVER_GAMEMODES_DM_H
+#include <game/server/gamecontroller.h>
+
+class CGameControllerDM : public IGameController
+{
+public:
+	CGameControllerDM(class CGameContext *pGameServer);
+	virtual void Tick();
+};
+#endif
diff --git a/src/game/server/gamemodes/dm.hpp b/src/game/server/gamemodes/dm.hpp
deleted file mode 100644
index 6fb25f61..00000000
--- a/src/game/server/gamemodes/dm.hpp
+++ /dev/null
@@ -1,10 +0,0 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-
-#include <game/server/gamecontroller.hpp>
-
-class GAMECONTROLLER_DM : public GAMECONTROLLER
-{
-public:
-	GAMECONTROLLER_DM();
-	virtual void tick();
-};
diff --git a/src/game/server/gamemodes/mod.cpp b/src/game/server/gamemodes/mod.cpp
index 87b37411..44d0effc 100644
--- a/src/game/server/gamemodes/mod.cpp
+++ b/src/game/server/gamemodes/mod.cpp
@@ -1,20 +1,21 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */

-#include "mod.hpp"

+// copyright (c) 2007 magnus auvinen, see licence.txt for more info
+#include "mod.h"

 

-GAMECONTROLLER_MOD::GAMECONTROLLER_MOD()

+CGameControllerMOD::CGameControllerMOD(class CGameContext *pGameServer)

+: IGameController(pGameServer)

 {

 	// Exchange this to a string that identifies your game mode.

 	// DM, TDM and CTF are reserved for teeworlds original modes.

-	gametype = "MOD";

+	m_pGameType = "MOD";

 	

-	//game_flags = GAMEFLAG_TEAMS; // GAMEFLAG_TEAMS makes it a two-team gamemode

+	//m_GameFlags = GAMEFLAG_TEAMS; // GAMEFLAG_TEAMS makes it a two-team gamemode

 }

 

-void GAMECONTROLLER_MOD::tick()

+void CGameControllerMOD::Tick()

 {

 	// this is the main part of the gamemode, this function is run every tick

-	do_player_score_wincheck(); // checks for winners, no teams version

-	//do_team_score_wincheck(); // checks for winners, two teams version

+	DoPlayerScoreWincheck(); // checks for winners, no teams version

+	//DoTeamScoreWincheck(); // checks for winners, two teams version

 	

-	GAMECONTROLLER::tick();

+	IGameController::Tick();

 }

diff --git a/src/game/server/gamemodes/mod.h b/src/game/server/gamemodes/mod.h
new file mode 100644
index 00000000..86dff78b
--- /dev/null
+++ b/src/game/server/gamemodes/mod.h
@@ -0,0 +1,14 @@
+#ifndef GAME_SERVER_GAMEMODES_MOD_H
+#define GAME_SERVER_GAMEMODES_MOD_H
+#include <game/server/gamecontroller.h>

+

+// you can subclass GAMECONTROLLER_CTF, GAMECONTROLLER_TDM etc if you want

+// todo a modification with their base as well.

+class CGameControllerMOD : public IGameController

+{

+public:

+	CGameControllerMOD(class CGameContext *pGameServer);

+	virtual void Tick();

+	// add more virtual functions here if you wish

+};

+#endif
diff --git a/src/game/server/gamemodes/mod.hpp b/src/game/server/gamemodes/mod.hpp
deleted file mode 100644
index 9915a615..00000000
--- a/src/game/server/gamemodes/mod.hpp
+++ /dev/null
@@ -1,13 +0,0 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */

-

-#include <game/server/gamecontroller.hpp>

-

-// you can subclass GAMECONTROLLER_CTF, GAMECONTROLLER_TDM etc if you want

-// todo a modification with their base as well.

-class GAMECONTROLLER_MOD : public GAMECONTROLLER

-{

-public:

-	GAMECONTROLLER_MOD();

-	virtual void tick();

-	// add more virtual functions here if you wish

-};

diff --git a/src/game/server/gamemodes/tdm.cpp b/src/game/server/gamemodes/tdm.cpp
index 72605000..b54e3ac0 100644
--- a/src/game/server/gamemodes/tdm.cpp
+++ b/src/game/server/gamemodes/tdm.cpp
@@ -1,34 +1,33 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-#include <engine/e_server_interface.h>
-#include <game/server/entities/character.hpp>
-#include <game/server/player.hpp>
-#include "tdm.hpp"
+// copyright (c) 2007 magnus auvinen, see licence.txt for more info
+#include <game/server/entities/character.h>
+#include <game/server/player.h>
+#include "tdm.h"
 
-GAMECONTROLLER_TDM::GAMECONTROLLER_TDM()
+CGameControllerTDM::CGameControllerTDM(class CGameContext *pGameServer) : IGameController(pGameServer)
 {
-	gametype = "TDM";
-	game_flags = GAMEFLAG_TEAMS;
+	m_pGameType = "TDM";
+	m_GameFlags = GAMEFLAG_TEAMS;
 }
 
-int GAMECONTROLLER_TDM::on_character_death(class CHARACTER *victim, class PLAYER *killer, int weapon)
+int CGameControllerTDM::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon)
 {
-	GAMECONTROLLER::on_character_death(victim, killer, weapon);
+	IGameController::OnCharacterDeath(pVictim, pKiller, Weapon);
 	
 	
-	if(weapon != WEAPON_GAME)
+	if(Weapon != WEAPON_GAME)
 	{
 		// do team scoring
-		if(killer == victim->player || killer->team == victim->player->team)
-			teamscore[killer->team&1]--; // klant arschel
+		if(pKiller == pVictim->GetPlayer() || pKiller->GetTeam() == pVictim->GetPlayer()->GetTeam())
+			m_aTeamscore[pKiller->GetTeam()&1]--; // klant arschel
 		else
-			teamscore[killer->team&1]++; // good shit
+			m_aTeamscore[pKiller->GetTeam()&1]++; // good shit
 	}
 		
 	return 0;
 }
 
-void GAMECONTROLLER_TDM::tick()
+void CGameControllerTDM::Tick()
 {
-	do_team_score_wincheck();
-	GAMECONTROLLER::tick();
+	DoTeamScoreWincheck();
+	IGameController::Tick();
 }
diff --git a/src/game/server/gamemodes/tdm.h b/src/game/server/gamemodes/tdm.h
new file mode 100644
index 00000000..2d149456
--- /dev/null
+++ b/src/game/server/gamemodes/tdm.h
@@ -0,0 +1,13 @@
+#ifndef GAME_SERVER_GAMEMODES_TDM_H
+#define GAME_SERVER_GAMEMODES_TDM_H
+#include <game/server/gamecontroller.h>
+
+class CGameControllerTDM : public IGameController
+{
+public:
+	CGameControllerTDM(class CGameContext *pGameServer);
+	
+	int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
+	virtual void Tick();
+};
+#endif
diff --git a/src/game/server/gamemodes/tdm.hpp b/src/game/server/gamemodes/tdm.hpp
deleted file mode 100644
index 51c47ca5..00000000
--- a/src/game/server/gamemodes/tdm.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-
-#include <game/server/gamecontroller.hpp>
-
-class GAMECONTROLLER_TDM : public GAMECONTROLLER
-{
-public:
-	GAMECONTROLLER_TDM();
-	
-	int on_character_death(class CHARACTER *victim, class PLAYER *killer, int weapon);
-	virtual void tick();
-};
diff --git a/src/game/server/gameworld.cpp b/src/game/server/gameworld.cpp
index 9e76f14b..42c19487 100644
--- a/src/game/server/gameworld.cpp
+++ b/src/game/server/gameworld.cpp
@@ -1,217 +1,226 @@
 
-#include "gameworld.hpp"
-#include "entity.hpp"
-#include "gamecontext.hpp"
+#include "gameworld.h"
+#include "entity.h"
+#include "gamecontext.h"
 
 //////////////////////////////////////////////////
 // game world
 //////////////////////////////////////////////////
-GAMEWORLD::GAMEWORLD()
+CGameWorld::CGameWorld()
 {
-	paused = false;
-	reset_requested = false;
-	first_entity = 0x0;
+	m_pGameServer = 0x0;
+	m_pServer = 0x0;
+	
+	m_Paused = false;
+	m_ResetRequested = false;
+	m_pFirstEntity = 0x0;
 	for(int i = 0; i < NUM_ENT_TYPES; i++)
-		first_entity_types[i] = 0;
+		m_apFirstEntityTypes[i] = 0;
 }
 
-GAMEWORLD::~GAMEWORLD()
+CGameWorld::~CGameWorld()
 {
 	// delete all entities
-	while(first_entity)
-		delete first_entity;
+	while(m_pFirstEntity)
+		delete m_pFirstEntity;
+}
+
+void CGameWorld::SetGameServer(CGameContext *pGameServer)
+{
+	m_pGameServer = pGameServer;
+	m_pServer = m_pGameServer->Server();
 }
 
-ENTITY *GAMEWORLD::find_first(int type)
+CEntity *CGameWorld::FindFirst(int Type)
 {
-	return first_entity_types[type];
+	return m_apFirstEntityTypes[Type];
 }
 
 
-int GAMEWORLD::find_entities(vec2 pos, float radius, ENTITY **ents, int max, int type)
+int CGameWorld::FindEntities(vec2 Pos, float Radius, CEntity **ppEnts, int Max, int Type)
 {
-	int num = 0;
-	for(ENTITY *ent = (type<0) ? first_entity : first_entity_types[type];
-		ent; ent = (type<0) ? ent->next_entity : ent->next_type_entity)
+	int Num = 0;
+	for(CEntity *pEnt = (Type<0) ? m_pFirstEntity : m_apFirstEntityTypes[Type];
+		pEnt; pEnt = (Type<0) ? pEnt->m_pNextEntity : pEnt->m_pNextTypeEntity)
 	{
-		if(distance(ent->pos, pos) < radius+ent->proximity_radius)
+		if(distance(pEnt->m_Pos, Pos) < Radius+pEnt->m_ProximityRadius)
 		{
-			ents[num] = ent;
-			num++;
-			if(num == max)
+			ppEnts[Num] = pEnt;
+			Num++;
+			if(Num == Max)
 				break;
 		}
 	}
 
-	return num;
+	return Num;
 }
 
-void GAMEWORLD::insert_entity(ENTITY *ent)
+void CGameWorld::InsertEntity(CEntity *pEnt)
 {
-	ENTITY *cur = first_entity;
-	while(cur)
+	CEntity *pCur = m_pFirstEntity;
+	while(pCur)
 	{
-		dbg_assert(cur != ent, "err");
-		cur = cur->next_entity;
+		dbg_assert(pCur != pEnt, "err");
+		pCur = pCur->m_pNextEntity;
 	}
 
 	// insert it
-	if(first_entity)
-		first_entity->prev_entity = ent;
-	ent->next_entity = first_entity;
-	ent->prev_entity = 0x0;
-	first_entity = ent;
+	if(m_pFirstEntity)
+		m_pFirstEntity->m_pPrevEntity = pEnt;
+	pEnt->m_pNextEntity = m_pFirstEntity;
+	pEnt->m_pPrevEntity = 0x0;
+	m_pFirstEntity = pEnt;
 
 	// into typelist aswell
-	if(first_entity_types[ent->objtype])
-		first_entity_types[ent->objtype]->prev_type_entity = ent;
-	ent->next_type_entity = first_entity_types[ent->objtype];
-	ent->prev_type_entity = 0x0;
-	first_entity_types[ent->objtype] = ent;
+	if(m_apFirstEntityTypes[pEnt->m_Objtype])
+		m_apFirstEntityTypes[pEnt->m_Objtype]->m_pPrevTypeEntity = pEnt;
+	pEnt->m_pNextTypeEntity = m_apFirstEntityTypes[pEnt->m_Objtype];
+	pEnt->m_pPrevTypeEntity = 0x0;
+	m_apFirstEntityTypes[pEnt->m_Objtype] = pEnt;
 }
 
-void GAMEWORLD::destroy_entity(ENTITY *ent)
+void CGameWorld::DestroyEntity(CEntity *pEnt)
 {
-	ent->marked_for_destroy = true;
+	pEnt->m_MarkedForDestroy = true;
 }
 
-void GAMEWORLD::remove_entity(ENTITY *ent)
+void CGameWorld::RemoveEntity(CEntity *pEnt)
 {
 	// not in the list
-	if(!ent->next_entity && !ent->prev_entity && first_entity != ent)
+	if(!pEnt->m_pNextEntity && !pEnt->m_pPrevEntity && m_pFirstEntity != pEnt)
 		return;
 
 	// remove
-	if(ent->prev_entity)
-		ent->prev_entity->next_entity = ent->next_entity;
+	if(pEnt->m_pPrevEntity)
+		pEnt->m_pPrevEntity->m_pNextEntity = pEnt->m_pNextEntity;
 	else
-		first_entity = ent->next_entity;
-	if(ent->next_entity)
-		ent->next_entity->prev_entity = ent->prev_entity;
+		m_pFirstEntity = pEnt->m_pNextEntity;
+	if(pEnt->m_pNextEntity)
+		pEnt->m_pNextEntity->m_pPrevEntity = pEnt->m_pPrevEntity;
 
-	if(ent->prev_type_entity)
-		ent->prev_type_entity->next_type_entity = ent->next_type_entity;
+	if(pEnt->m_pPrevTypeEntity)
+		pEnt->m_pPrevTypeEntity->m_pNextTypeEntity = pEnt->m_pNextTypeEntity;
 	else
-		first_entity_types[ent->objtype] = ent->next_type_entity;
-	if(ent->next_type_entity)
-		ent->next_type_entity->prev_type_entity = ent->prev_type_entity;
-
-	ent->next_entity = 0;
-	ent->prev_entity = 0;
-	ent->next_type_entity = 0;
-	ent->prev_type_entity = 0;
+		m_apFirstEntityTypes[pEnt->m_Objtype] = pEnt->m_pNextTypeEntity;
+	if(pEnt->m_pNextTypeEntity)
+		pEnt->m_pNextTypeEntity->m_pPrevTypeEntity = pEnt->m_pPrevTypeEntity;
+
+	pEnt->m_pNextEntity = 0;
+	pEnt->m_pPrevEntity = 0;
+	pEnt->m_pNextTypeEntity = 0;
+	pEnt->m_pPrevTypeEntity = 0;
 }
 
 //
-void GAMEWORLD::snap(int snapping_client)
+void CGameWorld::Snap(int SnappingClient)
 {
-	for(ENTITY *ent = first_entity; ent; ent = ent->next_entity)
-		ent->snap(snapping_client);
+	for(CEntity *pEnt = m_pFirstEntity; pEnt; pEnt = pEnt->m_pNextEntity)
+		pEnt->Snap(SnappingClient);
 }
 
-void GAMEWORLD::reset()
+void CGameWorld::Reset()
 {
 	// reset all entities
-	for(ENTITY *ent = first_entity; ent; ent = ent->next_entity)
-		ent->reset();
-	remove_entities();
+	for(CEntity *pEnt = m_pFirstEntity; pEnt; pEnt = pEnt->m_pNextEntity)
+		pEnt->Reset();
+	RemoveEntities();
 
-	game.controller->post_reset();
-	remove_entities();
+	GameServer()->m_pController->PostReset();
+	RemoveEntities();
 
-	reset_requested = false;
+	m_ResetRequested = false;
 }
 
-void GAMEWORLD::remove_entities()
+void CGameWorld::RemoveEntities()
 {
 	// destroy objects marked for destruction
-	ENTITY *ent = first_entity;
-	while(ent)
+	CEntity *pEnt = m_pFirstEntity;
+	while(pEnt)
 	{
-		ENTITY *next = ent->next_entity;
-		if(ent->marked_for_destroy)
+		CEntity *pNext = pEnt->m_pNextEntity;
+		if(pEnt->m_MarkedForDestroy)
 		{
-			remove_entity(ent);
-			ent->destroy();
+			RemoveEntity(pEnt);
+			pEnt->Destroy();
 		}
-		ent = next;
+		pEnt = pNext;
 	}
 }
 
-void GAMEWORLD::tick()
+void CGameWorld::Tick()
 {
-	if(reset_requested)
-		reset();
+	if(m_ResetRequested)
+		Reset();
 
-	if(!paused)
+	if(!m_Paused)
 	{
-		if(game.controller->is_force_balanced())
-			game.send_chat(-1, GAMECONTEXT::CHAT_ALL, "Teams have been balanced");
+		if(GameServer()->m_pController->IsForceBalanced())
+			GameServer()->SendChat(-1, CGameContext::CHAT_ALL, "Teams have been balanced");
 		// update all objects
-		for(ENTITY *ent = first_entity; ent; ent = ent->next_entity)
-			ent->tick();
+		for(CEntity *pEnt = m_pFirstEntity; pEnt; pEnt = pEnt->m_pNextEntity)
+			pEnt->Tick();
 		
-		for(ENTITY *ent = first_entity; ent; ent = ent->next_entity)
-			ent->tick_defered();
+		for(CEntity *pEnt = m_pFirstEntity; pEnt; pEnt = pEnt->m_pNextEntity)
+			pEnt->TickDefered();
 	}
 
-	remove_entities();
+	RemoveEntities();
 }
 
 
 // TODO: should be more general
-CHARACTER *GAMEWORLD::intersect_character(vec2 pos0, vec2 pos1, float radius, vec2& new_pos, ENTITY *notthis)
+CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2& NewPos, CEntity *pNotThis)
 {
 	// Find other players
-	float closest_len = distance(pos0, pos1) * 100.0f;
-	vec2 line_dir = normalize(pos1-pos0);
-	CHARACTER *closest = 0;
+	float ClosestLen = distance(Pos0, Pos1) * 100.0f;
+	vec2 LineDir = normalize(Pos1-Pos0);
+	CCharacter *pClosest = 0;
 
-	CHARACTER *p = (CHARACTER *)game.world.find_first(NETOBJTYPE_CHARACTER);
-	for(; p; p = (CHARACTER *)p->typenext())
+	CCharacter *p = (CCharacter *)FindFirst(NETOBJTYPE_CHARACTER);
+	for(; p; p = (CCharacter *)p->TypeNext())
  	{
-		if(p == notthis)
+		if(p == pNotThis)
 			continue;
 			
-		vec2 intersect_pos = closest_point_on_line(pos0, pos1, p->pos);
-		float len = distance(p->pos, intersect_pos);
-		if(len < CHARACTER::phys_size+radius)
+		vec2 IntersectPos = closest_point_on_line(Pos0, Pos1, p->m_Pos);
+		float Len = distance(p->m_Pos, IntersectPos);
+		if(Len < p->m_ProximityRadius+Radius)
 		{
-			if(len < closest_len)
+			if(Len < ClosestLen)
 			{
-				new_pos = intersect_pos;
-				closest_len = len;
-				closest = p;
+				NewPos = IntersectPos;
+				ClosestLen = Len;
+				pClosest = p;
 			}
 		}
 	}
 	
-	return closest;
+	return pClosest;
 }
 
 
-CHARACTER *GAMEWORLD::closest_character(vec2 pos, float radius, ENTITY *notthis)
+CCharacter *CGameWorld::ClosestCharacter(vec2 Pos, float Radius, CEntity *pNotThis)
 {
 	// Find other players
-	float closest_range = radius*2;
-	CHARACTER *closest = 0;
+	float ClosestRange = Radius*2;
+	CCharacter *pClosest = 0;
 		
-	CHARACTER *p = (CHARACTER *)game.world.find_first(NETOBJTYPE_CHARACTER);
-	for(; p; p = (CHARACTER *)p->typenext())
+	CCharacter *p = (CCharacter *)GameServer()->m_World.FindFirst(NETOBJTYPE_CHARACTER);
+	for(; p; p = (CCharacter *)p->TypeNext())
  	{
-		if(p == notthis)
+		if(p == pNotThis)
 			continue;
 			
-		float len = distance(pos, p->pos);
-		if(len < CHARACTER::phys_size+radius)
+		float Len = distance(Pos, p->m_Pos);
+		if(Len < p->m_ProximityRadius+Radius)
 		{
-			if(len < closest_range)
+			if(Len < ClosestRange)
 			{
-				closest_range = len;
-				closest = p;
+				ClosestRange = Len;
+				pClosest = p;
 			}
 		}
 	}
 	
-	return closest;
+	return pClosest;
 }
diff --git a/src/game/server/gameworld.hpp b/src/game/server/gameworld.h
index 4757ad67..2d1cc4be 100644
--- a/src/game/server/gameworld.hpp
+++ b/src/game/server/gameworld.h
@@ -1,20 +1,20 @@
 #ifndef GAME_SERVER_GAMEWORLD_H
 #define GAME_SERVER_GAMEWORLD_H
 
-#include <game/gamecore.hpp>
+#include <game/gamecore.h>
 
-class ENTITY;
-class CHARACTER;
+class CEntity;
+class CCharacter;
 
 /*
 	Class: Game World
 		Tracks all entities in the game. Propagates tick and
 		snap calls to all entities.
 */
-class GAMEWORLD
+class CGameWorld
 {
-	void reset();
-	void remove_entities();
+	void Reset();
+	void RemoveEntities();
 
 	enum
 	{
@@ -22,19 +22,27 @@ class GAMEWORLD
 	};
 
 	// TODO: two lists seams kinda not good, shouldn't be needed
-	ENTITY *first_entity;
-	ENTITY *first_entity_types[NUM_ENT_TYPES];
+	CEntity *m_pFirstEntity;
+	CEntity *m_apFirstEntityTypes[NUM_ENT_TYPES];
+	
+	class CGameContext *m_pGameServer;
+	class IServer *m_pServer;
 
 public:
-	bool reset_requested;
-	bool paused;
-	WORLD_CORE core;
+	class CGameContext *GameServer() { return m_pGameServer; }
+	class IServer *Server() { return m_pServer; }
+
+	bool m_ResetRequested;
+	bool m_Paused;
+	CWorldCore m_Core;
+	
+	CGameWorld();
+	~CGameWorld();
 	
-	GAMEWORLD();
-	~GAMEWORLD();
+	void SetGameServer(CGameContext *pGameServer);
 	
-	ENTITY *find_first() { return first_entity; }
-	ENTITY *find_first(int type);
+	CEntity *FindFirst() { return m_pFirstEntity; }
+	CEntity *FindFirst(int Type);
 	
 	/*
 		Function: find_entities
@@ -51,37 +59,37 @@ public:
 		Returns:
 			Number of entities found and added to the ents array.
 	*/
-	int find_entities(vec2 pos, float radius, ENTITY **ents, int max, int type = -1);
+	int FindEntities(vec2 Pos, float Radius, CEntity **ppEnts, int Max, int Type = -1);
 	
 	/*
-		Function: interserct_character
-			Finds the closest character that intersects the line.
+		Function: interserct_CCharacter
+			Finds the closest CCharacter that intersects the line.
 			
 		Arguments:
 			pos0 - Start position
 			pos2 - End position
-			radius - How for from the line the character is allowed to be.
+			radius - How for from the line the CCharacter is allowed to be.
 			new_pos - Intersection position
 			notthis - Entity to ignore intersecting with
 			
 		Returns:
 			Returns a pointer to the closest hit or NULL of there is no intersection.
 	*/
-	class CHARACTER *intersect_character(vec2 pos0, vec2 pos1, float radius, vec2 &new_pos, class ENTITY *notthis = 0);
+	class CCharacter *IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2 &NewPos, class CEntity *pNotThis = 0);
 	
 	/*
-		Function: closest_character
-			Finds the closest character to a specific point.
+		Function: closest_CCharacter
+			Finds the closest CCharacter to a specific point.
 			
 		Arguments:
 			pos - The center position.
-			radius - How far off the character is allowed to be
+			radius - How far off the CCharacter is allowed to be
 			notthis - Entity to ignore
 			
 		Returns:
-			Returns a pointer to the closest character or NULL if no character is close enough.
+			Returns a pointer to the closest CCharacter or NULL if no CCharacter is close enough.
 	*/
-	class CHARACTER *closest_character(vec2 pos, float radius, ENTITY *notthis);
+	class CCharacter *ClosestCharacter(vec2 Pos, float Radius, CEntity *ppNotThis);
 
 	/*
 		Function: insert_entity
@@ -90,7 +98,7 @@ public:
 		Arguments:
 			entity - Entity to add
 	*/
-	void insert_entity(ENTITY *entity);
+	void InsertEntity(CEntity *pEntity);
 
 	/*
 		Function: remove_entity
@@ -99,7 +107,7 @@ public:
 		Arguments:
 			entity - Entity to remove
 	*/
-	void remove_entity(ENTITY *entity);
+	void RemoveEntity(CEntity *pEntity);
 
 	/*
 		Function: destroy_entity
@@ -108,7 +116,7 @@ public:
 		Arguments:
 			entity - Entity to destroy
 	*/
-	void destroy_entity(ENTITY *entity);
+	void DestroyEntity(CEntity *pEntity);
 	
 	/*
 		Function: snap
@@ -119,7 +127,7 @@ public:
 			snapping_client - ID of the client which snapshot
 			is being created.
 	*/
-	void snap(int snapping_client);
+	void Snap(int SnappingClient);
 	
 	/*
 		Function: tick
@@ -127,7 +135,7 @@ public:
 			the world to the next tick.
 		
 	*/
-	void tick();
+	void Tick();
 };
 
 #endif
diff --git a/src/game/server/hooks.cpp b/src/game/server/hooks.cpp
deleted file mode 100644
index 89c95f79..00000000
--- a/src/game/server/hooks.cpp
+++ /dev/null
@@ -1,599 +0,0 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <base/math.hpp>
-
-#include <engine/e_config.h>
-#include <engine/e_server_interface.h>
-#include <engine/e_memheap.h>
-
-#include <game/version.hpp>
-#include <game/collision.hpp>
-#include <game/layers.hpp>
-
-#include <game/gamecore.hpp>
-
-#include "gamecontext.hpp"
-#include "gamemodes/dm.hpp"
-#include "gamemodes/tdm.hpp"
-#include "gamemodes/ctf.hpp"
-#include "gamemodes/mod.hpp"
-
-TUNING_PARAMS tuning;
-
-static void check_pure_tuning()
-{
-	// might not be created yet during start up
-	if(!game.controller)
-		return;
-	
-	if(	strcmp(game.controller->gametype, "DM")==0 ||
-		strcmp(game.controller->gametype, "TDM")==0 ||
-		strcmp(game.controller->gametype, "CTF")==0)
-	{
-		TUNING_PARAMS p;
-		if(memcmp(&p, &tuning, sizeof(TUNING_PARAMS)) != 0)
-		{
-			dbg_msg("server", "resetting tuning due to pure server");
-			tuning = p;
-		}
-	}	
-}
-
-struct VOTEOPTION
-{
-	VOTEOPTION *next;
-	VOTEOPTION *prev;
-	char command[1];
-};
-
-static HEAP *voteoption_heap = 0;
-static VOTEOPTION *voteoption_first = 0;
-static VOTEOPTION *voteoption_last = 0;
-
-void send_tuning_params(int cid)
-{
-	check_pure_tuning();
-	
-	msg_pack_start(NETMSGTYPE_SV_TUNEPARAMS, MSGFLAG_VITAL);
-	int *params = (int *)&tuning;
-	for(unsigned i = 0; i < sizeof(tuning)/sizeof(int); i++)
-		msg_pack_int(params[i]);
-	msg_pack_end();
-	server_send_msg(cid);
-}
-
-// Server hooks
-void mods_client_direct_input(int client_id, void *input)
-{
-	if(!game.world.paused)
-		game.players[client_id]->on_direct_input((NETOBJ_PLAYER_INPUT *)input);
-}
-
-void mods_client_predicted_input(int client_id, void *input)
-{
-	if(!game.world.paused)
-		game.players[client_id]->on_predicted_input((NETOBJ_PLAYER_INPUT *)input);
-}
-
-// Server hooks
-void mods_tick()
-{
-	check_pure_tuning();
-	
-	game.tick();
-
-#ifdef CONF_DEBUG
-	if(config.dbg_dummies)
-	{
-		for(int i = 0; i < config.dbg_dummies ; i++)
-		{
-			NETOBJ_PLAYER_INPUT input = {0};
-			input.direction = (i&1)?-1:1;
-			game.players[MAX_CLIENTS-i-1]->on_predicted_input(&input);
-		}
-	}
-#endif
-}
-
-void mods_snap(int client_id)
-{
-	game.snap(client_id);
-}
-
-void mods_client_enter(int client_id)
-{
-	//game.world.insert_entity(&game.players[client_id]);
-	game.players[client_id]->respawn();
-	dbg_msg("game", "join player='%d:%s'", client_id, server_clientname(client_id));
-
-
-	char buf[512];
-	str_format(buf, sizeof(buf), "%s entered and joined the %s", server_clientname(client_id), game.controller->get_team_name(game.players[client_id]->team));
-	game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf); 
-
-	dbg_msg("game", "team_join player='%d:%s' team=%d", client_id, server_clientname(client_id), game.players[client_id]->team);
-}
-
-void mods_connected(int client_id)
-{
-	game.players[client_id] = new(client_id) PLAYER(client_id);
-	//game.players[client_id].init(client_id);
-	//game.players[client_id].client_id = client_id;
-	
-	// Check which team the player should be on
-	if(config.sv_tournament_mode)
-		game.players[client_id]->team = -1;
-	else
-		game.players[client_id]->team = game.controller->get_auto_team(client_id);
-		
-	(void) game.controller->check_team_balance();
-
-	// send motd
-	NETMSG_SV_MOTD msg;
-	msg.message = config.sv_motd;
-	msg.pack(MSGFLAG_VITAL);
-	server_send_msg(client_id);
-}
-
-void mods_client_drop(int client_id)
-{
-	game.abort_vote_kick_on_disconnect(client_id);
-	game.players[client_id]->on_disconnect();
-	delete game.players[client_id];
-	game.players[client_id] = 0;
-	
-	(void) game.controller->check_team_balance();
-}
-
-/*static bool is_separator(char c) { return c == ';' || c == ' ' || c == ',' || c == '\t'; }
-
-static const char *liststr_find(const char *str, const char *needle)
-{
-	int needle_len = strlen(needle);
-	while(*str)
-	{
-		int wordlen = 0;
-		while(str[wordlen] && !is_separator(str[wordlen]))
-			wordlen++;
-		
-		if(wordlen == needle_len && strncmp(str, needle, needle_len) == 0)
-			return str;
-		
-		str += wordlen+1;
-	}
-	
-	return 0;
-}*/
-
-void mods_message(int msgtype, int client_id)
-{
-	void *rawmsg = netmsg_secure_unpack(msgtype);
-	PLAYER *p = game.players[client_id];
-	
-	if(!rawmsg)
-	{
-		dbg_msg("server", "dropped weird message '%s' (%d), failed on '%s'", netmsg_get_name(msgtype), msgtype, netmsg_failed_on());
-		return;
-	}
-	
-	if(msgtype == NETMSGTYPE_CL_SAY)
-	{
-		NETMSG_CL_SAY *msg = (NETMSG_CL_SAY *)rawmsg;
-		int team = msg->team;
-		if(team)
-			team = p->team;
-		else
-			team = GAMECONTEXT::CHAT_ALL;
-		
-		if(config.sv_spamprotection && p->last_chat+time_freq() > time_get())
-			return;
-		
-		p->last_chat = time_get();
-		
-		game.send_chat(client_id, team, msg->message);
-	}
-	else if(msgtype == NETMSGTYPE_CL_CALLVOTE)
-	{
-		int64 now = time_get();
-		if(game.vote_closetime)
-		{
-			game.send_chat_target(client_id, "Wait for current vote to end before calling a new one.");
-			return;
-		}
-		
-		int64 timeleft = p->last_votecall + time_freq()*60 - now;
-		if(timeleft > 0)
-		{
-			char chatmsg[512] = {0};
-			str_format(chatmsg, sizeof(chatmsg), "You must wait %d seconds before making another vote", (timeleft/time_freq())+1);
-			game.send_chat_target(client_id, chatmsg);
-			return;
-		}
-		
-		char chatmsg[512] = {0};
-		char desc[512] = {0};
-		char cmd[512] = {0};
-		NETMSG_CL_CALLVOTE *msg = (NETMSG_CL_CALLVOTE *)rawmsg;
-		if(str_comp_nocase(msg->type, "option") == 0)
-		{
-			VOTEOPTION *option = voteoption_first;
-			while(option)
-			{
-				if(str_comp_nocase(msg->value, option->command) == 0)
-				{
-					str_format(chatmsg, sizeof(chatmsg), "%s called vote to change server option '%s'", server_clientname(client_id), option->command);
-					str_format(desc, sizeof(desc), "%s", option->command);
-					str_format(cmd, sizeof(cmd), "%s", option->command);
-					break;
-				}
-
-				option = option->next;
-			}
-			
-			if(!option)
-			{
-				str_format(chatmsg, sizeof(chatmsg), "'%s' isn't an option on this server", msg->value);
-				game.send_chat_target(client_id, chatmsg);
-				return;
-			}
-		}
-		else if(str_comp_nocase(msg->type, "kick") == 0)
-		{
-			if(!config.sv_vote_kick)
-			{
-				game.send_chat_target(client_id, "Server does not allow voting to kick players");
-				return;
-			}
-			
-			int kick_id = atoi(msg->value);
-			if(kick_id < 0 || kick_id >= MAX_CLIENTS || !game.players[kick_id])
-			{
-				game.send_chat_target(client_id, "Invalid client id to kick");
-				return;
-			}
-			
-			str_format(chatmsg, sizeof(chatmsg), "%s called for vote to kick '%s'", server_clientname(client_id), server_clientname(kick_id));
-			str_format(desc, sizeof(desc), "Kick '%s'", server_clientname(kick_id));
-			str_format(cmd, sizeof(cmd), "kick %d", kick_id);
-			if (!config.sv_vote_kick_bantime)
-				str_format(cmd, sizeof(cmd), "kick %d", kick_id);
-			else
-				str_format(cmd, sizeof(cmd), "ban %d %d", kick_id, config.sv_vote_kick_bantime);
-		}
-		
-		if(cmd[0])
-		{
-			game.send_chat(-1, GAMECONTEXT::CHAT_ALL, chatmsg);
-			game.start_vote(desc, cmd);
-			p->vote = 1;
-			game.vote_creator = client_id;
-			p->last_votecall = now;
-			game.send_vote_status(-1);
-		}
-	}
-	else if(msgtype == NETMSGTYPE_CL_VOTE)
-	{
-		if(!game.vote_closetime)
-			return;
-
-		if(p->vote == 0)
-		{
-			NETMSG_CL_VOTE *msg = (NETMSG_CL_VOTE *)rawmsg;
-			p->vote = msg->vote;
-			game.send_vote_status(-1);
-		}
-	}
-	else if (msgtype == NETMSGTYPE_CL_SETTEAM && !game.world.paused)
-	{
-		NETMSG_CL_SETTEAM *msg = (NETMSG_CL_SETTEAM *)rawmsg;
-		
-		if(config.sv_spamprotection && p->last_setteam+time_freq()*3 > time_get())
-			return;
-
-		// Switch team on given client and kill/respawn him
-		if(game.controller->can_join_team(msg->team, client_id))
-		{
-			if(game.controller->can_change_team(p, msg->team))
-			{
-				p->last_setteam = time_get();
-				p->set_team(msg->team);
-				(void) game.controller->check_team_balance();
-			}
-			else
-				game.send_broadcast("Teams must be balanced, please join other team", client_id);
-		}
-		else
-		{
-			char buf[128];
-			str_format(buf, sizeof(buf), "Only %d active players are allowed", config.sv_max_clients-config.sv_spectator_slots);
-			game.send_broadcast(buf, client_id);
-		}
-	}
-	else if (msgtype == NETMSGTYPE_CL_CHANGEINFO || msgtype == NETMSGTYPE_CL_STARTINFO)
-	{
-		NETMSG_CL_CHANGEINFO *msg = (NETMSG_CL_CHANGEINFO *)rawmsg;
-		
-		if(config.sv_spamprotection && p->last_changeinfo+time_freq()*5 > time_get())
-			return;
-			
-		p->last_changeinfo = time_get();
-		
-		p->use_custom_color = msg->use_custom_color;
-		p->color_body = msg->color_body;
-		p->color_feet = msg->color_feet;
-
-		// check for invalid chars
-		unsigned char *name = (unsigned char *)msg->name;
-		while (*name)
-		{
-			if(*name < 32)
-				*name = ' ';
-			name++;
-		}
-
-		// copy old name
-		char oldname[MAX_NAME_LENGTH];
-		str_copy(oldname, server_clientname(client_id), MAX_NAME_LENGTH);
-		
-		server_setclientname(client_id, msg->name);
-		if(msgtype == NETMSGTYPE_CL_CHANGEINFO && strcmp(oldname, server_clientname(client_id)) != 0)
-		{
-			char chattext[256];
-			str_format(chattext, sizeof(chattext), "%s changed name to %s", oldname, server_clientname(client_id));
-			game.send_chat(-1, GAMECONTEXT::CHAT_ALL, chattext);
-		}
-		
-		// set skin
-		str_copy(p->skin_name, msg->skin, sizeof(p->skin_name));
-		
-		game.controller->on_player_info_change(p);
-		
-		if(msgtype == NETMSGTYPE_CL_STARTINFO)
-		{
-			// send vote options
-			NETMSG_SV_VOTE_CLEAROPTIONS clearmsg;
-			clearmsg.pack(MSGFLAG_VITAL);
-			server_send_msg(client_id);
-			VOTEOPTION *current = voteoption_first;
-			while(current)
-			{
-				NETMSG_SV_VOTE_OPTION optionmsg;
-				optionmsg.command = current->command;
-				optionmsg.pack(MSGFLAG_VITAL);
-				server_send_msg(client_id);
-				current = current->next;
-			}
-			
-			// send tuning parameters to client
-			send_tuning_params(client_id);
-
-			//
-			NETMSG_SV_READYTOENTER m;
-			m.pack(MSGFLAG_VITAL|MSGFLAG_FLUSH);
-			server_send_msg(client_id);
-		}
-	}
-	else if (msgtype == NETMSGTYPE_CL_EMOTICON && !game.world.paused)
-	{
-		NETMSG_CL_EMOTICON *msg = (NETMSG_CL_EMOTICON *)rawmsg;
-		
-		if(config.sv_spamprotection && p->last_emote+time_freq()*3 > time_get())
-			return;
-			
-		p->last_emote = time_get();
-		
-		game.send_emoticon(client_id, msg->emoticon);
-	}
-	else if (msgtype == NETMSGTYPE_CL_KILL && !game.world.paused)
-	{
-		if(p->last_kill+time_freq()*3 > time_get())
-			return;
-		
-		p->last_kill = time_get();
-		p->kill_character(WEAPON_SELF);
-		p->respawn_tick = server_tick()+server_tickspeed()*3;
-	}
-}
-
-static void con_tune_param(void *result, void *user_data)
-{
-	const char *param_name = console_arg_string(result, 0);
-	float new_value = console_arg_float(result, 1);
-
-	if(tuning.set(param_name, new_value))
-	{
-		dbg_msg("tuning", "%s changed to %.2f", param_name, new_value);
-		send_tuning_params(-1);
-	}
-	else
-		console_print("No such tuning parameter");
-}
-
-static void con_tune_reset(void *result, void *user_data)
-{
-	TUNING_PARAMS p;
-	tuning = p;
-	send_tuning_params(-1);
-	console_print("tuning reset");
-}
-
-static void con_tune_dump(void *result, void *user_data)
-{
-	for(int i = 0; i < tuning.num(); i++)
-	{
-		float v;
-		tuning.get(i, &v);
-		dbg_msg("tuning", "%s %.2f", tuning.names[i], v);
-	}
-}
-
-
-static void con_change_map(void *result, void *user_data)
-{
-	game.controller->change_map(console_arg_string(result, 0));
-}
-
-static void con_restart(void *result, void *user_data)
-{
-	if(console_arg_num(result))
-		game.controller->do_warmup(console_arg_int(result, 0));
-	else
-		game.controller->startround();
-}
-
-static void con_broadcast(void *result, void *user_data)
-{
-	game.send_broadcast(console_arg_string(result, 0), -1);
-}
-
-static void con_say(void *result, void *user_data)
-{
-	game.send_chat(-1, GAMECONTEXT::CHAT_ALL, console_arg_string(result, 0));
-}
-
-static void con_set_team(void *result, void *user_data)
-{
-	int client_id = clamp(console_arg_int(result, 0), 0, (int)MAX_CLIENTS);
-	int team = clamp(console_arg_int(result, 1), -1, 1);
-	
-	dbg_msg("", "%d %d", client_id, team);
-	
-	if(!game.players[client_id])
-		return;
-	
-	game.players[client_id]->set_team(team);
-	(void) game.controller->check_team_balance();
-}
-
-static void con_addvote(void *result, void *user_data)
-{
-	int len = strlen(console_arg_string(result, 0));
-	
-	if(!voteoption_heap)
-		voteoption_heap = memheap_create();
-	
-	VOTEOPTION *option = (VOTEOPTION *)memheap_allocate(voteoption_heap, sizeof(VOTEOPTION) + len);
-	option->next = 0;
-	option->prev = voteoption_last;
-	if(option->prev)
-		option->prev->next = option;
-	voteoption_last = option;
-	if(!voteoption_first)
-		voteoption_first = option;
-	
-	mem_copy(option->command, console_arg_string(result, 0), len+1);
-	dbg_msg("server", "added option '%s'", option->command);
-}
-
-static void con_vote(void *result, void *user_data)
-{
-	if(str_comp_nocase(console_arg_string(result, 0), "yes") == 0)
-		game.vote_enforce = GAMECONTEXT::VOTE_ENFORCE_YES;
-	else if(str_comp_nocase(console_arg_string(result, 0), "no") == 0)
-		game.vote_enforce = GAMECONTEXT::VOTE_ENFORCE_NO;
-	dbg_msg("server", "forcing vote %s", console_arg_string(result, 0));
-}
-
-void mods_console_init()
-{
-	MACRO_REGISTER_COMMAND("tune", "si", CFGFLAG_SERVER, con_tune_param, 0, "");
-	MACRO_REGISTER_COMMAND("tune_reset", "", CFGFLAG_SERVER, con_tune_reset, 0, "");
-	MACRO_REGISTER_COMMAND("tune_dump", "", CFGFLAG_SERVER, con_tune_dump, 0, "");
-
-	MACRO_REGISTER_COMMAND("change_map", "r", CFGFLAG_SERVER, con_change_map, 0, "");
-	MACRO_REGISTER_COMMAND("restart", "?i", CFGFLAG_SERVER, con_restart, 0, "");
-	MACRO_REGISTER_COMMAND("broadcast", "r", CFGFLAG_SERVER, con_broadcast, 0, "");
-	MACRO_REGISTER_COMMAND("say", "r", CFGFLAG_SERVER, con_say, 0, "");
-	MACRO_REGISTER_COMMAND("set_team", "ii", CFGFLAG_SERVER, con_set_team, 0, "");
-
-	MACRO_REGISTER_COMMAND("addvote", "r", CFGFLAG_SERVER, con_addvote, 0, "");
-	MACRO_REGISTER_COMMAND("vote", "r", CFGFLAG_SERVER, con_vote, 0, "");
-}
-
-void mods_init()
-{
-	//if(!data) /* only load once */
-		//data = load_data_from_memory(internal_data);
-		
-	for(int i = 0; i < NUM_NETOBJTYPES; i++)
-		snap_set_staticsize(i, netobj_get_size(i));
-
-	layers_init();
-	col_init();
-
-	// reset everything here
-	//world = new GAMEWORLD;
-	//players = new PLAYER[MAX_CLIENTS];
-
-	// select gametype
-	if(strcmp(config.sv_gametype, "mod") == 0)
-		game.controller = new GAMECONTROLLER_MOD;
-	else if(strcmp(config.sv_gametype, "ctf") == 0)
-		game.controller = new GAMECONTROLLER_CTF;
-	else if(strcmp(config.sv_gametype, "tdm") == 0)
-		game.controller = new GAMECONTROLLER_TDM;
-	else
-		game.controller = new GAMECONTROLLER_DM;
-
-	// setup core world
-	//for(int i = 0; i < MAX_CLIENTS; i++)
-	//	game.players[i].core.world = &game.world.core;
-
-	// create all entities from the game layer
-	MAPITEM_LAYER_TILEMAP *tmap = layers_game_layer();
-	TILE *tiles = (TILE *)map_get_data(tmap->data);
-	
-	/*
-	num_spawn_points[0] = 0;
-	num_spawn_points[1] = 0;
-	num_spawn_points[2] = 0;
-	*/
-	
-	for(int y = 0; y < tmap->height; y++)
-	{
-		for(int x = 0; x < tmap->width; x++)
-		{
-			int index = tiles[y*tmap->width+x].index;
-			
-			if(index >= ENTITY_OFFSET)
-			{
-				vec2 pos(x*32.0f+16.0f, y*32.0f+16.0f);
-				game.controller->on_entity(index-ENTITY_OFFSET, pos);
-			}
-		}
-	}
-
-	//game.world.insert_entity(game.controller);
-
-#ifdef CONF_DEBUG
-	if(config.dbg_dummies)
-	{
-		for(int i = 0; i < config.dbg_dummies ; i++)
-		{
-			mods_connected(MAX_CLIENTS-i-1);
-			mods_client_enter(MAX_CLIENTS-i-1);
-			if(game.controller->is_teamplay())
-				game.players[MAX_CLIENTS-i-1]->team = i&1;
-		}
-	}
-#endif
-}
-
-void mods_shutdown()
-{
-	delete game.controller;
-	game.controller = 0;
-	game.clear();
-}
-
-void mods_presnap() {}
-void mods_postsnap()
-{
-	game.events.clear();
-}
-
-const char *mods_net_version() { return GAME_NETVERSION; }
-const char *mods_version() { return GAME_VERSION; }
diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp
index a0a2b051..0eb61cac 100644
--- a/src/game/server/player.cpp
+++ b/src/game/server/player.cpp
@@ -1,183 +1,185 @@
 #include <new>
+#include "player.h"
 
-#include <engine/e_server_interface.h>
 
-#include "player.hpp"
-#include "gamecontext.hpp"
+MACRO_ALLOC_POOL_ID_IMPL(CPlayer, MAX_CLIENTS)
 
-MACRO_ALLOC_POOL_ID_IMPL(PLAYER, MAX_CLIENTS)
-
-PLAYER::PLAYER(int client_id)
+IServer *CPlayer::Server() const { return m_pGameServer->Server(); }
+	
+CPlayer::CPlayer(CGameContext *pGameServer, int CID, int Team)
 {
-	respawn_tick = server_tick();
-	character = 0;
-	this->client_id = client_id;
+	m_pGameServer = pGameServer;
+	m_RespawnTick = Server()->Tick();
+	m_DieTick = Server()->Tick();
+	Character = 0;
+	this->m_ClientID = CID;
+	m_Team = GameServer()->m_pController->ClampTeam(Team);
 }
 
-PLAYER::~PLAYER()
+CPlayer::~CPlayer()
 {
-	delete character;
-	character = 0;
+	delete Character;
+	Character = 0;
 }
 
-void PLAYER::tick()
+void CPlayer::Tick()
 {
-	server_setclientscore(client_id, score);
+	Server()->SetClientScore(m_ClientID, m_Score);
 
 	// do latency stuff
 	{
-		CLIENT_INFO info;
-		if(server_getclientinfo(client_id, &info))
+		IServer::CClientInfo Info;
+		if(Server()->GetClientInfo(m_ClientID, &Info))
 		{
-			latency.accum += info.latency;
-			latency.accum_max = max(latency.accum_max, info.latency);
-			latency.accum_min = min(latency.accum_min, info.latency);
+			m_Latency.m_Accum += Info.m_Latency;
+			m_Latency.m_AccumMax = max(m_Latency.m_AccumMax, Info.m_Latency);
+			m_Latency.m_AccumMin = min(m_Latency.m_AccumMin, Info.m_Latency);
 		}
-
-		if(server_tick()%server_tickspeed() == 0)
+		// each second
+		if(Server()->Tick()%Server()->TickSpeed() == 0)
 		{
-			latency.avg = latency.accum/server_tickspeed();
-			latency.max = latency.accum_max;
-			latency.min = latency.accum_min;
-			latency.accum = 0;
-			latency.accum_min = 1000;
-			latency.accum_max = 0;
+			m_Latency.m_Avg = m_Latency.m_Accum/Server()->TickSpeed();
+			m_Latency.m_Max = m_Latency.m_AccumMax;
+			m_Latency.m_Min = m_Latency.m_AccumMin;
+			m_Latency.m_Accum = 0;
+			m_Latency.m_AccumMin = 1000;
+			m_Latency.m_AccumMax = 0;
 		}
 	}
 	
-	if(!character && die_tick+server_tickspeed()*3 <= server_tick())
-		spawning = true;
+	if(!Character && m_DieTick+Server()->TickSpeed()*3 <= Server()->Tick())
+		m_Spawning = true;
 
-	if(character)
+	if(Character)
 	{
-		if(character->alive)
+		if(Character->IsAlive())
 		{
-			view_pos = character->pos;
+			m_ViewPos = Character->m_Pos;
 		}
 		else
 		{
-			delete character;
-			character = 0;
+			delete Character;
+			Character = 0;
 		}
 	}
-	else if(spawning && respawn_tick <= server_tick())
-		try_respawn();
+	else if(m_Spawning && m_RespawnTick <= Server()->Tick())
+		TryRespawn();
 }
 
-void PLAYER::snap(int snapping_client)
+void CPlayer::Snap(int SnappingClient)
 {
-	NETOBJ_CLIENT_INFO *client_info = (NETOBJ_CLIENT_INFO *)snap_new_item(NETOBJTYPE_CLIENT_INFO, client_id, sizeof(NETOBJ_CLIENT_INFO));
-	str_to_ints(&client_info->name0, 6, server_clientname(client_id));
-	str_to_ints(&client_info->skin0, 6, skin_name);
-	client_info->use_custom_color = use_custom_color;
-	client_info->color_body = color_body;
-	client_info->color_feet = color_feet;
-
-	NETOBJ_PLAYER_INFO *info = (NETOBJ_PLAYER_INFO *)snap_new_item(NETOBJTYPE_PLAYER_INFO, client_id, sizeof(NETOBJ_PLAYER_INFO));
-
-	info->latency = latency.min;
-	info->latency_flux = latency.max-latency.min;
-	info->local = 0;
-	info->cid = client_id;
-	info->score = score;
-	info->team = team;
-
-	if(client_id == snapping_client)
-		info->local = 1;	
+	CNetObj_ClientInfo *ClientInfo = static_cast<CNetObj_ClientInfo *>(Server()->SnapNewItem(NETOBJTYPE_CLIENTINFO, m_ClientID, sizeof(CNetObj_ClientInfo)));
+	StrToInts(&ClientInfo->m_Name0, 6, Server()->ClientName(m_ClientID));
+	StrToInts(&ClientInfo->m_Skin0, 6, m_TeeInfos.m_SkinName);
+	ClientInfo->m_UseCustomColor = m_TeeInfos.m_UseCustomColor;
+	ClientInfo->m_ColorBody = m_TeeInfos.m_ColorBody;
+	ClientInfo->m_ColorFeet = m_TeeInfos.m_ColorFeet;
+
+	CNetObj_PlayerInfo *Info = static_cast<CNetObj_PlayerInfo *>(Server()->SnapNewItem(NETOBJTYPE_PLAYERINFO, m_ClientID, sizeof(CNetObj_PlayerInfo)));
+
+	Info->m_Latency = m_Latency.m_Min;
+	Info->m_LatencyFlux = m_Latency.m_Max-m_Latency.m_Min;
+	Info->m_Local = 0;
+	Info->m_ClientId = m_ClientID;
+	Info->m_Score = m_Score;
+	Info->m_Team = m_Team;
+
+	if(m_ClientID == SnappingClient)
+		Info->m_Local = 1;	
 }
 
-void PLAYER::on_disconnect()
+void CPlayer::OnDisconnect()
 {
-	kill_character(WEAPON_GAME);
-	
-	//game.controller->on_player_death(&game.players[client_id], 0, -1);
-		
-	char buf[512];
-	str_format(buf, sizeof(buf),  "%s has left the game", server_clientname(client_id));
-	game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf);
+	KillCharacter();
+
+	if(Server()->ClientIngame(m_ClientID))
+	{
+		char Buf[512];
+		str_format(Buf, sizeof(Buf),  "%s has left the game", Server()->ClientName(m_ClientID));
+		GameServer()->SendChat(-1, CGameContext::CHAT_ALL, Buf);
 
-	dbg_msg("game", "leave player='%d:%s'", client_id, server_clientname(client_id));
+		dbg_msg("game", "leave player='%d:%s'", m_ClientID, Server()->ClientName(m_ClientID));
+	}
 }
 
-void PLAYER::on_predicted_input(NETOBJ_PLAYER_INPUT *new_input)
+void CPlayer::OnPredictedInput(CNetObj_PlayerInput *NewInput)
 {
-	CHARACTER *chr = get_character();
-	if(chr)
-		chr->on_predicted_input(new_input);
+	if(Character)
+		Character->OnPredictedInput(NewInput);
 }
 
-void PLAYER::on_direct_input(NETOBJ_PLAYER_INPUT *new_input)
+void CPlayer::OnDirectInput(CNetObj_PlayerInput *NewInput)
 {
-	CHARACTER *chr = get_character();
-	if(chr)
-		chr->on_direct_input(new_input);
+	if(Character)
+		Character->OnDirectInput(NewInput);
 
-	if(!chr && team >= 0 && (new_input->fire&1))
-		spawning = true;
+	if(!Character && m_Team >= 0 && (NewInput->m_Fire&1))
+		m_Spawning = true;
 	
-	if(!chr && team == -1)
-		view_pos = vec2(new_input->target_x, new_input->target_y);
+	if(!Character && m_Team == -1)
+		m_ViewPos = vec2(NewInput->m_TargetX, NewInput->m_TargetY);
 }
 
-CHARACTER *PLAYER::get_character()
+CCharacter *CPlayer::GetCharacter()
 {
-	if(character && character->alive)
-		return character;
+	if(Character && Character->IsAlive())
+		return Character;
 	return 0;
 }
 
-void PLAYER::kill_character(int weapon)
+void CPlayer::KillCharacter(int Weapon)
 {
-	//CHARACTER *chr = get_character();
-	if(character)
+	if(Character)
 	{
-		character->die(client_id, weapon);
-		delete character;
-		character = 0;
+		Character->Die(m_ClientID, Weapon);
+		delete Character;
+		Character = 0;
 	}
 }
 
-void PLAYER::respawn()
+void CPlayer::Respawn()
 {
-	if(team > -1)
-		spawning = true;
+	if(m_Team > -1)
+		m_Spawning = true;
 }
 
-void PLAYER::set_team(int new_team)
+void CPlayer::SetTeam(int Team)
 {
 	// clamp the team
-	new_team = game.controller->clampteam(new_team);
-	if(team == new_team)
+	Team = GameServer()->m_pController->ClampTeam(Team);
+	if(m_Team == Team)
 		return;
 		
-	char buf[512];
-	str_format(buf, sizeof(buf), "%s joined the %s", server_clientname(client_id), game.controller->get_team_name(new_team));
-	game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf); 
+	char Buf[512];
+	str_format(Buf, sizeof(Buf), "%s joined the %s", Server()->ClientName(m_ClientID), GameServer()->m_pController->GetTeamName(Team));
+	GameServer()->SendChat(-1, CGameContext::CHAT_ALL, Buf); 
 	
-	kill_character(WEAPON_GAME);
-	team = new_team;
-	score = 0;
-	dbg_msg("game", "team_join player='%d:%s' team=%d", client_id, server_clientname(client_id), team);
+	KillCharacter();
+	m_Team = Team;
+	m_Score = 0;
+	// we got to wait 0.5 secs before respawning
+	m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2;
+	dbg_msg("game", "team_join player='%d:%s' m_Team=%d", m_ClientID, Server()->ClientName(m_ClientID), m_Team);
 	
-	game.controller->on_player_info_change(game.players[client_id]);
+	GameServer()->m_pController->OnPlayerInfoChange(GameServer()->m_apPlayers[m_ClientID]);
 }
 
-void PLAYER::try_respawn()
+void CPlayer::TryRespawn()
 {
-	vec2 spawnpos = vec2(100.0f, -60.0f);
+	vec2 SpawnPos = vec2(100.0f, -60.0f);
 	
-	if(!game.controller->can_spawn(this, &spawnpos))
+	if(!GameServer()->m_pController->CanSpawn(this, &SpawnPos))
 		return;
 
 	// check if the position is occupado
-	ENTITY *ents[2] = {0};
-	int num_ents = game.world.find_entities(spawnpos, 64, ents, 2, NETOBJTYPE_CHARACTER);
+	CEntity *apEnts[2] = {0};
+	int NumEnts = GameServer()->m_World.FindEntities(SpawnPos, 64, apEnts, 2, NETOBJTYPE_CHARACTER);
 	
-	if(num_ents == 0)
+	if(NumEnts == 0)
 	{
-		spawning = false;
-		character = new(client_id) CHARACTER();
-		character->spawn(this, spawnpos, team);
-		game.create_playerspawn(spawnpos);
+		m_Spawning = false;
+		Character = new(m_ClientID) CCharacter(&GameServer()->m_World);
+		Character->Spawn(this, SpawnPos);
+		GameServer()->CreatePlayerSpawn(SpawnPos);
 	}
 }
diff --git a/src/game/server/player.h b/src/game/server/player.h
new file mode 100644
index 00000000..1b631d45
--- /dev/null
+++ b/src/game/server/player.h
@@ -0,0 +1,89 @@
+#ifndef GAME_SERVER_PLAYER_H
+#define GAME_SERVER_PLAYER_H
+
+// this include should perhaps be removed
+#include "entities/character.h"
+#include "gamecontext.h"
+
+// player object
+class CPlayer
+{
+	MACRO_ALLOC_POOL_ID()
+	
+public:
+	CPlayer(CGameContext *pGameServer, int CID, int Team);
+	~CPlayer();
+
+	void Init(int CID);
+
+	void TryRespawn();
+	void Respawn();
+	void SetTeam(int Team);
+	int GetTeam() const { return m_Team; };
+	int GetCID() const { return m_ClientID; };
+	
+	void Tick();
+	void Snap(int SnappingClient);
+
+	void OnDirectInput(CNetObj_PlayerInput *NewInput);
+	void OnPredictedInput(CNetObj_PlayerInput *NewInput);
+	void OnDisconnect();
+	
+	void KillCharacter(int Weapon = WEAPON_GAME);
+	CCharacter *GetCharacter();
+	
+	//---------------------------------------------------------
+	// this is used for snapping so we know how we can clip the view for the player
+	vec2 m_ViewPos;
+	
+	//
+	int m_Vote;
+	int m_VotePos;
+	//
+	int m_Last_VoteCall;
+	int m_Last_VoteTry;
+	int m_Last_Chat;
+	int m_Last_SetTeam;
+	int m_Last_ChangeInfo;
+	int m_Last_Emote;
+	int m_Last_Kill;
+	
+	// TODO: clean this up
+	struct 
+	{
+		char m_SkinName[64];
+		int m_UseCustomColor;
+		int m_ColorBody;
+		int m_ColorFeet;
+	} m_TeeInfos;
+	
+	int m_RespawnTick;
+	int m_DieTick;
+	int m_Score;
+	bool m_ForceBalanced;
+	
+private:
+	CCharacter *Character;
+	CGameContext *m_pGameServer;
+	
+	CGameContext *GameServer() const { return m_pGameServer; }
+	IServer *Server() const;
+	
+	//
+	bool m_Spawning;
+	int m_ClientID;
+	int m_Team;
+
+	// network latency calculations	
+	struct
+	{
+		int m_Accum;
+		int m_AccumMin;
+		int m_AccumMax;
+		int m_Avg;
+		int m_Min;
+		int m_Max;	
+	} m_Latency;
+};
+
+#endif
diff --git a/src/game/server/player.hpp b/src/game/server/player.hpp
deleted file mode 100644
index e93aee01..00000000
--- a/src/game/server/player.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef GAME_SERVER_PLAYER_H
-#define GAME_SERVER_PLAYER_H
-
-// this include should perhaps be removed
-#include "entities/character.hpp"
-
-// player object
-class PLAYER
-{
-	MACRO_ALLOC_POOL_ID()
-private:
-	CHARACTER *character;
-public:
-	PLAYER(int client_id);
-	~PLAYER();
-
-	// TODO: clean this up
-	char skin_name[64];
-	int use_custom_color;
-	int color_body;
-	int color_feet;
-	
-	int respawn_tick;
-	int die_tick;
-	//
-	bool spawning;
-	int client_id;
-	int team;
-	int score;
-	bool force_balanced;
-	
-	//
-	int vote;
-	int64 last_votecall;
-
-	//
-	int64 last_chat;
-	int64 last_setteam;
-	int64 last_changeinfo;
-	int64 last_emote;
-	int64 last_kill;
-
-	// network latency calculations	
-	struct
-	{
-		int accum;
-		int accum_min;
-		int accum_max;
-		int avg;
-		int min;
-		int max;	
-	} latency;
-	
-	// this is used for snapping so we know how we can clip the view for the player
-	vec2 view_pos;
-
-	void init(int client_id);
-	
-	CHARACTER *get_character();
-	
-	void kill_character(int weapon);
-
-	void try_respawn();
-	void respawn();
-	void set_team(int team);
-	
-	void tick();
-	void snap(int snapping_client);
-
-	void on_direct_input(NETOBJ_PLAYER_INPUT *new_input);
-	void on_predicted_input(NETOBJ_PLAYER_INPUT *new_input);
-	void on_disconnect();
-};
-
-#endif