about summary refs log tree commit diff
path: root/src/game/client/components/players.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/client/components/players.cpp')
-rw-r--r--src/game/client/components/players.cpp647
1 files changed, 366 insertions, 281 deletions
diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp
index e1fee3e8..8ad7b0cb 100644
--- a/src/game/client/components/players.cpp
+++ b/src/game/client/components/players.cpp
@@ -1,147 +1,269 @@
-#include <engine/e_client_interface.h>
-#include <engine/client/graphics.h>
-#include <game/generated/g_protocol.hpp>
-#include <game/generated/gc_data.hpp>
-
-#include <game/gamecore.hpp> // get_angle
-#include <game/client/animstate.hpp>
-#include <game/client/gameclient.hpp>
-#include <game/client/ui.hpp>
-#include <game/client/render.hpp>
-
-#include <game/client/components/flow.hpp>
-#include <game/client/components/skins.hpp>
-#include <game/client/components/effects.hpp>
-#include <game/client/components/sounds.hpp>
-#include <game/client/components/controls.hpp>
-
-#include "players.hpp"
-
-void PLAYERS::render_hand(TEE_RENDER_INFO *info, vec2 center_pos, vec2 dir, float angle_offset, vec2 post_rot_offset)
+#include <engine/graphics.h>
+#include <engine/shared/config.h>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
+
+#include <game/gamecore.h> // get_angle
+#include <game/client/animstate.h>
+#include <game/client/gameclient.h>
+#include <game/client/ui.h>
+#include <game/client/render.h>
+
+#include <game/client/components/flow.h>
+#include <game/client/components/skins.h>
+#include <game/client/components/effects.h>
+#include <game/client/components/sounds.h>
+#include <game/client/components/controls.h>
+
+#include "players.h"
+
+void CPlayers::RenderHand(CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float AngleOffset, vec2 PostRotOffset)
 {
 	// for drawing hand
 	//const skin *s = skin_get(skin_id);
 	
-	float basesize = 10.0f;
+	float BaseSize = 10.0f;
 	//dir = normalize(hook_pos-pos);
 
-	vec2 hand_pos = center_pos + dir;
-	float angle = get_angle(dir);
-	if (dir.x < 0)
-		angle -= angle_offset;
+	vec2 HandPos = CenterPos + Dir;
+	float Angle = GetAngle(Dir);
+	if (Dir.x < 0)
+		Angle -= AngleOffset;
 	else
-		angle += angle_offset;
+		Angle += AngleOffset;
 
-	vec2 dirx = dir;
-	vec2 diry(-dir.y,dir.x);
+	vec2 DirX = Dir;
+	vec2 DirY(-Dir.y,Dir.x);
 
-	if (dir.x < 0)
-		diry = -diry;
+	if (Dir.x < 0)
+		DirY = -DirY;
 
-	hand_pos += dirx * post_rot_offset.x;
-	hand_pos += diry * post_rot_offset.y;
+	HandPos += DirX * PostRotOffset.x;
+	HandPos += DirY * PostRotOffset.y;
 
-	//Graphics()->TextureSet(data->images[IMAGE_CHAR_DEFAULT].id);
-	Graphics()->TextureSet(info->texture);
+	//Graphics()->TextureSet(data->m_aImages[IMAGE_CHAR_DEFAULT].id);
+	Graphics()->TextureSet(pInfo->m_Texture);
 	Graphics()->QuadsBegin();
-	Graphics()->SetColor(info->color_body.r, info->color_body.g, info->color_body.b, info->color_body.a);
+	Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, pInfo->m_ColorBody.a);
 
 	// two passes
 	for (int i = 0; i < 2; i++)
 	{
-		bool outline = i == 0;
+		bool OutLine = i == 0;
 
-		RenderTools()->select_sprite(outline?SPRITE_TEE_HAND_OUTLINE:SPRITE_TEE_HAND, 0, 0, 0);
-		Graphics()->QuadsSetRotation(angle);
-		Graphics()->QuadsDraw(hand_pos.x, hand_pos.y, 2*basesize, 2*basesize);
+		RenderTools()->SelectSprite(OutLine?SPRITE_TEE_HAND_OUTLINE:SPRITE_TEE_HAND, 0, 0, 0);
+		Graphics()->QuadsSetRotation(Angle);
+		IGraphics::CQuadItem QuadItem(HandPos.x, HandPos.y, 2*BaseSize, 2*BaseSize);
+		Graphics()->QuadsDraw(&QuadItem, 1);
 	}
 
 	Graphics()->QuadsSetRotation(0);
 	Graphics()->QuadsEnd();
 }
 
-inline float normalize_angular(float f)
+inline float NormalizeAngular(float f)
 {
 	return fmod(f+pi*2, pi*2);
 }
 
-inline float angular_mix_direction(float src, float dst) { return sinf(dst-src) >0?1:-1; }
-inline float angular_distance(float src, float dst) { return asinf(sinf(dst-src)); }
+inline float AngularMixDirection (float Src, float Dst) { return sinf(Dst-Src) >0?1:-1; }
+inline float AngularDistance(float Src, float Dst) { return asinf(sinf(Dst-Src)); }
 
