[TeamTalk 62]: [599] usarsim/USARBotAPI: Import usarsim usarbotapi

tk@edam.speech.cs.cmu.edu tk at edam.speech.cs.cmu.edu
Thu May 10 11:24:00 EDT 2007


An HTML attachment was scrubbed...
URL: http://mailman.srv.cs.cmu.edu/pipermail/teamtalk-developers/attachments/20070510/9ad403eb/attachment-0001.html
-------------- next part --------------
Added: usarsim/USARBotAPI/Classes/BotConnection.uc
===================================================================
--- usarsim/USARBotAPI/Classes/BotConnection.uc	                        (rev 0)
+++ usarsim/USARBotAPI/Classes/BotConnection.uc	2007-05-10 15:24:00 UTC (rev 599)
@@ -0,0 +1,882 @@
+class BotConnection extends TcpLink
+	config(USARBotAPI);
+
+
+var string ReceivedData;
+var array<string> ReceivedArgs;
+var array<string> ReceivedVals;
+
+//used to store info inside function where local wont work
+//set property text dosent seem to work with a local
+var actor tempActor;
+var bool tempBool;
+
+
+var BotServer Parent;
+var RemoteBot theBot;
+
+// set true for verbose debug logs
+var config bool bDebug;
+
+
+// set true for iterative mode
+var config bool bIterative;
+
+
+// delay between visionUpdates
+var config float visionTime;
+var config bool bVision;
+
+var	int attrNum;
+
+// delimeters for strings sent to clients. set to match those of the server
+// as = identifies the start of an attribute
+var string as;
+// ae = attribute end
+var string ae;
+// ib = item break
+var string ib;
+
+//------------Message Types---------------------------
+// Each message appears on a seperate line. The first item
+//  of each message is the type identifier. It is a three
+//  letter code identifing what the message contains.
+// Used types are:
+//  (Asynchronous messages)
+//  FIN - game ended
+//  FAL - bot just hit a dropoff
+//  NFO - info about gametype. cue to register self
+//  AIN - added inventory. Bot got new inventory item
+//  VMS - recieved message from global chat channel
+//  VMT - recieved message from team chat channel
+//  VMG - recieved tokenized message
+//  ZCF - foot changed zones
+//  ZCH - head changed zones
+//  ZCB - bot changed zones
+//  CWP - changed weapon
+//  WAL - collided with a wall
+//  BMP - bumped another actor
+//  HRP - hear pickup
+//  HRN - hear noise
+//  SEE - see player - !!!DEPRICATED
+//  PRJ - incoming projectile
+//  KIL - some other player died
+//  DIE - bot died
+//  DAM - took damage
+//  HIT - hurt another player
+//  PTH - a series of nodes in response to a getpath call
+//  RCH - a bool result of a checkreach call
+// (Synchronous messages)
+//  PLR - see another player
+//  INV - see an inventory item (or weapon)
+//  NAV - see a navigation point
+//  DOM - see a domination point
+//  FLG - see a flag
+//  MOV - see a mover
+//  END - end of a vision batch
+//  BEG - begin of a vision batch
+//  SLF - random information about bots state
+//  GAM - random information about game state
+//--------------------------------------------------
+
+
+
+function PostBeginPlay()
+{
+    Parent = BotServer(Owner);
+	ib = Parent.ib;
+	as = Parent.as;
+	ae = Parent.ae;
+
+    if(bDebug)
+    	log("Spawned BotConnection");
+}
+
+//Socket established
+event Accepted()
+{
+	local string gameInfoStr, levelName;
+	local int i;
+
+    if(bDebug)
+    	log("Accepted BotConnection" @ self);
+
+ 	//no clean way to do this since gametypes are not derived from
+ 	//a common ancestor
+	switch(Parent.gameClass)
+	{
+		/*case "BotTeamGamePlus":
+			gameInfoStr = BotTeamGamePlus(Level.Game).GetGameInfo();
+			break;*/
+		case "BotDeathMatch":
+			gameInfoStr = BotDeathMatch(Level.Game).GetGameInfo();
+			break;
+		/*case "BotDomination":
+			gameInfoStr = BotDomination(Level.Game).GetGameInfo();
+			break;
+		case "BotCTF":
+			gameInfoStr = BotCTF(Level.Game).GetGameInfo();
+			break;*/
+	}
+
+	levelName = string(Level);
+	i = InStr(Caps(levelName), ".LEVELINFO");
+	if(i != -1)
+	levelName = Left(levelName, i);
+
+	SendLine("NFO" $ib$as$ "Gametype" $ib$ Parent.gameClass $ae$ib$as$
+		"Level" $ib$ levelName $ae$ gameInfoStr);
+	gotoState('monitoring','WaitingForInit');
+}
+
+//InitRecieved from client
+event InitRecieved()
+{
+local string clientName;
+local string teamString;
+local int teamNum;
+local vector startLocation;
+local rotator startRotation;
+local string className;
+
+  clientName = GetArgVal("Name");
+  teamString = GetArgVal("Team");
+  ParseVector(startLocation,"Location");
+  ParseRot(startRotation);
+  className = GetArgVal("ClassName");
+
+  if( teamString == "" )
+  	teamNum = 255;
+  else
+  	teamNum = int(teamString);
+
+ 	//no clean way to do this since gametypes are not derived from
+ 	//a common ancestor that has AddRemoteBot
+
+	if(bDebug)
+		log("InitRecieved");
+
+	//switch(Parent.gameClass)
+	//{
+	//	case "BotTeamGamePlus":
+			/*theBot = BotTeamGamePlus(Level.Game).AddRemoteBot(self, clientName, teamNum, startLocation, startRotation);
+			break;*/
+	//	case "BotDeathMatch":
+			theBot = BotDeathMatch(Level.Game).AddRemoteBot(self, clientName, teamNum, startLocation, startRotation, className);
+			//theBot = BotDeathMatchPlus(Level.Game).AddRemoteBot(self, clientName);
+	//		break;
+		/*case "BotDomination":
+			theBot = BotDomination(Level.Game).AddRemoteBot(self, clientName, teamNum, startLocation, startRotation);
+			break;
+		case "BotCTF":
+			theBot = BotCTF(Level.Game).AddRemoteBot(self, clientName, teamNum, startLocation, startRotation);
+			break;	*/
+	//}
+
+	// broadcast a welcome message.
+	//Level.Game.BroadcastMessage( theBot.PlayerReplicationInfo.PlayerName$Level.Game.EnteredMessage, false );	  // FIXME
+
+	if(bDebug)
+    		if(theBot != None) log("added bot, now running");
+    		else log("ERROR ADDING BOT");
+
+    gotoState('monitoring','Running');
+}
+
+
+
+//Closed on other end
+event Closed()
+{
+    local Pawn tempPawn;
+
+    if ( theBot != None && theBot.Pawn != None ) {
+        theBot.SetLocation(theBot.Pawn.Location);
+        theBot.Pawn.RemoteRole = ROLE_SimulatedProxy;
+        theBot.Pawn.UnPossessed();
+        tempPawn = theBot.Pawn;
+        theBot.Pawn = None;
+        tempPawn.Destroy();
+    }
+
+    if(theBot != None) {
+        theBot.Destroy();
+    }
+
+    Destroy();
+}
+
+//Recieve info - parse into lines and call RecievedLine
+event ReceivedText( string Text )
+{
+	local int i;
+	local string S;
+
+    if(bDebug)
+    	log("Recieved - "$Text);
+
+	ReceivedData = ReceivedData $ Text;
+
+	// remove a LF which arrived in a new packet
+	// and thus didn't get cleaned up by the code below
+	if(Left(ReceivedData, 1) == Chr(10))
+		ReceivedData = Mid(ReceivedData, 1);
+	i = InStr(ReceivedData, Chr(13));
+	while(i != -1)
+	{
+		S = Left(ReceivedData, i);
+		i++;
+		// check for any LF following the CR.
+		if(Mid(ReceivedData, i, 1) == Chr(10))
+			i++;
+
+		ReceivedData = Mid(ReceivedData, i);
+
+		ReceivedLine(S);
+
+		if(LinkState != STATE_Connected)
+			return;
+
+		i = InStr(ReceivedData, Chr(13));
+	}
+}
+
+
+
+
+
+//Here is where we handle incoming commands
+/* Commands expected to look like:
+{RUN {Argument value} {Arg value}...}
+Currently had coded to take no more than 9 args
+Command type and arguments can be
+any length, but first space terminates the name. Values can
+have spaces or any other kind of character.
+*/
+function ReceivedLine(string S)
+{
+	local string cmdType, argBody, rem;
+	local int endloc, wordsplit;
+    local name curBotState;
+
+    if(bDebug)
+    	log(S);
+
+	if( theBot != none ) {
+    	curBotState = theBot.GetStateName();
+    	if( curBotState == 'Dying' || curBotState == 'GameEnded')
+        	return;
+	}
+
+	wordsplit = InStr(S,ib);
+	if( wordsplit == -1)
+		wordsplit = Len(S);
+
+	cmdType = left(S,wordsplit);
+	rem = mid(S,InStr(S,as));
+	attrNum = 0;
+
+	//iterate through attr/val pairs, storring them in the
+	//parallel arrays RecievedArgs and RecievedVals
+	while(rem != "")
+	{
+		endloc = InStr(rem,ae);
+		argBody = mid(rem,1,(endloc - 1));
+
+		wordsplit = InStr(argBody,ib);
+		ReceivedArgs[attrNum] = left(argBody,wordsplit);
+		ReceivedVals[attrNum] = mid(argBody,(wordsplit + 1));
+
+		rem = mid(rem,1); //advance
+		rem = mid(rem,InStr(rem,as));
+		attrNum++;
+	}
+
+   	cmdType = Caps(cmdType);
+
+	ProcessAction(cmdType);
+}
+
+
+function string GetArgVal(string argName)
+{
+	local int i;
+	while (i < attrNum && ReceivedArgs[i] != "")
+	{
+		if (ReceivedArgs[i] ~= argName)
+			return ReceivedVals[i];
+		i++;
+	}
+
+	return "";
+}
+
+function ParseVector(out vector v, string vecName)
+{
+    local int i;
+    local string rem;
+    local string delim;
+
+    delim = ib;
+
+	rem = GetArgVal(vecName);
+	if(rem != "")
+	{
+        if( InStr(rem,delim) == -1 )
+        	delim = ",";
+        i = InStr(rem,delim);
+        v.X = float(left(rem,i));
+        rem = mid(rem,i+1);
+        i = InStr(rem,delim);
+        v.Y = float(left(rem,i));
+        v.Z = float(mid(rem,i+1));
+	}
+	else
+	{
+		v.x = float( GetArgVal("x") );
+		v.y = float( GetArgVal("y") );
+		v.z = float( GetArgVal("z") );
+	}
+}
+
+function ParseRotAsVec(out vector vec)
+{
+    local int i;
+    local string rem;
+    local string delim;
+
+    delim = ib;
+
+	rem = GetArgVal("Rotation");
+	if(rem != "")
+	{
+        if( InStr(rem,delim) == -1 )
+        	delim = ",";
+        i = InStr(rem,delim);
+        vec.X = float(left(rem,i));
+        rem = mid(rem,i+1);
+        i = InStr(rem,delim);
+        vec.Y = float(left(rem,i));
+        vec.Z = float(mid(rem,i+1));
+	}
+	else
+	{
+		vec.Y = float( GetArgVal("pitch") );
+		vec.Z = float( GetArgVal("yaw") );
+		vec.X = float( GetArgVal("roll") );
+	}
+}
+
+function ParseRot(out rotator rot)
+{
+    local int i;
+    local string rem;
+    local string delim;
+
+    delim = ib;
+
+	rem = GetArgVal("Rotation");
+	if(rem != "")
+	{
+        if( InStr(rem,delim) == -1 )
+        	delim = ",";
+        i = InStr(rem,delim);
+        rot.Pitch = float(left(rem,i));
+        rem = mid(rem,i+1);
+        i = InStr(rem,delim);
+        rot.Yaw = float(left(rem,i));
+        rot.Roll = float(mid(rem,i+1));
+	}
+	else
+	{
+		rot.Pitch = float( GetArgVal("pitch") );
+		rot.Yaw = float( GetArgVal("yaw") );
+		rot.Roll = float( GetArgVal("roll") );
+	}
+}
+
+function ProcessAction(string cmdType)
+{
+    local int i;
+    local vector v, v2;
+    local bool boolResult;
+    local string target, id, outBuf, focusTarg;
+    local rotator r, r2;
+    local float speed;
+    local float accel;
+
+    if(bDebug)
+		log("comandType:"@cmdType);
+
+    if (bIterative)
+    	Level.Pauser=None;
+
+
+   	switch(cmdType)
+   	{
+	case "TEST":
+	    theBot.GotoState('Startup', 'Test');
+	    break;
+	case "INIT":
+	    InitRecieved();
+	    break;
+	case "INCH":
+	    //test function
+	    /* must deal with target, focus and destination */
+	    theBot.StopWaiting();
+	    theBot.myDestination = (100 * vector(theBot.Pawn.Rotation)) + theBot.Pawn.Location;
+	    theBot.GotoState('Startup', 'Move');
+	    break;
+	case "SETWALK":
+	    target = GetArgVal("Walk");
+	    SetPropertyText("tempBool",target);
+	    theBot.Pawn.bIsWalking = tempBool;
+	    break;
+	case "SETPHYS":
+	    target = GetArgVal("Physics");
+	    switch(target) {
+	    case "Walking":
+		theBot.Pawn.SetPhysics(PHYS_Walking);
+		log("Setting Physics Walking");
+		if(theBot.Physics == PHYS_Walking)
+		    {
+			log("Bot already walking");
+		    }
+		break;
+	    case "Falling":
+		theBot.Pawn.SetPhysics(PHYS_Falling);
+		break;
+	    case "Swimming":
+		theBot.Pawn.SetPhysics(PHYS_Swimming);
+		break;
+	    case "Flying":
+		theBot.Pawn.SetPhysics(PHYS_Flying);
+		log("Setting Physics Flying");
+		if(theBot.Pawn.Physics == PHYS_Flying)
+		    {
+			log("Bot already flying");
+		    }
+		break;
+	    case "Rotating":
+		theBot.Pawn.SetPhysics(PHYS_Rotating);
+		break;
+	    case "Projectile":
+		theBot.Pawn.SetPhysics(PHYS_Projectile);
+		break;
+	    case "NONE":
+	    case "":
+		theBot.Pawn.SetPhysics(PHYS_None);
+		break;
+	    }
+	    break;
+	case "STOP":
+	    theBot.GotoState('Startup', 'Begin');
+	    break;
+	case "JUMP":
+	    theBot.RemoteJump();
+	    break;
+	case "DRM" : // May be we need to deal with time stamp to make time compensation. 02/06/17
+	case "RUN" :
+	case "SPIN": //jjwang 02/06/01
+	    if	(theBot.botDR==none) {
+		theBot.botDR = new class'DeadReckoning';
+		theBot.botDR.init(theBot.Pawn);
+	    }
+	    theBot.botDR.SetT(Level.TimeSeconds);
+
+	    //	SPIN
+	    if (GetArgVal("Rotation")!="") {
+		ParseRot(r);
+		theBot.botDR.SetRP(r);
+	    }
+	    if (GetArgVal("Rate")!="") {
+		ParseVector(v,"Rate");
+		r.Pitch = v.x;
+		r.Yaw = v.y;
+		r.Roll = v.z;
+		theBot.botDR.SetRV(r);
+	    }
+	    if (GetArgVal("AcRate")!="") {
+		ParseVector(v,"AcRate");
+		r.Pitch = v.x;
+		r.Yaw = v.y;
+		r.Roll = v.z;
+		theBot.botDR.SetRA(r);
+	    }
+
+	    // RUN
+	    if (GetArgVal("Location")!="") {
+		ParseVector(v2,"Location");
+		theBot.botDR.setLP(v2); // joe
+		//theBot.Pawn.SetLocation(v2); //joe
+	    }
+	    if (GetArgVal("Velocity")!="") {
+		ParseVector(v,"Velocity");
+		theBot.botDR.setLV(v);
+		theBot.botDR.setLA(vect(0,0,0));
+	    }
+	    if (GetArgVal("Acceleration")!="") {
+		ParseVector(v,"Acceleration");
+		theBot.botDR.SetLA(v);
+	    }
+
+	    // Used for replication DR. 02/06/27
+	    theBot.start.DR_T = theBot.botDR.start.DR_T;
+	    theBot.start.DR_P = theBot.botDR.start.DR_P;
+	    theBot.start.DR_V = theBot.botDR.start.DR_V;
+	    theBot.start.DR_A = theBot.botDR.start.DR_A;
+	    theBot.start.DR_RP = theBot.botDR.start.DR_RP;
+	    theBot.start.DR_RV = theBot.botDR.start.DR_RV;
+	    theBot.start.DR_RA = theBot.botDR.start.DR_RA;
+	    theBot.start.PreK = theBot.botDR.PreK;
+	    theBot.start.bLFilter = theBot.botDR.bLFilter;
+	    theBot.start.bRFilter = theBot.botDR.bRFilter;
+
+	    if (!theBot.isDR) {
+		log("STARTING DR");
+		theBot.isDR = true;
+		theBot.GotoState('Startup', 'DRM');
+	    }
+	    break;
+	case "RUNTO":
+	    speed = float(GetArgVal("Speed"));
+	    if(speed != 0.0)
+		{
+		    if(theBot.Physics == PHYS_Flying)
+			{
+			    theBot.pawn.airspeed = speed;
+			}
+		    else if(theBot.Physics == PHYS_Swimming)
+			{
+			    theBot.pawn.waterspeed = speed;
+			}
+		    else
+			{
+			    theBot.pawn.groundspeed = speed;
+			}
+		}
+	    accel = float(GetArgVal("Accel"));
+	    if(accel != 0.0)
+		{
+		    theBot.pawn.AccelRate = accel;
+		}
+	    target = GetArgVal("Target");
+	    if(target == "")
+		{
+		    ParseVector(v,"Location");
+		    theBot.myDestination = v;
+		    theBot.RemoteDestination = none;
+		    theBot.GotoState('Startup', 'Move');
+		}
+	    else
+		{
+		    SetPropertyText("tempActor",target);
+
+		    if( tempActor != none &&
+			theBot.FastTrace(tempActor.Location) &&
+			theBot.inFront(tempActor.Location) )
+		    	{
+			    //theBot.RemoteDestination = none;
+			    //zero out myDestination
+			    theBot.myDestination = tempActor.Location;
+			    theBot.GotoState('Startup', 'Move');
+			}
+		}
+	    break;
+		case "STRAFE":
+			speed = float(GetArgVal("Speed"));
+                        if(speed != 0.0)
+                        {
+                                if(theBot.Pawn.Physics == PHYS_Flying)
+                                {
+                                        theBot.pawn.airspeed = speed;
+                                }
+				else if(theBot.Physics == PHYS_Swimming)
+				{
+					theBot.pawn.waterspeed = speed;
+				}
+                                else
+                                {
+                                        theBot.pawn.groundspeed = speed;
+                                }
+                        }
+			accel = float(GetArgVal("Accel"));
+			if(accel != 0.0)
+			{
+				theBot.pawn.AccelRate = accel;
+			}
+			ParseVector(v,"Location");
+			theBot.myDestination = v;
+			focusTarg = GetArgVal("Target");
+			if(focusTarg == "")
+			{
+				ParseVector(v2,"Focus");
+				theBot.myFocus = v2;
+				theBot.RemoteFocus = none;
+		    }
+		    else
+		    {
+		    	SetPropertyText("tempActor",focusTarg);
+		    	if( tempActor != none &&
+		    		theBot.FastTrace(tempActor.Location) &&
+		    		theBot.inFront(tempActor.Location) )
+		    	{
+			    	theBot.RemoteFocus = tempActor;
+					//zero out myFocus
+					theBot.myFocus = v2;
+				}
+		    }
+			theBot.StopWaiting();
+	        theBot.GotoState('Startup', 'Strafe');
+	        break;
+     	case "SHOOT":
+			target = GetArgVal("Target");
+			ParseVector(v,"Location");
+			theBot.SetPropertyText("Enemy",target);
+			theBot.SetPropertyText("RemoteEnemy",target);
+			theBot.StopWaiting();
+			theBot.myTarget = v;
+
+			target = GetArgVal("Alt");
+			SetPropertyText("tempBool",target);
+			theBot.RemoteFireWeapon(tempBool);
+	        break;
+     	case "CHANGEWEAPON":
+			target = GetArgVal("ID");
+			if( target ~= "best" )
+			{
+				theBot.SwitchToBestWeapon();
+			}
+			else
+			{
+				SetPropertyText("tempActor",target);
+
+				if(tempActor != none)
+				{
+					theBot.pawn.PendingWeapon = Weapon(tempActor);
+					if ( theBot.pawn.Weapon == None )
+						theBot.ChangedWeapon();
+					else if ( theBot.pawn.Weapon != theBot.pawn.PendingWeapon )
+						theBot.pawn.Weapon.PutDown();
+				}
+			}
+	        break;
+     	case "STOPSHOOT":
+			theBot.StopWaiting();
+			theBot.HaltFiring();
+	        break;
+     	case "CHECKREACH":
+			target = GetArgVal("Target");
+		    id = GetArgVal("id");
+			if(target == "")
+			{
+				ParseVector(v,"Location");
+		    	boolResult = theBot.pointReachable(v);
+			    sendLine("RCH" $ib$as$ "ID" $ib$ id $ae$ib$as$ "Reachable" $ib$ boolResult
+			    	$ae$ib$as$ "From" $ib$ theBot.Location $ae);
+		    }
+		    else
+		    {
+		    	SetPropertyText("tempActor",target);
+		    	if( tempActor != none &&
+		    		theBot.FastTrace(tempActor.Location) &&
+		    		theBot.inFront(tempActor.Location) )
+		    	{
+			    	boolResult = theBot.actorReachable(tempActor);
+				    sendLine("RCH" $ib$as$ "ID" $ib$ id $ae$ib$as$ "Reachable" $ib$ boolResult
+				    	$ae$ib$as$ "From" $ib$ theBot.Location $ae$ib$as$ "To" $ib$ tempActor.Location $ae);
+				}
+		    }
+    		break;
+     	case "TURNTO":
+	    target = GetArgVal("Target");
+	    if(target == "")
+		{
+		    ParseRot(r);
+		    if(r.Yaw == 0 && r.Pitch == 0 && r.Roll == 0)
+			{
+			    //no target or rotation defined
+			    ParseVector(v,"Location");
+			    theBot.myFocus = v;
+			    theBot.RemoteFocus = none;
+			}
+		    else
+			{
+			  //no target, yes rotation
+			  theBot.myRotation = r;
+			  theBot.FocalPoint = theBot.Pawn.Location + ( vector(r) * 1000);
+			  //theBot.myFocus = vect(0,0,0);
+			  theBot.RemoteFocus = none;
+		    	}
+		}
+	    else
+		{
+		    //target defined
+		    SetPropertyText("tempActor",target);
+		    if( tempActor != none &&
+			theBot.FastTrace(tempActor.Location) &&
+			theBot.inFront(tempActor.Location) )
+		    	{
+			    theBot.RemoteFocus = tempActor;
+			    //zero out myFocus
+			    theBot.myFocus = v;
+			}
+		}
+	    if (GetArgVal("RotationRate")!="") {
+                ParseRot(r2);
+		theBot.myRotationRate = r2;
+	    }
+	    theBot.StopWaiting();
+	    theBot.GotoState('Startup', 'Turning');
+	    break;
+     	case "ROTATE":
+	    target = GetArgVal("Axis");
+	    r = theBot.Pawn.Rotation;
+	    i = int(GetArgVal("Amount"));
+	    if(target == "Vertical")
+		    {
+			r.Pitch = r.Pitch + i;
+		    }
+		else
+		    {
+			r.Yaw = r.Yaw + i;
+		    }
+	        if (GetArgVal("RotationRate")!="") {
+                    ParseRot(r2);
+		    theBot.myRotationRate = r2;
+	        }
+		theBot.myRotation = r;
+		theBot.myFocus = theBot.Pawn.Location + ( vector(r) * 1000 );
+		theBot.RemoteFocus = none;
+		theBot.StopWaiting();
+		theBot.GotoState('Startup', 'Turning');
+    		break;
+	case "TRACK":
+	    target = GetArgVal("Target");
+	    if(target != "")
+		{
+		    SetPropertyText("tempActor",target);
+		    if( theBot.FastTrace(tempActor.Location) && theBot.inFront(tempActor.Location) )
+		    	{
+			    theBot.RemoteFocus = tempActor;
+			    theBot.StopWaiting();
+			    theBot.GotoState('Startup', 'Tracking');
+		        }
+		}
+	    break;
+     	case "GETPATH":
+     		//clear the old path
+		    for ( i=0; i<16; i++ )
+			{
+				if ( theBot.RouteCache[i] == None )
+					break;
+				else
+				{
+					theBot.RouteCache[i] = None;
+				}
+			}
+			ParseVector(v,"Location");
+		    theBot.FindPathTo(v);
+		    id = GetArgVal("id");
+		    outBuf = "PTH"$ib$as$"ID"$ib$id$ae;
+		    for ( i=0; i<16; i++ )
+			{
+				if ( theBot.RouteCache[i] == None )
+					break;
+				else
+				{
+    				outBuf = outBuf$ib$as$i$ib$theBot.RouteCache[i]$ib$theBot.RouteCache[i].Location$ae;
+				}
+			}
+			SendLine(outBuf);
+    		break;
+     	case "MESSAGE":
+     		//Note - currently only allow messages under 256 chars
+			target = GetArgVal("Text");
+			boolResult = bool(GetArgVal("Global"));
+			if(target != "")
+			{
+				// @ preceding message makes it global. dont ask. not my code
+		/*		if(boolResult)
+					theBot.BroadcastLocalizedMessage("@"$target);
+				else
+					theBot.BroadcastLocalizedMessage(target); */
+			// FIXME
+		    }
+		    break;
+     	case "PING":
+     		SendLine("PONG");
+		    break;
+    }
+}
+
+
+
+
+//Send a line to the client
+function SendLine(string Text, optional bool bNoCRLF)
+{
+    if(bDebug)
+    	log("    Sending: "$Text);
+	if(bNoCRLF)
+		SendText(Text);
+	else
+		SendText(Text$Chr(13)$Chr(10));
+}
+
+
+//Concat two strings togeather with our list bookends
+function string MakeItem(string first, string second)
+{
+	return (as$first$ib$second$ae);
+}
+
+
+//fire right up into the loop for sending updates
+auto state monitoring
+{
+Begin:
+WaitingForInit:
+	sleep(0.1);
+	goto 'WaitingForInit';
+Running:
+  if(bVision && Level.Pauser == None && theBot != none && !theBot.IsInState('GameEnded') && !theBot.IsInState('Dying'))
+  {
+		SendLine("BEG" $ib$as$ "Time" $ib$ Level.TimeSeconds $ae);
+	 	//no clean way to do this since gametypes are not derived from
+	 	//a common ancestor that has AddRemoteBot
+		//switch(Parent.gameClass)
+		//{
+		/*	case "BotTeamGamePlus":
+				sendLine( BotTeamGamePlus(Level.Game).GetGameStatus() );
+				break;*/
+		//	case "BotDeathMatch":
+				sendLine( BotDeathMatch(Level.Game).GetGameStatus() );
+		//		break;
+			/*case "BotDomination":
+				sendLine( BotDomination(Level.Game).GetGameStatus() );
+				break;
+			case "BotCTF":
+				sendLine( BotCTF(Level.Game).GetGameStatus(theBot) );
+				break;	*/
+		//}
+	  	theBot.checkSelf();
+	  	theBot.checkVision();
+		SendLine("END" $ib$as$ "Time" $ib$ Level.TimeSeconds $ae);
+  }
+  if (bIterative)
+  	Level.Pauser=theBot.playerReplicationInfo;
+
+  sleep(visionTime);
+  goto 'Running';
+}
+
+defaultproperties
+{
+     bDebug=true
+     bVision=true
+     visionTime=0.100000
+     as="{"
+     ae="}"
+     ib=" "
+}

