Index: Daodan/MSVC/Daodan.c
===================================================================
--- Daodan/MSVC/Daodan.c	(revision 585)
+++ Daodan/MSVC/Daodan.c	(revision 586)
@@ -235,8 +235,34 @@
 		DDrPatch_Const(0x0051BB64, regen_patch);
 	}
+	
+	//Fix crappy ai2_shownames
+	if(1)
+	{
+		//Set distance above head to 4.0
+		DDrPatch_Int32(0x0048C998, 0x005296C8);
+		//texture height
+		DDrPatch_Byte( 0x0048C9DF, 0x3F );
+		//texture	width
+		DDrPatch_NOOP( (char*)0x0048C9CA, 6 );
+		//Set the text color to whatever we like ;)
+		DDrPatch_NOOP( 0x0048C898, 6 );
+		DDrPatch_Byte( 0x0048C898, 0x8B );
+		DDrPatch_Byte( 0x0048C899, 0xCE );
+		DDrPatch_MakeCall( 0x0048C8A3, FLrHook_DebugNameShadeHack);
+		
+		//Make the background black for additive blending
+		DDrPatch_MakeCall( 0x0048C802, FLrHook_DebugNameTextureInit );
+	}
+
+	if(1)
+	{
+		//DDrPatch_NOOP( 0x004E1957, 6 );
+		//DDrPatch_MakeCall( 0x004E17F6, FLrHook_Lasers );
+	}
+
 	//Flatline related stuff
 	DDrPatch_MakeCall(0x004FBCEA, DDrText_Hook);
 	
-	DDrPatch_Int32(	0x004B24D2, 	FLrSpawnHack);
+	DDrPatch_Int32(	0x004B24D2, FLrSpawnHack);
 
 	DDrPatch_NOOP(0x004C26CB, 6);
Index: Daodan/MSVC/Daodan_Utility.c
===================================================================
--- Daodan/MSVC/Daodan_Utility.c	(revision 585)
+++ Daodan/MSVC/Daodan_Utility.c	(revision 586)
@@ -145,5 +145,5 @@
 	COtTextArea* cons = *(COtTextArea**)0x00571B74;
 	char* clipboardText = 0;
-	if(GetAsyncKeyState(0x56) && GetAsyncKeyState(VK_CONTROL) )
+	if(ONgGameState->Input.Current.Actions1 & Action_Console && GetKeyState(0x56) & 0x80 && GetKeyState(VK_CONTROL) & 0x80 )
 	{
 		if(cons && cons->text_entries && cons->num_text_entries)
Index: Daodan/MSVC/Flatline.c
===================================================================
--- Daodan/MSVC/Flatline.c	(revision 585)
+++ Daodan/MSVC/Flatline.c	(revision 586)
@@ -26,183 +26,4 @@
 #define BETTER_SYNC
 
-bool FLrServer_PacketCallback(char* data, int datalen, int from)
-{
-	int i, j;
-	bool found_player = 0;
-	flatline_packet * packet = (flatline_packet*)data;
-	static int recieved = 0;
-	sockaddr_in sender;
-	sender.sin_family = AF_INET;
-	sender.sin_port = htons(27777);
-	sender.sin_addr = *((struct in_addr*)(int*)&from);
-
-
-	//packet->data[datalen] = '\0';
-
-	//DDrConsole_PrintF("Packet \r%d recieved from %i",  ++recieved, from);
-
-
-
-	//if data[0] != CONNECT_SEND, search in playerlist for ip address
-
-
-
-
-	switch(packet->id) {
-		flatline_packet connect_recv;
-		player_info * playah;
-		//rewrite this when we get TCP support.
-		//rewrite this before we get TCP support*
-		//the way of seeing if there is room for players sucks.
-	case CONNECT_SEND:
-		;
-
-		connect_recv.id = CONNECT_REPLY;
-
-		//if(Players[i].ip == sender.sin_addr.S_un.S_addr) break; //needs to send an error message
-		sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
-		playah = FLrServer_AddPlayer(from,packet->connect_send.name, 0, 0);
-		DDrConsole_PrintF("%s connected from %s", packet->connect_send.name, inet_ntoa(sender.sin_addr ) );
-		if(!((int)playah > -5 && (int)playah <= 0)) {
-			flatline_packet new_char = {0};
-			CharacterObject* Char;
-			connect_recv.connect_reply.goodtogo = 1;
-			connect_recv.connect_reply.player_slot = playah->list_slot;
-			DDrConsole_PrintF("Slot: %i", playah->list_slot);
-
-			//sending this several times to make sure it gets through. Really need to make up some form of packet tracking.
-			NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
-/*			NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
-			NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
-			NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
-			NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
-			Sleep(100);
-			*/
-			new_char.id = NEW_PLAYER;
-			Char = &new_char.new_player.Character;
-			memset(Char, 0, sizeof(CharacterObject));
-			Char->Header.Type = 'CHAR';
-			Char->OSD.Options = chr_dontaim;
-			for(j = 0; j < max_connections; j++) {
-				if(PlayerList[j] != 0) {
-					new_char.new_player.Playernumber = j;
-					sprintf(Char->OSD.Name,"%s",PlayerList[j]->name);
-
-					sprintf(Char->OSD.Class, "%s", TMrInstance_GetInstanceName(PlayerList[j]->Chr->ONCC));
-					DDrConsole_PrintF("Class %s", Char->OSD.Class );
-
-					sprintf(Char->OSD.Class, "konoko_generic");
-					NetTCPServer_Send((sockaddr *) &sender, (char*)&new_char, sizeof(new_player) + FLATLINE_HEADER );
-				}
-
-			}
-		}
-		else {
-			//fix the error messages...
-			DDrConsole_PrintF("Server is full. :(");
-			connect_recv.connect_reply.goodtogo = 0;
-			sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
-			memcpy(&connect_recv.connect_reply.message,"Server is full.", sizeof("Server is full."));
-			NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(bool)*2 + FLATLINE_HEADER + sizeof("Server is full."));	
-
-		} 
-
-
-		break;
-	case CONNECT_REPLY:
-		break;	//do nothing...a server shouldn't recieve this type of packet.
-	case MESSAGE:
-		for(i = 0; i < MAX_PLAYERS; i++) {
-			//DDrConsole_PrintF("%i : %i | %s : %s", from, Players[i].ip, inet_ntoa(*(struct in_addr*)&from), inet_ntoa(*(struct in_addr*)&(Players[i].ip)));
-			if(Players[i].ip == sender.sin_addr.S_un.S_addr) {
-				found_player = 1;
-				break;
-			}	
-		}
-		if(found_player == 0) return true;
-		else {
-			char message_buffer[512] = {0};
-			flatline_packet message;
-			int message_size;
-			data[datalen] = 0;
-
-			DDrConsole_PrintF("%s: %s", Players[i].name, packet->data);
-			sprintf(message_buffer, "%s: %s", Players[i].name, packet->data);
-
-			message.id = MESSAGE;
-			message_size = sprintf(message.data, "%s", message_buffer);
-			COrMessage_Print(message_buffer, "chat", 0);
-			UDPServer_SendToAll(&message, message_size + 1 + FLATLINE_HEADER);
-			break;
-		}
-	case CHANGE_NAME:
-		; //wtf, needed or i get an error.
-	//	DDrConsole_PrintF("Changing Name to: %s", packet->data);
-		for(i = 0; i < MAX_PLAYERS; i++) {
-			if(PlayerList[i] && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) {
-				found_player = 1;
-				break;
-			}	
-		}
-		if(found_player == 0) break;
-		else {
-			bool name_exists = 0;
-			for(j = 0; j < MAX_PLAYERS; j++) {
-				if(PlayerList[j] && !strcmp(packet->data, PlayerList[j]->name)) {
-					name_exists = 1;
-					break;
-				}
-			}
-			if(!name_exists) {
-				FLsUpdateName( i, packet->data );
-			}
-			break;
-		}
-	case PLAYER_INPUT:
-
-		for(i = 0; i < max_connections; i++) {
-			if(PlayerList[i] != 0 && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) {
-				found_player = 1;
-				break;
-			}	
-		}
-
-		if(found_player == 0) break;
-		else {
-			input_struct * packet_input = &packet->input_struct;
-
-
-			PlayerList[i]->InputFromClient.Actions1 = packet_input->Actions1;
-			PlayerList[i]->InputFromClient.Actions2 = packet_input->Actions2;
-			PlayerList[i]->InputFromClient.MouseDeltaX = packet_input->MouseDeltaX;
-			PlayerList[i]->InputFromClient.MouseDeltaY = packet_input->MouseDeltaY;
-			PlayerList[i]->LastInputTime = packet_input->Time;
-
-			break;
-		}
-	case PK_PONG:
-		for(i = 0; i < max_connections; i++) {
-			if(PlayerList[i] != 0 && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) {
-				found_player = 1;
-				break;
-			}	
-		}
-
-		if(found_player == 0) break;
-		if(packet->ping != lastPingTime)
-		{
-			PlayerList[i]->Ping = 999;
-		}
-		else
-		{
-			PlayerList[i]->Ping = GetTickCount() - packet->ping;
-		}
-		break;
-	default:
-		DDrConsole_PrintF("Warning, recieved badly formed packet!");
-		break;
-	}
-	return true;
-}
 
 bool FLrServer_Run()
