about summary refs log tree commit diff
path: root/src/game/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/client')
-rw-r--r--src/game/client/gc_client.cpp183
-rw-r--r--src/game/client/gc_client.h32
-rw-r--r--src/game/client/gc_hooks.cpp112
-rw-r--r--src/game/client/gc_menu.cpp16
-rw-r--r--src/game/client/gc_render.cpp30
-rw-r--r--src/game/client/gc_render.h12
-rw-r--r--src/game/client/gc_render_obj.cpp57
7 files changed, 258 insertions, 184 deletions
diff --git a/src/game/client/gc_client.cpp b/src/game/client/gc_client.cpp
index 20d1df7c..8446d729 100644
--- a/src/game/client/gc_client.cpp
+++ b/src/game/client/gc_client.cpp
@@ -27,7 +27,7 @@ extern "C" {
 struct data_container *data = 0;
 int64 debug_firedelay = 0;
 
-player_input input_data = {0};
+NETOBJ_PLAYER_INPUT input_data = {0};
 int input_target_lock = 0;
 
 int chat_mode = CHATMODE_NONE;
@@ -40,11 +40,16 @@ tuning_params tuning;
 vec2 mouse_pos;
 vec2 local_character_pos;
 vec2 local_target_pos;
-const obj_player_character *local_character = 0;
-const obj_player_character *local_prev_character = 0;
-const obj_player_info *local_info = 0;
-const obj_flag *flags[2] = {0,0};
-const obj_game *gameobj = 0;
+
+/*
+const NETOBJ_PLAYER_CHARACTER *local_character = 0;
+const NETOBJ_PLAYER_CHARACTER *local_prev_character = 0;
+const NETOBJ_PLAYER_INFO *local_info = 0;
+const NETOBJ_FLAG *flags[2] = {0,0};
+const NETOBJ_GAME *gameobj = 0;
+*/
+
+snapstate netobjects;
 
 int picked_up_weapon = -1;
 
@@ -54,7 +59,7 @@ void client_data::update_render_info()
 	render_info = skin_info;
 
 	// force team colors
-	if(gameobj && gameobj->gametype != GAMETYPE_DM)
+	if(netobjects.gameobj && netobjects.gameobj->gametype != GAMETYPE_DM)
 	{
 		const int team_colors[2] = {65387, 10223467};
 		if(team >= 0 || team <= 1)
@@ -232,7 +237,7 @@ void chat_add_line(int client_id, int team, const char *line)
 		if(client_datas[client_id].team == -1)
 			chat_lines[chat_current_line].name_color = -1;
 
-		if(gameobj && gameobj->gametype != GAMETYPE_DM)
+		if(netobjects.gameobj && netobjects.gameobj->gametype != GAMETYPE_DM)
 		{
 			if(client_datas[client_id].team == 0)
 				chat_lines[chat_current_line].name_color = 0;
@@ -261,41 +266,40 @@ void process_events(int snaptype)
 		SNAP_ITEM item;
 		const void *data = snap_get_item(snaptype, index, &item);
 
-		if(item.type == EVENT_DAMAGEINDICATION)
+		if(item.type == NETEVENTTYPE_DAMAGEIND)
 		{
-			ev_damageind *ev = (ev_damageind *)data;
+			NETEVENT_DAMAGEIND *ev = (NETEVENT_DAMAGEIND *)data;
 			effect_damage_indicator(vec2(ev->x, ev->y), get_direction(ev->angle));
 		}
-		else if(item.type == EVENT_AIR_JUMP)
+		else if(item.type == NETEVENTTYPE_AIR_JUMP)
 		{
-			ev_common *ev = (ev_common *)data;
+			NETEVENT_COMMON *ev = (NETEVENT_COMMON *)data;
 			effect_air_jump(vec2(ev->x, ev->y));
 		}
-		else if(item.type == EVENT_EXPLOSION)
+		else if(item.type == NETEVENTTYPE_EXPLOSION)
 		{
-			ev_explosion *ev = (ev_explosion *)data;
+			NETEVENT_EXPLOSION *ev = (NETEVENT_EXPLOSION *)data;
 			effect_explosion(vec2(ev->x, ev->y));
 		}
-		else if(item.type == EVENT_SMOKE)
+		/*else if(item.type == EVENT_SMOKE)
 		{
-			ev_explosion *ev = (ev_explosion *)data;
+			EV_EXPLOSION *ev = (EV_EXPLOSION *)data;
 			vec2 p(ev->x, ev->y);
-		}
-		else if(item.type == EVENT_PLAYERSPAWN)
+		}*/
+		else if(item.type == NETEVENTTYPE_SPAWN)
 		{
-			ev_explosion *ev = (ev_explosion *)data;
+			NETEVENT_SPAWN *ev = (NETEVENT_SPAWN *)data;
 			effect_playerspawn(vec2(ev->x, ev->y));
 		}
-		else if(item.type == EVENT_DEATH)
+		else if(item.type == NETEVENTTYPE_DEATH)
 		{
-			ev_explosion *ev = (ev_explosion *)data;
+			NETEVENT_DEATH *ev = (NETEVENT_DEATH *)data;
 			effect_playerdeath(vec2(ev->x, ev->y));
 		}
-		else if(item.type == EVENT_SOUND_WORLD)
+		else if(item.type == NETEVENTTYPE_SOUND_WORLD)
 		{
-			ev_sound *ev = (ev_sound *)data;
-			if(ev->sound >= 0 && ev->sound < NUM_SOUNDS)
-				snd_play_random(CHN_WORLD, ev->sound, 1.0f, vec2(ev->x, ev->y));
+			NETEVENT_SOUND_WORLD *ev = (NETEVENT_SOUND_WORLD *)data;
+			snd_play_random(CHN_WORLD, ev->soundid, 1.0f, vec2(ev->x, ev->y));
 		}
 	}
 }
@@ -303,12 +307,7 @@ void process_events(int snaptype)
 void clear_object_pointers()
 {
 	// clear out the invalid pointers
-	local_character = 0;
-	local_prev_character = 0;
-	local_info = 0;
-	flags[0] = 0;
-	flags[1] = 0;
-	gameobj = 0;
+	mem_zero(&netobjects, sizeof(netobjects));
 }
 
 void send_info(bool start)
@@ -526,16 +525,16 @@ void render_goals(float x, float y, float w)
 
 	// render goals
 	//y = ystart+h-54;
-	if(gameobj && gameobj->time_limit)
+	if(netobjects.gameobj && netobjects.gameobj->time_limit)
 	{
 		char buf[64];
-		str_format(buf, sizeof(buf), "Time Limit: %d min", gameobj->time_limit);
+		str_format(buf, sizeof(buf), "Time Limit: %d min", netobjects.gameobj->time_limit);
 		gfx_text(0, x+w/2, y, 24.0f, buf, -1);
 	}
-	if(gameobj && gameobj->score_limit)
+	if(netobjects.gameobj && netobjects.gameobj->score_limit)
 	{
 		char buf[64];
-		str_format(buf, sizeof(buf), "Score Limit: %d", gameobj->score_limit);
+		str_format(buf, sizeof(buf), "Score Limit: %d", netobjects.gameobj->score_limit);
 		gfx_text(0, x+40, y, 24.0f, buf, -1);
 	}
 }