Added: usarsim/USARBotAPI/Classes/BotDeathMatch.uc
===================================================================
--- usarsim/USARBotAPI/Classes/BotDeathMatch.uc	                        (rev 0)
+++ usarsim/USARBotAPI/Classes/BotDeathMatch.uc	2007-05-10 15:24:00 UTC (rev 599)
@@ -0,0 +1,210 @@
+class BotDeathMatch extends DeathMatch
+	config(USARBotAPI);
+
+var class<VizServer>	VizServerClass;
+var VizServer           theVizServer;
+var class<BotServer>	BotServerClass;
+var BotServer 	    	theBotServer;
+var bool 	 	        bServerLoaded;
+var class<RemoteBotInfo> RemoteBotConfigClass;
+var class<RemoteBot>    RemoteBotClass;
+var RemoteBotInfo       RemoteBotConfig;
+var int 		        NumRemoteBots;
+var ComServer			theComServer;
+var class<ComServer>	ComServerClass;
+
+
+function PostBeginPlay()
+{
+	Super.PostBeginPlay();
+
+	if(!bServerLoaded)
+	{
+	    theVizServer = spawn(VizServerClass, self);
+	    theVizServer.gameClass = "BotDeathMatch";
+	    
+	    theBotServer = spawn(BotServerClass);
+	    theBotServer.gameClass = "BotDeathMatch";
+		
+		theComServer = spawn(ComServerClass,self);
+	    theComServer.gameClass = "BotDeathMatch";
+		
+	    bServerLoaded = true;
+	}
+	RemoteBotConfig = spawn(RemoteBotConfigClass);
+}
+
+function RemoteBot AddRemoteBot(BotConnection theConnection, string clientName, int teamNum, vector startLocation, rotator startRotation, string className)
+{
+	local RemoteBot NewBot;
+	local NavigationPoint startSpot;
+
+	startSpot = FindPlayerStart(NewBot);
+
+	newBot = Spawn(RemoteBotClass, self, ,startLocation, startRotation);
+
+	newBot.bIsPlayer = true;
+	newBot.bHidden = false;
+	if ( NewBot != None ) {
+		NewBot.myConnection = theConnection;
+		NewBot.as = theConnection.as;
+		NewBot.ae = theConnection.ae;
+		NewBot.ib = theConnection.ib;
+		NewBot.PlayerReplicationInfo.PlayerID = CurrentID++;
+		NumRemoteBots++;
+		NumPlayers++;
+		if(clientName == "") {
+		    newBot.PlayerReplicationInfo.PlayerName = "Unnamed_Bot_" $ NumRemoteBots;
+		} else {
+		    newBot.PlayerReplicationInfo.PlayerName = clientName;
+		}
+
+		if(className != "") {
+			newBot.PawnClass = class<Pawn>(DynamicLoadObject(className, class'Class'));
+		} else if(newBot.PawnClass == None) {
+			log("newBot.PawnClass is None");
+			newBot.PawnClass = class<Pawn>(DynamicLoadObject("xGame.xPawn", class'Class'));
+		}
+
+		SpawnPlayer(newBot, startLocation, startRotation);
+	} else {
+	    log("NewBot was none");
+	}
+
+	return NewBot;
+}
+
+function SpawnPlayer(RemoteBot newBot, optional vector startLocation, optional rotator startRotation) {
+	local NavigationPoint startSpot;
+
+	if(NewBot == None) {
+		log("NewBot was none");
+		return;
+	}
+	if(NewBot.Pawn != None) {
+	    log("Already had pawn");
+	    return;
+	}
+
+	startSpot = FindPlayerStart(NewBot);
+
+	if(startLocation == vect(0,0,0)) {
+	    NewBot.Pawn = Spawn(GetDefaultPlayerClass(NewBot),,,StartSpot.Location,StartSpot.Rotation);
+	} else {
+	    NewBot.Pawn = Spawn(NewBot.PawnClass,,,startLocation,startRotation);
+	}
+	log("PawnClass: "$NewBot.PawnClass);
+
+	if ( NewBot.Pawn == None )
+	{
+	   	log("Couldn't spawn player of type "$NewBot.PawnClass$" at "$StartSpot);
+	   	return;
+	} else {
+		log("Spawned player of type "$NewBot.PawnClass$" at "$StartSpot);
+	}
+
+	NewBot.Pawn.Anchor = startSpot;
+	NewBot.Pawn.LastStartSpot = PlayerStart(startSpot);
+	NewBot.Pawn.LastStartTime = Level.TimeSeconds;
+	NewBot.PreviousPawnClass = NewBot.Pawn.Class;
+
+	NewBot.Possess(NewBot.Pawn);
+	NewBot.PawnClass = NewBot.Pawn.Class;
+
+	NewBot.Squad = spawn(DeathMatch(Level.Game).DMSquadClass);
+	if(NewBot.Squad == None) log("NewBot.Squad == None");
+
+	NewBot.Pawn.PlayTeleportEffect(true, true);
+	//	NewBot.ClientSetRotation(NewBot.Pawn.Rotation);
+	AddDefaultInventory(NewBot.Pawn);
+	TriggerEvent( StartSpot.Event, StartSpot, NewBot.Pawn );
+	BroadcastLocalizedMessage(GameMessageClass, 1, NewBot.PlayerReplicationInfo);
+	NewBot.GotoState('StartUp', 'Begin');
+}
+
+function string GetGameStatus()
+{
+	local string ib, as, ae;
+	local string outStr;
+	local Controller P;
+	
+	ib = theBotServer.ib;
+	as = theBotServer.as;
+	ae = theBotServer.ae;
+	
+	outStr = "GAM";
+			
+	outStr = ( outStr $ib$as$ "PlayerScores" );
+	for ( P=Level.ControllerList; P!=None; P=P.NextController )
+	{
+		if( !P.PlayerReplicationInfo.bIsSpectator )
+			outStr = ( outStr $ib$as$ P $ib$ P.PlayerReplicationInfo.Score $ae );
+	}
+	
+	outStr = ( outStr $ae );				
+					
+	return outStr;
+}
+
+function string GetGameInfo()
+{
+	local string ib, as, ae;
+	local string outStr;
+	
+	ib = theBotServer.ib;
+	as = theBotServer.as;
+	ae = theBotServer.ae;
+	
+	//outStr = (ib$as$ "FragLimit" $ib$ $ae$ib$as$ "TimeLimit" $ib$ $ae);	
+	outStr = (ib$as$ "TimeLimit" $ib$ TimeLimit $ae);	
+					
+	return outStr;
+}
+
+function RestartPlayer( Controller aPlayer )
+{
+    if(aPlayer.IsA('RemoteBot')) {
+	 	if(aPlayer.IsInState('Dying')) {
+		    log("BOTRESTRTPLAYER"@aPlayer);
+	    	SpawnPlayer(RemoteBot(aPlayer));	
+		}
+    } else if (aPlayer.IsA('Player')){
+		log("RESTARTPLAYER"@aPlayer);
+		Super.RestartPlayer(aPlayer);
+    }
+}
+
+function Killed( Controller Killer, Controller Killed, Pawn KilledPawn, class<DamageType> damageType )
+{
+    local string ib, as, ae;
+	
+	ib = theBotServer.ib;
+	as = theBotServer.as;
+	ae = theBotServer.ae;
+
+	Killer.PlayerReplicationInfo.Score += 1.0;
+
+	if(!Killed.IsA('RemoteBot')) {
+	    Super.Killed(Killer, Killed, KilledPawn, damageType);
+	} else 	if(Killed != None) 
+	    RemoteBot(Killed).myConnection.SendLine("DIE" $ib$as$ "Killer" $ib$ Killer $ae$ib$as$
+						    "DamageType" $ib$ damageType $ae);
+}
+
+defaultproperties
+{
+	 BotServerClass=USARBotAPI.BotServer
+	 VizServerClass=USARBotAPI.VizServer
+	 ComServerClass=USARBotAPI.ComServer
+	 RemoteBotConfigClass=USARBotAPI.RemoteBotInfo
+	 RemoteBotClass=USARBotAPI.RemoteBot;	 
+     NetWait=0
+     CountDown=0
+     DefaultEnemyRosterClass="XGame.xDMRoster"
+     bPauseable=True
+     AutoAim=0.930000
+     GameSpeed=1.500000
+     MaxPlayers=16
+     GameName="Remote Bot DeathMatch"
+     PlayerControllerClassName="USARBotAPI.ViewTestPlayerController"
+}