@@ -295,9 +116,10 @@
 
 		input_packet.id = PLAYER_INPUT;
-		input_packet.input_struct.Time = ONgGameState->GameTime;
+//		input_packet.input_struct.Time = ONgGameState->GameTime;
 		input_packet.input_struct.Actions1 = ONgGameState->Input.Current.Actions1;
 		input_packet.input_struct.Actions2 = ONgGameState->Input.Current.Actions2;
 		input_packet.input_struct.MouseDeltaX = ONgGameState->Input.MouseDeltaX;
 		input_packet.input_struct.MouseDeltaY = ONgGameState->Input.MouseDeltaY;
+		input_packet.input_struct.DesiredFacing = ONgGameState->PlayerCharacter->DesiredFacing;
 
 		sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&input_packet, sizeof(input_struct) + FLATLINE_HEADER);
@@ -310,20 +132,5 @@
 
 
-	if(server_started)
-	{
-		if(ONgGameState->GameTime % 120 == 0)
-		{
-			FLsPingAll();
-		}
-
-		if(PlayerList[0])
-		{
-			PlayerList[0]->InputFromClient.Actions1 = ONgGameState->Input.Current.Actions1;
-			PlayerList[0]->InputFromClient.Actions2 = ONgGameState->Input.Current.Actions2;
-			PlayerList[0]->InputFromClient.MouseDeltaX = ONgGameState->Input.MouseDeltaX;
-			PlayerList[0]->InputFromClient.MouseDeltaY = ONgGameState->Input.MouseDeltaY;
-		}
-		FLsSendPlayerData();
-	}
+
 	for(i = 0; i < max_connections; i++) {
 		ActiveCharacter * Active_Player;
@@ -343,13 +150,20 @@
 		}
 
+		if( server_started && i != 0 )
+		{
+			PlayerList[i]->Chr->DesiredFacing = PlayerList[i]->FacingFromClient;
+		}
+
 
 		
 		//Set the health properly first.
+		//Always overridden by the server because of the chance of random damage and such
 		if( client_connected && DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Health) )
 		{
 			PlayerList[i]->Chr->MaxHealth = PlayerList[i]->Health.MaxHealth;
 			ONrCharacter_SetHitPoints(  PlayerList[i]->Chr, PlayerList[i]->Health.Health);
-			PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Health );
-		}
+			//PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Health );
+		}
+
 		//If the player is dead
 		if( PlayerList[i]->Chr->Health == 0 )
@@ -415,8 +229,20 @@
 		PlayerList[i]->state = STATE_ALIVE;
 
-		if( DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Facing ) )
+		if( client_connected && DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Class ) )
+		{
+			if(PlayerList[i]->Class)
+			{
+				ONrCharacter_SetCharacterClass( PlayerList[i]->Chr, PlayerList[i]->Class );
+			}
+			PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Class );
+		}
+
+		if( client_connected &&  DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Facing ) )
 		{
 			PlayerList[i]->Chr->Facing = PlayerList[i]->Facings.Facing;					
-			PlayerList[i]->Chr->DesiredFacing = PlayerList[i]->Facings.DesiredFacing;
+			if(i != client_slot)
+			{
+				PlayerList[i]->Chr->DesiredFacing = PlayerList[i]->Facings.DesiredFacing;
+			}
 			PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Facing );
 		}