@@ -560,14 +559,14 @@ void render_spectators(float x, float y, float w)
 		SNAP_ITEM item;
 		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
 
-		if(item.type == OBJTYPE_PLAYER_INFO)
+		if(item.type == NETOBJTYPE_PLAYER_INFO)
 		{
-			const obj_player_info *info = (const obj_player_info *)data;
+			const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
 			if(info->team == -1)
 			{
 				if(count)
 					strcat(buffer, ", ");
-				strcat(buffer, client_datas[info->clientid].name);
+				strcat(buffer, client_datas[info->cid].name);
 				count++;
 			}
 		}
@@ -595,7 +594,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 	// render title
 	if(!title)
 	{
-		if(gameobj->game_over)
+		if(netobjects.gameobj->game_over)
 			title = "Game Over";
 		else
 			title = "Score Board";
@@ -611,10 +610,11 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 	{
 		gfx_text(0, x+10, y, 48, title, -1);
 
-		if(gameobj)
+		if(netobjects.gameobj)
 		{
 			char buf[128];
-			str_format(buf, sizeof(buf), "%d", gameobj->teamscore[team&1]);
+			int score = team ? netobjects.gameobj->teamscore_blue : netobjects.gameobj->teamscore_red;
+			str_format(buf, sizeof(buf), "%d", score);
 			tw = gfx_text_width(0, 48, buf, -1);
 			gfx_text(0, x+w-tw-30, y, 48, buf, -1);
 		}
@@ -623,16 +623,16 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 	y += 54.0f;
 
 	// find players
-	const obj_player_info *players[MAX_CLIENTS] = {0};
+	const NETOBJ_PLAYER_INFO *players[MAX_CLIENTS] = {0};
 	int num_players = 0;
 	for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++)
 	{
 		SNAP_ITEM item;
 		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
 
-		if(item.type == OBJTYPE_PLAYER_INFO)
+		if(item.type == NETOBJTYPE_PLAYER_INFO)
 		{
-			players[num_players] = (const obj_player_info *)data;
+			players[num_players] = (const NETOBJ_PLAYER_INFO *)data;
 			num_players++;
 		}
 	}
@@ -644,7 +644,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 		{
 			if(players[i]->score < players[i+1]->score)
 			{
-				const obj_player_info *tmp = players[i];
+				const NETOBJ_PLAYER_INFO *tmp = players[i];
 				players[i] = players[i+1];
 				players[i+1] = tmp;
 			}
@@ -660,7 +660,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 	// render player scores
 	for(int i = 0; i < num_players; i++)
 	{
-		const obj_player_info *info = players[i];
+		const NETOBJ_PLAYER_INFO *info = players[i];
 
 		// make sure that we render the correct team
 		if(team == -1 || info->team != team)
@@ -683,18 +683,19 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 		
 		if(config.cl_show_player_ids)
 		{
-			str_format(buf, sizeof(buf), "%d | %s", info->clientid, client_datas[info->clientid].name);
+			str_format(buf, sizeof(buf), "%d | %s", info->cid, client_datas[info->cid].name);
 			gfx_text(0, x+128, y, font_size, buf, -1);
 		}
 		else
-			gfx_text(0, x+128, y, font_size, client_datas[info->clientid].name, -1);
+			gfx_text(0, x+128, y, font_size, client_datas[info->cid].name, -1);
 
 		str_format(buf, sizeof(buf), "%4d", info->latency);
 		float tw = gfx_text_width(0, font_size, buf, -1);
 		gfx_text(0, x+w-tw-35, y, font_size, buf, -1);
 
 		// render avatar
-		if((flags[0] && flags[0]->carried_by == info->clientid) || (flags[1] && flags[1]->carried_by == info->clientid))
+		if((netobjects.flags[0] && netobjects.flags[0]->carried_by == info->cid) ||
+			(netobjects.flags[1] && netobjects.flags[1]->carried_by == info->cid))
 		{
 			gfx_blend_normal();
 			gfx_texture_set(data->images[IMAGE_GAME].id);
@@ -708,7 +709,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 			gfx_quads_end();
 		}
 		
-		render_tee(&idlestate, &client_datas[info->clientid].render_info, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28));
+		render_tee(&idlestate, &client_datas[info->cid].render_info, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28));
 
 		
 		y += 50.0f;
@@ -739,21 +740,21 @@ void render_game()
 
 	if(config.cl_predict)
 	{
-		if(!local_character || (local_character->health < 0) || (gameobj && gameobj->game_over))
+		if(!netobjects.local_character || (netobjects.local_character->health < 0) || (netobjects.gameobj && netobjects.gameobj->game_over))
 		{
 			// don't use predicted
 		}
 		else
 			local_character_pos = mix(predicted_prev_player.pos, predicted_player.pos, client_predintratick());
 	}
-	else if(local_character && local_prev_character)
+	else if(netobjects.local_character && netobjects.local_prev_character)
 	{
 		local_character_pos = mix(
-			vec2(local_prev_character->x, local_prev_character->y),
-			vec2(local_character->x, local_character->y), client_intratick());
+			vec2(netobjects.local_prev_character->x, netobjects.local_prev_character->y),
+			vec2(netobjects.local_character->x, netobjects.local_character->y), client_intratick());
 	}
 	
