Index: Daodan/src/BFW_Utility.h
===================================================================
--- Daodan/src/BFW_Utility.h	(revision 483)
+++ Daodan/src/BFW_Utility.h	(revision 484)
@@ -29,5 +29,5 @@
 int16_t ONICALL TSrContext_New( void* FontInstance, int size, int hthsik1,int hthsik2,int hthsik3, void* TSrContext); //int16_t TSrContext_New( TSFF*, size 7, ??? 1, ??? 1, ??? 0, TSrContext*);
 int16_t ONICALL TMrInstance_GetDataPtr(int, char*, void*);	//int TMrInstance_GetDataPtr( Type 'TSFF', char* "Tahoma", ptr);
-
+char* ONICALL TMrInstance_GetInstanceName(void* InstancePointer);
 int __cdecl AUrMessageBox(int Buttons, char *Message, ...);
 
Index: Daodan/src/Daodan_BSL.c
===================================================================
--- Daodan/src/Daodan_BSL.c	(revision 483)
+++ Daodan/src/Daodan_BSL.c	(revision 484)
@@ -7,4 +7,5 @@
 
 #include "Daodan_BSL.h"
+#include "Flatline_BSL.h"
 #include "Daodan_Utility.h"
 #include "Daodan_Patch.h"
@@ -17,4 +18,6 @@
 #include "Daodan_Character.h"
 