Added: usarsim/USARBotAPI/Classes/BotServer.uc
===================================================================
--- usarsim/USARBotAPI/Classes/BotServer.uc	                        (rev 0)
+++ usarsim/USARBotAPI/Classes/BotServer.uc	2007-05-10 15:24:00 UTC (rev 599)
@@ -0,0 +1,96 @@
+class BotServer extends TcpLink
+	config(USARBotAPI);
+
+
+var config int ListenPort;
+var config int MaxConnections;
+
+var string gameClass;
+var bool bBound;
+var config bool bDebug;
+
+var int ConnectionCount;
+
+
+
+// configurable delimeters for strings sent to clients
+// currently of form (with multiple possible attributes):
+// "type"$ib$"identifier"$ib$as$"attrname1"$ib$"attrvalue1"$ae
+
+// as = identifies the start of an attribute
+var string as;
+// ae = attribute end
+var string ae;
+// ib = item break
+var string ib;
+
+
+
+//shouldn't happen
+event ReceivedText( string Text )
+{
+    if(bDebug)
+    	log("RecievedTest in Server - "$Text);
+}
+
+
+
+function BeginPlay()
+{
+	Super.BeginPlay();
+    if(!bBound)
+    {
+		BindPort( ListenPort );
+		if(bDebug)
+    		log("BotServer bound to port "$ListenPort);
+		Listen();
+        bBound = true;
+    }
+}
+
+//should never happen - accepted connections should be forwarded to a botconnection
+event Accepted()
+{
+    if(bDebug)
+    	log("Accepted connection in BotServer");
+}
+
+//called everytime a new botconnection is spawned
+event GainedChild( Actor C )
+{
+	Super.GainedChild(C);
+	ConnectionCount++;
+
+    //BotConnection(C).Parent = self;
+	// if too many connections, close down listen.
+	if(MaxConnections > 0 && ConnectionCount > MaxConnections && LinkState == STATE_Listening)
+	{
+		if(bDebug)
+    		Log("BotServer: Too many connections - closing down Listen.");
+		Close();
+	}
+}
+
+event LostChild( Actor C )
+{
+	Super.LostChild(C);
+	ConnectionCount--;
+
+	// if closed due to too many connections, start listening again.
+	if(ConnectionCount <= MaxConnections && LinkState != STATE_Listening)
+	{
+		if(bDebug)
+    		Log("BotServer: Listening again - connections have been closed.");
+		Listen();
+	}
+}
+
+defaultproperties
+{
+     ListenPort=3000
+     MaxConnections=64
+     as="{"
+     ae="}"
+     ib=" "
+     AcceptClass=Class'USARBotAPI.BotConnection'
+}