-	if(local_info && local_info->team == -1)
+	if(netobjects.local_info && netobjects.local_info->team == -1)
 		spectate = true;
 
 	animstate idlestate;
@@ -1089,7 +1090,7 @@ void render_game()
 		gfx_quads_end();
 	}*/
 
-	if(local_character && !spectate && !(gameobj && gameobj->game_over))
+	if(netobjects.local_character && !spectate && !(netobjects.gameobj && netobjects.gameobj->game_over))
 	{
 		gfx_texture_set(data->images[IMAGE_GAME].id);
 		gfx_quads_begin();
@@ -1097,7 +1098,7 @@ void render_game()
 		// render cursor
 		if (!menu_active && !emoticon_selector_active)
 		{
-			select_sprite(data->weapons[local_character->weapon%data->num_weapons].sprite_cursor);
+			select_sprite(data->weapons[netobjects.local_character->weapon%data->num_weapons].sprite_cursor);
 			float cursorsize = 64;
 			draw_sprite(local_target_pos.x, local_target_pos.y, cursorsize);
 		}
@@ -1113,10 +1114,10 @@ void render_game()
 		
 		// if weaponstage is active, put a "glow" around the stage ammo
 		select_sprite(SPRITE_TEE_BODY);
-		for (int i = 0; i < local_character->weaponstage; i++)
-			gfx_quads_drawTL(x+local_character->ammocount * 12 -i*12, y+22, 11, 11);
-		select_sprite(data->weapons[local_character->weapon%data->num_weapons].sprite_proj);
-		for (int i = 0; i < min(local_character->ammocount, 10); i++)
+		for (int i = 0; i < netobjects.local_character->weaponstage; i++)
+			gfx_quads_drawTL(x+netobjects.local_character->ammocount * 12 -i*12, y+22, 11, 11);
+		select_sprite(data->weapons[netobjects.local_character->weapon%data->num_weapons].sprite_proj);
+		for (int i = 0; i < min(netobjects.local_character->ammocount, 10); i++)
 			gfx_quads_drawTL(x+i*12,y+24,10,10);
 
 		gfx_quads_end();
@@ -1127,7 +1128,7 @@ void render_game()
 
 		// render health
 		select_sprite(SPRITE_HEALTH_FULL);
-		for(; h < local_character->health; h++)
+		for(; h < netobjects.local_character->health; h++)
 			gfx_quads_drawTL(x+h*12,y,10,10);
 
 		select_sprite(SPRITE_HEALTH_EMPTY);
@@ -1137,7 +1138,7 @@ void render_game()
 		// render armor meter
 		h = 0;
 		select_sprite(SPRITE_ARMOR_FULL);
-		for(; h < local_character->armor; h++)
+		for(; h < netobjects.local_character->armor; h++)
 			gfx_quads_drawTL(x+h*12,y+12,10,10);
 
 		select_sprite(SPRITE_ARMOR_EMPTY);
@@ -1172,7 +1173,7 @@ void render_game()
 			// render victim tee
 			x -= 24.0f;
 			
-			if(gameobj && gameobj->gametype == GAMETYPE_CTF)
+			if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_CTF)
 			{
 				if(killmsgs[r].mode_special&1)
 				{
@@ -1206,7 +1207,7 @@ void render_game()
 
 			if(killmsgs[r].victim != killmsgs[r].killer)
 			{
-				if(gameobj && gameobj->gametype == GAMETYPE_CTF)
+				if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_CTF)
 				{
 					if(killmsgs[r].mode_special&2)
 					{
@@ -1305,34 +1306,34 @@ void render_game()
 	}
 
 	// render goals
-	if(gameobj)
+	if(netobjects.gameobj)
 	{
-		int gametype = gameobj->gametype;
+		int gametype = netobjects.gameobj->gametype;
 		
 		float whole = 300*gfx_screenaspect();
 		float half = whole/2.0f;
 		
 		gfx_mapscreen(0,0,300*gfx_screenaspect(),300);
-		if(!gameobj->sudden_death)
+		if(!netobjects.gameobj->sudden_death)
 		{
 			char buf[32];
 			int time = 0;
-			if(gameobj->time_limit)
+			if(netobjects.gameobj->time_limit)
 			{
-				time = gameobj->time_limit*60 - ((client_tick()-gameobj->round_start_tick)/client_tickspeed());
+				time = netobjects.gameobj->time_limit*60 - ((client_tick()-netobjects.gameobj->round_start_tick)/client_tickspeed());
 
-				if(gameobj->game_over)
+				if(netobjects.gameobj->game_over)
 					time  = 0;
 			}
 			else
-				time = (client_tick()-gameobj->round_start_tick)/client_tickspeed();
+				time = (client_tick()-netobjects.gameobj->round_start_tick)/client_tickspeed();
 
 			str_format(buf, sizeof(buf), "%d:%02d", time /60, time %60);
 			float w = gfx_text_width(0, 16, buf, -1);
 			gfx_text(0, half-w/2, 2, 16, buf, -1);
 		}
 
-		if(gameobj->sudden_death)
+		if(netobjects.gameobj->sudden_death)
 		{
 			const char *text = "Sudden Death";
 			float w = gfx_text_width(0, 16, text, -1);
@@ -1340,7 +1341,7 @@ void render_game()
 		}
 
 		// render small score hud
-		if(!(gameobj && gameobj->game_over) && (gametype == GAMETYPE_TDM || gametype == GAMETYPE_CTF))
+		if(!(netobjects.gameobj && netobjects.gameobj->game_over) && (gametype == GAMETYPE_TDM || gametype == GAMETYPE_CTF))
 		{
 			for(int t = 0; t < 2; t++)
 			{
@@ -1355,15 +1356,15 @@ void render_game()
 				gfx_quads_end();
 
 				char buf[32];
-				str_format(buf, sizeof(buf), "%d", gameobj->teamscore[t]);
+				str_format(buf, sizeof(buf), "%d", t?netobjects.gameobj->teamscore_blue:netobjects.gameobj->teamscore_red);
 				float w = gfx_text_width(0, 14, buf, -1);
 				
 				if(gametype == GAMETYPE_CTF)
 				{
 					gfx_text(0, whole-20-w/2+5, 300-40-15+t*20+2, 14, buf, -1);
-					if(flags[t])
+					if(netobjects.flags[t])
 					{
- 						if(flags[t]->carried_by == -2 || (flags[t]->carried_by == -1 && ((client_tick()/10)&1)))
+ 						if(netobjects.flags[t]->carried_by == -2 || (netobjects.flags[t]->carried_by == -1 && ((client_tick()/10)&1)))
  						{
 							gfx_blend_normal();
 							gfx_texture_set(data->images[IMAGE_GAME].id);
@@ -1376,9 +1377,9 @@ void render_game()
 							gfx_quads_drawTL(whole-40+5, 300-40-15+t*20+1, size/2, size);
 							gfx_quads_end();
 						}
-						else if(flags[t]->carried_by >= 0)
+						else if(netobjects.flags[t]->carried_by >= 0)
 						{
-							int id = flags[t]->carried_by%MAX_CLIENTS;
+							int id = netobjects.flags[t]->carried_by%MAX_CLIENTS;
 							const char *name = client_datas[id].name;
 							float w = gfx_text_width(0, 10, name, -1);
 							gfx_text(0, whole-40-5-w, 300-40-15+t*20+2, 10, name, -1);
@@ -1396,15 +1397,15 @@ void render_game()
 		}
 
 		// render warmup timer
-		if(gameobj->warmup)
+		if(netobjects.gameobj->warmup)
 		{
 			char buf[256];
 			float w = gfx_text_width(0, 24, "Warmup", -1);
 			gfx_text(0, 150*gfx_screenaspect()+-w/2, 50, 24, "Warmup", -1);
 
-			int seconds = gameobj->warmup/SERVER_TICK_SPEED;
+			int seconds = netobjects.gameobj->warmup/SERVER_TICK_SPEED;
 			if(seconds < 5)
-				str_format(buf, sizeof(buf), "%d.%d", seconds, (gameobj->warmup*10/SERVER_TICK_SPEED)%10);
+				str_format(buf, sizeof(buf), "%d.%d", seconds, (netobjects.gameobj->warmup*10/SERVER_TICK_SPEED)%10);
 			else
 				str_format(buf, sizeof(buf), "%d", seconds);
 			w = gfx_text_width(0, 24, buf, -1);
@@ -1439,12 +1440,12 @@ void render_game()
 		}
 	}
 	
-	if(config.debug && local_character && local_prev_character)
+	if(config.debug && netobjects.local_character && netobjects.local_prev_character)
 	{
 		gfx_mapscreen(0, 0, 300*gfx_screenaspect(), 300);
 		
-		float speed = distance(vec2(local_prev_character->x, local_prev_character->y),
-			vec2(local_character->x, local_character->y));
+		float speed = distance(vec2(netobjects.local_prev_character->x, netobjects.local_prev_character->y),
+			vec2(netobjects.local_character->x, netobjects.local_character->y));
 		
 		char buf[512];
 		str_format(buf, sizeof(buf), "%.2f", speed/2);
@@ -1453,15 +1454,15 @@ void render_game()
 
 	// render score board
 	if(inp_key_pressed(KEY_TAB) || // user requested
-		(!spectate && (!local_character || local_character->health < 0)) || // not spectating and is dead
-		(gameobj && gameobj->game_over) // game over
+		(!spectate && (!netobjects.local_character || netobjects.local_character->health < 0)) || // not spectating and is dead
+		(netobjects.gameobj && netobjects.gameobj->game_over) // game over
 		)
 	{
 		gfx_mapscreen(0, 0, width, height);
 
 		float w = 650.0f;
 
-		if (gameobj && gameobj->gametype == GAMETYPE_DM)
+		if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_DM)
 		{
 			render_scoreboard(width/2-w/2, 150.0f, w, 0, 0);
 			//render_scoreboard(gameobj, 0, 0, -1, 0);
@@ -1469,12 +1470,12 @@ void render_game()
 		else
 		{
 				
-			if(gameobj && gameobj->game_over)
+			if(netobjects.gameobj && netobjects.gameobj->game_over)
 			{
 				const char *text = "DRAW!";
-				if(gameobj->teamscore[0] > gameobj->teamscore[1])
+				if(netobjects.gameobj->teamscore_red > netobjects.gameobj->teamscore_blue)
 					text = "Red Team Wins!";
-				else if(gameobj->teamscore[1] > gameobj->teamscore[0])
+				else if(netobjects.gameobj->teamscore_blue > netobjects.gameobj->teamscore_red)
 					text = "Blue Team Wins!";
 					
 				float w = gfx_text_width(0, 92.0f, text, -1);
diff --git a/src/game/client/gc_client.h b/src/game/client/gc_client.h
index 857a9088..93a90a86 100644
--- a/src/game/client/gc_client.h
+++ b/src/game/client/gc_client.h
@@ -20,11 +20,29 @@ extern vec2 local_character_pos;
 extern vec2 local_target_pos;
 
 // snap pointers
-extern const obj_player_character *local_character;
-extern const obj_player_character *local_prev_character;
-extern const obj_player_info *local_info;
-extern const obj_flag *flags[2];
-extern const obj_game *gameobj;
+struct snapstate
+{
+	const NETOBJ_PLAYER_CHARACTER *local_character;
+	const NETOBJ_PLAYER_CHARACTER *local_prev_character;
+	const NETOBJ_PLAYER_INFO *local_info;
+	const NETOBJ_FLAG *flags[2];
+	const NETOBJ_GAME *gameobj;
+
+	const NETOBJ_PLAYER_INFO *player_infos[MAX_CLIENTS];
+	const NETOBJ_PLAYER_INFO *info_by_score[MAX_CLIENTS];
+	int num_players;
+};
+
+extern snapstate netobjects;
+
+/*
+extern const NETOBJ_PLAYER_CHARACTER *local_character;
+extern const NETOBJ_PLAYER_CHARACTER *local_prev_character;
+extern const NETOBJ_PLAYER_INFO *local_info;
+extern const NETOBJ_FLAG *flags[2];
+extern const NETOBJ_GAME *gameobj;
+* */
+
 extern tuning_params tuning;
 
 // predicted players
@@ -33,7 +51,7 @@ extern player_core predicted_player;
 
 // input
 extern int picked_up_weapon;
-extern player_input input_data;
+extern NETOBJ_PLAYER_INPUT input_data;
 extern int input_target_lock;
 
 // debug
@@ -45,7 +63,7 @@ enum
 	MAX_EXTRA_PROJECTILES=32,
 };
 
-extern obj_projectile extraproj_projectiles[MAX_EXTRA_PROJECTILES];
+extern NETOBJ_PROJECTILE extraproj_projectiles[MAX_EXTRA_PROJECTILES];
 extern int extraproj_num;
 
 void extraproj_reset();
diff --git a/src/game/client/gc_hooks.cpp b/src/game/client/gc_hooks.cpp
index a6391007..9292d08c 100644
--- a/src/game/client/gc_hooks.cpp
+++ b/src/game/client/gc_hooks.cpp
@@ -120,17 +120,17 @@ extern "C" void modc_predict()
 		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
 		int client_id = item.id;
 
-		if(item.type == OBJTYPE_PLAYER_CHARACTER)
+		if(item.type == NETOBJTYPE_PLAYER_CHARACTER)
 		{
-			const obj_player_character *character = (const obj_player_character *)data;
+			const NETOBJ_PLAYER_CHARACTER *character = (const NETOBJ_PLAYER_CHARACTER *)data;
 			client_datas[client_id].predicted.world = &world;
 			world.players[client_id] = &client_datas[client_id].predicted;
 
 			client_datas[client_id].predicted.read(character);
 		}
-		else if(item.type == OBJTYPE_PLAYER_INFO)
+		else if(item.type == NETOBJTYPE_PLAYER_INFO)
 		{
-			const obj_player_info *info = (const obj_player_info *)data;
+			const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
 			if(info->local)
 				local_cid = client_id;
 		}
@@ -155,7 +155,7 @@ extern "C" void modc_predict()
 				// apply player input
 				int *input = client_get_input(tick);
 				if(input)
-					world.players[c]->input = *((player_input*)input);
+					world.players[c]->input = *((NETOBJ_PLAYER_INPUT*)input);
 			}
 
 			world.players[c]->tick();
@@ -230,6 +230,23 @@ extern "C" void modc_newsnapshot()
 	static int snapshot_count = 0;
 	snapshot_count++;
 	
+	// secure snapshot
+	{
+		int num = snap_num_items(SNAP_CURRENT);
+		for(int index = 0; index < num; index++)
+		{
+			SNAP_ITEM item;
+			void *data = snap_get_item(SNAP_CURRENT, index, &item);
+			if(netobj_secure(item.type, data, item.datasize) != 0)
+			{
+				if(config.debug)
+					dbg_msg("game", "invalidated %d %d (%s) %d", index, item.type, netobj_get_name(item.type), item.id);
+				snap_invalidate_item(SNAP_CURRENT, index);
+			}
+		}
+	}
+	
+	
 	process_events(SNAP_CURRENT);
 
 	if(config.dbg_stress)
@@ -256,32 +273,32 @@ extern "C" void modc_newsnapshot()
 			SNAP_ITEM item;
 			const void *data = snap_get_item(SNAP_CURRENT, i, &item);
 
-			if(item.type == OBJTYPE_PLAYER_INFO)
+			if(item.type == NETOBJTYPE_PLAYER_INFO)
 			{
-				const obj_player_info *info = (const obj_player_info *)data;
+				const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
 				
-				client_datas[info->clientid].team = info->team;
+				client_datas[info->cid].team = info->team;
 				
 				if(info->local)
 				{
-					local_info = info;
-					const void *data = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_CHARACTER, item.id);
+					netobjects.local_info = info;
+					const void *data = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_CHARACTER, item.id);
 					if(data)
 					{
-						local_character = (const obj_player_character *)data;
-						local_character_pos = vec2(local_character->x, local_character->y);
+						netobjects.local_character = (const NETOBJ_PLAYER_CHARACTER *)data;
+						local_character_pos = vec2(netobjects.local_character->x, netobjects.local_character->y);
 
-						const void *p = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_CHARACTER, item.id);
+						const void *p = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_CHARACTER, item.id);
 						if(p)
-							local_prev_character = (obj_player_character *)p;
+							netobjects.local_prev_character = (NETOBJ_PLAYER_CHARACTER *)p;
 					}
 				}
 			}
-			else if(item.type == OBJTYPE_GAME)
-				gameobj = (obj_game *)data;
-			else if(item.type == OBJTYPE_FLAG)
+			else if(item.type == NETOBJTYPE_GAME)
+				netobjects.gameobj = (NETOBJ_GAME *)data;
+			else if(item.type == NETOBJTYPE_FLAG)
 			{
-				flags[item.id%2] = (const obj_flag *)data;
+				netobjects.flags[item.id%2] = (const NETOBJ_FLAG *)data;
 			}
 		}
 	}
@@ -394,7 +411,7 @@ extern "C" void modc_statechange(int state, int old)
 	}
 }
 
-obj_projectile extraproj_projectiles[MAX_EXTRA_PROJECTILES];
+NETOBJ_PROJECTILE extraproj_projectiles[MAX_EXTRA_PROJECTILES];
 int extraproj_num;
 
 void extraproj_reset()
@@ -409,6 +426,11 @@ extern "C" void modc_message(int msg)
 		int cid = msg_unpack_int();
 		int team = msg_unpack_int();
 		const char *message = msg_unpack_string();
+
+		/* check for errors and invalid inputs */
+		if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS)
+			return;
+			
 		dbg_msg("message", "chat cid=%d team=%d msg='%s'", cid, team, message);
 		chat_add_line(cid, team, message);
 