@@ -425,129 +251,10 @@
 
 		
-		if(client_connected) {
-			Active_Player->PlayingFilm.Flags = 1;
-		}
-
-
-		if( client_connected && DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Position) )
-		{
-			Active_Player->PhyContext->Position = PlayerList[i]->Position;
-			
-			PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Position );
-		}
-
-
-
-
-		if (!(Player->Flags & ONcCharacterFlag_BeingThrown) &&
-			DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Animation) && (PlayerList[i]->Animation))
-		{
-			// get a pointer to the animation
-
-			
-			if (PlayerList[i]->Animation != Active_Player->Animation)
-			{
-
-				///////////////////////////////////
-				//TODO: Check age of animation
-				///////////////////////////////////
-				DDrConsole_PrintF("Changing animation from %s to %s", 
-					TMrInstance_GetInstanceName( Active_Player->Animation ),
-					TMrInstance_GetInstanceName( PlayerList[i]->Animation ) );
-				// set the characters animation
-				/*ONrCharacter_SetAnimationInternal(Player,
-				Active_Player,
-				Active_Player->AnimationToState,
-				0,
-				PlayerList[i]->Animation);*/
-				//ONrCharacter_NewAnimationHook(Player, Active_Player);
-				ONrCharacter_SetAnimationExternal(Player, TRrAnimation_GetFrom(PlayerList[i]->Animation), PlayerList[i]->Animation, 1);
-				//ONrCharacter_NewAnimationHook(Player, Active_Player);
-			}
-			
-			
-		}
-		PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Animation );
-
-		//Don't update the frame if we are waiting to change the animation
-		if(DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_FramePing) && PlayerList[i]->Frame != -1 
-			//&& !DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Animation) 
-			)
-		{
-			if( abs(PlayerList[i]->Frame - Active_Player->Frame) > 2 )
-			{
-				short AnimationLength;
-				AnimationLength = TRrAnimation_GetDuration(Active_Player->Animation);
-				if (PlayerList[i]->Frame >= AnimationLength)
-				{
-					Active_Player->Frame = AnimationLength - 1;
-					//Active_Player->Frame = 0;
-				}
-				else
-				{
-					Active_Player->Frame = PlayerList[i]->Frame;
-				}
-			}
-			PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_FramePing );
-		}
-
-		//Increment frame in case we were waiting
-		PlayerList[i]->Frame++;
-
-		if (DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Throws) 
-			&& PlayerList[i]->ThrowData.throwName[0] != 0)
-		{
-			if(PlayerList[PlayerList[i]->ThrowData.throwing])
-			{
-				short throwTarget = PlayerList[PlayerList[i]->ThrowData.throwing]->spawnnumber;
-				if ((throwTarget != Active_Player->throwing) &&
-					(PlayerList[i]->ThrowData.throwFrame < 10))
-				{
-					void	*throw_animation;
-					ActiveCharacter* Target;
-					// get the animation
-
-					TMrInstance_GetDataPtr(
-						'TRAM',
-						PlayerList[i]->ThrowData.throwName,
-						&throw_animation);
-					//if (error) return;
-
-					// set the throw target
-					Active_Player->ThrowTargetCharacter = &ONgGameState->CharacterStorage[throwTarget];
-					Target = ONrGetActiveCharacter(Active_Player->ThrowTargetCharacter);
-					if ((Target->Animation != throw_animation) &&
-					//	(OldAnimation != Animation) &&
-						!(Active_Player->ThrowTargetCharacter->Flags & ONcCharacterFlag_BeingThrown))
-					{
-						// set the throw variables
-						Active_Player->targetThrow	= throw_animation;
-						Active_Player->throwing		= throwTarget;
-
-						// run the throw
-						ONrCharacter_NewAnimationHook(Player, Active_Player);
-
-						if (Active_Player->ThrowTargetCharacter)
-						{
-							Target->Frame += 2;
-							DDrConsole_PrintF("Thrown by player %hi", Player->Number );
-							DDrStartupMessage("Thrown by player %hi", Player->Number );
-							Target->thrownBy = Player->Number & 0x00ff;
-						}
-					}
-				}
-			}
-			else
-			{
-				DDrConsole_PrintF("Warning, tried to throw nonexistant player %hi", 
-					PlayerList[i]->ThrowData.throwing );
-			}
-		} 
-
-		//Always discard old throw data, even if it isnt applied
-		PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Throws );
-
-		Active_Input = &(Active_Player->Input);
-
+		
+			//		Active_Player->PlayingFilm.Flags = 1;
+
+					Active_Input = &(Active_Player->Input);
+
+		
 		if( (server_started && i !=0)  || !server_started ) 
 		{
@@ -561,45 +268,214 @@
 			Active_Input->Stopped.Actions1 = ~Active_Input->Current.Actions1;
 			Active_Input->Stopped.Actions2 = ~Active_Input->Current.Actions2;
-			Active_Input->MouseDeltaX = PlayerList[i]->Input.MouseDeltaX;
-			Active_Input->MouseDeltaY = PlayerList[i]->Input.MouseDeltaY;
+			if(client_connected && i == client_slot)
+			{
+				Active_Input->MouseDeltaX = ONgGameState->Input.MouseDeltaX;
+				Active_Input->MouseDeltaY = ONgGameState->Input.MouseDeltaY;
+			}
+			else
+			{
+				Active_Input->MouseDeltaX = PlayerList[i]->Input.MouseDeltaX;
+				Active_Input->MouseDeltaY = PlayerList[i]->Input.MouseDeltaY;
+			}
 		} 
 		
+		{
+		void* ConsoleAnimation = 0; 
+		TMrInstance_GetDataPtr( 'TRAM', "KONOKOwatch_idle", &ConsoleAnimation);
+
+		if(!Active_Player->IsInAir && Active_Input->Current.Actions1 & (Action_Console | Action_PauseScreen) 
+			&& !(PlayerList[i]->Chr->Flags & ONcCharacterFlag_BeingThrown)
+			&& Active_Player->ThrowTargetCharacter != -1)
+		{
+			if(ConsoleAnimation && ConsoleAnimation != Active_Player->Animation)
+			{
+				ONrCharacter_SetAnimationExternal(PlayerList[i]->Chr, Active_Player->AnimationFromState, ConsoleAnimation, 10);
+				Player->Flags |= 0x00200000;
+				Active_Player->ForcedAnimationFrames = -1;// TRrAnimation_GetDuration(ConsoleAnimation);
+			}
+		}
+		else if(Active_Input->Stopped.Actions1 & (Action_Console | Action_PauseScreen) )
+		{
+			Active_Player->ForcedAnimationFrames = 0;
+		}
+
+		}
+
 		//Check for character switching requests