Added: usarsim/USARBotAPI/Classes/ComConnection.uc
===================================================================
--- usarsim/USARBotAPI/Classes/ComConnection.uc	                        (rev 0)
+++ usarsim/USARBotAPI/Classes/ComConnection.uc	2007-05-10 15:24:00 UTC (rev 599)
@@ -0,0 +1,107 @@
+class ComConnection extends Actor config(USARComServer);
+
+var ComLink link1,link2;
+var bool bInit;
+var class<ComLink> CLclass;
+var config bool bDebug;
+
+function setUp(string id1,string id2)
+{
+	if(!bInit)
+	{
+		//Spawn two ComLink objects
+		link1=spawn(CLclass,self);
+		if(link1!=None)
+		{
+			link1.setUp(id1);
+		}
+		link2=spawn(CLclass,self);
+		if(link2!=None)
+		{
+			link2.setUp(id2);
+		}
+		
+		if(link1!=None && link2!=None)
+			bInit=true;
+		else
+		{
+			if(bDebug)
+				log("ComConnection : Cannot spawn ComLink classes");
+		}
+	}
+}
+
+//Process the requests sent by the robot
+function processMessage(string cmd, int Count, byte M[255], string id)
+{	
+	//Processing the command
+	switch(cmd)
+	{
+		case "SEND":
+			if(!(ComServer(Owner).isReachable(link1.id,link2.id)))
+			{
+				if(bDebug) log("ComConnection: Lost connectivity between "$link1.id$" and "$link2.id);
+				if(id==link1.id)
+				{
+					//link1.SendText("Fail: Lost connectivity between "$link1.id$" and "$link2.id$";");
+				}
+				else
+				{
+					//link2.SendText("Fail: Lost connectivity between "$link1.id$" and "$link2.id$";");
+				}
+				link1.Close();
+				link2.Close();
+				link1.bInit=false;
+				link2.bInit=false;
+				break;
+			}
+			if(id==link1.id)
+			{
+				if(link2.bInit==true)
+					link2.SendBinary(Count,M);
+				//link1.SendText("OK;");
+			}
+			else
+			{
+				if(link1.bInit==true)
+					link1.SendBinary(Count,M);
+				//link2.SendText("OK;");
+			}
+			break;
+		case "CLOSE":
+			if(link1.bInit==true)
+			{
+				if (bDebug) log("ComConnection: Closing connection to "$link1.id);
+				link1.Close();
+				link1.bInit=false;
+			}
+			if(link2.bInit==true)
+			{
+				if (bDebug) log("ComConnection: Closing connection to "$link2.id);
+				link2.Close();
+				link2.bInit=false;
+			}
+			break;
+		//These should not occur
+		case "REGISTER":
+		case "LISTEN":
+		case "OPEN":
+		default:
+			if(bDebug) log("ComConnection: Unknown message - "$cmd);
+			if(id==link1.id)
+			{
+				Link1.SendText("Fail: Unknown message;");
+			}
+			else
+			{
+				Link2.SendText("Fail: Unknown message;");
+			}
+	}
+}
+
+defaultproperties
+{
+	CLclass=USARBotApi.ComLink
+	bInit=false
+	bDebug=true
+}
\ No newline at end of file