-inline float angular_approach(float src, float dst, float amount)
+inline float AngularApproach(float Src, float Dst, float Amount)
 {
-	float d = angular_mix_direction(src, dst);
-	float n = src + amount*d;
-	if(angular_mix_direction(n, dst) != d)
-		return dst;
+	float d = AngularMixDirection (Src, Dst);
+	float n = Src + Amount*d;
+	if(AngularMixDirection (n, Dst) != d)
+		return Dst;
 	return n;
 }
 
-void PLAYERS::render_player(
-	const NETOBJ_CHARACTER *prev_char,
-	const NETOBJ_CHARACTER *player_char,
-	const NETOBJ_PLAYER_INFO *prev_info,
-	const NETOBJ_PLAYER_INFO *player_info
+void CPlayers::RenderHook(
+	const CNetObj_Character *pPrevChar,
+	const CNetObj_Character *pPlayerChar,
+	const CNetObj_PlayerInfo *pPrevInfo,
+	const CNetObj_PlayerInfo *pPlayerInfo
 	)
 {
-	NETOBJ_CHARACTER prev;
-	NETOBJ_CHARACTER player;
-	prev = *prev_char;
-	player = *player_char;
+	CNetObj_Character Prev;
+	CNetObj_Character Player;
+	Prev = *pPrevChar;
+	Player = *pPlayerChar;
 
-	NETOBJ_PLAYER_INFO info = *player_info;
-	TEE_RENDER_INFO render_info = gameclient.clients[info.cid].render_info;
+	CNetObj_PlayerInfo pInfo = *pPlayerInfo;
+	CTeeRenderInfo RenderInfo = m_pClient->m_aClients[pInfo.m_ClientId].m_RenderInfo;
 
 	// check for teamplay modes
-	bool is_teamplay = false;
-	bool new_tick = gameclient.new_tick;
-	if(gameclient.snap.gameobj)
-		is_teamplay = (gameclient.snap.gameobj->flags&GAMEFLAG_TEAMS) != 0;
+	bool IsTeamplay = false;
+	if(m_pClient->m_Snap.m_pGameobj)
+		IsTeamplay = (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0;
 
 	// check for ninja	
-	if (player.weapon == WEAPON_NINJA)
+	if (Player.m_Weapon == WEAPON_NINJA)
 	{
 		// change the skin for the player to the ninja
-		int skin = gameclient.skins->find("x_ninja");
-		if(skin != -1)
+		int Skin = m_pClient->m_pSkins->Find("x_ninja");
+		if(Skin != -1)
 		{
-			if(is_teamplay)
-				render_info.texture = gameclient.skins->get(skin)->color_texture;
+			if(IsTeamplay)
+				RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_ColorTexture;
 			else
 			{
-				render_info.texture = gameclient.skins->get(skin)->org_texture;
-				render_info.color_body = vec4(1,1,1,1);
-				render_info.color_feet = vec4(1,1,1,1);
+				RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_OrgTexture;
+				RenderInfo.m_ColorBody = vec4(1,1,1,1);
+				RenderInfo.m_ColorFeet = vec4(1,1,1,1);
+			}
+		}	
+	}
+
+	float IntraTick = Client()->IntraGameTick();
+
+	if(Player.m_Health < 0) // dont render dead players
+		return;
+
+	// set size
+	RenderInfo.m_Size = 64.0f;
+
+	
+	// use preditect players if needed
+	if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK)
+	{
+		if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pLocalCharacter->m_Health < 0) || (m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver))
+		{
+		}
+		else
+		{
+			// apply predicted results
+			m_pClient->m_PredictedChar.Write(&Player);
+			m_pClient->m_PredictedPrevChar.Write(&Prev);
+			IntraTick = Client()->PredIntraGameTick();
+		}
+	}
+
+	vec2 Position = mix(vec2(Prev.m_X, Prev.m_Y), vec2(Player.m_X, Player.m_Y), IntraTick);
+
+	if(Prev.m_Health < 0) // Don't flicker from previous position
+		Position = vec2(Player.m_X, Player.m_Y);
+
+	// draw hook
+	if (Prev.m_HookState>0 && Player.m_HookState>0)
+	{
+		Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
+		Graphics()->QuadsBegin();
+		//Graphics()->QuadsBegin();
+
+		vec2 Pos = Position;
+		vec2 HookPos;
+		
+		if(pPlayerChar->m_HookedPlayer != -1)
+		{
+			if(m_pClient->m_Snap.m_pLocalInfo && pPlayerChar->m_HookedPlayer == m_pClient->m_Snap.m_pLocalInfo->m_ClientId)
+			{
+				if(Client()->State() == IClient::STATE_DEMOPLAYBACK) // only use prediction if needed
+					HookPos = vec2(m_pClient->m_LocalCharacterPos.x, m_pClient->m_LocalCharacterPos.y);
+				else
+					HookPos = mix(vec2(m_pClient->m_PredictedPrevChar.m_Pos.x, m_pClient->m_PredictedPrevChar.m_Pos.y),
+						vec2(m_pClient->m_PredictedChar.m_Pos.x, m_pClient->m_PredictedChar.m_Pos.y), Client()->PredIntraGameTick());
+			}
+			else
+				HookPos = mix(vec2(pPrevChar->m_HookX, pPrevChar->m_HookY), vec2(pPlayerChar->m_HookX, pPlayerChar->m_HookY), Client()->IntraGameTick());
+		}
+		else
+			HookPos = mix(vec2(Prev.m_HookX, Prev.m_HookY), vec2(Player.m_HookX, Player.m_HookY), IntraTick);
+
+		float d = distance(Pos, HookPos);
+		vec2 Dir = normalize(Pos-HookPos);
+
+		Graphics()->QuadsSetRotation(GetAngle(Dir)+pi);
+
+		// render head
+		RenderTools()->SelectSprite(SPRITE_HOOK_HEAD);
+		IGraphics::CQuadItem QuadItem(HookPos.x, HookPos.y, 24,16);
+		Graphics()->QuadsDraw(&QuadItem, 1);
+
+		// render chain
+		RenderTools()->SelectSprite(SPRITE_HOOK_CHAIN);
+		IGraphics::CQuadItem Array[1024];
+		int i = 0;
+		for(float f = 24; f < d && i < 1024; f += 24, i++)
+		{
+			vec2 p = HookPos + Dir*f;
+			Array[i] = IGraphics::CQuadItem(p.x, p.y,24,16);
+		}
+
+		Graphics()->QuadsDraw(Array, i);
+		Graphics()->QuadsSetRotation(0);
+		Graphics()->QuadsEnd();
+
+		RenderHand(&RenderInfo, Position, normalize(HookPos-Pos), -pi/2, vec2(20, 0));
+	}
+}
+
+void CPlayers::RenderPlayer(
+	const CNetObj_Character *pPrevChar,
+	const CNetObj_Character *pPlayerChar,
+	const CNetObj_PlayerInfo *pPrevInfo,
+	const CNetObj_PlayerInfo *pPlayerInfo
+	)
+{
+	CNetObj_Character Prev;
+	CNetObj_Character Player;
+	Prev = *pPrevChar;
+	Player = *pPlayerChar;
+
+	CNetObj_PlayerInfo pInfo = *pPlayerInfo;
+	CTeeRenderInfo RenderInfo = m_pClient->m_aClients[pInfo.m_ClientId].m_RenderInfo;
+
+	// check for teamplay modes
+	bool IsTeamplay = false;
+	bool NewTick = m_pClient->m_NewTick;
+	if(m_pClient->m_Snap.m_pGameobj)
+		IsTeamplay = (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0;
+
+	// check for ninja	
+	if (Player.m_Weapon == WEAPON_NINJA)
+	{
+		// change the skin for the player to the ninja
+		int Skin = m_pClient->m_pSkins->Find("x_ninja");
+		if(Skin != -1)
+		{
+			if(IsTeamplay)
+				RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_ColorTexture;
+			else
+			{
+				RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_OrgTexture;
+				RenderInfo.m_ColorBody = vec4(1,1,1,1);
+				RenderInfo.m_ColorFeet = vec4(1,1,1,1);
 			}
 		}	
 	}
 	
 	// set size
-	render_info.size = 64.0f;
+	RenderInfo.m_Size = 64.0f;
 
-	float intratick = client_intratick();
+	float IntraTick = Client()->IntraGameTick();
 	
-	if(player.health < 0) // dont render dead players
+	if(Player.m_Health < 0) // dont render dead players
 		return;
 
-	float angle = mix((float)prev.angle, (float)player.angle, intratick)/256.0f;
+	float Angle = mix((float)Prev.m_Angle, (float)Player.m_Angle, IntraTick)/256.0f;
 	
 	//float angle = 0;
 	
-	if(info.local && client_state() != CLIENTSTATE_DEMOPLAYBACK)
+	if(pInfo.m_Local && Client()->State() != IClient::STATE_DEMOPLAYBACK)
 	{
 		// just use the direct input if it's local player we are rendering
-		angle = get_angle(gameclient.controls->mouse_pos);
+		Angle = GetAngle(m_pClient->m_pControls->m_MousePos);
 	}
 	else
 	{
 		/*
-		float mixspeed = client_frametime()*2.5f;
+		float mixspeed = Client()->FrameTime()*2.5f;
 		if(player.attacktick != prev.attacktick) // shooting boosts the mixing speed
 			mixspeed *= 15.0f;
 		
 		// move the delta on a constant speed on a x^2 curve
-		float current = gameclient.clients[info.cid].angle;
+		float current = g_GameClient.m_aClients[info.cid].angle;
 		float target = player.angle/256.0f;
 		float delta = angular_distance(current, target);
 		float sign = delta < 0 ? -1 : 1;
@@ -153,342 +275,305 @@ void PLAYERS::render_player(
 		else
 			angle = angular_approach(current, target, fabs(delta-new_delta));
 
-		gameclient.clients[info.cid].angle = angle;*/
+		g_GameClient.m_aClients[info.cid].angle = angle;*/
 	}
 	
 	// use preditect players if needed
-	if(info.local && config.cl_predict && client_state() != CLIENTSTATE_DEMOPLAYBACK)
+	if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK)
 	{
-		if(!gameclient.snap.local_character || (gameclient.snap.local_character->health < 0) || (gameclient.snap.gameobj && gameclient.snap.gameobj->game_over))
+		if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pLocalCharacter->m_Health < 0) || (m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver))
 		{
 		}
 		else
 		{
 			// apply predicted results
-			gameclient.predicted_char.write(&player);
-			gameclient.predicted_prev_char.write(&prev);
-			intratick = client_predintratick();
-			new_tick = gameclient.new_predicted_tick;
+			m_pClient->m_PredictedChar.Write(&Player);
+			m_pClient->m_PredictedPrevChar.Write(&Prev);
+			IntraTick = Client()->PredIntraGameTick();
+			NewTick = m_pClient->m_NewPredictedTick;
 		}
 	}
 	