@@ -423,10 +445,13 @@ extern "C" void modc_message(int msg)
 		
 		for(int k = 0; k < num; k++)
 		{
-			obj_projectile proj;
-			for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++)
+			NETOBJ_PROJECTILE proj;
+			for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
 				((int *)&proj)[i] = msg_unpack_int();
 				
+			if(msg_unpack_error())
+				return;
+				
 			if(extraproj_num != MAX_EXTRA_PROJECTILES)
 			{
 				extraproj_projectiles[extraproj_num] = proj;
@@ -440,6 +465,10 @@ extern "C" void modc_message(int msg)
 		const char *name = msg_unpack_string();
 		const char *skinname = msg_unpack_string();
 		
+		/* check for errors and invalid inputs */
+		if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS)
+			return;
+		
 		strncpy(client_datas[cid].name, name, 64);
 		strncpy(client_datas[cid].skin_name, skinname, 64);
 		
@@ -466,13 +495,24 @@ extern "C" void modc_message(int msg)
 	}
 	else if(msg == MSG_TUNE_PARAMS)
 	{
-		int *params = (int *)&tuning;
+		// unpack the new tuning		
+		tuning_params new_tuning;
+		int *params = (int *)&new_tuning;
 		for(unsigned i = 0; i < sizeof(tuning_params)/sizeof(int); i++)
 			params[i] = msg_unpack_int();
+
+		// check for unpacking errors
+		if(msg_unpack_error())
+			return;
+			
+		// apply new tuning
+		tuning = new_tuning;
 	}
     else if(msg == MSG_WEAPON_PICKUP)
     {
         int weapon = msg_unpack_int();
+		if(msg_unpack_error())
+			return;
         picked_up_weapon = weapon+1;
     }
 	else if(msg == MSG_READY_TO_ENTER)