Added: usarsim/USARBotAPI/Classes/ComLink.uc
===================================================================
--- usarsim/USARBotAPI/Classes/ComLink.uc	                        (rev 0)
+++ usarsim/USARBotAPI/Classes/ComLink.uc	2007-05-10 15:24:00 UTC (rev 599)
@@ -0,0 +1,327 @@
+class ComLink extends TcpLink config(USARComServer);
+
+var string id;
+var string PartMsg;
+var string MsgEnd;
+var bool bInit;
+var config bool bDebug;
+var int RPort;
+
+
+//Variables to process the binary message
+var bool bNewMsg;
+var int mLen;
+var string sLen;
+var int mProc;
+var byte Msg[255];
+var int aProc;
+var string Com;
+var byte C[5];
+
+
+function setUp(string iden)
+{
+	if(!bInit)
+	{
+		id=iden;
+		bInit=true;
+		LinkMode=MODE_Binary;
+	}
+}
+
+function Connect(string Ip, string Port)
+{
+	RPort=int(Port);
+	if(bDebug)
+		log("ComLink: Connect is resolving IP address "$Ip);
+	Resolve(Ip);
+}
+
+event Resolved(IpAddr Addr)
+{
+	if(bDebug)
+		log("ComLink: IP address resolved");
+	Addr.Port=RPort;
+	BindPort();
+	Open(Addr);
+}
+
+event ResolveFailed()
+{
+  if(bDebug) log("ComLink: Could not resolve IP address");
+}
+
+event Opened()
+{
+	if(bDebug)
+		log("ComLink: "$id$" Connected to "$IpAddrToString(RemoteAddr));
+}
+
+function bool Open(IpAddr Addr)
+{
+	if(bDebug)
+		log("ComLink: "$id$" Connecting to "$IpAddrToString(Addr));
+	return super.Open(Addr);
+}
+
+event ReceivedLine(string Line)
+{
+	if(bInit)
+	{
+		ComConnection(Owner).processMessage(Line,0,Msg,id);
+	}
+}
+
+event ReceivedText( string Text )
+{
+	local int i;
+	local string M;
+	
+	i=0;
+	if(bDebug)
+    	log("ComLink: Recieved Text in Server - "$Text);
+		
+	i=InStr(Text,MsgEnd);
+	if(i==-1)				//Incomplete message
+	{
+		PartMsg$=Text;
+	}
+	else
+	{
+		M=PartMsg$Left(Text,i+1);
+		PartMsg=Mid(Text,i+1);
+		ReceivedLine(M);
+	}
+}
+
+//convert the byte array to a string (SEND, CLOSE or ERR)
+function string getCommand(byte B[5])
+{
+	if(B[0]==83 && B[1]==69 && B[2]==78 && B[3]==68 && B[4]==32)
+	{
+		return "SEND";
+	}
+	else if(B[0]==67 && B[1]==76 && B[2]==79 && B[3]==83 && B[4]==69)
+	{
+		return "CLOSE";
+	}
+	else
+	{
+		return "ERR";
+	}
+}
+
+//If you recieve a binary message
+event ReceivedBinary( int Count, byte B[255] )
+{
+	local int ctr;
+	local string m;
+	ctr=0;
+	
+	if(bDebug)
+	{
+		m="";
+		while(ctr<Count)
+		{
+			m=m$string(B[ctr]);
+			ctr++;
+		}
+		ctr=0;
+		log("ComLink: Recived "$m);
+	}
+	
+	while(ctr<Count)
+	{
+		//The command part of the message
+		if(mProc<5)
+		{
+			C[mProc]=B[ctr];
+			ctr++;
+			mProc++;
+		}
+		//If the command part has just been processed
+		if(mProc==5)
+		{
+			Com=getCommand(C);
+			if(bDebug) log("ComLink: command received is "$Com);
+		}
+		
+		//If the command part has been processed
+		if(mProc>=5)
+		{
+			switch(Com)
+			{
+				case "SEND": 
+					//Get the size
+					if(mLen<0)
+					{
+						while(ctr<Count)
+						{
+							if(B[ctr]==32) break;
+							sLen=sLen$string(int(B[ctr])-48);
+							ctr++;
+						}
+						if(ctr<Count)
+						{
+							mLen=int(sLen);
+							if(bDebug) log("ComLink: Message length is "$sLen$" converted to "$mLen);
+							aProc=0;
+							ctr++;
+						}
+					}
+					//Get the message
+					if(mLen>=0)
+					{
+						while(aProc<mLen && ctr<Count)
+						{
+							Msg[aProc]=B[ctr];
+							ctr++;
+							aProc++;
+							//If the message buffer is full
+							if(aProc==255)
+							{
+								//Process message
+								if(bDebug) log("ComLink: message of size "$aProc$" being sent");
+								ComConnection(Owner).processMessage(Com,aProc,Msg,id);
+								mLen=mLen-aProc;
+								aProc=0;
+							}
+						}
+						if(ctr<Count)
+						{
+							if(bDebug) log("ComLink: message of size "$aProc$" being sent");
+							ComConnection(Owner).processMessage(Com,aProc,Msg,id);
+							ctr++;
+							mProc=0;
+							aProc=0;
+							mLen=-1;
+							sLen="";
+							Com="None";
+						}
+					}
+					break;
+				case "CLOSE":
+				//Go to the next semicolon
+					while(ctr<Count)
+					{
+						if(B[ctr]==59) break;
+						ctr++;
+						mProc++;
+					}
+					//If this is the semi colon
+					if(ctr<Count)
+					{
+						//Process message
+						ComConnection(Owner).processMessage(Com,0,B,id);
+						ctr++;
+						mProc=0;
+						Com="None";
+					}
+					break;
+				case "ERR":
+				//Go to the next semicolon
+					while(B[ctr]!=59 && ctr<Count)
+					{
+						ctr++;
+						mProc++;
+					}
+					//If this is the semi colon
+					if(ctr<Count)
+					{
+						//Process message
+						
+						//ComConnection(Owner).processMessage(Com,0,B,id);
+						ctr++;
+						mProc=0;
+						Com="None";
+					}
+					break;
+			}
+		}
+	}	
+		
+		/*
+		//If the command type is SEND the get the message into the byte array
+		if(Com=="SEND" && B[ctr]!=59 && mProc>4)
+		{
+			Msg[aProc]=B[ctr];
+			aProc=aProc+1;
+		}
+		
+		//if the message buffer is full
+		if(Com=="SEND" && aProc==255)
+		{
+			ComConnection(Owner).processMessage(Com,aProc,Msg,id);
+			aProc=0;
+		}
+	
+		mProc=mProc+1;
+		bNewMsg=false;
+		//End of message
+		if(Com!="SEND" && B[ctr]==59)
+		{
+			//Process message
+			if(bInit)
+				ComConnection(Owner).processMessage(Com,0,Msg,id);
+			//Reset counters
+			mLen=0;
+			mProc=0;
+			aProc=0;
+			bNewMsg=true;
+			Com="NONE";
+		}
+		if(Com=="SEND" && B[ctr]==59 && mProc>=mLen)
+		{
+			//Process message
+			if(bInit)
+				ComConnection(Owner).processMessage(Com,aProc,Msg,id);
+			//Reset counters
+			mLen=0;
+			mProc=0;
+			aProc=0;
+			bNewMsg=true;
+			Com="NONE";
+		}
+		ctr=ctr+1;
+	}
+	*/
+}
+
+//Should never be called
+function processMessage(string Msg, string id)
+{
+	if (bDebug)
+		log("ComLink "$id$" - Incorrect owner");
+}
+
+//Closed on other end
+event Closed()
+{
+	
+	//Process message
+	if(bInit)
+	{
+		if(bDebug)
+		{
+			log("ComLink: Robot "$id$" closed the connection");
+		}
+		bInit=false;
+		ComConnection(Owner).processMessage("CLOSE",0,Msg,id);
+	}
+}
+
+defaultproperties
+{
+	id=""
+	bInit=false
+	PartMsg=""
+	MsgEnd=";"
+	bDebug=true
+	RPort=""
+	bNewMsg=true
+	mLen=-1;
+	sLen="";
+	mProc=0
+	aProc=0
+	Com=""
+}
\ No newline at end of file