-	vec2 direction = get_direction((int)(angle*256.0f));
-	vec2 position = mix(vec2(prev.x, prev.y), vec2(player.x, player.y), intratick);
-	vec2 vel = mix(vec2(prev.vx/256.0f, prev.vy/256.0f), vec2(player.vx/256.0f, player.vy/256.0f), intratick);
+	vec2 Direction = GetDirection((int)(Angle*256.0f));
+	vec2 Position = mix(vec2(Prev.m_X, Prev.m_Y), vec2(Player.m_X, Player.m_Y), IntraTick);
+	vec2 Vel = mix(vec2(Prev.m_VelX/256.0f, Prev.m_VelY/256.0f), vec2(Player.m_VelX/256.0f, Player.m_VelY/256.0f), IntraTick);
 	
-	gameclient.flow->add(position, vel*100.0f, 10.0f);
+	m_pClient->m_pFlow->Add(Position, Vel*100.0f, 10.0f);
 	
-	render_info.got_airjump = player.jumped&2?0:1;
+	RenderInfo.m_GotAirJump = Player.m_Jumped&2?0:1;
 	
 	
 	// detect events
-	if(new_tick)
+	if(NewTick)
 	{
 		// detect air jump
-		if(!render_info.got_airjump && !(prev.jumped&2))
-			gameclient.effects->air_jump(position);
+		if(!RenderInfo.m_GotAirJump && !(Prev.m_Jumped&2))
+			m_pClient->m_pEffects->AirJump(Position);
 	}
 