@@ -481,23 +521,41 @@ extern "C" void modc_message(int msg)
 	}
 	else if(msg == MSG_KILLMSG)
 	{
+		// unpack messages
+		killmsg msg;
+		msg.killer = msg_unpack_int();
+		msg.victim = msg_unpack_int();
+		msg.weapon = msg_unpack_int();
+		msg.mode_special = msg_unpack_int();
+		msg.tick = client_tick();
+
+		// check for unpacking errors
+		if(msg_unpack_error() || msg.killer >= MAX_CLIENTS || msg.victim >= MAX_CLIENTS || msg.weapon >= NUM_WEAPONS)
+			return;
+
+		// add the message
 		killmsg_current = (killmsg_current+1)%killmsg_max;
-		killmsgs[killmsg_current].killer = msg_unpack_int();
-		killmsgs[killmsg_current].victim = msg_unpack_int();
-		killmsgs[killmsg_current].weapon = msg_unpack_int();
-		killmsgs[killmsg_current].mode_special = msg_unpack_int();
-		killmsgs[killmsg_current].tick = client_tick();
+		killmsgs[killmsg_current] = msg;
 	}
 	else if (msg == MSG_EMOTICON)
 	{
+		// unpack
 		int cid = msg_unpack_int();
 		int emoticon = msg_unpack_int();
+
+		// check for errors
+		if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS)
+			return;
+
+		// apply
 		client_datas[cid].emoticon = emoticon;
 		client_datas[cid].emoticon_start = client_tick();
 	}
 	else if(msg == MSG_SOUND_GLOBAL)
 	{
 		int soundid = msg_unpack_int();
+		if(msg_unpack_error() || soundid < 0)
+			return;
 		snd_play_random(CHN_GLOBAL, soundid, 1.0f, vec2(0,0));
 	}
 }