-		if(server_started && PlayerList[i]->Chr->Health != 0 && PlayerList[i]->InputFromClient.Actions1 & Action_Block && PlayerList[i]->ShapeshiftCooldown < ONgGameState->GameTime)
-		{
-			int error;
-
-
-
-			ONCC *newClass;
-			short numClasses = (short)TMrInstance_GetTagCount('ONCC');
-			/*
-			if(Active_Player->Input.Start.Actions1 & Action_Block)
-			{
+		if(server_started && PlayerList[i]->Chr->Health != 0 
+			&& PlayerList[i]->InputFromClient.Actions1 & Action_Block)
+		{
+			if( PlayerList[i]->ShapeshiftCooldown < ONgGameState->GameTime)
+			{
+				int error;
+
+
+
+				ONCC *newClass;
+				short numClasses = (short)TMrInstance_GetTagCount('ONCC');
+				/*
+				if(Active_Player->Input.Start.Actions1 & Action_Block)
+				{
 				//This might not be getting hit. Find out why, eh?
 				PlayerList[i]->ShapeshiftCooldown = ONgGameState->GameTime + 15;
-			}
-			else
-			{
+				}
+				else
+				{
 				PlayerList[i]->ShapeshiftCooldown = ONgGameState->GameTime + 5;
-			}
-			*/
-			if (PlayerList[i]->InputFromClient.Actions1 & Action_Crouch) {
-				Player->ONCCnumber += numClasses - 1;
-			}
-			else {
-				Player->ONCCnumber += 1;
-			}
-
-			if (numClasses > 0) {
-				Player->ONCCnumber = Player->ONCCnumber % numClasses;
-
-				error = TMrInstance_GetDataPtr_ByNumber('ONCC', Player->ONCCnumber, &newClass); 
-
-				if ((newClass != NULL) && (!error)) {
-					ONrCharacter_SetCharacterClass(Player, newClass);
-				}
-			}
-
+				}
+				*/
+
+				PlayerList[i]->ShapeshiftCooldown = ONgGameState->GameTime + 15;
+
+				if (PlayerList[i]->InputFromClient.Actions1 & Action_Crouch) {
+					Player->ONCCnumber += numClasses - 1;
+				}
+				else {
+					Player->ONCCnumber += 1;
+				}
+
+				if (numClasses > 0) {
+					Player->ONCCnumber = Player->ONCCnumber % numClasses;
+
+					error = TMrInstance_GetDataPtr_ByNumber('ONCC', Player->ONCCnumber, &newClass); 
+
+					if ((newClass != NULL) && (!error)) {
+						ONrCharacter_SetCharacterClass(Player, newClass);
+					}
+				}
+
+			}
+		}
+		else
+		{
+			PlayerList[i]->ShapeshiftCooldown = 0;
+		}
+		if(client_connected) {
+
+			if( DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Position) )
+			{
+				//Active_Player->PhyContext->Position = PlayerList[i]->Position;
+
+				Active_Player->PhyContext->Position.X = 
+					(PlayerList[i]->Position.X + Active_Player->PhyContext->Position.X) / 2;
+
+				Active_Player->PhyContext->Position.Y = 
+					(PlayerList[i]->Position.Y + Active_Player->PhyContext->Position.Y) / 2;
+
+				Active_Player->PhyContext->Position.Z = 
+					(PlayerList[i]->Position.Z + Active_Player->PhyContext->Position.Z) / 2;
+
+				PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Position );
+			}
+
+
+
+
+			if (!(Player->Flags & ONcCharacterFlag_BeingThrown) &&
+				DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Animation) && (PlayerList[i]->Animation))
+			{
+				// get a pointer to the animation
+
+
+				if (PlayerList[i]->Animation != Active_Player->Animation)
+				{
+
+					///////////////////////////////////
+					//TODO: Check age of animation
+					///////////////////////////////////
+					// set the characters animation
+					/*ONrCharacter_SetAnimationInternal(Player,
+					Active_Player,
+					Active_Player->AnimationToState,
+					0,
+					PlayerList[i]->Animation);*/
+					//ONrCharacter_NewAnimationHook(Player, Active_Player);
+					ONrCharacter_SetAnimationExternal(Player, TRrAnimation_GetFrom(PlayerList[i]->Animation), PlayerList[i]->Animation, 1);
+					//ONrCharacter_NewAnimationHook(Player, Active_Player);
+				}
+
+
+			}
+			PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Animation );
+
+			//Disabled Frame syncing for now. In most cases it won't be useful.
+			if(0 && DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_FramePing) && PlayerList[i]->Frame != -1 
+				//&& !DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Animation) 
+				)
+			{
+				if( abs(PlayerList[i]->Frame - Active_Player->Frame) > 2 )
+				{
+					short AnimationLength;
+					AnimationLength = TRrAnimation_GetDuration(Active_Player->Animation);
+					if (PlayerList[i]->Frame >= AnimationLength)
+					{
+						Active_Player->Frame = AnimationLength - 1;
+						//Active_Player->Frame = 0;
+					}
+					else
+					{
+						Active_Player->Frame = PlayerList[i]->Frame;
+					}
+				}
+
+			}
+			PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_FramePing );
+
+			//Increment frame in case we were waiting
+			PlayerList[i]->Frame++;
+
+			if (DoWeUpdateThis( PlayerList[i]->UpdateFlags, PFlag_Throws) 
+				&& PlayerList[i]->ThrowData.throwName[0] != 0)
+			{
+				if(PlayerList[PlayerList[i]->ThrowData.throwing])
+				{
+					short throwTarget = PlayerList[PlayerList[i]->ThrowData.throwing]->spawnnumber;
+					/*if ((throwTarget != Active_Player->throwing) &&
+					(PlayerList[i]->ThrowData.throwFrame < 10))*/
+					{
+						void	*throw_animation;
+						ActiveCharacter* Target;
+						// get the animation
+
+						TMrInstance_GetDataPtr(
+							'TRAM',
+							PlayerList[i]->ThrowData.throwName,
+							&throw_animation);
+						//if (error) return;
+
+						// set the throw target
+						Active_Player->ThrowTargetCharacter = &ONgGameState->CharacterStorage[throwTarget];
+						Target = ONrGetActiveCharacter(Active_Player->ThrowTargetCharacter);
+						//if (/*(Target->Animation != throw_animation) &&*/
+						//	(OldAnimation != Animation) &&
+						//	!(Active_Player->ThrowTargetCharacter->Flags & ONcCharacterFlag_BeingThrown))
+						//	Target->thrownBy == -
+						{
+							// set the throw variables
+							Active_Player->targetThrow	= throw_animation;
+							Active_Player->throwing		= throwTarget;
+
+							// run the throw
+							ONrCharacter_NewAnimationHook(Player, Active_Player);
+
+							//if (Active_Player->ThrowTargetCharacter)
+							{
+								//		Target->Frame += 2;
+								//DDrConsole_PrintF("Thrown by player %hi", Player->Number );
+								//DDrStartupMessage("Thrown by player %hi", Player->Number );
+								Target->thrownBy = Player->Number & 0x00ff;
+							}
+						}
+					}
+				}
+				else
+				{
+					DDrConsole_PrintF("Warning, tried to throw nonexistant player %hi", 
+						PlayerList[i]->ThrowData.throwing );
+				}
+			} 
+
+			//Always discard old throw data, even if it isnt applied
+			PlayerList[i]->UpdateFlags &= ~( 1 << PFlag_Throws );
 		}
 