-	if(prev.health < 0) // Don't flicker from previous position
-		position = vec2(player.x, player.y);
+	if(Prev.m_Health < 0) // Don't flicker from previous position
+		Position = vec2(Player.m_X, Player.m_Y);
 
-	bool stationary = player.vx < 1 && player.vx > -1;
-	bool inair = col_check_point(player.x, player.y+16) == 0;
-	bool want_other_dir = (player.direction == -1 && vel.x > 0) || (player.direction == 1 && vel.x < 0);
+	bool Stationary = Player.m_VelX <= 1 && Player.m_VelX >= -1;
+	bool InAir = !Collision()->CheckPoint(Player.m_X, Player.m_Y+16);
+	bool WantOtherDir = (Player.m_Direction == -1 && Vel.x > 0) || (Player.m_Direction == 1 && Vel.x < 0);
 
 	// evaluate animation
-	float walk_time = fmod(position.x, 100.0f)/100.0f;
-	ANIMSTATE state;
-	state.set(&data->animations[ANIM_BASE], 0);
-
-	if(inair)
-		state.add(&data->animations[ANIM_INAIR], 0, 1.0f); // TODO: some sort of time here
-	else if(stationary)
-		state.add(&data->animations[ANIM_IDLE], 0, 1.0f); // TODO: some sort of time here
-	else if(!want_other_dir)
-		state.add(&data->animations[ANIM_WALK], walk_time, 1.0f);
-
-	if (player.weapon == WEAPON_HAMMER)
+	float WalkTime = fmod(Position.x, 100.0f)/100.0f;
+	CAnimState State;
+	State.Set(&g_pData->m_aAnimations[ANIM_BASE], 0);
+
+	if(InAir)
+		State.Add(&g_pData->m_aAnimations[ANIM_INAIR], 0, 1.0f); // TODO: some sort of time here
+	else if(Stationary)
+		State.Add(&g_pData->m_aAnimations[ANIM_IDLE], 0, 1.0f); // TODO: some sort of time here
+	else if(!WantOtherDir)
+		State.Add(&g_pData->m_aAnimations[ANIM_WALK], WalkTime, 1.0f);
+
+	if (Player.m_Weapon == WEAPON_HAMMER)
 	{
-		float ct = (client_prevtick()-player.attacktick)/(float)SERVER_TICK_SPEED + client_ticktime();
-		state.add(&data->animations[ANIM_HAMMER_SWING], clamp(ct*5.0f,0.0f,1.0f), 1.0f);
+		float ct = (Client()->PrevGameTick()-Player.m_AttackTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime();
+		State.Add(&g_pData->m_aAnimations[ANIM_HAMMER_SWING], clamp(ct*5.0f,0.0f,1.0f), 1.0f);
 	}
-	if (player.weapon == WEAPON_NINJA)
+	if (Player.m_Weapon == WEAPON_NINJA)
 	{
-		float ct = (client_prevtick()-player.attacktick)/(float)SERVER_TICK_SPEED + client_ticktime();
-		state.add(&data->animations[ANIM_NINJA_SWING], clamp(ct*2.0f,0.0f,1.0f), 1.0f);
+		float ct = (Client()->PrevGameTick()-Player.m_AttackTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime();
+		State.Add(&g_pData->m_aAnimations[ANIM_NINJA_SWING], clamp(ct*2.0f,0.0f,1.0f), 1.0f);
 	}
 	
 	// do skidding
-	if(!inair && want_other_dir && length(vel*50) > 500.0f)
+	if(!InAir && WantOtherDir && length(Vel*50) > 500.0f)
 	{
-		static int64 skid_sound_time = 0;
-		if(time_get()-skid_sound_time > time_freq()/10)
+		static int64 SkidSoundTime = 0;
+		if(time_get()-SkidSoundTime > time_freq()/10)
 		{
-			gameclient.sounds->play(SOUNDS::CHN_WORLD, SOUND_PLAYER_SKID, 0.25f, position);
-			skid_sound_time = time_get();
+			m_pClient->m_pSounds->Play(CSounds::CHN_WORLD, SOUND_PLAYER_SKID, 0.25f, Position);
+			SkidSoundTime = time_get();
 		}
 		
-		gameclient.effects->skidtrail(
-			position+vec2(-player.direction*6,12),
-			vec2(-player.direction*100*length(vel),-50)
+		m_pClient->m_pEffects->SkidTrail(
+			Position+vec2(-Player.m_Direction*6,12),
+			vec2(-Player.m_Direction*100*length(Vel),-50)
 		);
 	}
 
-	// draw hook
-	if (prev.hook_state>0 && player.hook_state>0)
-	{
-		Graphics()->TextureSet(data->images[IMAGE_GAME].id);
-		Graphics()->QuadsBegin();
-		//Graphics()->QuadsBegin();
-
-		vec2 pos = position;
-		vec2 hook_pos;
-		
-		if(player_char->hooked_player != -1)
-		{
-			if(gameclient.snap.local_info && player_char->hooked_player == gameclient.snap.local_info->cid)
-			{
-				hook_pos = mix(vec2(gameclient.predicted_prev_char.pos.x, gameclient.predicted_prev_char.pos.y),
-					vec2(gameclient.predicted_char.pos.x, gameclient.predicted_char.pos.y), client_predintratick());
-			}
-			else
-				hook_pos = mix(vec2(prev_char->hook_x, prev_char->hook_y), vec2(player_char->hook_x, player_char->hook_y), client_intratick());
-		}
-		else
-			hook_pos = mix(vec2(prev.hook_x, prev.hook_y), vec2(player.hook_x, player.hook_y), intratick);
-
-		float d = distance(pos, hook_pos);
-		vec2 dir = normalize(pos-hook_pos);
-
-		Graphics()->QuadsSetRotation(get_angle(dir)+pi);
-
-		// render head
-		RenderTools()->select_sprite(SPRITE_HOOK_HEAD);
-		Graphics()->QuadsDraw(hook_pos.x, hook_pos.y, 24,16);
-
-		// render chain
-		RenderTools()->select_sprite(SPRITE_HOOK_CHAIN);
-		int i = 0;
-		for(float f = 24; f < d && i < 1024; f += 24, i++)
-		{
-			vec2 p = hook_pos + dir*f;
-			Graphics()->QuadsDraw(p.x, p.y,24,16);
-		}
-
-		Graphics()->QuadsSetRotation(0);
-		Graphics()->QuadsEnd();
-
-		render_hand(&render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0));
-	}
-
 	// draw gun
 	{
-		Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+		Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
 		Graphics()->QuadsBegin();
-		Graphics()->QuadsSetRotation(state.attach.angle*pi*2+angle);
+		Graphics()->QuadsSetRotation(State.GetAttach()->m_Angle*pi*2+Angle);
 
 		// normal weapons
-		int iw = clamp(player.weapon, 0, NUM_WEAPONS-1);
-		RenderTools()->select_sprite(data->weapons.id[iw].sprite_body, direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
+		int iw = clamp(Player.m_Weapon, 0, NUM_WEAPONS-1);
+		RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_pSpriteBody, Direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
 
-		vec2 dir = direction;
-		float recoil = 0.0f;
+		vec2 Dir = Direction;
+		float Recoil = 0.0f;
 		vec2 p;
-		if (player.weapon == WEAPON_HAMMER)
+		if (Player.m_Weapon == WEAPON_HAMMER)
 		{
 			// Static position for hammer
-			p = position + vec2(state.attach.x, state.attach.y);
-			p.y += data->weapons.id[iw].offsety;
+			p = Position + vec2(State.GetAttach()->m_X, State.GetAttach()->m_Y);
+			p.y += g_pData->m_Weapons.m_aId[iw].m_Offsety;
 			// if attack is under way, bash stuffs
-			if(direction.x < 0)
+			if(Direction.x < 0)
 			{
-				Graphics()->QuadsSetRotation(-pi/2-state.attach.angle*pi*2);
-				p.x -= data->weapons.id[iw].offsetx;
+				Graphics()->QuadsSetRotation(-pi/2-State.GetAttach()->m_Angle*pi*2);
+				p.x -= g_pData->m_Weapons.m_aId[iw].m_Offsetx;
 			}
 			else
 			{
-				Graphics()->QuadsSetRotation(-pi/2+state.attach.angle*pi*2);
+				Graphics()->QuadsSetRotation(-pi/2+State.GetAttach()->m_Angle*pi*2);
 			}
-			RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size);
+			RenderTools()->DrawSprite(p.x, p.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize);
 		}
-		else if (player.weapon == WEAPON_NINJA)
+		else if (Player.m_Weapon == WEAPON_NINJA)
 		{
-			p = position;
-			p.y += data->weapons.id[iw].offsety;
+			p = Position;
+			p.y += g_pData->m_Weapons.m_aId[iw].m_Offsety;
 
-			if(direction.x < 0)
+			if(Direction.x < 0)
 			{
-				Graphics()->QuadsSetRotation(-pi/2-state.attach.angle*pi*2);
-				p.x -= data->weapons.id[iw].offsetx;
-				gameclient.effects->powerupshine(p+vec2(32,0), vec2(32,12));
+				Graphics()->QuadsSetRotation(-pi/2-State.GetAttach()->m_Angle*pi*2);
+				p.x -= g_pData->m_Weapons.m_aId[iw].m_Offsetx;
+				m_pClient->m_pEffects->PowerupShine(p+vec2(32,0), vec2(32,12));
 			}
 			else
 			{
-				Graphics()->QuadsSetRotation(-pi/2+state.attach.angle*pi*2);
-				gameclient.effects->powerupshine(p-vec2(32,0), vec2(32,12));
+				Graphics()->QuadsSetRotation(-pi/2+State.GetAttach()->m_Angle*pi*2);
+				m_pClient->m_pEffects->PowerupShine(p-vec2(32,0), vec2(32,12));
 			}
-			RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size);
+			RenderTools()->DrawSprite(p.x, p.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize);
 
 			// HADOKEN
-			if ((client_tick()-player.attacktick) <= (SERVER_TICK_SPEED / 6) && data->weapons.id[iw].num_sprite_muzzles)
+			if ((Client()->GameTick()-Player.m_AttackTick) <= (SERVER_TICK_SPEED / 6) && g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles)
 			{
-				int itex = rand() % data->weapons.id[iw].num_sprite_muzzles;
-				float alpha = 1.0f;
-				if (alpha > 0.0f && data->weapons.id[iw].sprite_muzzles[itex])
+				int IteX = rand() % g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles;
+				float Alpha = 1.0f;
+				if (Alpha > 0.0f && g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX])
 				{
-					vec2 dir = vec2(player_char->x,player_char->y) - vec2(prev_char->x, prev_char->y);
-					dir = normalize(dir);
-					float hadokenangle = get_angle(dir);
-					Graphics()->QuadsSetRotation(hadokenangle);
+					vec2 Dir = vec2(pPlayerChar->m_X,pPlayerChar->m_Y) - vec2(pPrevChar->m_X, pPrevChar->m_Y);
+					Dir = normalize(Dir);
+					float HadOkenAngle  = GetAngle(Dir);
+					Graphics()->QuadsSetRotation(HadOkenAngle );
 					//float offsety = -data->weapons[iw].muzzleoffsety;
-					RenderTools()->select_sprite(data->weapons.id[iw].sprite_muzzles[itex], 0);
-					vec2 diry(-dir.y,dir.x);
-					p = position;
-					float offsetx = data->weapons.id[iw].muzzleoffsetx;
-					p -= dir * offsetx;
-					RenderTools()->draw_sprite(p.x, p.y, 160.0f);
+					RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX], 0);
+					vec2 DirY(-Dir.y,Dir.x);
+					p = Position;
+					float OffsetX = g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx;
+					p -= Dir * OffsetX;
+					RenderTools()->DrawSprite(p.x, p.y, 160.0f);
 				}
 			}
 		}
 		else
 		{
 			// TODO: should be an animation
-			recoil = 0;
-			float a = (client_tick()-player.attacktick+intratick)/5.0f;
+			Recoil = 0;
+			float a = (Client()->GameTick()-Player.m_AttackTick+IntraTick)/5.0f;
 			if(a < 1)
-				recoil = sinf(a*pi);
-			p = position + dir * data->weapons.id[iw].offsetx - dir*recoil*10.0f;
-			p.y += data->weapons.id[iw].offsety;
-			RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size);
+				Recoil = sinf(a*pi);
+			p = Position + Dir * g_pData->m_Weapons.m_aId[iw].m_Offsetx - Dir*Recoil*10.0f;
+			p.y += g_pData->m_Weapons.m_aId[iw].m_Offsety;
+			RenderTools()->DrawSprite(p.x, p.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize);
 		}
 