diff --git a/src/game/client/gc_menu.cpp b/src/game/client/gc_menu.cpp
index 51333288..ec2cc2fe 100644
--- a/src/game/client/gc_menu.cpp
+++ b/src/game/client/gc_menu.cpp
@@ -27,10 +27,6 @@ extern "C" {
 
 extern data_container *data;
 
-// abit uglyness
-extern const obj_player_info *local_info;
-extern const obj_game *gameobj;
-
 extern bool menu_active;
 extern bool menu_game_active;
 
@@ -1614,9 +1610,9 @@ static void menu2_render_game(RECT main_view)
 	if(ui_do_button(&disconnect_button, "Disconnect", 0, &button, ui_draw_menu_button, 0))
 		client_disconnect();
 
-	if(local_info && gameobj)
+	if(netobjects.local_info && netobjects.gameobj)
 	{
-		if(local_info->team != -1)
+		if(netobjects.local_info->team != -1)
 		{
 			ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
 			ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
@@ -1628,9 +1624,9 @@ static void menu2_render_game(RECT main_view)
 			}
 		}
 		
-		if(gameobj->gametype == GAMETYPE_DM)
+		if(netobjects.gameobj->gametype == GAMETYPE_DM)
 		{
-			if(local_info->team != 0)
+			if(netobjects.local_info->team != 0)
 			{
 				ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
 				ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
@@ -1644,7 +1640,7 @@ static void menu2_render_game(RECT main_view)
 		}
 		else
 		{
-			if(local_info->team != 0)
+			if(netobjects.local_info->team != 0)
 			{
 				ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
 				ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
@@ -1656,7 +1652,7 @@ static void menu2_render_game(RECT main_view)
 				}
 			}
 
-			if(local_info->team != 1)
+			if(netobjects.local_info->team != 1)
 			{
 				ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
 				ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
diff --git a/src/game/client/gc_render.cpp b/src/game/client/gc_render.cpp
index 1d276ec3..6e001bd1 100644
--- a/src/game/client/gc_render.cpp
+++ b/src/game/client/gc_render.cpp
@@ -349,25 +349,25 @@ static void render_items()
 		SNAP_ITEM item;
 		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
 
-		if(item.type == OBJTYPE_PROJECTILE)
+		if(item.type == NETOBJTYPE_PROJECTILE)
 		{
-			render_projectile((const obj_projectile *)data, item.id);
+			render_projectile((const NETOBJ_PROJECTILE *)data, item.id);
 		}
-		else if(item.type == OBJTYPE_POWERUP)
+		else if(item.type == NETOBJTYPE_POWERUP)
 		{
 			const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
 			if(prev)
-				render_powerup((const obj_powerup *)prev, (const obj_powerup *)data);
+				render_powerup((const NETOBJ_POWERUP *)prev, (const NETOBJ_POWERUP *)data);
 		}
-		else if(item.type == OBJTYPE_LASER)
+		else if(item.type == NETOBJTYPE_LASER)
 		{
-			render_laser((const obj_laser *)data);
+			render_laser((const NETOBJ_LASER *)data);
 		}
-		else if(item.type == OBJTYPE_FLAG)
+		else if(item.type == NETOBJTYPE_FLAG)
 		{
 			const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
 			if (prev)
-				render_flag((const obj_flag *)prev, (const obj_flag *)data);
+				render_flag((const NETOBJ_FLAG *)prev, (const NETOBJ_FLAG *)data);
 		}
 	}
 
@@ -393,19 +393,19 @@ static void render_players()
 		SNAP_ITEM item;
 		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
 
-		if(item.type == OBJTYPE_PLAYER_CHARACTER)
+		if(item.type == NETOBJTYPE_PLAYER_CHARACTER)
 		{
 			const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
-			const void *prev_info = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_INFO, item.id);
-			const void *info = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_INFO, item.id);
+			const void *prev_info = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_INFO, item.id);
+			const void *info = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_INFO, item.id);
 
 			if(prev && prev_info && info)
 			{
 				render_player(
-						(const obj_player_character *)prev,
-						(const obj_player_character *)data,
-						(const obj_player_info *)prev_info,
-						(const obj_player_info *)info
+						(const NETOBJ_PLAYER_CHARACTER *)prev,
+						(const NETOBJ_PLAYER_CHARACTER *)data,
+						(const NETOBJ_PLAYER_INFO *)prev_info,
+						(const NETOBJ_PLAYER_INFO *)info
 					);
 			}
 		}