+
+
 uint16_t ONICALL bsl_int32mul(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
 {
@@ -50,5 +53,4 @@
 	return 0;
 }
-
 uint16_t ONICALL bsl_div(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
 {
@@ -218,6 +220,17 @@
 	else index = args[0].value_int32;
 	Character* Chr = ONgGameState + 0x1260 ;
-	int* health = (int)&Chr[index] + 0x144;
-
+	int* health = (int*)Chr[index].ScriptNoPath;
+	
+	/*
+	DDrConsole_PrintF("Character %s", Chr[index].Name);
+	DDrConsole_PrintF("Spawn %s", Chr[index].ScriptSpawn);
+	DDrConsole_PrintF("Death %s", Chr[index].ScriptDie);
+	DDrConsole_PrintF("Aware %s", Chr[index].ScriptAware);
+	DDrConsole_PrintF("Alarm %s", Chr[index].ScriptAlarm);
+	DDrConsole_PrintF("Hurt %s", Chr[index].ScriptHurt);
+	DDrConsole_PrintF("Defeat %s", Chr[index].ScriptDefeat);
+	DDrConsole_PrintF("NoAmmo %s", Chr[index].ScriptNoAmmo);
+	DDrConsole_PrintF("NoPath %s", Chr[index].ScriptNoPath);
+	*/
 	ret->value_int32 = *health;
 	ret->type = sl_int32;
@@ -743,10 +756,16 @@
 {
 
-	//const char regen_patch[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
-	//DDrPatch_Const(OniExe + 0x0011BB6D, regen_patch);
-	
-	//This one should work but doesn't.
-	//const char regen_patch[] ={0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x8B, 0x86, 0x44};
-	//DDrPatch_Const(OniExe + 0x0011BB64, regen_patch);
+
+	//Calculating the value of the needed offset is much more reliable when the compiler does it for you.
+
+	//TODO: fix moonshadow.
+	Character * Chr = 0;
+	char NoPath = (char)(0x100 - (int)(Chr->ScriptNoPath));
+	const char regen_patch[] =
+		{0x90, 0x90, 0x90, 0x90, 0x90,	// mov     al, _WPgRegenerationCheat
+		0x90, 0x90,						// test    al, al
+		0x90, 0x90,						// jz      short loc_51BB98
+		0x8B, 0x86, NoPath};	
+	DDrPatch_Const(OniExe + 0x0011BB64, regen_patch);
 
 	SLrConfig();
@@ -783,7 +802,9 @@
 	SLrScript_Command_Register_ReturnType("sprintf", "C-style sprintf.", "format:string arg1 arg2 ...", sl_str32, bsl_sprintf);
 	
-	SLrScript_Command_Register_ReturnType("d_dprint", "prints to console in color", "text:string [color: r b g] [color: r b g]", sl_void, bsl_dprintcolored);
-	
-	//SLrScript_Command_Register_ReturnType("d_offset", "a test", "thing:int", sl_int32, bsl_returnoffset);
+	SLrScript_Command_Register_ReturnType("st", "prints to console in color", "text:string [color: r b g] [color: r b g]", sl_void, bsl_dprintcolored);
+	
+	//Flatline
+	SLrFlatline_Initialize();
+
 }
 
Index: Daodan/src/Flatline.c
===================================================================
--- Daodan/src/Flatline.c	(revision 484)
+++ Daodan/src/Flatline.c	(revision 484)
@@ -0,0 +1,419 @@
+#include "Flatline.h"
+#include "Oni_Character.h"
+#include "Flatline_Server.h"
+#include <sys/time.h>
+#include <time.h>
+uint32_t last1 = 0; uint32_t last2 = 0;
+player_info Players[MAX_PLAYERS] = {{0}, {0}, {0}, {0}};
+player_info * PlayerList[MAX_CONNECTIONS] = {0};
+const char * Rejection_Messages[][255] = {
+	{"Server is full"},
+	{"-2"},
+	{"-3"},
+	{"-4"},
+	{"-5"},
+};
+
+bool FLrServer_PacketCallback(char* data, int datalen, int from)
+{
+	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
+	
+	int i, j; //stupid C90, won't let me declare my counter inside a for loop.
+	bool found_player = 0;
+	
+	switch(packet->id) {
+		//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:
+			;
+			flatline_packet connect_recv;
+			connect_recv.id = CONNECT_REPLY;
+			//if(Players[i].ip == sender.sin_addr.S_un.S_addr) break; //needs to send an error message
+			DDrConsole_PrintF("%s connected from IP_ADDRESS", ((connect_send*)(packet->data))->name);
+			sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
+			player_info * playah = FLrServer_AddPlayer(from,((connect_send*)(packet->data))->name, 0);
+			if(!((int)playah > -5 && (int)playah <= 0)) {
+				((connect_reply*)(connect_recv.data))->goodtogo = 1;
+				((connect_reply*)(connect_recv.data))->player_slot = playah->list_slot;
+				DDrConsole_PrintF("Slot: %i", playah->list_slot);
+				NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) - 256 + FLATLINE_HEADER);
+				Sleep(100); //remove when we implement TCP.
+				flatline_packet new_char = {0};
+				new_char.id = NEW_PLAYER;
+				CharacterObject* Char = &(((new_player*)(new_char.data))->Character);
+				memset(Char, 0, sizeof(CharacterObject));
+				Char->Header.Type = 'CHAR';
+				Char->OSD.Options = char_dontaim;
+				for(j = 0; j < max_connections; j++) {
+					if(PlayerList[j] != 0) {
+						(*(new_player*)(void*)&new_char.data).Playernumber = j;
+						sprintf(Char->OSD.Name,"%s",PlayerList[j]->name);
+						sprintf(Char->OSD.Class, "%s", TMrInstance_GetInstanceName(PlayerList[j]->Chr->ONCC));
+						NetTCPServer_Send((sockaddr *) &sender, (char*)&new_char, sizeof(new_player) + FLATLINE_HEADER );
+					}
+
+				}
+			}
+			else {
+				//fix the error messages...
+				DDrConsole_PrintF("Server is full. :(");
+				((connect_reply*)(connect_recv.data))->goodtogo = 0;
+				sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
+				memcpy(((connect_reply*)(connect_recv.data))->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;
+
+			data[datalen] = 0;
+			char message_buffer[512] = {0};
+			DDrConsole_PrintF("%s: %s", Players[i].name, packet->data);
+			sprintf(message_buffer, "%s: %s", Players[i].name, packet->data);
+			flatline_packet message;
+			message.id = MESSAGE;
+			int 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(Players[i].ip == sender.sin_addr.S_un.S_addr) {
+					found_player = 1;
+					break;
+				}	
+			}
+			if(found_player == 0) return true;
+			bool name_exists = 0;
+			for(j = 0; j < MAX_PLAYERS; j++) {
+				if(!strcmp(packet->data, Players[j].name)) {
+					name_exists = 1;
+					break;
+				}
+			}
+			if(!name_exists) {
+				char message_buffer[1024];
+				sprintf(message_buffer,"%s changed their name to %s", Players[i].name, packet->data);
+				COrMessage_Print(message_buffer, "name_change", 0);
+				memcpy(Players[i].name, packet->data, 256);
+
+			}
+			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) return true;
+
+			input_struct * packet_input = (input_struct*)(packet->data);
+
+			
+			PlayerList[i]->Actions1 = packet_input->Actions1;
+			PlayerList[i]->Actions2 = packet_input->Actions2;
+			PlayerList[i]->MouseDeltaX = packet_input->MouseDeltaX;
+			PlayerList[i]->MouseDeltaY = packet_input->MouseDeltaY;
+			
+		
+			break;
+		default:
+			DDrConsole_PrintF("Warning, recieved badly formed packet!");
+			break;
+	}
+	return true;
+}
+
+bool FLrServer_Run()
+{
+	// Get the local hostname
+	char szHostName[255];
+	gethostname(szHostName, 255);
+	struct hostent *host_entry;
+	host_entry=gethostbyname(szHostName);
+	DDrConsole_PrintF("Server started at %s...", inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list));
+	return NetUDPServer_Listen(27777, FLrServer_PacketCallback);
+}
+
+	RGBA green = {0, 0xFF, 0, 0};
+	RGBA red = {0, 0, 0xFF, 0};
+	RGBA grey = {0x80,0x80,0x80,0x80};
+	
+//FLrClient_Run
+//Looping function that waits for packets from the server.
+//TODO: Convert connection packet stuff to TCP
+int client_slot = 0;
+bool FLrClient_Run(flatline_packet* packet)
+{
+	client_connected = 0;
+	char data[1400];
+	uint16_t len;
+	int j;
+	
+	//starts the connection
+	DDrConsole_PrintF("Connecting to server %s on socket %i",  inet_ntoa(address.sin_addr), client_sock);
+	int sent_bytes = NetUDPSocket_Send(client_sock, (sockaddr*)&address, (char*)packet, 255);
+	if(sent_bytes == SOCKET_ERROR) {
+		NetCatchError();
+	}
+	//loops once per second waiting for a reply.
+	for(j = 0; j < CONNECTION_TIMEOUT; j++) {
+		while(NetUDPSocket_Recieve(client_sock, (sockaddr_storage *) &client_address, data, &len)){		
+			packet = (flatline_packet*)data;
+			if(packet->id == CONNECT_REPLY) {
+				if(((connect_reply*)packet->data)->goodtogo){
+					client_connected = 1;
+					client_slot = ((connect_reply*)packet->data)->player_slot;
+					DDrConsole_PrintColored("Connection successful!",0,green, grey);
+					//DDrConsole_PrintF("Slot %i",  ((connect_reply*)packet)->player_slot);
+					break;
+				}
+				else {
+					DDrConsole_PrintF("Connection rejected: %s", ((connect_reply*)packet->data)->message);
+					return false;
+					break;
+				}
+			}
+		}
+		if(client_connected) break;
+		DDrConsole_PrintF("Connection timing out in %i seconds...", CONNECTION_TIMEOUT - j);
+		Sleep(1000);
+	}
+	//the client timed out without recieving an error message.
+	if(!client_connected) {
+		DDrConsole_PrintColored("Connection timed out.",0,red, grey);
+		return false;
+	}
+#define SPAM_INPUT
+#ifdef SPAM_INPUT
+		struct timeval lasttime;
+		gettimeofday(&lasttime, 0);
+		struct timeval thistime;
+#endif
+		while(1) {
+#ifdef SPAM_INPUT
+			gettimeofday(&thistime, 0);
+			
+			//DDrConsole_PrintF("%i.%i | %i.%i | %i.%i",lasttime.tv_sec, lasttime.tv_usec, thistime.tv_sec, thistime.tv_usec,
+			//	thistime.tv_sec - lasttime.tv_sec, thistime.tv_usec - lasttime.tv_usec);
+			//checks to see if enough time has passed since the last input update (by default once every 10ms)
+			if( 
+				((thistime.tv_sec > lasttime.tv_sec) && ((thistime.tv_usec + 1000000 - lasttime.tv_usec ) > update_rate * 1000) )
+				|| ((thistime.tv_sec == lasttime.tv_sec) && ((thistime.tv_usec - lasttime.tv_usec ) > update_rate * 1000))
+			) {
+				
+				lasttime.tv_usec = ++thistime.tv_usec; //in case recieving packets takes less than 1 ms.
+				flatline_packet input_packet;
+				input_packet.id = PLAYER_INPUT;
+				
+				if( ((GameState*)(ONgGameState))->Input.Current.Actions1 != last1 || ((GameState*)(ONgGameState))->Input.Current.Actions2 != last2) {
+					last1 =((GameState*)(ONgGameState))->Input.Current.Actions1;
+					last2 =((GameState*)(ONgGameState))->Input.Current.Actions2;
+				}
+
+				((input_struct*)(void*)(input_packet.data))->Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
+				((input_struct*)(void*)(input_packet.data))->Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
+				((input_struct*)(void*)(input_packet.data))->MouseDeltaX = ((GameState*)(ONgGameState))->Input.MouseDeltaX;
+				((input_struct*)(void*)(input_packet.data))->MouseDeltaY = ((GameState*)(ONgGameState))->Input.MouseDeltaY;
+				sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&input_packet, sizeof(input_struct) + FLATLINE_HEADER);			
+				//if(sent_bytes == SOCKET_ERROR)	NetCatchError();
+			}
+#endif
+			if(NetUDPSocket_Recieve(client_sock, (sockaddr_storage *) &client_address, data, &len)) {
+				packet = (flatline_packet*)data;
+				//DDrConsole_PrintF("Data recieved, length %i, type %i", len, ((flatline_packet*)data)->id);
+				switch(packet->id) {
+		case MESSAGE:
+			COrMessage_Print(packet->data, "chat", 0);
+			break;
+		case CONNECT_SEND:
+			;
+			flatline_packet connect_recv;
+			memcpy(((connect_reply*)&(connect_recv.data))->message,"This isn't a server!", sizeof("This isn't a server!"));
+			NetUDPSocket_Send(client_sock, (sockaddr *) &address, (char*)&connect_recv, sizeof(bool) + FLATLINE_HEADER + sizeof("This isn't a server!"));			
+		case CONNECT_REPLY:
+			break; //extra packet or something.
+		case NEW_PLAYER:
+			;
+			uint32_t chr_index;
+			DDrConsole_PrintF("%i |  %i", ((new_player*)(packet->data))->Playernumber ,client_slot);
+			
+			if(((new_player*)(packet->data))->Playernumber == client_slot) {
+				PlayerList[((new_player*)(packet->data))->Playernumber] = Players;
+				Character* PC = (Character*)(((GameState*)ONgGameState)->PlayerCharacter);
+				Players[0].Chr = PC;
+
+			}
+			else {
+				ONrGameState_NewCharacter(&(((new_player*)(packet->data))->Character), NULL, NULL, &chr_index);
+				PlayerList[((new_player*)(packet->data))->Playernumber] = &Players[chr_index];
+				Players[chr_index].Chr = &(((GameState*)ONgGameState)->CharacterStorage[chr_index]);
+				DDrConsole_PrintF("Spawning player %s, class %s, slot  %i", ((new_player*)(packet->data))->Character.OSD.Name, ((new_player*)(packet->data))->Character.OSD.Class,chr_index) ;
+			}
+			//Players[((new_player*)(packet->data))->Playernumber].spawnnumber = ONrGameState_NewCharacter(&(((new_player*)(packet->data))->Character), NULL, NULL, 0);
+			break;
+		case PLAYER_DATA:;
+			player_data * data = (void*)packet->data;
+			uint16_t i = data->PlayerNum;
+			//DDrConsole_PrintF("Got data for Player %i, %x", i, PlayerList[i]);
+			if (!PlayerList[i] || i > max_connections) break;
+			PlayerList[i]->Chr = ((GameState *)ONgGameState)->CharacterStorage;
+			PlayerList[i]->Chr->Health = data->Health;
+			PlayerList[i]->Chr->MaxHealth = data->MaxHealth;
+			PlayerList[i]->Chr->Position = data->Position;
+			PlayerList[i]->Chr->Location = data->Location;
+			PlayerList[i]->Chr->LastPosition = data->LastPosition;
+			PlayerList[i]->Chr->Facing = data->Facing;
+			PlayerList[i]->Chr->DesiredFacing = data->DesiredFacing;
+			PlayerList[i]->Chr->CosmeticFacing = data->CosmeticFacing;
+			PlayerList[i]->Actions1 = data->Inputs.Actions1;
+			PlayerList[i]->Actions2 = data->Inputs.Actions2;
+			ActiveCharacter * Active = ((ActiveCharacter*)(ONrGetActiveCharacter(PlayerList[i]->Chr)));
+			
+			//needs special case for jumping\possibly falling characters
+			Active->PhyContext_->Position = data->Position;
+			
+			//antilag, lol.
+			if((int)*((char*)(Active + 0x1AF8) + 0x166) > data->Frame)
+			*(uint16_t *)((char*)Active + 0x1C88) = data->Frame;
+			break;
+		default:
+			DDrConsole_PrintF("Warning, recieved badly formed packet!");
+			break;
+				}
+			}
+			else {
+				Sleep(1);
+			}
+		}
+
+	return true;
+}
+
+//UDPServer_SendToAll
+//Sends a packet to all the clients currently connected.
+//Returns the number of players sent to.
+int UDPServer_SendToAll(void* packet, int size) {
+	int j;
+	int players = 0;
+	sockaddr_in address;
+	memset(&address, 0, sizeof(sockaddr_in)); 
+	address.sin_family = AF_INET;
+	address.sin_addr.s_addr = htonl(INADDR_ANY);
+	address.sin_port = htons(27777);
+	for(j = 0; j < max_connections; j++) {
+		if (PlayerList[j] != 0 && PlayerList[j]->ip != inet_addr("127.0.0.1")) {
+			address.sin_addr.s_addr = htonl(PlayerList[j]->ip);//*((struct in_addr*)(int*)&(Players[j].ip));		
+			int sent_bytes = NetUDPServer_Send((sockaddr *) &address, (char*)packet, size);
+			if(sent_bytes == SOCKET_ERROR) NetCatchError();
+			else players++;
+		}
+	}
+	return players;
+}
+
+player_info *FLr_FindEmptySlot() {
+	int j;
+	for(j = 0; j < MAX_PLAYERS; j++) {
+		if (Players[j].ip == 0) {
+			return &Players[j];
+		}
+	}
+	return 0;
+}
+
+extern uint16_t max_connections;
+uint16_t FLr_FindEmptyListSlot() {
+	int j;
+	for(j = 0; j < max_connections; j++) {
+		if (PlayerList[j] == 0) {
+			return j;
+		}
+	}
+	return -1;
+}
+void * ONICALL FLrInput_Update_Keys(void) {
+#ifndef SPAM_INPUT
+	if(client_connected) {
+		flatline_packet input_packet;
+		input_packet.id = PLAYER_INPUT;
+		((input_struct*)(void*)(input_packet.data))->Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
+		((input_struct*)(void*)(input_packet.data))->Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
+		((input_struct*)(void*)(input_packet.data))->MouseDeltaX = ((GameState*)(ONgGameState))->Input.MouseDeltaX;
+		((input_struct*)(void*)(input_packet.data))->MouseDeltaY = ((GameState*)(ONgGameState))->Input.MouseDeltaY;
+		int sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&input_packet, sizeof(input_struct) + FLATLINE_HEADER);
+		return ONgGameState;
+	}
+#endif
+	if(!server_started) return ONgGameState;
+	uint16_t i;
+	for(i = 0; i < max_connections; i++) {
+		if(!PlayerList[i]) continue;
+		char * Active_Player = (void*)ONrGetActiveCharacter(PlayerList[i]->Chr);
+		if(!Active_Player) return ONgGameState;
+		GameInput * Active_Input = (void*)( Active_Player + 0x2158);
+			
+			flatline_packet data_out = {0};
+			data_out.id = PLAYER_DATA;
+			player_data * data = (void*)&(data_out.data);
+			data->PlayerNum = i;
+			data->Health = PlayerList[i]->Chr->Health;
+			data->MaxHealth = PlayerList[i]->Chr->MaxHealth;
+			data->Position = PlayerList[i]->Chr->Position;
+			data->Location = PlayerList[i]->Chr->Location;
+			data->LastPosition = PlayerList[i]->Chr->LastPosition;
+			data->Facing = PlayerList[i]->Chr->Facing;
+			data->DesiredFacing = PlayerList[i]->Chr->DesiredFacing;
+			data->CosmeticFacing = PlayerList[i]->Chr->CosmeticFacing;
+			data->Frame = *(Active_Player + 0x1C88);
+			data->Inputs.Actions1 = PlayerList[i]->Actions1;
+			data->Inputs.Actions2 = PlayerList[i]->Actions2;
+
+			if(!server_started || i != 0 ) {
+			Active_Input->Stop.Actions1 = ~PlayerList[i]->Actions1 & Active_Input->Current.Actions1;
+			Active_Input->Stop.Actions2 = ~PlayerList[i]->Actions2 & Active_Input->Current.Actions2;
+			Active_Input->Start.Actions1 = ~Active_Input->Current.Actions1 & PlayerList[i]->Actions1;
+			Active_Input->Start.Actions2 = ~Active_Input->Current.Actions2 & PlayerList[i]->Actions2;
+			Active_Input->Current.Actions1 = PlayerList[i]->Actions1;
+			Active_Input->Current.Actions2 = PlayerList[i]->Actions2;
+			Active_Input->Stopped.Actions1 = ~Active_Input->Current.Actions1;
+			Active_Input->Stopped.Actions2 = ~Active_Input->Current.Actions2;
+			Active_Input->MouseDeltaX = PlayerList[i]->MouseDeltaX;
+			Active_Input->MouseDeltaY = PlayerList[i]->MouseDeltaY;
+			UDPServer_SendToAll(&data_out, sizeof(player_data) + FLATLINE_HEADER);
+			}
+	}
+	return ONgGameState;
+}
Index: Daodan/src/Flatline.h
===================================================================
--- Daodan/src/Flatline.h	(revision 484)
+++ Daodan/src/Flatline.h	(revision 484)
@@ -0,0 +1,177 @@
+#pragma once
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+//#define DDrStartupMessage printf
+
+#include <string.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#define thread __thread
+
+#ifdef WIN32
+#include <winsock2.h>
+#include "Flatline_Win32.h"
+#else
+#include <sys/ioctl.h> 
+#include <sys/types.h>
+#include <sys/socket.h> 
+#include <unistd.h> 
+#include <stropts.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#define NetPlatform_Initalize() /* */
+#define NetPlatform_Shutdown() /* */
+#define closesocket close
+#define ioctlsocket ioctl
+#endif
+
+#include "Daodan.h"
+#include "BFW_Utility.h"
+#include "Daodan_Console.h"
+#include "Oni_Character.h"
+
+
+#define pad1_size (sizeof(int64_t) - sizeof(short))
+#define pad2_size (128 - (sizeof(short) + pad1_size + sizeof(int64_t)))
+
+typedef struct {
+	short ss_family;
+	char pad1[pad1_size];
+	uint64_t pad64;
+	char pad2[pad2_size];
+} sockaddr_storage;
+
+typedef struct sockaddr sockaddr;
+typedef struct sockaddr_in sockaddr_in;
+typedef sockaddr_storage sockaddr_in6;
+
+bool NetUDPServer_Listen(uint16_t port, bool (*packet_callback)(char* data, int datalen, int from));
+bool NetUDPServer_Send(sockaddr* address, char* data, int datalen);
+
+int NetUDPSocket_Create(uint16_t port);
+int NetUDPSocket_Send(int socket, const sockaddr* address, const char* data, int datalen);
+void NetUDPSocket_Close(int sock);
+bool NetUDPSocket_Recieve(int socket, sockaddr_storage* address, char* data, uint16_t* datalen);
+
+DWORD WINAPI StartServer(void* lol);
+DWORD WINAPI StartClient(void* lol);
+
+//oh snap, I just realized this is rossy's version of flatline_packet. :|
+typedef struct {
+	char signature[8];
+	uint16_t protocol_version;
+	char data[0];				//data[0] doesn't work well with simple casts, btw. If you allocate enough space for a handshake_packet
+} handshake_packet;				//there won't be enough room for data. You would have to manually manage the memory (ew)
+
+//initial connection
+typedef struct {
+	char country[2];
+	char name[256];
+} connect_send; //signature="CONNECT\0"
+
+//reply to connection.
+//goodtogo is if it is going to let you in
+//message is optional, only used for denial message
+typedef struct {
+	bool goodtogo;
+	int player_slot;
+	char message[256];
+} connect_reply;
+
+//um, status of the server? :/
+typedef struct {
+	char name[256];
+	uint32_t numplayers; //signature="STATUS\0\0"
+} server_status;
+
+typedef struct {
+	uint16_t	 Playernumber;
+	CharacterObject Character;
+} new_player;
+extern int update_rate;
+
+typedef struct {
+	float MouseDeltaX;
+	float MouseDeltaY;
+	uint32_t Actions1;
+	uint32_t Actions2;
+} input_struct;
+
+//
+typedef struct {
+	uint16_t PlayerNum;
+	Vector3 Position;
+	Vector3 LastPosition;
+	Vector3 Location;
+	float Facing;
+	float DesiredFacing;
+	float CosmeticFacing;
+	uint32_t Health;
+	uint32_t MaxHealth;
+	input_struct Inputs;
+	uint16_t Frame;
+} player_data;
+
+//used for storing data about each player
+typedef struct {
+	char id;
+	int  packet_index;
+	char data[1080];	
+} flatline_packet;
+#define FLATLINE_HEADER sizeof(flatline_packet)-sizeof(char)*1080
+
+bool FLrServer_PacketCallback(char* data, int datalen, int from);
+bool FLrServer_Run();
+bool FLrClient_Run(flatline_packet* packet);
+extern int sock;
+
+enum {
+	CONNECT_SEND,
+	CONNECT_REPLY,
+	STATUS,
+	MESSAGE,
+	CHANGE_NAME,
+	ECHO,
+	NEW_PLAYER,
+	PLAYER_INPUT,
+	PLAYER_DATA,
+};
+
+
+typedef struct {
+	int	 ip;
+	char name[32];
+	char country[2];
+	Character* Chr;
+	uint16_t spawnnumber;
+	uint16_t list_slot;
+	uint32_t Actions1;
+	uint32_t Actions2;
+	float MouseDeltaX;
+	float MouseDeltaY;
+} player_info;
+
+player_info * FLr_FindEmptySlot();
+uint16_t FLr_FindEmptyListSlot();
+void * ONICALL FLrInput_Update_Keys(void);
+
+void NetCatchError();
+#define MAX_PLAYERS 128
+#define CONNECTION_TIMEOUT 15
+#define MAX_CONNECTIONS 32
+#define NetTCPSocket_Send NetUDPSocket_Send
+#define NetTCPServer_Send NetUDPServer_Send
+extern int client_sock;
+//these two could probably be combined
+extern sockaddr_in client_address;
+extern sockaddr_in address;
+extern player_info Players[];
+extern player_info * PlayerList[];
+int UDPServer_SendToAll(void* packet, int size);
+extern bool client_connected;
+extern bool server_started;
+extern char player_name[];
Index: Daodan/src/Flatline_BSL.c
===================================================================
--- Daodan/src/Flatline_BSL.c	(revision 484)
+++ Daodan/src/Flatline_BSL.c	(revision 484)
@@ -0,0 +1,123 @@
+#include "BFW_ScriptLang.h"
+
+#include "Daodan_Patch.h"
+#include "Daodan_BSL.h"
+#include "Flatline_BSL.h"
+#include "Flatline.h"
+#include "Flatline_Server.h"
+bool server_started = 0;
+bool client_connected = 0;
+int sock = 0;
+sockaddr_in address;
+char player_name[32] = {0};
+char player_country[256] = {0};
+int update_rate = 5;
+
+uint16_t ONICALL start_server(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
+{
+	CreateThread(NULL, 0, StartServer, NULL, 0, 0);
+	server_started = 1;
+	return 0;
+}
+
+uint16_t ONICALL control_update_rate(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
+{
+	update_rate = args[0].value_int32;
+	server_started = 1;
+	return 0;
+}
+
+uint16_t ONICALL change_name(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
+{
+	//should also return your name...
+	sprintf(player_name, "%.31s", args[0].value_str32);
+	flatline_packet packet;
+	packet.id = CHANGE_NAME;
+	memcpy(packet.data, args[0].value_str32, 256);
+
+
+	NetUDPSocket_Send(client_sock, (sockaddr*)&address, (char*)&packet, 257);
+	return 0;
+}
+
+uint16_t ONICALL send_message(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
+{
+
+	flatline_packet message;
+	message.id = MESSAGE;
+
+	if(server_started) {
+		int message_size = sprintf(message.data, "%s", args[0].value_str32);
+		UDPServer_SendToAll(&message, message_size + FLATLINE_HEADER);
+	}
+	else if(client_connected) {
+		sprintf(message.data, "%s", args[0].value_str32);
+		NetUDPSocket_Send(client_sock, (sockaddr*)&address, (char*)&message, 257);
+	}
+	else {
+		DDrConsole_PrintF("You aren't connected to a server!");
+	}
+	return 0;
+}
+
+
+uint16_t ONICALL connect_to_server(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
+{
+	NetPlatform_Initalize();
+	sock = NetUDPSocket_Create(27777);
+	address.sin_family = AF_INET; address.sin_port = htons(27777); address.sin_addr.S_un.S_addr = inet_addr(args[0].value_str32 );	
+	static flatline_packet packet;
+
+	packet.id = CONNECT_SEND;
+	memcpy(((connect_send*)(packet.data))->country ,  player_country, 2);
+	memcpy(((connect_send*)(packet.data))->name, player_name, 256);
+	DDrConsole_PrintF("%s", ((connect_send*)(packet.data))->name);
+	CreateThread(NULL, 0, StartClient, &packet, 0, 0);
+
+
+
+	return 0;
+}
+uint16_t ONICALL status(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
+{
+	int j;
+	if(server_started) {
+		for(j = 0; j < max_connections; j++) {
+
+			if (PlayerList[j] != 0) {
+				DDrConsole_PrintF("Client %i: %s from %s", 
+					j,
+					PlayerList[j]->name,
+					(inet_ntoa(*( (struct in_addr*)(int*)&(PlayerList[j]->ip )   ))));
+			}
+		}
+	}
+	else if(client_connected) {
+		DDrConsole_PrintF("Connected to %s, port %i, socket %i", inet_ntoa(address.sin_addr), ntohs(address.sin_port), sock);
+		for(j = 0; j < max_connections; j++) {
+
+			if (PlayerList[j] != 0) {
+				DDrConsole_PrintF("Client %i: %s %x", 
+					j,
+					PlayerList[j]->name,
+					PlayerList[j]->Chr
+			);
+			}
+		}
+	}
+	else{}
+	return 0;
+}
+
+#include "Oni.h"
+void SLrFlatline_Initialize() {
+	
+	DDrPatch_MakeCall(OniExe + 0x000FA88B, FLrInput_Update_Keys);
+	SLrGlobalVariable_Register_Int32("skip", "skips", &(((GameState*)ONgGameState)->field_40) );
+	SLrScript_Command_Register_Void("connect","Connects to a server", "address", connect_to_server);
+	SLrScript_Command_Register_Void("host","Starts a server", "", start_server);
+	SLrScript_Command_Register_Void("msg","Sends a message", "", send_message);
+	SLrScript_Command_Register_Void("name","changes your name", "name:str", change_name);
+	SLrScript_Command_Register_Void("status","shows the connection status", "", status);
+	SLrGlobalVariable_Register_String("country", "Your Multiplayer country", player_name);
+}
Index: Daodan/src/Flatline_BSL.h
===================================================================
--- Daodan/src/Flatline_BSL.h	(revision 484)
+++ Daodan/src/Flatline_BSL.h	(revision 484)
@@ -0,0 +1,6 @@
+#ifndef FLATLINE_BSL_H
+#define FLATLINE_BSL_H
+
+void SLrFlatline_Initialize();
+
+#endif
Index: Daodan/src/Flatline_Net.c
===================================================================
--- Daodan/src/Flatline_Net.c	(revision 484)
+++ Daodan/src/Flatline_Net.c	(revision 484)
@@ -0,0 +1,224 @@
+#include "Flatline.h"
+#include "Flatline_Server.h"
+
+
+#define TRACK_PACKETS
+thread int UDPServer_Socket = 0;
+
+
+
+
+bool NetUDPServer_Listen(uint16_t port, bool (*packet_callback)(char* data, int datalen, int from))
+{
+	UDPServer_Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	
+	if (UDPServer_Socket < 0)
+	{
+		DDrConsole_PrintF("could not create socket");
+		return false;
+	}
+	
+	sockaddr_in address;
+	memset(&address, 0, sizeof(sockaddr_in));
+	address.sin_family = AF_INET;
+	address.sin_addr.s_addr = htonl(INADDR_ANY);
+	address.sin_port = htons(port);
+	
+	if (bind(UDPServer_Socket, (sockaddr*)&address, sizeof(sockaddr_in)) < 0)
+	{
+		DDrConsole_PrintF("could not bind port %d", port);
+		closesocket(UDPServer_Socket);
+		return false;
+	}
+	
+	FLrServer_Initialize();
+
+	char data[65537];
+	data[65536] = '\0';
+	sockaddr_in from;
+	int recvlen;
+	for (;;)
+	{
+		int fromlen = sizeof(sockaddr_in);
+		memset(&from, 0, sizeof(sockaddr_in));
+		recvlen = recvfrom(UDPServer_Socket, data, sizeof(data) - 1, 0, (sockaddr*)&from, (void*)&fromlen);
+		if (!packet_callback(data, recvlen, ntohl(from.sin_addr.s_addr)))
+			break;
+	}
+	closesocket(UDPServer_Socket);
+	return true;
+}
+
+bool NetUDPServer_Send(sockaddr* address, char* data, int datalen)
+{
+	//DDrConsole_PrintF("Sending data size %u to %s on socket %i", datalen, inet_ntoa( ((sockaddr_in*)address)->sin_addr ), UDPServer_Socket);
+	return NetUDPSocket_Send(UDPServer_Socket, address, data, datalen);
+}
+
+int client_sock = 0;
+sockaddr_in client_address;
+
+int NetUDPSocket_Create(uint16_t port)
+{
+	int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	
+	if (sock < 0)
+	{
+		DDrConsole_PrintF("could not create socket");
+		return -1;
+	}
+	
+	sockaddr_in address;
+	memset(&client_address, 0, sizeof(sockaddr_in));
+	address.sin_family = AF_INET;
+	address.sin_addr.s_addr = htonl(INADDR_ANY);
+	address.sin_port =  htons(port);
+	
+	if (bind(sock, (sockaddr*)&address, sizeof(sockaddr_in)) < 0)
+	{
+		DDrConsole_PrintF("could not bind port %d", port);
+		return false;
+	}
+	
+	unsigned long nonBlocking = 1;
+	if (ioctlsocket(sock, FIONBIO, &nonBlocking))
+	{
+		DDrConsole_PrintF("failed to set non-blocking socket");
+		return false;
+	}
+	client_sock = sock;
+	client_address = address;
+	return sock;
+}
+
+int NetTCPSocket_Create(uint16_t port)
+{
+	int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+	
+	if (sock < 0)
+	{
+		DDrConsole_PrintF("could not create socket");
+		return -1;
+	}
+	
+	sockaddr_in address;
+	memset(&client_address, 0, sizeof(sockaddr_in));
+	address.sin_family = AF_INET;
+	address.sin_addr.s_addr = htonl(INADDR_ANY);
+	address.sin_port =  htons(port);
+	
+	if (bind(sock, (sockaddr*)&address, sizeof(sockaddr_in)) < 0)
+	{
+		DDrConsole_PrintF("could not bind port %d", port);
+		return false;
+	}
+	
+	unsigned long nonBlocking = 1;
+	if (ioctlsocket(sock, FIONBIO, &nonBlocking))
+	{
+		DDrConsole_PrintF("failed to set non-blocking socket");
+		return false;
+	}
+	client_sock = sock;
+	client_address = address;
+	return sock;
+}
+
+
+void NetUDPSocket_Close(int socket)
+{
+	closesocket(socket);
+}
+
+int NetUDPSocket_Send(int socket, const sockaddr* address, const char* data, int datalen)
+{
+	//currently only protects against duplicate packets.
+#ifdef TRACK_PACKETS
+	static uint32_t packet_index = 0;
+	packet_index = (packet_index + 1);
+	((flatline_packet*)(data))->packet_index = packet_index;
+#endif
+	int addr_size;
+	switch (address->sa_family)
+	{
+		case AF_INET:
+			addr_size = sizeof(sockaddr_in);
+			break;
+		case AF_INET6:
+			addr_size = sizeof(sockaddr_in6);
+			break;
+		default:
+			addr_size = sizeof(sockaddr_storage);
+	}
+	return sendto(socket, data, datalen, 0, address, addr_size);
+}
+
+#ifdef TRACK_PACKETS
+uint32_t last_packet = -1;
+#endif
+
+bool NetUDPSocket_Recieve(int socket, sockaddr_storage* address, char* data, uint16_t* datalen)
+{
+	int address_size = sizeof(sockaddr_storage);
+	uint32_t msg_size = recvfrom(socket, data, 1400, 0, (SOCKADDR *)address, &address_size);
+	if (msg_size == 0)
+		return false;
+	else if (msg_size == SOCKET_ERROR) {
+		int errorno = WSAGetLastError();
+		if (errorno == WSAEWOULDBLOCK) return false; //no packets.
+		else {
+			DDrConsole_PrintF("Packet type %i", ((flatline_packet*)data)->id);
+			NetCatchError();
+			return false;
+		}
+	}	
+	/*
+#ifdef TRACK_PACKETS
+	if(client_connected && !server_started) {
+		uint32_t index_mkr = ((flatline_packet*)(data))->packet_index;
+		//fancy way of checking if index_mkr is on one side of the max size of an int and last_packet is on the other
+		if( ((index_mkr - last_packet < 0x80000000) && (index_mkr > last_packet))
+		//if it is, subtract half the size of an int from each. ^_^
+			|| ((index_mkr - 0x80000000) > (last_packet - 0x80000000) ) )
+		{
+			return false;
+		}
+		else {
+			last_packet = index_mkr;
+		}
+	}
+	
+#endif
+	*/
+
+	*datalen = msg_size;				
+	return true;
+	
+}
+
+DWORD WINAPI StartServer(void* lol){
+	NetPlatform_Initalize();
+	FLrServer_Run();
+	return 0;
+} 
+
+DWORD WINAPI StartClient(void* lol){
+	//NetPlatform_Initalize();
+	FLrClient_Run((flatline_packet*)lol);
+	return 0;
+} 
+void NetCatchError(){
+				int errorno = WSAGetLastError();
+				if(errno == WSAEWOULDBLOCK) {
+					return;
+				}
+				#ifdef WIN32
+				char Message[1024];
+				FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
+					FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, errorno,
+					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+					(LPSTR) Message, 1024, NULL);
+				DDrConsole_Print(Message);
+				#endif
+
+}
Index: Daodan/src/Flatline_Server.c
===================================================================
--- Daodan/src/Flatline_Server.c	(revision 484)
+++ Daodan/src/Flatline_Server.c	(revision 484)
@@ -0,0 +1,74 @@
+#include "Flatline.h"
+#include "Flatline_Server.h"
+
+int total_players = 0;
+uint16_t max_connections = MAX_CONNECTIONS;
+
+player_info* FLrServer_AddPlayer(int ip, char* name, bool is_server) {
+	uint32_t player_slot = 0;
+	int playerlist_slot = 0;
+	if(is_server) goto server;
+	if(total_players < max_connections) {
+		playerlist_slot = FLr_FindEmptyListSlot();
+		total_players++;
+
+		//send new player packet to all players
+		//char tempname[32] = {0};
+		int i = 0;
+		int k = 0;
+		//checks to see if a name exists or not
+		//then appends [#] on the end of it if it does
+		char* zero = strchr(name, 0);
+		if(zero - name > 28) zero = name + 28; 
+		for(i = 0; i < max_connections; i++) {
+			if(PlayerList[i] != 0 && strcmp(name, PlayerList[i]->name)) {
+				k++;				
+				sprintf(zero, "[%i]", k);
+				i = 0;
+			}
+		}
+
+server:		;flatline_packet new_char = {0};
+		CharacterObject* Char = &(((new_player*)(new_char.data))->Character);
+		memset(Char, 0, sizeof(CharacterObject));
+		Char->Header.Type = 'CHAR';
+		//Char->OSD.Options = char_dontaim;
+		sprintf(Char->OSD.Name,"%s",name);
+		sprintf(Char->OSD.Class, "%s", "striker_easy_1");
+		
+		
+		
+		//TMrInstance_GetDataPtr('ONCC', "striker_easy_1", PlayerList[playerlist_slot]->Chr->ONCC);
+		
+
+		new_char.id = NEW_PLAYER;
+		if(!is_server) { 
+			ONrGameState_NewCharacter(Char, NULL, NULL, &(player_slot));
+			PlayerList[playerlist_slot] = Players+player_slot;
+			PlayerList[playerlist_slot]->Chr = &((Character *)(((GameState * )(ONgGameState))->CharacterStorage))[player_slot];
+			PlayerList[playerlist_slot]->Chr->Flags &= 0xFFBFFFFF;
+			sprintf(PlayerList[playerlist_slot]->Chr->Name, "%.31s", name);		
+			UDPServer_SendToAll( (char*)&new_char, sizeof(new_player) + FLATLINE_HEADER );
+			
+		}
+		else {
+			PlayerList[0] = Players;
+			PlayerList[0]->Chr = (Character *)(((GameState * )(ONgGameState))->CharacterStorage);
+		}
+
+		//add player to list
+		
+		PlayerList[playerlist_slot]->ip = ip;
+		PlayerList[playerlist_slot]->list_slot = playerlist_slot;
+		sprintf(PlayerList[playerlist_slot]->name,"%.31s",name);
+		
+		return &Players[player_slot];
+	}
+	return (player_info*)-1;
+}
+
+void FLrServer_Initialize(){
+	FLrServer_AddPlayer(inet_addr("127.0.0.1"), "host", 1);
+
+
+}
Index: Daodan/src/Flatline_Server.h
===================================================================
--- Daodan/src/Flatline_Server.h	(revision 484)
+++ Daodan/src/Flatline_Server.h	(revision 484)
@@ -0,0 +1,12 @@
+#ifndef FLATLINE_SERVER_H
+#define FLATLINE_SERVER_H
+
+#define TOO_MANY_CONNECTIONS -1
+#include "Flatline.h"
+#include "winsock.h"
+
+
+extern uint16_t max_connections;
+player_info* FLrServer_AddPlayer(int ip, char* name, bool is_server);
+void FLrServer_Initialize();
+#endif
Index: Daodan/src/Flatline_Win32.c
===================================================================
--- Daodan/src/Flatline_Win32.c	(revision 484)
+++ Daodan/src/Flatline_Win32.c	(revision 484)
@@ -0,0 +1,20 @@
+#include "Flatline.h"
+
+bool NetPlatform_Initalize()
+{
+	WSADATA wsaData;
+	
+	if (WSAStartup(MAKEWORD(2, 2), &wsaData))
+	{
+		DDrConsole_PrintF("WSA initalization failed");
+		return false;
+	}
+	DDrConsole_PrintF("net started using WSA version %d.%d", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
+	return true;
+}
+
+bool NetPlatform_Shutdown()
+{
+	WSACleanup();
+	return true;
+}
Index: Daodan/src/Flatline_Win32.h
===================================================================
--- Daodan/src/Flatline_Win32.h	(revision 484)
+++ Daodan/src/Flatline_Win32.h	(revision 484)
@@ -0,0 +1,4 @@
+#pragma once
+
+bool NetPlatform_Initalize();
+bool NetPlatform_Shutdown();
Index: Daodan/src/Oni.h
===================================================================
--- Daodan/src/Oni.h	(revision 483)
+++ Daodan/src/Oni.h	(revision 484)
@@ -49,3 +49,4 @@
 
 
+
 #endif
Index: Daodan/src/Oni_Character.h
===================================================================
--- Daodan/src/Oni_Character.h	(revision 483)
+++ Daodan/src/Oni_Character.h	(revision 484)
@@ -126,4 +126,42 @@
 	int32_t FILMInstance;
 } PlayingFilm;
+
+typedef enum {
+	chr_isplayer          = 1 << 0,
+	chr_randomskin        = 1 << 1,
+	chr_notprespawned     = 1 << 2,
+	chr_noncombatant      = 1 << 3,
+	chr_multispawnable    = 1 << 4,
+	chr_unkillable        = 1 << 5,
+	chr_superammo         = 1 << 6,
+	chr_omniscient        = 1 << 8,
+	chr_haslsi            = 1 << 9,
+	chr_boss              = 1 << 10,
+	chr_upgradedifficulty = 1 << 11,
+	chr_noautodrop        = 1 << 12,
+	chr_dontaim           = 1 << 13,
+	chr_nocollision       = 1 << 17,
+	chr_noshadow          = 1 << 24,
+	chr_invincible        = 1 << 25,
+	chr_bossshield        = 1 << 30,
+	chr_weaponimmune      = 1 << 31,
+} chr_flags;
+/*
+enum {
+chr_isplayer			=		0x00000001,	//is player character
+chr_randomskin			=		0x00000002,	//gets random skin from ONCV
+chr_notprespawned		=		0x00000004,	//isn't spawned at level creation
+chr_noncombatant		=		0x00000008,	//doesn't fight
+chr_multispawnable		=		0x00000010,	//can spawn up to 5 without forcing
+chr_unknown				=		0x00000020,	//
+chr_unkillable			=		0x00000040,	//can only be brought to 1 hp
+chr_superammo			=		0x00000080,	//infinite ammo
+chr_omniscient			=		0x00000100,	//touchofdeath
+chr_haslsi				=		0x00000200,	//drops an lsi
+chr_boss				=		0x00000400,	//is a boss character
+chr_upgradedifficulty	=		0x00000800,	//upgrade the difficulty if you play on med\hard
+chr_noautodrop			=		0x00001000,	//uses drop fields instead of has fields on death
+}; //
+*/
 
 typedef struct {
@@ -216,8 +254,33 @@
 } Inventory;
 
+typedef struct {
+	uint32_t SphereTree;
+	Vector3 ObBox[8];
+	Vector3 * ObBowPtr;
+	Vector3 Velocity;
+	Quaternion field_74;
+	Vector3 Position;
+	Quaternion Rotation;
+	float Scale;
+	Matrix4x3 Matrix;
+	Matrix4x3 InitMatrix;
+	float field_104;
+	float Gravity;
+	float field_10C;
+	float field_110;
+	float Friction_1;
+	float Friction_2;
+	Vector3 Force;
+	uint32_t Flags;
+	uint32_t Type;
+	char AnimState[0x18];
+	void* Callbacks;
+	void* Owner;
+} PhyContext;
+
 typedef struct { //ActiveCharacter
 	int16_t Number;
 	int16_t field_2; //probably Number is an int32
-	int32_t PhyContext;
+	PhyContext * PhyContext_;
 	SphereTreeNode SphereTree1;		//probably SphereTree[7]...
 	SphereTreeNode SphereTree3[4];
@@ -441,5 +504,5 @@
 	int32_t Flags;
 	int32_t field_8;
-	int32_t ONCC;			//change type to ONCC when we get that far...
+	int32_t* ONCC;			//change type to ONCC when we get that far...
 	int16_t field_10;
 	int16_t Team;
@@ -542,43 +605,5 @@
 	team_syndicateaccessory,
 };
-
-typedef enum {
-	chr_isplayer          = 1 << 0,
-	chr_randomskin        = 1 << 1,
-	chr_notprespawned     = 1 << 2,
-	chr_noncombatant      = 1 << 3,
-	chr_multispawnable    = 1 << 4,
-	chr_unkillable        = 1 << 5,
-	chr_superammo         = 1 << 6,
-	chr_omniscient        = 1 << 8,
-	chr_haslsi            = 1 << 9,
-	chr_boss              = 1 << 10,
-	chr_upgradedifficulty = 1 << 11,
-	chr_noautodrop        = 1 << 12,
-	chr_dontaim           = 1 << 13,
-	chr_nocollision       = 1 << 17,
-	chr_noshadow          = 1 << 24,
-	chr_invincible        = 1 << 25,
-	chr_bossshield        = 1 << 30,
-	chr_weaponimmune      = 1 << 31,
-} chr_flags;
-/*
-enum {
-chr_isplayer			=		0x00000001,	//is player character
-chr_randomskin			=		0x00000002,	//gets random skin from ONCV
-chr_notprespawned		=		0x00000004,	//isn't spawned at level creation
-chr_noncombatant		=		0x00000008,	//doesn't fight
-chr_multispawnable		=		0x00000010,	//can spawn up to 5 without forcing
-chr_unknown				=		0x00000020,	//
-chr_unkillable			=		0x00000040,	//can only be brought to 1 hp
-chr_superammo			=		0x00000080,	//infinite ammo
-chr_omniscient			=		0x00000100,	//touchofdeath
-chr_haslsi				=		0x00000200,	//drops an lsi
-chr_boss				=		0x00000400,	//is a boss character
-chr_upgradedifficulty	=		0x00000800,	//upgrade the difficulty if you play on med\hard
-chr_noautodrop			=		0x00001000,	//uses drop fields instead of has fields on death
-}; //
-*/
-int16_t ONICALL ONrGameState_NewCharacter(CharacterObject* CHAR, void* AISA, void* flag, int* list_location);
+int16_t ONICALL ONrGameState_NewCharacter(CharacterObject* CHAR, void* AISA, void* flag, uint32_t* list_location);
 int32_t* ONICALL ONrGetActiveCharacter(void* CharacterPtr);
 //int16_t ONICALL ONrGameState_GetPlayerCharacter();
@@ -596,3 +621,103 @@
 #define char_weaponimmune      (1 << 31)
 
+
+//We need a Oni_Structs #include file.
+
+typedef struct {
+	uint32_t TimerMode;
+	char TimerName[32];
+	uint32_t TimerDuration;
+	uint32_t field_28;
+	uint32_t field_2C;
+	uint32_t Letterbox[3];
+	uint32_t field_3C;
+	uint32_t field_40;
+	uint32_t CutsceneSyncMark;
+	uint32_t SomeCutsceneSyncMarkField;
+	uint32_t field_4C;
+	uint32_t SplashScreenMachineTime;
+	uint32_t field_54;
+	uint32_t field_58;
+	uint32_t field_5C;
+	uint32_t field_60;
+	uint32_t field_64;
+	uint32_t field_68;
+	uint32_t field_6C;
+	uint32_t field_70;
+	uint32_t FadeStartTime;
+	uint32_t FadeEndTime;
+	uint32_t field_7C;
+	uint32_t Camera;
+	char PathFindingGraph[0x28];
+	struct Character *PlayerCharacter;
+	uint32_t field_B0;
+	uint32_t field_B4;
+	GameInput Input;
+	uint32_t field_E8;
+	uint32_t field_EC;
+	uint32_t ScreenshotEveryFrame; //bool?
+	uint32_t field_F4;
+	char field_F8;
+	char field_F9;
+	char field_FA;
+	char field_FB;
+	uint32_t field_FC;
+	uint32_t field_100;
+	uint32_t SlowMo;	//bool
+	uint32_t SlowMotion;
+	uint32_t field_10C;
+	uint32_t field_110;
+	uint32_t field_114;
+	char SplashScreenTextureName[32];
+	uint32_t field_138;
+	uint32_t field_13C;
+	uint32_t field_140;
+	uint32_t GameTime;
+	uint32_t field_148;
+	uint32_t field_14C;
+	uint32_t Level;
+	uint32_t field_154;
+	char MotionBlur[0x44][64];
+	uint32_t MotionBlurCount;
+	uint16_t field_125C;
+	uint16_t field_125E;
+	Character CharacterStorage[128];
+	uint16_t CharacterCount;
+	uint16_t padding_1;
+	uint32_t field_B6264;
+	char ActiveCharacters[0x2838][64]; //Active Character Struct isn't the proper size atm.
+	uint16_t ActiveCharactersCount;
+	char Shadows[32][0x804];
+	uint32_t field_1670EA;
+	uint32_t ShadowCount;
+	ActiveCharacter* ActiveCharacterList[128]; //or just Character*? Anyways, we wont need to use this.
+	uint32_t ActiveCharacterListCount;
+	uint32_t ActiveCharacterListLock;
+	Character* LivingCharacterList[128]; 
+	uint32_t LivingCharacterListCount;
+	uint32_t LivingCharacterListLock;
+	ActiveCharacter* PresentCharacterList[128];
+	uint32_t PresentCharacterListCount;
+	uint32_t PresentCharacterListLock;
+	void* ObjectList;
+	char DoorArray[8];
+	char Sky[0x290];
+	uint32_t field_1679A4;
+	uint32_t Triggers;
+	char IsGamePaused;
+	char IsInputEnabled;
+	char field_1679AE;
+	char field_1679AF;
+	uint32_t LockedActions1;
+	uint32_t LockedActions2;
+	uint32_t field_1679B8;
+	uint32_t WinLose;
+	uint32_t ConditionSoundsCount;
+	uint32_t ConditionSounds[5];
+	uint16_t LevelNumber;
+	uint16_t padding_5;
+	uint16_t field_1679DC;
+} GameState;
+
+
 #endif
Index: Daodan/src/Oni_Symbols.S
===================================================================
--- Daodan/src/Oni_Symbols.S	(revision 483)
+++ Daodan/src/Oni_Symbols.S	(revision 484)
@@ -65,5 +65,5 @@
 symbol ( @TSrContext_New@24                        , 0x0002EA30 )
 symbol ( @TMrInstance_GetDataPtr@12                , 0x000232E0 )
-
+symbol ( @TMrInstance_GetInstanceName@4			   , 0x00023D90 )
 symbol ( @COrTextArea_Print@28                     , 0x00031340 )
 
@@ -83,4 +83,5 @@
 symbol ( @SLrGlobalVariable_Register_Int32@12      , 0x00077e30 )
 symbol ( @SLrGlobalVariable_Register_Float@12      , 0x00077ec0 )
+symbol ( @SLrGlobalVariable_Register_String@12      , 0x00077fe0 )
 
 // Messages