-		if (player.weapon == WEAPON_GUN || player.weapon == WEAPON_SHOTGUN)
+		if (Player.m_Weapon == WEAPON_GUN || Player.m_Weapon == WEAPON_SHOTGUN)
 		{
 			// check if we're firing stuff
-			if(data->weapons.id[iw].num_sprite_muzzles)//prev.attackticks)
+			if(g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles)//prev.attackticks)
 			{
-				float alpha = 0.0f;
-				int phase1tick = (client_tick() - player.attacktick);
-				if (phase1tick < (data->weapons.id[iw].muzzleduration + 3))
+				float Alpha = 0.0f;
+				int Phase1Tick = (Client()->GameTick() - Player.m_AttackTick);
+				if (Phase1Tick < (g_pData->m_Weapons.m_aId[iw].m_Muzzleduration + 3))
 				{
-					float t = ((((float)phase1tick) + intratick)/(float)data->weapons.id[iw].muzzleduration);
-					alpha = LERP(2.0, 0.0f, min(1.0f,max(0.0f,t)));
+					float t = ((((float)Phase1Tick) + IntraTick)/(float)g_pData->m_Weapons.m_aId[iw].m_Muzzleduration);
+					Alpha = mix(2.0f, 0.0f, min(1.0f,max(0.0f,t)));
 				}
 
-				int itex = rand() % data->weapons.id[iw].num_sprite_muzzles;
-				if (alpha > 0.0f && data->weapons.id[iw].sprite_muzzles[itex])
+				int IteX = rand() % g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles;
+				if (Alpha > 0.0f && g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX])
 				{
-					float offsety = -data->weapons.id[iw].muzzleoffsety;
-					RenderTools()->select_sprite(data->weapons.id[iw].sprite_muzzles[itex], direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
-					if(direction.x < 0)
-						offsety = -offsety;
+					float OffsetY = -g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsety;
+					RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX], Direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
+					if(Direction.x < 0)
+						OffsetY = -OffsetY;
 
-					vec2 diry(-dir.y,dir.x);
-					vec2 muzzlepos = p + dir * data->weapons.id[iw].muzzleoffsetx + diry * offsety;
+					vec2 DirY(-Dir.y,Dir.x);
+					vec2 MuzzlePos = p + Dir * g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx + DirY * OffsetY;
 
-					RenderTools()->draw_sprite(muzzlepos.x, muzzlepos.y, data->weapons.id[iw].visual_size);
+					RenderTools()->DrawSprite(MuzzlePos.x, MuzzlePos.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize);
 				}
 			}
 		}
 		Graphics()->QuadsEnd();
 
