Index: Daodan/src/Daodan_Character.c
===================================================================
--- Daodan/src/Daodan_Character.c	(revision 427)
+++ Daodan/src/Daodan_Character.c	(revision 427)
@@ -0,0 +1,25 @@
+#include <stdlib.h>
+#include "Oni_Character.h"
+
+int DDr_TeamToTeamID(const char* team_string) { //Already something like this in the engine, but I'm reimplementing it...
+	if (!strcmp(team_string, "Konoko")) return 0;
+	if (!strcmp(team_string, "TCTF")) return 1;
+	if (!strcmp(team_string, "Syndicate")) return 2;
+	if (!strcmp(team_string, "Neutral")) return 3;
+	if (!strcmp(team_string, "SecurityGuard")) return 4;
+	if (!strcmp(team_string, "RougeKonoko")) return 5;
+	if (!strcmp(team_string, "Switzerland")) return 6;
+	if (!strcmp(team_string, "SyndicateAccessory")) return 7;
+	return 3; //if you enter a bad teamname, return Neutral.....
+}
+
+int CHARTest() {
+	CharacterObject TestCHAR;
+	memset(&TestCHAR, 0, sizeof(CharacterObject));
+	TestCHAR.Header.Type = "CHAR";
+	TestCHAR.OSD.Name = "Gumby";
+	TestCHAR.OSD.Class = "muro_generic";
+	TestCHAR.OSD.TeamID = DDr_TeamToTeamID("Syndicate");
+	ONrGameState_NewCharacter(&TestCHAR, 0);
+	return 0;
+}
Index: Daodan/src/Daodan_WindowHack.c
===================================================================
--- Daodan/src/Daodan_WindowHack.c	(revision 426)
+++ Daodan/src/Daodan_WindowHack.c	(revision 427)
@@ -6,4 +6,6 @@
 #include "BFW_Motoko_Draw.h"
 #include "oni_gl.h"
+
+#include "Oni_Character.h"
 
 volatile HWND onihwnd, boxhwnd = NULL;
@@ -129,4 +131,8 @@
 		lpPoint->y = gl->DisplayMode.Height / 2;
 	}
+	if (GetAsyncKeyState(VK_F12))
+	{
+		CHARTest();
+	}
 	else
 	{
Index: Daodan/src/Oni_Character.h
===================================================================
--- Daodan/src/Oni_Character.h	(revision 427)
+++ Daodan/src/Oni_Character.h	(revision 427)
@@ -0,0 +1,88 @@
+#pragma once
+#ifndef ONI_CHARS_H
+#define ONI_CHARS_H
+#endif
+
+#include "Daodan.h"
+#include <stdint.h>
+
+int DDr_TeamToTeamID(const char*);
+ONICALL ONrGameState_NewCharacter(int, int);
+int CHARTest();
+
+typedef struct {
+	float X;
+	float Y;
+	float Z;	
+} Vector3; //probably move to utilities...
+
+
+
+typedef struct {
+	char Type[4];			//"CHAR" etc.
+	int ObjectId;			//not needed
+	int Flags;				//The flags of the object...not used for CHAR
+	Vector3 Position;		//Position of Object
+	Vector3 Rotation;		//Rotation of Object
+	int EditorCallbacks;	//Lets try not to mess with it for now. :P
+	int field_28;			//unknown
+	
+} OSD_Header;
+
+
+typedef struct {
+	int32_t Options;				//A bitset. Someone had better define these
+	char Class[64];					//Name of the ONCC we use. ONCCName in idb
+	char Name[32];					//Name of the character. ie: ai2_spawn Muro
+	char Weapon[64];				//Name of the weapon he holds. ONWCName in idb
+	char ScriptSpawn[32];			//Script function called when char spawns
+	char ScriptDie[32];				//Script function called when char dies
+	char ScriptAware[32];			//Script function called when char detects something
+	char ScriptAlarm[32];			//Script function called when char is alarmed at something
+	char ScriptHurt[32];			//Script function called when char is hurt for the first time
+	char ScriptDefeat[32];			//Script function called when char is at 1 HP
+	char ScriptNoPath[32];			//Script function called when char loses path. Broken.
+	char ScriptNoAmmo[32];			//Script function called when char is out of ammo for the first time. Char must have ammo at spawn.
+	int32_t AdditionalHealth;		//Additional Health given to the character
+	int16_t AmmoUsed;				//Ammo given for the char to use
+	int16_t AmmoDropped;			//Ammo the char drops
+	int16_t CellsUsed;				//Cells given for the char to use
+	int16_t CellsDropped;			//Cells the char drops
+	int16_t HypoUsed;				//Hypo given for the char to use
+	int16_t HypoDropped;			//Hypo the char drops
+	int16_t ShieldUsed;				//Bullet shield given for the char to use
+	int16_t ShieldDropped;			//Bullet shield the char drops
+	int16_t CloakUsed;				//Phase Cloak given for the char to use
+	int16_t CloakDropped;			//Phase Cloak the char drops
+	int16_t NCIUsed;				//Don't use this...
+	int16_t NCIDropped;				//Don't use this...
+	
+	int32_t TeamID;					//Team ID
+	int32_t AmmoPercent;			//Percent of weapon ammo full
+	int32_t JobID;					//Job ID...
+									//0 - none 
+									//1 - idle 
+									//2 - guard (never used in Oni) 
+									//3 - patrol 
+									//4 - teambattle (never used in Oni)
+	int16_t PatrolID;				//patrol path ID (reference to the Patrol_Path.BINA file)
+	int16_t CombatID;				//combat ID (reference to the Combat.BINA file)
+	int16_t	MeleeID;				//melee ID (reference to the Melee Profile.BINA file)
+	int16_t NeutralID;				//neutral ID (reference to the Neutral.BINA file)
+	int32_t	AlarmGroups;			//Bitset. http://wiki.oni2.net/CHAR
+	int32_t InitialAlertLevel;		//0 - lull, 1 - low, 2 - medium, 3 - high, 4 - combat
+	int32_t MinimalAlertLevel;		//0 - lull, 1 - low, 2 - medium, 3 - high, 4 - combat
+	int32_t StartJobAlertLevel;		//0 - lull, 1 - low, 2 - medium, 3 - high, 4 - combat
+	int32_t InvestigatingAlertLevel;//0 - lull, 1 - low, 2 - medium, 3 - high, 4 - combat
+	int32_t PursuitStrongLow;
+	int32_t PursuitWeakLow;
+	int32_t PursuitStrongHigh;
+	int32_t PursuitWeakHigh;
+	int32_t Pursuit5;
+	int32_t field_1FC;
+} CharacterOSD;
+
+typedef struct {
+	OSD_Header Header;
+	CharacterOSD OSD;
+} CharacterObject;
Index: Daodan/src/Oni_Symbols.S
===================================================================
--- Daodan/src/Oni_Symbols.S	(revision 426)
+++ Daodan/src/Oni_Symbols.S	(revision 427)
@@ -47,2 +47,5 @@
 symbol ( _gl_gamma_ramp                      , 0x0015fdfc )
 symbol ( _gl_gamma_ramp_valid                , 0x001603fc )
+
+// Chars
+symbol ( @ONrGameState_NewCharacter@8		 , 0x000daC50 )