Added: usarsim/USARBotAPI/Classes/ComServer.uc
===================================================================
--- usarsim/USARBotAPI/Classes/ComServer.uc	                        (rev 0)
+++ usarsim/USARBotAPI/Classes/ComServer.uc	2007-05-10 15:24:00 UTC (rev 599)
@@ -0,0 +1,447 @@
+class ComServer extends TcpLink
+		config(USARComServer);
+
+
+var config int ListenPort;
+
+var string gameClass;
+var bool bBound;
+var config bool bDebug;
+
+var int ConnectionCount;
+
+var array<string> ParsedMessg;
+var string MsgSplit;
+var string MsgEnd;
+var string PartMsg;
+
+struct StrPair {
+	var string str1;
+	var string str2;
+};
+
+// The names and IP's of robots registered
+var array<StrPair> RegRobots;
+var int numReg;
+// The name and port of robots which are listening
+var array<StrPair> Listening;
+var int numListen;
+//Connections between two robots set up by the server
+var array<ComConnection> Connected;
+var int numCon;
+
+//Variables controlling the dropping of packets
+var config float ePdo;
+var config float eDo;
+var config float eN;
+var config float eCutoff;
+var config float eAttenFac;
+var config float eMaxObs;
+
+//Check if a robot is registered with the server
+function bool isRegistered(string name)
+{
+	local int i;
+	i=0;
+	while(i<numReg)
+	{
+		if(name==RegRobots[i].str1)
+		{
+			return true;
+		}
+		i++;
+	}
+	return false;
+}
+
+//Check if a robot is listening
+function bool isListening(string name)
+{
+	local int i;
+	i=0;
+	while(i<numListen)
+	{
+		if(name==Listening[i].str1)
+		{
+			return true;
+		}
+		i++;
+	}
+	return false;
+}
+
+//Check if a robot is listening at a specific port
+function bool isListening2(string name, string port)
+{
+	local int i;
+	i=0;
+	while(i<numListen)
+	{
+		if(name==Listening[i].str1 && port==Listening[i].str2)
+		{
+			return true;
+		}
+		i++;
+	}
+	return false;
+}
+
+//Get the index of the robot listening at the specific port
+function int getListenerNum(string name, string port)
+{
+	local int i;
+	i=0;
+	while(i<numListen)
+	{
+		if(name==Listening[i].str1 && port==Listening[i].str2)
+		{
+			return i;
+		}
+		i++;
+	}
+	return -1;
+}
+
+//Get the IP of the robot
+function string getRobotIP(string name)
+{
+	local int i;
+	i=0;
+	while(i<numReg)
+	{
+		if(name==RegRobots[i].str1)
+		{
+			return RegRobots[i].str2;
+		}
+		i++;
+	}
+	return "";
+}
+
+//Get the port the robot is listening at
+function string getRobotPort(string name)
+{
+	local int i;
+	i=0;
+	while(i<numListen)
+	{
+		if(name==Listening[i].str1)
+		{
+			return Listening[i].str2;
+		}
+		i++;
+	}
+	return "";
+}
+
+//Get Signal Strength
+function float getSigStrength(string r1,string r2)
+{
+	if (bDebug) log("ComServer: Cannot calculate signal strength");
+	return 1;
+}
+
+//Check for connectivity
+function bool isReachable(string r1,string r2)
+{
+	if(bDebug)
+		log("ComServer: Cannot get robot information");
+	return true;
+}
+
+function BeginPlay()
+{
+	local bool temp;
+	Super.BeginPlay();
+	LinkMode=MODE_Text;
+    if(!bBound)
+    {
+		BindPort( ListenPort );
+		if(bDebug)
+    		log("ComServer bound to port "$ListenPort);
+		temp=Listen();
+		if(temp)
+			bBound = true;
+		else
+		{
+			if(bDebug)
+				log("ComServer: Not able to listen");
+		}
+    }
+}
+
+function HandleLine(string Line,TCPLink ep)
+{
+    //Parsing the message
+	local string cmdType;
+	local int attrNum, i;
+	local bool b1,b2;
+	local float ss;
+   
+	if(bDebug)
+    	log("ComServer: Recieved Message - "$Line);
+
+	//Removing end of message delim
+	i=InStr(Line,MsgEnd);
+	if(i == -1)
+	{
+		i=Len(Line);
+		if(bDebug)
+			log("ComServer: Recieved Message does not terminate well - "$Line);
+	}
+	Line=left(Line,i);
+	
+	if(bDebug)
+		log("ComServer: After removing end of message limiter - "$Line);
+
+	//Splitting message	
+	attrNum=Split(Line,MsgSplit,ParsedMessg);
+	if(bDebug)
+		log("ComServer: Message contained "@attrNum$" words");
+	
+	cmdType=ParsedMessg[0];
+   	cmdType = Caps(cmdType);
+	
+	//Processing the command
+	switch(cmdType)
+	{
+		case "REGISTER":
+			//Checking for correct message length
+			if(attrNum!=3)
+			{
+				if(bDebug) log("ComServer: Incorrect message length in "$Line);
+				ep.SendText("Fail: Incorrect Message;");
+				break;
+			}
+			//Checking if a robot with the same name is registered
+			if(isRegistered(ParsedMessg[1]))
+			{
+				if(bDebug) log("ComServer: Robot with name "$ParsedMessg[1]$" already registerd");
+				ep.SendText("Fail: Robot with name "$ParsedMessg[1]$" already registered;");
+				break;
+			}
+			//Registering
+			RegRobots.insert(numReg,1);
+			RegRobots[numReg].str1$=ParsedMessg[1];
+			RegRobots[numReg].str2$=ParsedMessg[2];
+			if(bDebug)
+			{
+				log("ComServer: "$RegRobots[numReg].str1$" registered with IP "$RegRobots[numReg].str2);
+				log("ComServer: "$(numReg+1)$" robots registered");
+			}
+			numReg++;
+			ep.SendText("OK;");
+			break;
+		case "LISTEN":
+			//Checking for correct message length
+			if(attrNum!=3)
+			{
+				if(bDebug) log("ComServer: Incorrect message length in "$Line);
+				ep.SendText("Fail: Incorrect Message;");
+				break;
+			}
+			//Checking if the robot is registered
+			if(!isRegistered(ParsedMessg[1]))
+			{
+				if(bDebug) log("ComServer: Robot "$ParsedMessg[1]$" not registered");
+				ep.SendText("Fail: Robot "$ParsedMessg[1]$" not registered;");
+				break;
+			}
+			//Checking if a robot with the same name is listening at the same port
+			if(isListening(ParsedMessg[1]))
+			{
+				if(getRobotPort(ParsedMessg[1])==ParsedMessg[2])
+				{
+					if(bDebug) log("ComServer: Robot with name "$ParsedMessg[1]$" already listening at port "$ParsedMessg[2]);
+					ep.SendText("Fail: Robot with name "$ParsedMessg[1]$" already listening at port "$ParsedMessg[2]$";");
+					break;
+				}
+			}
+			//Adding to listening list
+			Listening.insert(numListen,1);
+			Listening[numListen].str1$=ParsedMessg[1];
+			Listening[numListen].str2$=ParsedMessg[2];
+			if(bDebug)
+			{
+				log("ComServer: "$Listening[numListen].str1$" listening at port "$Listening[numListen].str2);
+				log("ComServer: "$(numListen+1)$" robots listening");
+			}
+			numListen++;
+			ep.SendText("OK;");
+			break;
+		case "OPEN":
+			//Checking for correct message length
+			if(attrNum!=5)
+			{
+				if(bDebug) log("ComServer: Incorrect message length in "$Line);
+				ep.SendText("Fail: Incorrect Message;");
+				break;
+			}
+			//Check if host is listening on specified port
+			if(!isListening2(ParsedMessg[3],ParsedMessg[4]))
+			{
+				if(bDebug) log("ComServer: "$ParsedMessg[3]$" not listening on port "$ParsedMessg[4]);
+				ep.SendText("Fail: "$ParsedMessg[3]$" not listening on port "$ParsedMessg[4]$";");
+				break;
+			}
+			//Check for connectivity
+			if(!isReachable(ParsedMessg[1],ParsedMessg[3]))
+			{
+				if(bDebug) log("ComServer: Cannot connect to "$ParsedMessg[3]);
+				ep.SendText("Fail: Cannot connect to "$ParsedMessg[3]$";");
+				break;
+			}
+			//Try setting up the needed connections
+			Connected.insert(numCon,1);
+			Connected[numCon]=spawn(class'ComConnection',self);
+			Connected[numCon].setUp(ParsedMessg[1],ParsedMessg[3]);
+			
+			Connected[numCon].link1.Connect(getRobotIP(ParsedMessg[1]),ParsedMessg[2]);
+			Connected[numCon].link2.Connect(getRobotIP(ParsedMessg[3]),ParsedMessg[4]);
+			
+			//Checking if the connection was established
+			b1=(Connected[numCon].link1.LinkState==STATE_Connecting || Connected[numCon].link1.LinkState==STATE_Connected);
+			b2=(Connected[numCon].link2.LinkState==STATE_Connecting || Connected[numCon].link2.LinkState==STATE_Connected);
+			//If the connection was established
+			if(b1 && b2)
+			{
+				//Remove listening robot
+				i=getListenerNum(ParsedMessg[3],ParsedMessg[4]);
+				Listening.remove(i,1);
+				numListen--;
+				if(bDebug)
+				{
+					log("ComServer: "$ParsedMessg[1]$" connected to "$ParsedMessg[3]);
+					log("ComServer: "$(numCon+1)$" connections created");
+				}
+				ep.SendText("OK;");
+				numCon++;
+			}
+			else
+			{
+				Connected.remove(numCon,1);
+				if(bDebug)	log("ComServer: "$ParsedMessg[1]$" could not connect to "$ParsedMessg[3]);
+				ep.SendText("Fail: Could not establish connection;");
+			}
+			break;
+		//Command to get signal strength between two robots
+		case "GETSS":
+			//Checking for correct message length
+			if(attrNum!=3)
+			{
+				if(bDebug) log("ComServer: Incorrect message length in "$Line);
+				ep.SendText("Fail: Incorrect Message;");
+				break;
+			}
+			ss=getSigStrength(ParsedMessg[1],ParsedMessg[2]);
+			if(bDebug) log("ComServer: Signal strength between "$ParsedMessg[1]$" and "$ParsedMessg[2]$" is "$ss);
+			if (ss>0) 
+			{
+				ep.SendText("Fail: Could not calculate signal strength;");
+			}
+			else
+			{
+				ep.SendText("OK:"$ss$";");
+			}
+			break;
+		//These cases should not occur here
+		case "SEND":
+		case "CLOSE":
+		default:
+			if(bDebug) log("ComServer: Unknown message - "$Line);
+			ep.SendText("Fail: Unknown message;");
+	}
+}
+
+//If you recieve text instead of by line
+event ReceivedText( string Text )
+{
+	local int i;
+	local string Msg;
+	
+	i=0;
+    if(bDebug)
+    	log("ComServer: Recieved Text in Server - "$Text);
+		
+	i=InStr(Text,MsgEnd);
+	if(i==-1)				//Incomplete message
+	{
+		PartMsg$=Text;		//Concatenate
+	}
+	else
+	{
+		Msg=PartMsg$Left(Text,i+1);
+		PartMsg=Mid(Text,i+1);
+		HandleLine(Msg,Self);
+	}
+}
+
+//If you recieve a binary message
+event ReceivedBinary( int Count, byte B[255] )
+{
+	if(bDebug)
+		log("ComServer: Recieved some binary message (should not occur)");
+}
+
+//Whena connection is accepted
+event Accepted()
+{
+	if(bDebug)
+		log("ComServer: Connected to "$IpAddrToString(RemoteAddr));
+}
+
+//Closed on other end
+event Closed()
+{
+	local bool temp;
+	if(LinkState!=STATE_Listening && LinkState!=STATE_Connecting && LinkState!=STATE_Connected)
+	{
+		temp=Listen();
+	}
+	if(bDebug)
+	{
+		log(temp);
+		log(LinkState);
+		log("ComServer: Old connection closed, listening for new connections");
+	}
+}
+
+//called everytime a new botconnection is spawned
+event GainedChild( Actor C )
+{
+	local ComServerCon con;
+	con=ComServerCon(C);
+	con.MessageHandler=Self;
+	con.bInit=true;
+	if (bDebug) log("ComServer: New connection Initialized");
+}
+
+event LostChild( Actor C )
+{
+	local ComServerCon con;
+	con=ComServerCon(C);
+	con.MessageHandler=None;
+	con.bInit=false;
+	if (bDebug) log("ComServer: Old connection de-initialized");
+}
+
+defaultproperties
+{
+	AcceptClass=USARBotApi.ComServerCon
+     ListenPort=5874
+	 bBound=false
+	 bDebug=true
+	 ConnectionCount=0
+	 MsgSplit=" "
+	 MsgEnd=";"
+	 numReg=0
+	 numListen=0
+	 numCon=0
+	 PartMsg=""
+	 ePdo=-49.67
+	 eDo=2
+	 eN=1.09
+	 eCutoff=-93
+	 eAttenFac=6.625
+	 eMaxObs=5
+}