-		switch (player.weapon)
+		switch (Player.m_Weapon)
 		{
-			case WEAPON_GUN: render_hand(&render_info, p, direction, -3*pi/4, vec2(-15, 4)); break;
-			case WEAPON_SHOTGUN: render_hand(&render_info, p, direction, -pi/2, vec2(-5, 4)); break;
-			case WEAPON_GRENADE: render_hand(&render_info, p, direction, -pi/2, vec2(-4, 7)); break;
+			case WEAPON_GUN: RenderHand(&RenderInfo, p, Direction, -3*pi/4, vec2(-15, 4)); break;
+			case WEAPON_SHOTGUN: RenderHand(&RenderInfo, p, Direction, -pi/2, vec2(-5, 4)); break;
+			case WEAPON_GRENADE: RenderHand(&RenderInfo, p, Direction, -pi/2, vec2(-4, 7)); break;
 		}
 
 	}
 
 	// render the "shadow" tee
-	if(info.local && config.debug)
+	if(pInfo.m_Local && g_Config.m_Debug)
 	{
-		vec2 ghost_position = mix(vec2(prev_char->x, prev_char->y), vec2(player_char->x, player_char->y), client_intratick());
-		TEE_RENDER_INFO ghost = render_info;
-		ghost.color_body.a = 0.5f;
-		ghost.color_feet.a = 0.5f;
-		RenderTools()->RenderTee(&state, &ghost, player.emote, direction, ghost_position); // render ghost
+		vec2 GhostPosition = mix(vec2(pPrevChar->m_X, pPrevChar->m_Y), vec2(pPlayerChar->m_X, pPlayerChar->m_Y), Client()->IntraGameTick());
+		CTeeRenderInfo Ghost = RenderInfo;
+		Ghost.m_ColorBody.a = 0.5f;
+		Ghost.m_ColorFeet.a = 0.5f;
+		RenderTools()->RenderTee(&State, &Ghost, Player.m_Emote, Direction, GhostPosition); // render ghost
 	}
 