diff --git a/src/game/client/gc_render.h b/src/game/client/gc_render.h
index b62206f7..a6f57b7b 100644
--- a/src/game/client/gc_render.h
+++ b/src/game/client/gc_render.h
@@ -54,13 +54,13 @@ void render_particles();
 
 // object render methods (gc_render_obj.cpp)
 void render_tee(class animstate *anim, tee_render_info *info, int emote, vec2 dir, vec2 pos);
-void render_flag(const struct obj_flag *prev, const struct obj_flag *current);
-void render_powerup(const struct obj_powerup *prev, const struct obj_powerup *current);
-void render_projectile(const struct obj_projectile *current, int itemid);
-void render_laser(const struct obj_laser *current);
+void render_flag(const struct NETOBJ_FLAG *prev, const struct NETOBJ_FLAG *current);
+void render_powerup(const struct NETOBJ_POWERUP *prev, const struct NETOBJ_POWERUP *current);
+void render_projectile(const struct NETOBJ_PROJECTILE *current, int itemid);
+void render_laser(const struct NETOBJ_LASER *current);
 void render_player(
-	const struct obj_player_character *prev_char, const struct obj_player_character *player_char,
-	const struct obj_player_info *prev_info, const struct obj_player_info *player_info);
+	const struct NETOBJ_PLAYER_CHARACTER *prev_char, const struct NETOBJ_PLAYER_CHARACTER *player_char,
+	const struct NETOBJ_PLAYER_INFO *prev_info, const struct NETOBJ_PLAYER_INFO *player_info);
 	
 // map render methods (gc_render_map.cpp)
 void render_eval_envelope(ENVPOINT *points, int num_points, int channels, float time, float *result);
diff --git a/src/game/client/gc_render_obj.cpp b/src/game/client/gc_render_obj.cpp
index cedfc129..995994ed 100644
--- a/src/game/client/gc_render_obj.cpp
+++ b/src/game/client/gc_render_obj.cpp
@@ -11,7 +11,7 @@
 #include "gc_client.h"
 
 