Added: usarsim/USARBotAPI/Classes/ComServerCon.uc
===================================================================
--- usarsim/USARBotAPI/Classes/ComServerCon.uc	                        (rev 0)
+++ usarsim/USARBotAPI/Classes/ComServerCon.uc	2007-05-10 15:24:00 UTC (rev 599)
@@ -0,0 +1,70 @@
+class ComServerCon extends TcpLink;
+
+var bool bInit;
+var ComServer MessageHandler;
+var config bool bDebug;
+var string MsgEnd;
+var string PartMsg;
+
+
+event ReceivedLine( string Line )
+{
+	if(bInit==False)
+	{
+		if (bDebug) log("ComServerCon: Not initialized");
+	}
+	else
+	{
+		if(MessageHandler==None)
+		{
+			if (bDebug) log("ComServerCon: No message handler");
+		}
+		else
+		{
+			MessageHandler.HandleLine(Line,Self);
+		}
+	}
+}
+
+event ReceivedText( string Text )
+{
+	local int i;
+	local string Msg;
+	if(bInit==false)
+	{
+		if(bDebug) log("ComServerCon: Not Initialized");
+	}
+	else
+	{
+		i=0;
+		if(bDebug)
+			log("ComServerCon: Recieved Text in Server - "$Text);
+		
+		i=InStr(Text,MsgEnd);
+		if(i==-1)				//Incomplete message
+		{
+			PartMsg$=Text;		//Concatenate
+		}
+		else
+		{
+			Msg=PartMsg$Left(Text,i+1);
+			PartMsg=Mid(Text,i+1);
+			if(MessageHandler==None)
+			{
+				if (bDebug) log("ComServerCon: No message handler");
+			}
+			else
+			{
+				MessageHandler.HandleLine(Msg,Self);
+			}
+		}
+	}
+}
+
+defaultproperties
+{
+	bInit=false
+	MessageHandler=None
+	bDebug=true
+	MsgEnd=";"
+}
\ No newline at end of file