-	render_info.size = 64.0f; // force some settings
-	render_info.color_body.a = 1.0f;
-	render_info.color_feet.a = 1.0f;
-	RenderTools()->RenderTee(&state, &render_info, player.emote, direction, position);
+	RenderInfo.m_Size = 64.0f; // force some settings
+	RenderInfo.m_ColorBody.a = 1.0f;
+	RenderInfo.m_ColorFeet.a = 1.0f;
+	RenderTools()->RenderTee(&State, &RenderInfo, Player.m_Emote, Direction, Position);
 
-	if(player.player_state == PLAYERSTATE_CHATTING)
+	if(Player.m_PlayerState == PLAYERSTATE_CHATTING)
 	{
-		Graphics()->TextureSet(data->images[IMAGE_EMOTICONS].id);
+		Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
 		Graphics()->QuadsBegin();
-		RenderTools()->select_sprite(SPRITE_DOTDOT);
-		Graphics()->QuadsDraw(position.x + 24, position.y - 40, 64,64);
+		RenderTools()->SelectSprite(SPRITE_DOTDOT);
+		IGraphics::CQuadItem QuadItem(Position.x + 24, Position.y - 40, 64,64);
+		Graphics()->QuadsDraw(&QuadItem, 1);
 		Graphics()->QuadsEnd();
 	}
 