@@ -607,4 +483,20 @@
 	}
 	
+	if(server_started)
+	{
+		if(ONgGameState->GameTime % 120 == 0)
+		{
+			FLsPingAll();
+		}
+
+		if(PlayerList[0])
+		{
+			PlayerList[0]->InputFromClient.Actions1 = ONgGameState->Input.Current.Actions1;
+			PlayerList[0]->InputFromClient.Actions2 = ONgGameState->Input.Current.Actions2;
+			PlayerList[0]->InputFromClient.MouseDeltaX = ONgGameState->Input.MouseDeltaX;
+			PlayerList[0]->InputFromClient.MouseDeltaY = ONgGameState->Input.MouseDeltaY;
+		}
+		FLsSendPlayerData();
+	}
 	MultiplayerStatus.PleaseUpdateAllPlayers = 0;
 	return ONgGameState;
@@ -651,11 +543,14 @@
 			const int green =	0x0000FF00;
 			const int red =		0x00FF0000;
+			const int blue =	0x000000FF;
 			int i;
 			char DrawString[255];
 			const int LineHeight = 15;
-			IMtPoint2D DrawLocation = {20, 20};
+			IMtPoint2D DrawLocation = {25, 20};
 			TSrContext_SetShade(ScoreboardInstance, white);
 			TSrContext_DrawText(ScoreboardInstance, "Oni Flatline build " __DATE__ " " __TIME__, 255, 0, &DrawLocation);
+			TSrContext_SetShade(ScoreboardInstance, white);
 			DrawLocation.y += LineHeight;
+			DrawLocation.x = 25;
 			TSrContext_DrawText(ScoreboardInstance, "Name", 255, 0, &DrawLocation);
 			DrawLocation.x += 150;
@@ -667,6 +562,10 @@
 				if(PlayerList[i] == 0 || PlayerList[i]->Chr == 0) continue;
 
-				DrawLocation.x = 20;
+				DrawLocation.x = 10;
 				DrawLocation.y += LineHeight;
+
+				sprintf(DrawString, "%i.", i );
+				TSrContext_DrawText(ScoreboardInstance, DrawString, 255, 0, &DrawLocation);
+				DrawLocation.x += 15;
 
 				if(PlayerList[i]->Chr && PlayerList[i]->Chr->Health == 0) 
Index: Daodan/MSVC/Flatline.h
===================================================================
--- Daodan/MSVC/Flatline.h	(revision 585)
+++ Daodan/MSVC/Flatline.h	(revision 586)
@@ -101,5 +101,6 @@
 	uint32_t Actions1;
 	uint32_t Actions2;
-	unsigned int Time;
+	float DesiredFacing;
+	//unsigned int Time;
 } input_struct;
 
@@ -182,4 +183,5 @@
 		uint32_t		ping;
 		//player_input	all_input[33];
+		uint32_t		integer; //generic integer ;)
 	};
 } flatline_packet;
@@ -211,4 +213,5 @@
 	//PK_ALL_INPUT,
 	PK_PLAYER_DATA,
+	PK_MISSING_PLAYER,
 };
 
@@ -252,4 +255,5 @@
 
 	PlayerInput InputFromClient;
+	float FacingFromClient;
 
 	////////////////////////////
@@ -263,7 +267,9 @@
 	PlayerScore Score;
 	void* Animation;
+	char AnimationString[32];
 	uint16_t Frame;
 	PlayerThrowData ThrowData;
 	void* Class;
+	char ClassString[32];
 	PlayerInventory Inventory;
 	Vector3 Position;
@@ -272,5 +278,4 @@
 
 	unsigned int LastInputTime;
-
 
 
Index: Daodan/MSVC/Flatline_BSL.c
===================================================================
--- Daodan/MSVC/Flatline_BSL.c	(revision 585)
+++ Daodan/MSVC/Flatline_BSL.c	(revision 586)
@@ -216,5 +216,13 @@
 }
 