Added: usarsim/USARBotAPI/Classes/DeadReckoning.uc
===================================================================
--- usarsim/USARBotAPI/Classes/DeadReckoning.uc	                        (rev 0)
+++ usarsim/USARBotAPI/Classes/DeadReckoning.uc	2007-05-10 15:24:00 UTC (rev 599)
@@ -0,0 +1,343 @@
+//=============================================================================
+// Dead Reckoning.
+//=============================================================================
+class DeadReckoning extends Object config(USARBotAPI);
+
+//-----------------------------------------------------------------------------
+// Structurs.
+
+struct DRMovement {
+	var float DR_T;
+	
+	var vector DR_P;
+	var vector DR_V;
+	var vector DR_A;
+
+	var rotator DR_RP;
+	var rotator DR_RV;
+	var rotator DR_RA;
+};
+
+struct Inf {
+	var rotator RotationRate;
+	var bool bRotateToDesired;
+	var bool bRollToDesired;
+	//var bool bCarriedItem;
+	var float NetPriority;
+};
+
+//-----------------------------------------------------------------------------
+// Variables.
+var DRMovement start;
+var DRMovement current;
+var DRMovement cache;
+var float deltatime;
+var Inf oldInf;
+var bool bRunning;
+var bool bLFilter;
+var bool bRFilter;
+var Pawn owner;
+
+var config int PreK;
+var config int MaxErr;
+
+var bool bNewBase;
+var bool bLocked;
+var bool bAutoTurn;
+
+//-----------------------------------------------------------------------------
+// Functions.
+
+function Save(Pawn owner) {
+	oldInf.RotationRate = owner.RotationRate;
+	oldInf.bRotateToDesired = owner.bRotateToDesired;
+	oldInf.bRollToDesired = owner.bRollToDesired;
+	//oldInf.bCarriedItem = owner.bCarriedItem;
+	oldInf.NetPriority = owner.NetPriority;
+}
+
+function Restore(Pawn owner) {
+	owner.RotationRate = oldInf.RotationRate;
+	owner.bRotateToDesired = oldInf.bRotateToDesired;
+	owner.bRollToDesired = oldInf.bRollToDesired;
+	//owner.bCarriedItem = oldInf.bCarriedItem;
+	owner.NetPriority = oldInf.NetPriority;
+}
+
+function SetT(float time) {
+	CurL(time);
+	CurR(time);
+
+	current.DR_P = owner.Location;
+	start.DR_P = current.DR_P;
+	start.DR_V = current.DR_V;
+	start.DR_A = current.DR_A;
+	current.DR_RP = owner.Rotation;
+	start.DR_RP = current.DR_RP;
+	start.DR_RV = current.DR_RV;
+	start.DR_RA = current.DR_RA;
+	start.DR_T = time;
+	bNewBase=true;
+	bLocked=false;
+	if (current.DR_RV.Pitch==0 && current.DR_RV.Yaw==0 && current.DR_RV.Roll==0 &&
+		current.DR_RA.Pitch==0 && current.DR_RA.Yaw==0 && current.DR_RA.Roll==0)
+		bAutoTurn=true;
+	//if(oldInf.NetPriority>0) owner.NetPriority = oldInf.NetPriority;
+}
+
+function SetDT(float dt) {
+	deltatime = dt;
+	//current.DR_V = current.DR_V + current.DR_A * dt * 0.5; // init
+	//current.DR_RV = current.DR_RV + current.DR_RA * dt * 0.5; // init
+}
+
+function SetLP(vector p) {
+	start.DR_P = p;
+	current.DR_P = p;	
+	bLFilter = true;
+}
+
+function SetLV(vector v) {
+	start.DR_V = v;
+	current.DR_V = v;	
+}
+
+function SetLA(vector a) {
+	start.DR_A = a;
+	current.DR_A = a;	
+}
+
+function SetRP(rotator p) {
+	start.DR_RP = p;
+	current.DR_RP = p;	
+	bRFilter = false;
+	bAutoTurn=false;
+	//bRFilter = true;
+}
+
+function SetRV(rotator v) {
+	start.DR_RV = v;
+	current.DR_RV = v;	
+	bAutoTurn=false;
+}
+
+function SetRA(rotator a) {
+	start.DR_RA = a;
+	current.DR_RA = a;	
+	bAutoTurn=false;
+}
+
+function SetL(vector p, vector v, vector a) {
+	start.DR_P = p;
+	start.DR_V = v;
+	start.DR_A = a;
+	current.DR_P = p;
+	current.DR_V = v;
+	current.DR_A = a;
+}
+
+function SetR(rotator p, rotator v, rotator a) {
+	start.DR_RP = p;
+	start.DR_RV = v;
+	start.DR_RA = a;
+	current.DR_RP = p;
+	current.DR_RV = v;
+	current.DR_RA = a;
+}
+
+function bool setCache() {
+	if (!bLocked) {
+		cache.DR_P = current.DR_P;
+		cache.DR_V = current.DR_V;
+		cache.DR_A = current.DR_A;
+		return true;
+	}
+	return false;
+}
+
+function bool Recover() {
+	if (!bLocked) {
+		current.DR_V = cache.DR_V;
+		current.DR_A = cache.DR_A;
+		return true;
+	}
+	return false;
+}
+
+function Locked() {
+	bLocked=true;
+}
+
+function UnLocked() {
+	bLocked=false;
+}
+
+function bool isLocked() {
+	return bLocked;
+}
+
+function NewBase(bool b) {
+	bNewBase=b;
+}
+
+function bool isNewBase() {
+	return bNewBase;
+}
+
+function CurL(float t) {
+	local float dt,tmp;
+	dt = t - start.DR_T;
+	tmp = dt*dt*0.5;
+	current.DR_P = start.DR_P + start.DR_V * dt + start.DR_A * tmp;
+	current.DR_V = start.DR_V + start.DR_A * dt;
+}
+
+function CurR(float t) {
+	local float dt,tmp;
+	dt = t - start.DR_T;
+	tmp = dt*dt*0.5;
+	current.DR_RP = start.DR_RP + start.DR_RV * dt + start.DR_RA * tmp;
+	current.DR_RV = start.DR_RV + start.DR_RA * dt;
+}
+
+function vector PreLP(float t) {
+	local float dt,tmp;
+	dt = t - start.DR_T;
+	tmp = dt*dt*0.5;
+	return (start.DR_P + start.DR_V * dt + start.DR_A * tmp);
+}
+
+function rotator PreRP(float t) {
+	local float dt,tmp;
+	dt = t - start.DR_T;
+	tmp = dt*dt*0.5;
+	return (start.DR_RP + start.DR_RV * dt + start.DR_RA * tmp);
+}
+
+function GetL( ) {
+	current.DR_V = current.DR_V + current.DR_A * deltatime;
+	current.DR_P = current.DR_P + current.DR_V * deltatime;
+}
+
+function GetR( ) {
+	current.DR_RV = current.DR_RV + current.DR_RA * deltatime;
+	current.DR_RP = current.DR_RP + current.DR_RV * deltatime;
+}
+
+function vector FGetL( ) {
+	local int i;
+	local vector v,p;
+	
+	if (current.DR_V.x==0 && current.DR_V.y==0 && current.DR_V.z==0 &&
+	    current.DR_A.x==0 && current.DR_A.y==0 && current.DR_A.z==0 ) // This means we need to forcely relocate a bot
+		return current.DR_P;
+		
+	GetL();
+	v = current.DR_V;
+	p = current.DR_P;
+	for (i=1;i<PreK;i++) {
+		v += current.DR_A * deltatime;
+		p += v * deltatime;
+	}
+	return (p-owner.Location)/PreK+owner.Location;
+}
+
+function rotator FGetR( ) {
+	local int i;
+	local rotator rv,rp;
+
+	if (current.DR_RV.pitch==0 && current.DR_RV.yaw==0 && current.DR_RV.roll==0 &&
+	    current.DR_RA.pitch==0 && current.DR_RA.yaw==0 && current.DR_RA.roll==0 ) // This means we need to forcely relocate a bot
+		return current.DR_RP;
+
+	GetR();
+	rv = current.DR_RV;
+	rp = current.DR_RP;
+	for (i=1;i<PreK;i++) {
+		rv += current.DR_RA * deltatime;
+		rp += rv * deltatime;
+	}
+	return (rp-owner.Rotation)/PreK+owner.Rotation;
+}
+
+
+function bool Step(float dt) {
+	log("Step()");
+	if (bRunning) {
+		deltatime = dt;
+		GetR();
+		owner.RotationRate=rot(0,0,0);
+		owner.DesiredRotation = current.DR_RP;
+		owner.SetRotation(current.DR_RP);
+		GetL();
+		return owner.SetLocation(current.DR_P);
+	}
+}
+
+function bool IsRunning() {
+//	log("DeadReckoning running:"$bRunning$" rp("$current.DR_RP$") rv("$current.DR_RV$") ra("$current.DR_RA$") p("$current.DR_P$") v("$current.DR_V$") a("$current.DR_A$")");
+	return bRunning;
+}
+
+function init(Pawn act) {
+	owner = act;
+	SetL(act.Location,act.Velocity,act.Acceleration);
+	SetRP(act.Rotation);
+}
+
+function Stop() {
+	bRunning = false;
+	bLFilter = false;
+	bRFilter = false;
+	// Reset all the args.
+	SetL(owner.Location,vect(0,0,0),vect(0,0,0));
+	SetR(owner.Rotation,rot(0,0,0),rot(0,0,0));
+	Restore(owner);
+}
+
+function Begin() {
+	bRunning = true;
+	bAutoTurn=true;
+	Save(owner);
+	owner.RotationRate=rot(0,0,0);
+	owner.bRotateToDesired=true;
+	owner.bRollToDesired=true;
+	//owner.NetPriority=2.0; // Because we can control remotebot from client, we set the NetPriority lower.
+	owner.bCollideWorld=true; // Should I set this?
+	// Hack 10JAN03
+	//owner.bCarriedItem = true; // Disable replicate Location and Rotation between S/C
+		/*
+		Region.Zone.ZoneGravity.z=0;
+		Region.Zone.ZoneGroundFriction=0;
+		Region.Zone.ZoneFluidFriction=0;
+		AirControl = 0;
+		*/
+}
+
+function bool Correct(float time) {
+	local rotator dr;
+	CurR(time);
+	dr = owner.Rotation-current.DR_RP;
+	if (bRFilter&& (dr.pitch*dr.pitch+dr.yaw*dr.yaw+dr.roll*dr.roll)<MaxErr*MaxErr*10000) {
+		bRFilter=false;
+		owner.RotationRate=rot(0,0,0);
+		owner.DesiredRotation = current.DR_RP;
+		owner.SetRotation(current.DR_RP);
+	}
+
+	CurL(time);
+	if (bLFilter&&VSize(owner.Location-current.DR_P)<MaxErr) {
+		bLFilter=false;
+		owner.SetLocation(current.DR_P);
+	}
+
+	if (VSize(owner.Location-current.DR_P)>1) return false;
+	//bRunning=true;
+	return true;
+}
+
+defaultproperties
+{
+     PreK=15
+     MaxErr=20
+}

Added: usarsim/USARBotAPI/Classes/GPSStart.uc
===================================================================
--- usarsim/USARBotAPI/Classes/GPSStart.uc	                        (rev 0)
+++ usarsim/USARBotAPI/Classes/GPSStart.uc	2007-05-10 15:24:00 UTC (rev 599)
@@ -0,0 +1,30 @@
+//=============================================================================
+// GPSStart
+//=============================================================================
+// this is not yet functional;
+// TCF 12/14/06
+
+class GPSStart extends Actor;
+
+// Lat and Longitude of the origin in microdegrees
+var(GPS) int LatitudeOrigin;
+var(GPS) int LongitudeOrigin;
+var(GPS) int MetersPerDegreeLat;
+var(GPS) int MetersPerDegreeLon;
+var(GPS) float GPSavailability;  // 1.0=always; 0=never
+var(GPS) int MeanDropOutTime;  //  seconds
+var(GPS) string RNDFfile;
+var(GPS) string MDFfile;
+
+defaultproperties
+{
+     LatitudeOrigin=38872104  // 38.872104 degrees North
+     LongitudeOrigin=-77202840 // 77.20284 degrees West
+     MetersPerDegreeLat=111000
+     MetersPerDegreeLon=87822
+     RNDFfile="Sample_RNDF.txt"
+     MDFfile="Sample_MDF.txt"
+     GPSavailability = 0.1
+     MeanDropOutTime=60
+}
+


Property changes on: usarsim/USARBotAPI/Classes/GPSStart.uc
___________________________________________________________________
Name: svn:executable
   + 

Added: usarsim/USARBotAPI/Classes/MyInteraction.uc
===================================================================
--- usarsim/USARBotAPI/Classes/MyInteraction.uc	                        (rev 0)
+++ usarsim/USARBotAPI/Classes/MyInteraction.uc	2007-05-10 15:24:00 UTC (rev 599)
@@ -0,0 +1,120 @@
+class MyInteraction extends Interaction;
+
+var bool bDrawEnemy;
+var bool bDrawFriendly;
+var bool bControlPawn;
+var PlayerController OldController;
+var Pawn myPawn;
+
+function Initialize()
+{
+    Log("Interaction Initialized");
+}
+
+/*function bool KeyEvent(EInputKey Key, EInputAction Action, FLOAT Delta )
+{
+    log(Action);
+    if (Action == IST_Press)
+    ViewportOwner.Actor.ClientMessage("Key PRESSED:" @ Key);
+    if (Action == IST_Release)
+    ViewportOwner.Actor.ClientMessage("Key RELEASED:" @ Key);
+    if (Action == IST_Hold)
+    ViewportOwner.Actor.ClientMessage("Key HELD:" @ Key);
+    if (Action == IST_Axis)
+    ViewportOwner.Actor.ClientMessage("Key AXIS:" @ Key);
+
+    return false;
+}*/
+

@@ Diff output truncated at 60000 characters. @@


More information about the TeamTalk-developers mailing list