-	if (gameclient.clients[info.cid].emoticon_start != -1 && gameclient.clients[info.cid].emoticon_start + 2 * client_tickspeed() > client_tick())
+	if (m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart != -1 && m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart + 2 * Client()->GameTickSpeed() > Client()->GameTick())
 	{
-		Graphics()->TextureSet(data->images[IMAGE_EMOTICONS].id);
+		Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
 		Graphics()->QuadsBegin();
 
-		int since_start = client_tick() - gameclient.clients[info.cid].emoticon_start;
-		int from_end = gameclient.clients[info.cid].emoticon_start + 2 * client_tickspeed() - client_tick();
+		int SinceStart = Client()->GameTick() - m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart;
+		int FromEnd = m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart + 2 * Client()->GameTickSpeed() - Client()->GameTick();
 
 		float a = 1;
 
-		if (from_end < client_tickspeed() / 5)
-			a = from_end / (client_tickspeed() / 5.0);
+		if (FromEnd < Client()->GameTickSpeed() / 5)
+			a = FromEnd / (Client()->GameTickSpeed() / 5.0);
 
 		float h = 1;
-		if (since_start < client_tickspeed() / 10)
-			h = since_start / (client_tickspeed() / 10.0);
+		if (SinceStart < Client()->GameTickSpeed() / 10)
+			h = SinceStart / (Client()->GameTickSpeed() / 10.0);
 
-		float wiggle = 0;
-		if (since_start < client_tickspeed() / 5)
-			wiggle = since_start / (client_tickspeed() / 5.0);
+		float Wiggle = 0;
+		if (SinceStart < Client()->GameTickSpeed() / 5)
+			Wiggle = SinceStart / (Client()->GameTickSpeed() / 5.0);
 
-		float wiggle_angle = sin(5*wiggle);
+		float WiggleAngle = sinf(5*Wiggle);
 
-		Graphics()->QuadsSetRotation(pi/6*wiggle_angle);
+		Graphics()->QuadsSetRotation(pi/6*WiggleAngle);
 
 		Graphics()->SetColor(1.0f,1.0f,1.0f,a);
 		// client_datas::emoticon is an offset from the first emoticon
-		RenderTools()->select_sprite(SPRITE_OOP + gameclient.clients[info.cid].emoticon);
-		Graphics()->QuadsDraw(position.x, position.y - 23 - 32*h, 64, 64*h);
+		RenderTools()->SelectSprite(SPRITE_OOP + m_pClient->m_aClients[pInfo.m_ClientId].m_Emoticon);
+		IGraphics::CQuadItem QuadItem(Position.x, Position.y - 23 - 32*h, 64, 64*h);
+		Graphics()->QuadsDraw(&QuadItem, 1);
 		Graphics()->QuadsEnd();
 	}
 }
 
-void PLAYERS::on_render()
+void CPlayers::OnRender()
 {
 	// render other players in two passes, first pass we render the other, second pass we render our self
-	for(int p = 0; p < 2; p++)
+	for(int p = 0; p < 4; p++)
 	{
 		for(int i = 0; i < MAX_CLIENTS; i++)
 		{
 			// only render active characters
-			if(!gameclient.snap.characters[i].active)
+			if(!m_pClient->m_Snap.m_aCharacters[i].m_Active)
 				continue;
 
-			const void *prev_info = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_INFO, i);
-			const void *info = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_INFO, i);
+			const void *pPrevInfo = Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_PLAYERINFO, i);
+			const void *pInfo = Client()->SnapFindItem(IClient::SNAP_CURRENT, NETOBJTYPE_PLAYERINFO, i);
 
-			if(prev_info && info)
+			if(pPrevInfo && pInfo)
 			{
 				//
-				bool local = ((const NETOBJ_PLAYER_INFO *)info)->local !=0;
-				if(p == 0 && local) continue;
-				if(p == 1 && !local) continue;
+				bool Local = ((const CNetObj_PlayerInfo *)pInfo)->m_Local !=0;
+				if((p % 2) == 0 && Local) continue;
+				if((p % 2) == 1 && !Local) continue;
 				
-				NETOBJ_CHARACTER prev_char = gameclient.snap.characters[i].prev;
-				NETOBJ_CHARACTER cur_char = gameclient.snap.characters[i].cur;
-
-				render_player(
-						&prev_char,
-						&cur_char,
-						(const NETOBJ_PLAYER_INFO *)prev_info,
-						(const NETOBJ_PLAYER_INFO *)info
-					);
+				CNetObj_Character PrevChar = m_pClient->m_Snap.m_aCharacters[i].m_Prev;
+				CNetObj_Character CurChar = m_pClient->m_Snap.m_aCharacters[i].m_Cur;
+
+				if(p<2)
+					RenderHook(
+							&PrevChar,
+							&CurChar,
+							(const CNetObj_PlayerInfo *)pPrevInfo,
+							(const CNetObj_PlayerInfo *)pInfo
+						);
+				else
+					RenderPlayer(
+							&PrevChar,
+							&CurChar,
+							(const CNetObj_PlayerInfo *)pPrevInfo,
+							(const CNetObj_PlayerInfo *)pInfo
+						);
 			}		
 		}
 	}