-
+uint16_t tele(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
+{
+	ActiveCharacter *AC = ONrGetActiveCharacter(ONgGameState->PlayerCharacter);
+//	AC->PhyContext->Position = AC->AimTarget;
+	AC->PhyContext->Position.X += AC->AimVector.X;
+	AC->PhyContext->Position.Y += AC->AimVector.Y;
+	AC->PhyContext->Position.Z += AC->AimVector.Z;
+	return 0;
+}
 void SLrFlatline_Initialize() 
 {
@@ -223,4 +231,5 @@
 	FLrInput_Update_Keys();
 	SLrGlobalVariable_Register_Int32("skip", "skips", &(((GameState*)ONgGameState)->field_40) );
+	SLrScript_Command_Register_Void("tele","teleports", "", tele);
 	SLrScript_Command_Register_ReturnType("connect","Connects to a server", "ip:string", sl_void, connect_to_server);
 	SLrScript_Command_Register_Void("host","Starts a server", "", start_server);
Index: Daodan/MSVC/Flatline_Client.c
===================================================================
--- Daodan/MSVC/Flatline_Client.c	(revision 585)
+++ Daodan/MSVC/Flatline_Client.c	(revision 586)
@@ -23,4 +23,7 @@
 		OBJrConsole_OnActivate( OBJrConsole_GetByID(args[0]), PlayerList[args[1]]->Chr );
 		break;
+	case(EV_RESPAWN):
+		ONrCorpse_Create(PlayerList[args[0]]->Chr);
+		break;
 	default:
 		break;
@@ -42,5 +45,5 @@
 	//starts the connection
 	DDrConsole_PrintF("Connecting to server %s on socket %i",  inet_ntoa(address.sin_addr), client_sock);
-	sent_bytes = NetUDPSocket_Send(client_sock, (sockaddr*)&address, (char*)packet, 255);
+	sent_bytes = NetUDPSocket_Send(client_sock, (sockaddr*)&address, (char*)packet, FLATLINE_HEADER + sizeof(connect_send) );
 	if(sent_bytes == SOCKET_ERROR) {
 		NetCatchError();
@@ -73,5 +76,5 @@
 
 
-					DDrPatch_Byte(0x04ED6FB, 0xEB);
+					//DDrPatch_Byte(0x04ED6FB, 0xEB);
 
 					//DDrConsole_PrintF("Slot %i",  ((connect_reply*)packet)->player_slot);
Index: Daodan/MSVC/Flatline_Hooks.c
===================================================================
--- Daodan/MSVC/Flatline_Hooks.c	(revision 585)
+++ Daodan/MSVC/Flatline_Hooks.c	(revision 586)
@@ -32,2 +32,44 @@
 }
 
+int FLrHook_DebugNameTextureInit(short width, short height, int type, int allocated, int flags, char* name, void** output)
+{
+	//flags = (1 << 10);
+	type = 1;
+	//DDrPatch_Byte( 0x005EB83C + 3, 0xff );
+	DDrPatch_Int32( 0x005EB83C, 0xFF000000 );
+	return M3rTextureMap_New(width, height, type, allocated, flags, name, output);
+}
+
+short FLrHook_DebugNameShadeHack( Character* Char )
+{
+	
+	return TSrContext_SetShade(*(void**)0x005EB844, ONrCharacter_GetHealthShade( Char->Health, Char->MaxHealth ));
+	//return TSrContext_SetShade(*(void**)0x005EB844, 0xFFFFFFFF);
+}
+/*
+void FLrHook_Lasers( Character* PlayerChar )
+{
+	if(server_started || client_connected)
+	{
+		int i;
+		for(i = 0; i < MAX_PLAYERS; i++)
+		{
+			if(PlayerList[i] && PlayerList[i]->Chr && PlayerList[i]->Chr->Inventory.Weapons[0])
+			{
+				ONiDrawWeaponSight( PlayerList[i]->Chr );
+			}
+		}
+	}
+	else
+	{
+		if(
+		ONiDrawWeaponSight( ONgGameState->PlayerCharacter );
+	}
+}
+*/
+
+void FLrHook_Lasers( Character* Char )
+{
+	ONiDrawWeaponSight( Char );
+	AI2rDisplayDebuggingInfo( Char );
+}
Index: Daodan/MSVC/Flatline_Hooks.h
===================================================================
--- Daodan/MSVC/Flatline_Hooks.h	(revision 585)
+++ Daodan/MSVC/Flatline_Hooks.h	(revision 586)
@@ -2,2 +2,5 @@
 char * FLrHook_DoorOpen( DoorObject *Door, Character *Char);
 short FLrHook_ConsoleActivate( void *inObject, Character *inCharacter );
+int FLrHook_DebugNameTextureInit(short width, short height, int type, int allocated, int flags, char* name, void** output);
+short FLrHook_DebugNameShadeHack( Character* Char );
+void FLrHook_Lasers( Character* PlayerChar );
Index: Daodan/MSVC/Flatline_PacketBuilder.c
===================================================================
--- Daodan/MSVC/Flatline_PacketBuilder.c	(revision 585)
+++ Daodan/MSVC/Flatline_PacketBuilder.c	(revision 586)
@@ -4,5 +4,5 @@
 #define FLAG_AND_INCREMENT( FLAG )	PD->UpdateFlags |= (1 << FLAG ); DataPointer += FLpData_PartSize( FLAG );
 
-void FLsPacketBuild( uint8_t p, PlayerData* PD )
+void FLsPacketBuild( uint8_t p, PlayerData* PD, bool UpdateAll )
 {
 	Character* Player = PlayerList[p]->Chr;
@@ -38,5 +38,5 @@
 
 	if( PI->Facings.Facing != Player->Facing ||
-		PI->Facings.DesiredFacing != Player->DesiredFacing )
+		PI->Facings.DesiredFacing != Player->DesiredFacing || UpdateAll )
 	{
 		PlayerFacing* ptr = (void*)DataPointer;
@@ -50,5 +50,5 @@
 
 	if(PI->Health.Health != Player->Health ||
-		PI->Health.MaxHealth != Player->MaxHealth )
+		PI->Health.MaxHealth != Player->MaxHealth || UpdateAll )
 	{
 		PlayerHealth* ptr = (void*)DataPointer;
@@ -89,7 +89,8 @@
 	}
 
-	if( PI->Class != Player->ONCC )
+	if( PI->Class != Player->ONCC || UpdateAll )
 	{
 		sprintf_s( DataPointer, 32, "%s", TMrInstance_GetInstanceName( Player->ONCC ) );
+		sprintf_s( PI->ClassString, 32, "%s", DataPointer );
 		PI->Class = Player->ONCC;
 
@@ -99,5 +100,5 @@
 	if(APlayer)
 	{
-		if( (APlayer->PhyContext) && memcmp(&PI->Position, &APlayer->PhyContext->Position, sizeof(Vector3)) )
+		if( (APlayer->PhyContext) && (memcmp(&PI->Position, &APlayer->PhyContext->Position, sizeof(Vector3)) || UpdateAll ))
 		{
 			Vector3* ptr = (Vector3*)DataPointer;
@@ -107,8 +108,10 @@
 		}
 
-		if(APlayer->Animation != PI->Animation)
+		if(APlayer->Animation != PI->Animation || !APlayer->Frame || UpdateAll )
 		{
 			sprintf_s( DataPointer, 32, "%s", TMrInstance_GetInstanceName( APlayer->Animation ) );
+			sprintf_s( PI->AnimationString, 32, "%s", DataPointer );
 			PI->Animation = APlayer->Animation;
+
 			
 			FLAG_AND_INCREMENT( PFlag_Animation );
@@ -117,5 +120,5 @@
 		if(APlayer->targetThrow)
 		{
-			if(!PI->HasAppliedThrow)
+			if(!PI->HasAppliedThrow || UpdateAll )
 			{
 				PlayerThrowData* ptr = (void*)DataPointer;
@@ -164,5 +167,5 @@
 		if(PlayerList[p] && PlayerList[p]->Chr)
 		{
-			FLsPacketBuild(p, &BuildData[p]);
+			FLsPacketBuild(p, &BuildData[p], 0);
 			
 			assert( BuildData[p].Size < 255 );
Index: Daodan/MSVC/Flatline_PacketReader.c
===================================================================
--- Daodan/MSVC/Flatline_PacketReader.c	(revision 585)
+++ Daodan/MSVC/Flatline_PacketReader.c	(revision 586)
@@ -9,4 +9,6 @@
 //Long winded?
 
+
+
 void FLcPacketBufferToPlayerData( PlayerData* PD)
 {
@@ -14,8 +16,48 @@
 	uint8_t * DataPointer = PD->data;
 
+	static player_info BufferData[MAX_PLAYERS] = {0};
+	static bool IsBuffered[32];
+	
+
 	if(!PI)
 	{
 		//TODO: Store this data and then apply it once we have a character that matches!
-		return;
+		flatline_packet pk;
+		pk.id = PK_MISSING_PLAYER;
+		pk.integer = PD->ID;
+		NetUDPSocket_Send(client_sock, (sockaddr*)&address, (char*)&pk, FLATLINE_HEADER + 4 );
+		
+		IsBuffered[PD->ID] = 1;
+		PI = &BufferData[PD->ID];
+		
+		//return;
+	}
+	else if(IsBuffered[PD->ID])
+	{
+		player_info* Buffer = BufferData + PD->ID;
+		if( DoWeUpdateThis( Buffer->UpdateFlags, PFlag_Input) )	PI->Input = Buffer->Input;
+		if( DoWeUpdateThis( Buffer->UpdateFlags, PFlag_Facing) )	PI->Facings = Buffer->Facings;
+		if( DoWeUpdateThis( Buffer->UpdateFlags, PFlag_Health) )	PI->Health = Buffer->Health;
+		if( DoWeUpdateThis( Buffer->UpdateFlags, PFlag_FramePing) )	{
+			PI->Frame = Buffer->Frame;
+			PI->Ping = Buffer->Ping;
+		}
+		//if( DoWeUpdateThis( Buffer->UpdateFlags, PFlag_Inventory) )	PI->invi= Buffer->Input;
+		if( DoWeUpdateThis( Buffer->UpdateFlags, PFlag_Class) )	
+		{
+			PI->Class = Buffer->Class;
+			sprintf_s( PI->ClassString, 32, "%s", Buffer->ClassString );
+		}
+
+		if( DoWeUpdateThis( Buffer->UpdateFlags, PFlag_Position) )	PI->Position = Buffer->Position;
+		if( DoWeUpdateThis( Buffer->UpdateFlags, PFlag_Animation) )	
+		{
+			PI->Animation = Buffer->Animation;
+			sprintf_s( PI->AnimationString, 32, "%s", Buffer->AnimationString);
+		}
+		if( DoWeUpdateThis( Buffer->UpdateFlags, PFlag_Throws) )	PI->ThrowData = Buffer->ThrowData;
+		
+		PI->UpdateFlags |= Buffer->UpdateFlags;
+		IsBuffered[PD->ID] = 0;
 	}
 
@@ -70,5 +112,6 @@
 	if( DoWeUpdateThis( PD->UpdateFlags, PFlag_Class ) )
 	{
-		TMrInstance_GetDataPtr( 'ONCC', (char*)DataPointer, &PI->Class );
+		sprintf_s( PI->ClassString, 32, "%s", DataPointer );
+		TMrInstance_GetDataPtr( 'ONCC', (char*)DataPointer, &PI->Class ); 
 		DataPointer += FLpData_PartSize( PFlag_Class );
 	}
@@ -82,5 +125,6 @@
 	if( DoWeUpdateThis( PD->UpdateFlags, PFlag_Animation ) )
 	{
-		TMrInstance_GetDataPtr( 'TRAM', (char*)DataPointer, &PI->Animation );
+		sprintf_s( PI->AnimationString, 32, "%s", DataPointer );
+		TMrInstance_GetDataPtr( 'TRAM', PI->AnimationString, &PI->Animation );
 		DataPointer += FLpData_PartSize( PFlag_Animation );
 	}
Index: Daodan/MSVC/Flatline_Server.c
===================================================================
--- Daodan/MSVC/Flatline_Server.c	(revision 585)
+++ Daodan/MSVC/Flatline_Server.c	(revision 586)
@@ -172,2 +172,206 @@
 	UDPServer_SendToAll(&message, message_size + 2 + FLATLINE_HEADER);
 }
+void FLsSend_BINACHAR( short j, sockaddr* socket )
+{
+
+	ActiveCharacter* AC = ONrGetActiveCharacter( PlayerList[j]->Chr);
+	flatline_packet new_char = {0};
+	CharacterObject* Char = &new_char.new_player.Character; 
+
+	new_char.id = NEW_PLAYER;
+	new_char.new_player.Playernumber = j;
+
+//	memset(Char, 0, sizeof(CharacterObject));
+	Char->Header.Type = 'CHAR';
+	Char->OSD.Options = chr_dontaim;
+
+	sprintf(Char->OSD.Name,"%s",PlayerList[j]->name);
+
+	sprintf(Char->OSD.Class, "%s", TMrInstance_GetInstanceName(PlayerList[j]->Chr->ONCC));
+		
+	if(AC)
+	{
+		Char->Header.Position = AC->PhyContext->Position;
+	}
+	else
+	{
+		Char->Header.Position.X = 0;
+		Char->Header.Position.Y = 0;
+		Char->Header.Position.Z = 0;
+	}
+	
+	NetTCPServer_Send(socket, (char*)&new_char, sizeof(new_player) + FLATLINE_HEADER );
+}
+bool FLrServer_PacketCallback(char* data, int datalen, int from)
+{
+	int i, j;
+	bool found_player = 0;
+	flatline_packet * packet = (flatline_packet*)data;
+	static int recieved = 0;
+	sockaddr_in sender;
+	sender.sin_family = AF_INET;
+	sender.sin_port = htons(27777);
+	sender.sin_addr = *((struct in_addr*)(int*)&from);
+
+
+	//packet->data[datalen] = '\0';
+
+	//DDrConsole_PrintF("Packet \r%d recieved from %i",  ++recieved, from);
+
+
+
+	//if data[0] != CONNECT_SEND, search in playerlist for ip address
+
+
+
+
+	switch(packet->id) {
+		flatline_packet connect_recv;
+		player_info * playah;
+		//rewrite this when we get TCP support.
+		//rewrite this before we get TCP support*
+		//the way of seeing if there is room for players sucks.
+	case CONNECT_SEND:
+		;
+
+		connect_recv.id = CONNECT_REPLY;
+
+		//if(Players[i].ip == sender.sin_addr.S_un.S_addr) break; //needs to send an error message
+		sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
+		playah = FLrServer_AddPlayer(from,packet->connect_send.name, 0, 0);
+		DDrConsole_PrintF("%s connected from %s", packet->connect_send.name, inet_ntoa(sender.sin_addr ) );
+		if(!((int)playah > -5 && (int)playah <= 0)) {
+			
+			connect_recv.connect_reply.goodtogo = 1;
+			connect_recv.connect_reply.player_slot = playah->list_slot;
+			//DDrConsole_PrintF("Slot: %i", playah->list_slot);
+
+			//sending this several times to make sure it gets through. Really need to make up some form of packet tracking.
+			NetUDPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
+			NetUDPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
+			NetUDPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
+			NetUDPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
+			NetUDPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
+			Sleep(100);
+
+			
+			
+			for(j = 0; j < max_connections; j++) {
+				if(PlayerList[j] != 0) {
+					FLsSend_BINACHAR( j, (sockaddr *)&sender);
+				}
+
+			}
+		}
+		else {
+			//fix the error messages...
+			DDrConsole_PrintF("Server is full. :(");
+			connect_recv.connect_reply.goodtogo = 0;
+			sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
+			memcpy(&connect_recv.connect_reply.message,"Server is full.", sizeof("Server is full."));
+			NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(bool)*2 + FLATLINE_HEADER + sizeof("Server is full."));	
+
+		} 
+
+
+		break;
+	case CONNECT_REPLY:
+		break;	//do nothing...a server shouldn't recieve this type of packet.
+	case MESSAGE:
+		for(i = 0; i < MAX_PLAYERS; i++) {
+			//DDrConsole_PrintF("%i : %i | %s : %s", from, Players[i].ip, inet_ntoa(*(struct in_addr*)&from), inet_ntoa(*(struct in_addr*)&(Players[i].ip)));
+			if(Players[i].ip == sender.sin_addr.S_un.S_addr) {
+				found_player = 1;
+				break;
+			}	
+		}
+		if(found_player == 0) break;
+		else {
+			char message_buffer[512] = {0};
+			flatline_packet message;
+			int message_size;
+			data[datalen] = 0;
+
+			DDrConsole_PrintF("%s: %s", Players[i].name, packet->data);
+			sprintf(message_buffer, "%s: %s", Players[i].name, packet->data);
+
+			message.id = MESSAGE;
+			message_size = sprintf(message.data, "%s", message_buffer);
+			COrMessage_Print(message_buffer, "chat", 0);
+			UDPServer_SendToAll(&message, message_size + 1 + FLATLINE_HEADER);
+			break;
+		}
+	case CHANGE_NAME:
+		for(i = 0; i < MAX_PLAYERS; i++) {
+			if(PlayerList[i] && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) {
+				found_player = 1;
+				break;
+			}	
+		}
+		if(found_player == 0) break;
+		else {
+			bool name_exists = 0;
+			for(j = 0; j < MAX_PLAYERS; j++) {
+				if(PlayerList[j] && !strcmp(packet->data, PlayerList[j]->name)) {
+					name_exists = 1;
+					break;
+				}
+			}
+			if(!name_exists) {
+				FLsUpdateName( i, packet->data );
+			}
+			break;
+		}
+	case PLAYER_INPUT:
+
+		for(i = 0; i < max_connections; i++) {
+			if(PlayerList[i] != 0 && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) {
+				found_player = 1;
+				break;
+			}	
+		}
+
+		if(found_player == 0) break;
+		else {
+			input_struct * packet_input = &packet->input_struct;
+
+
+			PlayerList[i]->InputFromClient.Actions1 = packet_input->Actions1;
+			PlayerList[i]->InputFromClient.Actions2 = packet_input->Actions2;
+			PlayerList[i]->InputFromClient.MouseDeltaX = packet_input->MouseDeltaX;
+			PlayerList[i]->InputFromClient.MouseDeltaY = packet_input->MouseDeltaY;
+			PlayerList[i]->FacingFromClient = packet_input->DesiredFacing;
+			//PlayerList[i]->LastInputTime = packet_input->Time;
+
+			break;
+		}
+	case PK_PONG:
+		for(i = 0; i < max_connections; i++) {
+			if(PlayerList[i] != 0 && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) {
+				found_player = 1;
+				break;
+			}	
+		}
+
+		if(found_player == 0) break;
+		if(packet->ping != lastPingTime)
+		{
+			PlayerList[i]->Ping = 999;
+		}
+		else
+		{
+			PlayerList[i]->Ping = GetTickCount() - packet->ping;
+		}
+		break;
+	case PK_MISSING_PLAYER:
+		if(packet->integer < MAX_PLAYERS)
+		{
+			FLsSend_BINACHAR( packet->integer, &sender);
+		}
+		break;
+	default:
+		DDrConsole_PrintF("Warning, recieved badly formed packet!");
+		break;
+	}
+	return true;
+}
Index: Daodan/MSVC/Oni_GameState.h
===================================================================
--- Daodan/MSVC/Oni_GameState.h	(revision 585)
+++ Daodan/MSVC/Oni_GameState.h	(revision 586)
@@ -1211,7 +1211,7 @@
   __int16 HardPause;
   __int16 field_1C8E;
-  int field_1C90;
-  __int16 field_1C94;
-  __int16 field_1C96;
+  int ForcedAnimationFrames;
+  __int16 HitStun;
+  __int16 BlockStun;
   __int16 Dizzy;
   __int16 field_1C9A;
@@ -1252,9 +1252,7 @@
   char field_2195;
   char gap_2196[2];
-  Vector3 field_2198;
-  int field_21A4;
-  int field_21A8;
-  int field_21AC;
-  Vector3 field_21B0;
+  Vector3 AimTarget;
+  Vector3 AimVector;
+  Vector3 CamVector;
   float HeadFacing;
   float HeadPitch;
Index: Daodan/MSVC/Oni_Symbols.h
===================================================================
--- Daodan/MSVC/Oni_Symbols.h	(revision 585)
+++ Daodan/MSVC/Oni_Symbols.h	(revision 586)
@@ -232,3 +232,11 @@
 DefFunc( short, TMrInstance_GetDataPtr_ByNumber, (int tag, int number, void** out), 0x00423680 );
 DefFunc( uint32_t, TMrInstance_GetTagCount, (int tag), 0x004236F0);
+//DefFunc( uint32_t, stdcall M3rTextureMap_New, (int tag), 0x041EB00);
+//(short width, short height, int type, int allocated, int flags, char* name, void** output)
+DefFunc( uint32_t, ONrCharacter_GetHealthShade, (uint32_t health, uint32_t maxhealth), 0x004EF450);
+//DefFunc( short, TSrContext_SetShade, (void* context, int shade ), 0x0042EE50);
+DefFunc( void, ONiDrawWeaponSight, (Character* Char), 0x004E1900 );
+DefFunc( void, AI2rDisplayDebuggingInfo, (Character* Char), 0x0048C5F0 );
+ static const  uint32_t ( * M3rTextureMap_New)(short width, short height, int type, int allocated, int flags, char* name, void** output) 
+	 = (const uint32_t(*)(short width, short height, int type, int allocated, int flags, char* name, void** output))0x041EB00;
 #endif