-void render_projectile(const obj_projectile *current, int itemid)
+void render_projectile(const NETOBJ_PROJECTILE *current, int itemid)
 {
 	if(debug_firedelay)
 	{
@@ -34,7 +34,7 @@ void render_projectile(const obj_projectile *current, int itemid)
 	vec2 pos = calc_pos(startpos, startvel, gravity, ct);
 	vec2 prevpos = calc_pos(startpos, startvel, gravity, ct-0.001f);
 
-	select_sprite(data->weapons[current->type%data->num_weapons].sprite_proj);
+	select_sprite(data->weapons[clamp(current->type, 0, NUM_WEAPONS-1)].sprite_proj);
 	vec2 vel = pos-prevpos;
 	//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
 	
@@ -63,7 +63,7 @@ void render_projectile(const obj_projectile *current, int itemid)
 	gfx_quads_end();
 }
 
-void render_powerup(const obj_powerup *prev, const obj_powerup *current)
+void render_powerup(const NETOBJ_POWERUP *prev, const NETOBJ_POWERUP *current)
 {
 	gfx_texture_set(data->images[IMAGE_GAME].id);
 	gfx_quads_begin();
@@ -73,8 +73,8 @@ void render_powerup(const obj_powerup *prev, const obj_powerup *current)
 	if (current->type == POWERUP_WEAPON)
 	{
 		angle = 0; //-pi/6;//-0.25f * pi * 2.0f;
-		select_sprite(data->weapons[current->subtype%data->num_weapons].sprite_body);
-		size = data->weapons[current->subtype%data->num_weapons].visual_size;
+		select_sprite(data->weapons[clamp(current->subtype, 0, NUM_WEAPONS-1)].sprite_body);
+		size = data->weapons[clamp(current->subtype, 0, NUM_WEAPONS-1)].visual_size;
 	}
 	else
 	{
@@ -107,7 +107,7 @@ void render_powerup(const obj_powerup *prev, const obj_powerup *current)
 	gfx_quads_end();
 }
 
-void render_flag(const obj_flag *prev, const obj_flag *current)
+void render_flag(const NETOBJ_FLAG *prev, const NETOBJ_FLAG *current)
 {
 	float angle = 0.0f;
 	float size = 42.0f;
@@ -125,7 +125,7 @@ void render_flag(const obj_flag *prev, const obj_flag *current)
 
 	vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
 
-	if(local_info && current->carried_by == local_info->clientid)
+	if(netobjects.local_info && current->carried_by == netobjects.local_info->cid)
 		pos = local_character_pos;
 
     //gfx_setcolor(current->team ? 0 : 1,0,current->team ? 1 : 0,1);
@@ -135,7 +135,7 @@ void render_flag(const obj_flag *prev, const obj_flag *current)
 }
 
 
-void render_laser(const struct obj_laser *current)
+void render_laser(const struct NETOBJ_LASER *current)
 {
 
 	vec2 pos = vec2(current->x, current->y);
@@ -245,19 +245,19 @@ static void render_hand(tee_render_info *info, vec2 center_pos, vec2 dir, float
 }
 
 void render_player(
-	const obj_player_character *prev_char,
-	const obj_player_character *player_char,
-	const obj_player_info *prev_info,
-	const obj_player_info *player_info
+	const NETOBJ_PLAYER_CHARACTER *prev_char,
+	const NETOBJ_PLAYER_CHARACTER *player_char,
+	const NETOBJ_PLAYER_INFO *prev_info,
+	const NETOBJ_PLAYER_INFO *player_info
 	)
 {
-	obj_player_character prev;
-	obj_player_character player;
+	NETOBJ_PLAYER_CHARACTER prev;
+	NETOBJ_PLAYER_CHARACTER player;
 	prev = *prev_char;
 	player = *player_char;
 
-	obj_player_info info = *player_info;
-	tee_render_info render_info = client_datas[info.clientid].render_info;
+	NETOBJ_PLAYER_INFO info = *player_info;
+	tee_render_info render_info = client_datas[info.cid].render_info;
 
 	float intratick = client_intratick();
 	float ticktime = client_ticktime();
@@ -267,7 +267,7 @@ void render_player(
 
 	if(info.local && config.cl_predict)
 	{
-		if(!local_character || (local_character->health < 0) || (gameobj && gameobj->game_over))
+		if(!netobjects.local_character || (netobjects.local_character->health < 0) || (netobjects.gameobj && netobjects.gameobj->game_over))
 		{
 		}
 		else
@@ -329,7 +329,7 @@ void render_player(
 		
 		if(player_char->hooked_player != -1)
 		{
-			if(local_info && player_char->hooked_player == local_info->clientid)
+			if(netobjects.local_info && player_char->hooked_player == netobjects.local_info->cid)
 			{
 				hook_pos = mix(vec2(predicted_prev_player.pos.x, predicted_prev_player.pos.y),
 					vec2(predicted_player.pos.x, predicted_player.pos.y), client_predintratick());
@@ -351,7 +351,8 @@ void render_player(
 
 		// render chain
 		select_sprite(SPRITE_HOOK_CHAIN);
-		for(float f = 24; f < d; f += 24)
+		int i = 0;
+		for(float f = 24; f < d && i < 1024; f += 24, i++)
 		{
 			vec2 p = hook_pos + dir*f;
 			gfx_quads_draw(p.x, p.y,24,16);
@@ -360,7 +361,7 @@ void render_player(
 		gfx_quads_setrotation(0);
 		gfx_quads_end();
 
-		render_hand(&client_datas[info.clientid].render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0));
+		render_hand(&client_datas[info.cid].render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0));
 	}
 
 	// draw gun
@@ -478,9 +479,9 @@ void render_player(
 
 		switch (player.weapon)
 		{
-			case WEAPON_GUN: render_hand(&client_datas[info.clientid].render_info, p, direction, -3*pi/4, vec2(-15, 4)); break;
-			case WEAPON_SHOTGUN: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-5, 4)); break;
-			case WEAPON_GRENADE: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-4, 7)); break;
+			case WEAPON_GUN: render_hand(&client_datas[info.cid].render_info, p, direction, -3*pi/4, vec2(-15, 4)); break;
+			case WEAPON_SHOTGUN: render_hand(&client_datas[info.cid].render_info, p, direction, -pi/2, vec2(-5, 4)); break;
+			case WEAPON_GRENADE: render_hand(&client_datas[info.cid].render_info, p, direction, -pi/2, vec2(-4, 7)); break;
 		}
 
 	}
@@ -507,13 +508,13 @@ void render_player(
 		gfx_quads_end();
 	}
 
-	if (client_datas[info.clientid].emoticon_start != -1 && client_datas[info.clientid].emoticon_start + 2 * client_tickspeed() > client_tick())
+	if (client_datas[info.cid].emoticon_start != -1 && client_datas[info.cid].emoticon_start + 2 * client_tickspeed() > client_tick())
 	{
 		gfx_texture_set(data->images[IMAGE_EMOTICONS].id);
 		gfx_quads_begin();
 
-		int since_start = client_tick() - client_datas[info.clientid].emoticon_start;
-		int from_end = client_datas[info.clientid].emoticon_start + 2 * client_tickspeed() - client_tick();
+		int since_start = client_tick() - client_datas[info.cid].emoticon_start;
+		int from_end = client_datas[info.cid].emoticon_start + 2 * client_tickspeed() - client_tick();
 
 		float a = 1;
 
@@ -534,7 +535,7 @@ void render_player(
 
 		gfx_setcolor(1.0f,1.0f,1.0f,a);
 		// client_datas::emoticon is an offset from the first emoticon
-		select_sprite(SPRITE_OOP + client_datas[info.clientid].emoticon);
+		select_sprite(SPRITE_OOP + client_datas[info.cid].emoticon);
 		gfx_quads_draw(position.x, position.y - 23 - 32*h, 64, 64*h);
 		gfx_quads_end();
 	}
@@ -547,7 +548,7 @@ void render_player(
 		if(config.cl_nameplates_always == 0)
 			a = clamp(1-powf(distance(local_target_pos, position)/200.0f,16.0f), 0.0f, 1.0f);
 			
-		const char *name = client_datas[info.clientid].name;
+		const char *name = client_datas[info.cid].name;
 		float tw = gfx_text_width(0, 28.0f, name, -1);
 		gfx_text_color(1,1,1,a);
 		gfx_text(0, position.x-tw/2.0f, position.y-60, 28.0f, name, -1);