XIIIMP
Class BotController

source: C:\XIII\XIIIMP\Classes\BotController.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Controller
         |
         +--Engine.AIController
            |
            +--XIIIMP.BotController
Direct Known Subclasses:CatchableDuckBotController, DuckBotController, SabotageBotController, TeamBotController

class BotController
extends Engine.AIController

//----------------------------------------------------------- // //-----------------------------------------------------------
Variables
 TimePassedBeforeSeeingMyEnemy
           Use For Team Game
 Array ArmorList
 int AttackArea
 bool CloseCombat
           Use For Team Game
 Order CurrentOrder
 int ExcludeIds
 WaitBeforeFire, ForceFear
           Use For Team Game
 array FullPickUpList
 GameReplicationInfo GRI
 bool GrenadIsLauched
           Use For Team Game
 int HeadShotModificator
 FearActor, HidePoint
 RespawnTime, InitialShotError
 Actor Item
 JumpHeight, JumpSpeed
 , KillOrderPriority
 float LastAdjustAimTime
           Use For Team Game
 , LastDefaultOrderTime
 float LastDistCheckTime
           Use For Team Game
 vector LastEnemyPos
           Use For Team Game
 bool MarioMode
 float MaxDistModificator
 int MaxSeekDist_Life,MaxSeekDist_Weapon,MaxSeekDist_Armor
 , MaxSnipeTime
 Array MedKitList
 float MissPercent,StraffeDelay
 GrenadPathNode MyGrenadTarget
           Use For Team Game
 string MyName
 NavigationPoint NavToUpDate
           Use For Team Game
 LastStraffeDir, NbStraffe
           Use For Team Game
 vector NextPosition
 Array OrderList
 Actor PathCache[16]
 PathErrorToAllWeapon, PathErrorToAllLife
 , PathIndex
 int Priority
 bool ReloadableWeapon
 Array SnipeSpotList
 MyWeaponIsAGrenad, Sniping
 float StraffeValue
           Use For Team Game
 int TeamID
           Use For Team Game
 int TeamRole
           Use For Team Game
 , TrakNarPoint
 Array TrakNarSpotList
 int TypeId
 string TypeName
 array UseableWatchPointList
           Use For Team Game
 array WatchPointList
           Use For Team Game
 Array WeaponList
 bool bBackMove
           Use For Team Game
 , bFireMove
 , bIsJumping

States
GrenadLauncher, GameEnded, TrakNar, UnBlock, SnipeAndKill, SnipeSpot, Blind, Jumping, Dead, Seek, Kill, Armor, Life, Fear, Weapon

Function Summary
 void ActorPathStorage(Actor Target)
     
//__________________________________________________________________
 void AddOrder(int Priority, int TypeId, optional string, optional int)
 rotator AdjustAim(Ammunition FiredAmmunition, vector projStart, int aimerror)
     
//__________________________________________________________________
 int CalcPathWeight()
     
//FRD FindPathToward with height and radius tolerance
 bool CheckPath()
     
//__________________________________________________________________
 bool CheckThePowerOfTheEnemy(Pawn Other)
     
//__________________________________________________________________
 void ClearAllOrders()
 void ClientGameEnded()
     
//__________________________________________________________________
 void ExcludeOrders(int ExcludeIds)
 Actor ExtendFindPathToward(Actor Desired, optional float, optional float)
     
//__________________________________________________________________
//__________________________________________________________________
// native
//__________________________________________________________________
//__________________________________________________________________
 void FindAllNearestWatchPoint(Pawn CenterActor)
 void FindBestArmor()
 void FindBestWeapon()
 void FindMedKit()
 void FindMostImportantOrder()
 void FindNearestArmor()
 void FindNearestWeapon()
 bool FindOrder(int IdToFind)
     
// Calc the full path dist between Pawn and Target
 void Flashed()
     
//__________________________________________________________________
 int GetDistToMyTarget()
     
//__________________________________________________________________
 int GetLifePriority()
     
//__________________________________________________________________
 bool GetNumberOfEnemyInTheGrenadArea(BotGrenadTarget Target)
     
//__________________________________________________________________
 void GetRandomLocation()
     
//__________________________________________________________________
 void GrenadPossibility(GrenadPathNode GrenadNode)
     
//__________________________________________________________________
 void InitBotJump(int V, int H, NavigationPoint T)
     
//__________________________________________________________________
 void InitPickUpList()
     
//__________________________________________________________________
 void InitShotError(bool ReduceError)
     
//__________________________________________________________________
 void InitSnipe()
     
//__________________________________________________________________
 void InitWeaponParam()
     
//__________________________________________________________________
 void Initialize(int BotID, int BotLevel, string BotName)
     
//__________________________________________________________________
 bool IsEnemy(Pawn Target)
     
//__________________________________________________________________
 bool IsInAttackArea(Actor Enemy)
 bool IsNearest(Actor Enemy1, Actor Enemy2)
 bool IsShootable(Pawn ShootTarget)
     
//__________________________________________________________________
 bool MissTheShoot()
     
//__________________________________________________________________
 void ModifyOrder(int IdToModify, int NewPriority)
 void NavPathStorage(NavigationPoint NavPoint)
     
//__________________________________________________________________
 void PawnDied()
     
//__________________________________________________________________
 void PickUpPathStorage(Actor Target)
     
//__________________________________________________________________
 void RemoveOrder(int IdToKill)
 void SearchHidePoint()
 void SomeoneWantKillMe(Pawn Agressor)
     
//__________________________________________________________________
 void StopMvtWhenMayFall()
 void SwitchWeapon()
     
//__________________________________________________________________
 void TestCloseCombat()
     
//__________________________________________________________________
 void TryToChangePath(NavigationPoint NavToUpDate)
     
//__________________________________________________________________
 void UpDateOrder(int OldOrder, int NewOrder)
     
//__________________________________________________________________
//__________________________________________________________________
// List of Orders Manadgment
//__________________________________________________________________
//__________________________________________________________________


State GrenadLauncher Function Summary
 void SomeoneWantKillMe(Pawn Agressor)
     
//--------------------------------------------------------------


State GameEnded Function Summary
 void SomeoneWantKillMe(Pawn Agressor)


State TrakNar Function Summary
 void FindGoodTrakNarSpot()


State UnBlock Function Summary
 void GetRandomUnblockPoint()
     
//--------------------------------------------------------------


State SnipeAndKill Function Summary
 void SomeoneWantKillMe(Pawn Agressor)
 rotator AdjustAim(Ammunition FiredAmmunition, vector projStart, int aimerror)


State SnipeSpot Function Summary
 void FindGoodSnipeSpot()
 void SomeoneWantKillMe(Pawn Agressor)


State Blind Function Summary
 void SomeoneWantKillMe(Pawn Agressor)
 rotator AdjustAim(Ammunition FiredAmmunition, vector projStart, int aimerror)


State Jumping Function Summary
 void SomeoneWantKillMe(Pawn Agressor)


State Dead Function Summary
 bool CheckGameEnded()
 void SomeoneWantKillMe(Pawn Agressor)


State Seek Function Summary
 void FindPathToMyEnemy()
 void SomeoneWantKillMe(Pawn Agressor)


State Kill Function Summary
 int CheckBackMove()
     
//--------------------------------------------------------------
 int CheckStraffe(int Direction)
     
//--------------------------------------------------------------


State Armor Function Summary


State Life Function Summary
 bool ForceAttack(Pawn Other)
 void SomeoneWantKillMe(Pawn Agressor)


State Fear Function Summary
 void SomeoneWantKillMe(Pawn Agressor)


State Weapon Function Summary
 void SomeoneWantKillMe(Pawn Agressor)



Source Code


00001	//-----------------------------------------------------------
00002	//
00003	//-----------------------------------------------------------
00004	class BotController extends AIController native;
00005	
00006	struct Order
00007	{
00008	    var int Priority;
00009	    var int TypeId;
00010	    var string TypeName;
00011	    var int ExcludeIds;
00012	};
00013	
00014	var int ID, OrderNumber , KillOrderPriority;
00015	var Array<Order> OrderList;
00016	var Order CurrentOrder;
00017	var bool DBugBot, DBugWarning ,DBugOrder, FirstWeaponPickUp , bInitPickUpList , bIsJumping;
00018	var actor Item;
00019	var float MoveSpeed , MaxMoveSpeed , ShotErrorTime, MaxShotErrorTime, SeekTime , MaxSeekTime ,SnipeTime , MaxSnipeTime;
00020	var int RespawnTime, InitialShotError;
00021	var string MyName;
00022	var actor FearActor, HidePoint;
00023	var Array<actor> MedKitList;
00024	var Array<actor> WeaponList;
00025	var Array<actor> ArmorList;
00026	var Array<NavigationPoint> SnipeSpotList;
00027	var Array<NavigationPoint> TrakNarSpotList;
00028	var array<actor> FullPickUpList;
00029	var int JumpHeight, JumpSpeed;
00030	var NavigationPoint JumpTarget, SnipePoint , TrakNarPoint;
00031	var bool PathErrorToAllArmor, PathErrorToAllWeapon, PathErrorToAllLife;
00032	var bool DamnedImFlashed, MyWeaponIsAGrenad, Sniping;
00033	var int HeadShotModificator;
00034	var bool ReloadableWeapon;
00035	var int MaxSeekDist_Life,MaxSeekDist_Weapon,MaxSeekDist_Armor;
00036	var float MaxDistModificator;
00037	var float AimTime , LastDefaultOrderTime;
00038	var Actor PathCache[16];
00039	var int PathCacheSize , PathIndex;
00040	var bool FullPath , bFireMove;
00041	var GameReplicationInfo GRI;
00042	var vector NextPosition;
00043	var bool MarioMode;
00044	var int AttackArea;
00045	var float MissPercent,StraffeDelay;
00046	var int TeamRole; // Use For Team Game
00047	//CTF --> 0:Attacker,1:Defender;2:Support( Mixte )
00048	//BOMB --> ID of BombPoint To defend/Attack
00049	var bool WaitBeforeFire, ForceFear;
00050	var float LastAdjustAimTime;
00051	var vector LastEnemyPos;
00052	var int LastStraffeDir, NbStraffe;
00053	var float StraffeValue;
00054	var GrenadPathNode MyGrenadTarget;
00055	var bool GrenadIsLauched;
00056	var float LastDistCheckTime;
00057	var bool CloseCombat;
00058	var bool bBackMove;
00059	var navigationPoint NavToUpDate;
00060	var array<XIIIMPWatchPoint> WatchPointList;
00061	var array<XIIIMPWatchPoint> UseableWatchPointList;
00062	var int TeamID;
00063	var float TimePassedBeforeSeeingMyEnemy ;
00064	
00065	const Order_Weapon        = 1;
00066	const Order_Life          = 2;
00067	const Order_Armor         = 4;
00068	const Order_Kill          = 8;
00069	const Order_Fear          = 16;
00070	const Order_SnipeSpot     = 32;
00071	const Order_SnipeAndKill  = 64;
00072	const Order_Seek          = 128;
00073	const Order_Unblock       = 256;
00074	const Order_TrakNar       = 65536;
00075	const Order_GrenadLauncher= 1073741824;//30
00076	
00077	
00078	//__________________________________________________________________
00079	//__________________________________________________________________
00080	// native
00081	//__________________________________________________________________
00082	//__________________________________________________________________
00083	
00084	native static final function actor ExtendFindPathToward(actor Desired,optional float xyMargin,optional float heightMargin); //FRD FindPathToward with height and radius tolerance
00085	native(639) static final function int CalcPathWeight(); // Calc the full path dist between Pawn and Target
00086	native(638) static final function bool FindOrder( int IdToFind );
00087	native(637) static final function FindMostImportantOrder();
00088	native(636) static final function RemoveOrder( int IdToKill );
00089	native(635) static final function ExcludeOrders( int ExcludeIds );
00090	native(634) static final function AddOrder( int Priority , int TypeId , optional string TypeName , optional int ExcludeIds  );
00091	native(633) static final function ModifyOrder( int IdToModify , int NewPriority );
00092	native(632) static final function SearchHidePoint();
00093	native(631) static final function FindMedKit();
00094	native(630) static final function FindNearestArmor();
00095	native(629) static final function FindBestArmor();
00096	native(628) static final function FindNearestWeapon();
00097	native(627) static final function FindBestWeapon();
00098	native(626) static final function bool IsNearest( Actor Enemy1, Actor Enemy2);
00099	native(625) static final function bool IsInAttackArea( Actor Enemy );
00100	native function ClearAllOrders();
00101	native function StopMvtWhenMayFall();
00102	native function FindAllNearestWatchPoint(Pawn CenterActor);
00103	
00104	//__________________________________________________________________
00105	//__________________________________________________________________
00106	// List of Orders Manadgment
00107	//__________________________________________________________________
00108	//__________________________________________________________________
00109	
00110	function UpDateOrder(int OldOrder,int NewOrder)
00111	{
00112	    TeamRole = NewOrder;
00113	}
00114	
00115	//__________________________________________________________________
00116	
00117	function ClientGameEnded()
00118	{
00119	    gotostate('GameEnded');
00120	}
00121	
00122	//__________________________________________________________________
00123	
00124	function int GetDistToMyTarget()
00125	{
00126	    local int Loop;
00127	    local float DistToTheItem;
00128	
00129	    if( ! FullPath )
00130	         return 10000000;
00131	
00132	    for( Loop = PathIndex; Loop < PathCacheSize ; Loop ++ )
00133	    {
00134	        if( Loop == PathIndex )
00135	            DistToTheItem += VSize( Pawn.Location - PathCache[ Loop ].Location );
00136	        else
00137	            DistToTheItem += VSize( PathCache[ Loop-1 ].Location - PathCache[ Loop ].Location );
00138	    }
00139	
00140	    return int( DistToTheItem );
00141	}
00142	
00143	//__________________________________________________________________
00144	
00145	event LogOrderList()
00146	{
00147	    local int index;
00148	    local Order MyOrder;
00149	
00150	    Log("");
00151	    Log("[ BOT"@ID@"] : Order("$OrderNumber$")");
00152	
00153	    if( OrderNumber == 0 )
00154	        return;
00155	
00156	    for( index = 0; index < OrderNumber; index++ )
00157	    {
00158	        MyOrder = OrderList[ index ];
00159	        Log("    > Order("@MyOrder.TypeName@") --->"@MyOrder.Priority);
00160	    }
00161	}
00162	
00163	//__________________________________________________________________
00164	
00165	event AddDefaultOrders()
00166	{
00167	    if( ( Level.TimeSeconds - LastDefaultOrderTime < 2.0 ) && ( LastDefaultOrderTime != 0) )
00168	    {
00169			 if( ( DBugBot ) || ( DBugWarning ) )
00170				Log("[ WARNING ][ ORDER ][ BOT"@ID@"] : Runaway Loop !...");
00171	
00172	        AddOrder(79,Order_UnBlock,"UnBlock",0);
00173	    }
00174	    else
00175	    {
00176	        if( ! PathErrorToAllLife )
00177	            AddOrder(GetLifePriority(),Order_Life,"Life",0);
00178	
00179	        if( ! PathErrorToAllWeapon )
00180	            AddOrder(60,Order_Weapon,"Weapon",0);
00181	
00182	        if( ! PathErrorToAllArmor )
00183	            AddOrder(40,Order_Armor,"Armor",0);
00184	
00185	        if( TrakNarSpotList.Length > 0 )
00186	            AddOrder(30,Order_TrakNar,"TrakNar",0);
00187	    }
00188	
00189	    LastDefaultOrderTime = Level.TimeSeconds;
00190	}
00191	
00192	//__________________________________________________________________
00193	
00194	function bool CheckPath()
00195	{
00196	    local vector              HitLocation;
00197	    local vector              HitNormal;
00198	    local actor               ColActor;
00199	
00200	    ColActor=Trace( HitLocation,HitNormal,MoveTarget.Location,Pawn.Location, true);
00201	
00202	    if( ColActor == none )
00203	        return true;
00204	    else
00205	        return false;
00206	}
00207	
00208	//__________________________________________________________________
00209	
00210	function TryToChangePath(NavigationPoint NavToUpDate)
00211	{
00212	    NavToUpDate.bSpecialCost=true;
00213	
00214	    NavToUpDate.bSpecialCost=false;
00215	}
00216	
00217	//__________________________________________________________________
00218	
00219	event ChangeState()
00220	{
00221	    switch( CurrentOrder.TypeId )
00222	    {
00223	        case Order_Kill : GotoState( 'Kill' ); break;
00224	        case Order_Life : GotoState( 'Life' ); break;
00225	        case Order_Seek : GotoState( 'Seek' ); break;
00226	        case Order_Fear : gotoState( 'Fear' ); break;
00227	        case Order_Weapon : GotoState( 'Weapon' ); break;
00228	        case Order_Armor : GotoState( 'Armor' ); break;
00229	        case Order_SnipeSpot : GotoState( 'SnipeSpot' ); break;
00230	        case Order_SnipeAndKill : GotoState( 'SnipeAndKill' ); break;
00231	        case Order_UnBlock : gotoState( 'UnBlock' ); break;
00232	        case Order_TrakNar : gotoState( 'TrakNar' ); break;
00233	        case Order_GrenadLauncher : gotoState( 'GrenadLauncher' ); break;
00234	    }
00235	}
00236	
00237	//__________________________________________________________________
00238	
00239	function Initialize(int BotID, int BotLevel , string BotName )
00240	{
00241		 if (pawn==none) //FRD controller did not manage to spawn the pawn
00242		 {
00243			gotostate('dead');
00244			return;
00245		 }
00246	    MyName = BotName;
00247	    ID = BotID;
00248	    //Skill = BotLevel;
00249	    MaxMoveSpeed = 1.0;//0.9;//0.9 + BotLevel*0.5;
00250	    MoveSpeed = MaxMoveSpeed;
00251	    KillOrderPriority = 80;
00252	    MaxSeekTime = 10 - Skill;
00253	    OrderNumber = 0;
00254	    OrderList.Length = 0;
00255	
00256	    if( DBugBot )
00257	    {
00258	        Log("");
00259	        Log("[ BOT"@ID@"][ Level"@int(Skill)@"][ Team"@TeamID@"] : *INIT*");
00260	        log("    > Contoller ="@Self);
00261	        log("    > Pawn ="@Pawn);
00262	        log("    > name ="@BotName);
00263	    }
00264	
00265	    FirstWeaponPickUp = true;
00266	    DamnedImFlashed = False;
00267	    MyWeaponIsAGrenad = false;
00268	    PathErrorToAllArmor = false;
00269	    PathErrorToAllWeapon = false;
00270	    PathErrorToAllLife = false;
00271	    Sniping = false;
00272	    ReloadableWeapon = true;
00273	    LastDefaultOrderTime = 0;
00274	    Enemy = none;
00275	    FearActor = none;
00276	    HidePoint = none;
00277	    Item = none;
00278	    JumpTarget = none;
00279	    SnipePoint = none;
00280	    MoveSpeed = MaxMoveSpeed;
00281	
00282	    Pawn.SetPhysics(Phys_Walking);
00283	    Pawn.Velocity = vect(0,0,0);
00284	    Pawn.Acceleration = vect(0,0,0);
00285	
00286	    switch( XIIIGameInfo(Level.Game).Plateforme )
00287	    {
00288	        case PF_PC : MaxDistModificator = 2; break;
00289	        case PF_PS2 : MaxDistModificator = 1; break;
00290	        case PF_GC : MaxDistModificator = 1; break;
00291	        case PF_XBOX : MaxDistModificator = 1.5; break;
00292	    }
00293	
00294	    MaxDistModificator = 2;
00295	
00296	    MaxSeekDist_Life = default.MaxSeekDist_Life * MaxDistModificator;
00297	    MaxSeekDist_Weapon = default.MaxSeekDist_Weapon * MaxDistModificator;
00298	    MaxSeekDist_Armor = default.MaxSeekDist_Armor * MaxDistModificator;
00299	
00300	    Pawn.SetAnimStatus('Alert');
00301	
00302	    if( ! bInitPickUpList )
00303	        InitPickUpList();
00304	
00305	    SetTimer( 0.0,False );
00306	    SetTimer2(0.0,false);
00307	
00308		 SwitchWeapon();
00309	    AddDefaultOrders();
00310	}
00311	
00312	//__________________________________________________________________
00313	
00314	function PickUpPathStorage( actor Target)
00315	{
00316	    local int Loop;
00317	
00318	    if( NavToUpDate != none )
00319	    {
00320	        NavToUpDate.bSpecialCost=false;
00321	        NavToUpDate = none;
00322	    }
00323		 if (Vsize(Target.location-pawn.location)<400 && ActorReachable(Target))  //FRD in order to test direct and near path
00324		 {
00325			 movetarget=target;
00326			 PathCacheSize = 1;
00327			 PathCache[ 0 ] = target;
00328	       FullPath=true;
00329			 return;
00330		 }
00331	
00332	    MoveTarget = ExtendFindPathToward(Target);
00333	
00334	//    if( MoveTarget == none )
00335	//        MoveTarget = FindPathToward(Target);
00336	
00337	    PathCacheSize = 0;
00338	
00339	    for( Loop=0;Loop<16;Loop++)
00340	    {
00341	        if( RouteCache[ Loop ] == none )
00342	            break;
00343	
00344	        PathCache[ Loop ] = RouteCache[ Loop ];
00345	        PathCacheSize++;
00346	    }
00347	
00348	    FullPath = ( InventorySpot(PathCache[ PathCacheSize-1 ]) == PickUp(Target).MyMarker );
00349	}
00350	
00351	//__________________________________________________________________
00352	
00353	
00354	function NavPathStorage( NavigationPoint NavPoint )
00355	{
00356	    local int Loop;
00357	
00358		if (pawn==none || pawn.bIsDead)
00359		{
00360			 FullPath=true; //FRD to exit loop in states
00361			 return;
00362		}
00363	    if( NavToUpDate != none )
00364	    {
00365	        NavToUpDate.bSpecialCost=false;
00366	        NavToUpDate = none;
00367	    }
00368	    if (Vsize(NavPoint.location-pawn.location)<400 && ActorReachable(NavPoint))
00369	    {//FRD in order to test direct and near path
00370	        movetarget=NavPoint;
00371	        PathCacheSize = 1;
00372	        PathCache[ 0 ]=NavPoint;
00373	        FullPath=true;
00374	        return;
00375	    }
00376	
00377	    MoveTarget = ExtendFindPathToward(NavPoint);
00378	
00379	//    if( MoveTarget == none )
00380	//        MoveTarget = FindPathToward(NavPoint);
00381	
00382	    PathCacheSize = 0;
00383	
00384	//    log("");
00385	//    log("[ BOT"@ID@"] : NavPathStorage to"@NavPoint);
00386	
00387	//    if( NavToUpDate != none )
00388	//        log("NavToUpDate="@NavToUpDate);
00389	
00390	    if( ( MoveTarget == none ) && DBugWarning )
00391	        log("!!! WARNING NavPathStorage !!!");
00392	
00393	    for( Loop=0;Loop<16;Loop++)
00394	    {
00395	        if( RouteCache[ Loop ] == none )
00396	            break;
00397	
00398	//        log(" >"@Loop@":"@RouteCache[ Loop ]);
00399	
00400	        PathCache[ Loop ] = RouteCache[ Loop ];
00401	        PathCacheSize++;
00402	    }
00403	
00404	//    log("");
00405	
00406	    FullPath = ( NavigationPoint(PathCache[ PathCacheSize-1 ]) == NavPoint );
00407	}
00408	
00409	//__________________________________________________________________
00410	
00411	function ActorPathStorage( actor Target)
00412	{
00413	    local int Loop;
00414	
00415	    if( NavToUpDate != none )
00416	    {
00417	        NavToUpDate.bSpecialCost=false;
00418	        NavToUpDate = none;
00419	    }
00420		 if (Vsize(Target.location-pawn.location)<400 && ActorReachable(Target))  //FRD in order to test direct and near path
00421		 {
00422			 movetarget=target;
00423			 PathCacheSize = 1;
00424			 PathCache[ 0 ] = target;
00425	       FullPath=true;
00426			 return;
00427		 }
00428	    MoveTarget = ExtendFindPathToward( Target);
00429	
00430	//    if( MoveTarget == none )
00431	//        MoveTarget = FindPathToward(Target);
00432	
00433	    PathCacheSize = 0;
00434	
00435	    for( Loop=0;Loop<16;Loop++)
00436	    {
00437	        if( RouteCache[ Loop ] == none )
00438	            break;
00439	
00440	        PathCache[ Loop ] = RouteCache[ Loop ];
00441	        PathCacheSize++;
00442	    }
00443	
00444	    FullPath = true;
00445	}
00446	
00447	//__________________________________________________________________
00448	
00449	function int GetLifePriority()
00450	{
00451	    local float LifePriority;
00452	
00453	    LifePriority = Pawn.Health;
00454	    LifePriority /= Pawn.default.Health;
00455	    LifePriority = 100 - LifePriority*100;
00456	
00457	    if( Pawn == none )
00458	        LifePriority =1;
00459	
00460	    return int(LifePriority);
00461	}
00462	
00463	//__________________________________________________________________
00464	
00465	function GetRandomLocation()
00466	{
00467	    local int Loop;
00468	    local actor A;
00469	
00470	    Item = none;
00471	
00472	    for( Loop=Rand(FullPickUpList.Length);Loop < FullPickUpList.Length ; Loop++ )
00473	    {
00474	        A = FullPickUpList[ Loop ];
00475	
00476	        MoveTarget = ExtendFindPathToward( A);
00477	
00478	//        if( MoveTarget == none )
00479	//            MoveTarget = FindPathToward(A);
00480	
00481	
00482	        Item = A;
00483	        break;
00484	    }
00485	
00486	    Log("[ ERROR ][ PATH ][ BOT"@ID@"] : Item ="@Item@"Pawn ="@Pawn);
00487	
00488	    if( Item == none )
00489	        Log("[ ERROR ][ PATH ][ BOT"@ID@"] : All Path Failed ! ...");
00490	}
00491	
00492	//__________________________________________________________________
00493	
00494	function bool MissTheShoot()
00495	{
00496	    if( LastAdjustAimTime == -1 )
00497	    {
00498	        LastAdjustAimTime = Level.TimeSeconds;
00499	        LastEnemyPos = Enemy.Location;
00500	    }
00501	    else if( Level.TimeSeconds - LastAdjustAimTime > 1.0 )
00502	    {
00503	        LastAdjustAimTime = Level.TimeSeconds;
00504	
00505	        if( VSize( LastEnemyPos - Enemy.Location ) > 150 )
00506	        {
00507	            if( Rand( 100 ) < 30+ Skill*20 )
00508	            {
00509	                ShotErrorTime = 1.0 + Level.TimeSeconds;
00510	                InitialShotError = 200 + Rand(400);
00511	            }
00512	        }
00513	
00514	        LastEnemyPos = Enemy.Location;
00515	    }
00516	
00517	    if( ( DamnedImFlashed ) || ( Enemy.DrawType == DT_None ) )
00518	    {
00519	        InitialShotError = 3000 + Rand(6000);
00520	        return true;
00521	    }
00522	    else
00523	    {
00524	        if( Rand( 100 ) < (3.5-Skill)*MissPercent )
00525	            return true;
00526	        else
00527	            return false;
00528	    }
00529	}
00530	
00531	//__________________________________________________________________
00532	
00533	function TestCloseCombat()
00534	{
00535	    if( Level.TimeSeconds - LastDistCheckTime > 0.5 )
00536	    {
00537	        //log("time"@Level.TimeSeconds - LastDistCheckTime);
00538	
00539	        LastDistCheckTime = Level.TimeSeconds;
00540	
00541	        if( VSize( Enemy.Location - Pawn.Location ) < 300 )
00542	            CloseCombat = true;
00543	        else
00544	            CloseCombat = false;
00545	    }
00546	}
00547	
00548	
00549	//__________________________________________________________________
00550	
00551	function rotator AdjustAim(Ammunition FiredAmmunition, vector projStart, int aimerror)
00552	{
00553		local rotator RotatorError;
00554	
00555		if( Enemy == none )
00556	    	return ( Rotation );
00557	
00558	    TestCloseCombat();
00559	
00560	    if( ( MissTheShoot() ) || ( Level.TimeSeconds - ShotErrorTime < 0 ) )
00561	    {
00562	        //log("MISS");
00563	
00564	        if( Rand( 2 ) == 1 )
00565	            RotatorError.Yaw = InitialShotError;
00566	        else
00567	            RotatorError.Yaw = 65535-InitialShotError;
00568	
00569	        SetRotation( rotator(Enemy.GetBoneCoords('X Spine1').Origin-(Pawn.Location+Pawn.EyePosition()) ) );
00570	        Pawn.ControllerPitch = Rotation.Pitch / 256;
00571	    }
00572	    else
00573	    {
00574	        //log("TOUCH");
00575	
00576	        if( ( Rand( 100 ) < (Skill+1)*10 + HeadShotModificator ) || ( ( CloseCombat ) && ( Rand( 100 ) < 55 + (Skill)*15 ) ) )
00577	        {
00578	            SetRotation( rotator(Enemy.GetBoneCoords('X Head').Origin-(Pawn.Location+Pawn.EyePosition()) ) );
00579	            Pawn.ControllerPitch = Rotation.Pitch / 256;
00580	        }
00581	        else
00582	        {
00583	            SetRotation( rotator(Enemy.GetBoneCoords('X Spine1').Origin-(Pawn.Location+Pawn.EyePosition()) ) );
00584	            Pawn.ControllerPitch = Rotation.Pitch / 256;
00585	        }
00586	    }
00587	
00588	    //log(" > RotatorError="@RotatorError.Yaw);
00589	
00590	    return ( Rotation + RotatorError );
00591	}
00592	
00593	//__________________________________________________________________
00594	
00595	function InitShotError(bool ReduceError)
00596	{
00597	    local float ErrorTime;
00598	
00599	    ErrorTime = MaxShotErrorTime - Skill + FRand();
00600	
00601	    if ( ReduceError )
00602	        ErrorTime -= 1.0;
00603	
00604	    ShotErrorTime = ErrorTime + Level.TimeSeconds;
00605	    InitialShotError = 200 + Rand(400);
00606	    LastAdjustAimTime = -1;
00607	    LastDistCheckTime = Level.TimeSeconds;
00608	}
00609	
00610	//__________________________________________________________________
00611	
00612	function InitWeaponParam()
00613	{
00614	    //if( DBugBot ) Log("[ BOT"@ID@"] : InitWeaponParam "@Pawn.PendingWeapon.InventoryGroup);
00615	
00616	    HeadShotModificator = 30 ;
00617	    MissPercent = 3;
00618	    MyWeaponIsAGrenad = false;
00619	    MoveSpeed = MaxMoveSpeed;
00620	    Pawn.SightRadius = 2500;
00621	
00622	    if( Pawn.PendingWeapon == none )
00623	        return;
00624	
00625	    switch( Pawn.PendingWeapon.InventoryGroup )
00626	    {
00627	//        case 1 :    //Knife
00628	//                    HeadShotModificator = 40 ;
00629	//                    MissPercent = 5;
00630	//                    MyWeaponIsAGrenad = false;
00631	//                    MoveSpeed = MaxMoveSpeed;
00632	//                    break;
00633	        case 2 :    // Beretta
00634	                    HeadShotModificator = 30 ;
00635	                    MissPercent = 3;
00636	                    MyWeaponIsAGrenad = false;
00637	                    MoveSpeed = MaxMoveSpeed;
00638	                    Pawn.SightRadius = 2500;
00639	                    break;
00640	        case 3 :    // Magnum
00641	                    HeadShotModificator = 30 ;
00642	                    MissPercent = 3;
00643	                    MyWeaponIsAGrenad = false;
00644	                    MoveSpeed = MaxMoveSpeed;
00645	                    Pawn.SightRadius = 2500;
00646	                    break;
00647	        case 4 :    // Grenad
00648	                    HeadShotModificator = 50 ;
00649	                    MissPercent = 0;
00650	                    MyWeaponIsAGrenad = true;
00651	                    MoveSpeed = MaxMoveSpeed;
00652	                    Pawn.SightRadius = 2500;
00653	                    break;
00654	        case 5 :    // Grenad Frag
00655	                    HeadShotModificator = 50 ;
00656	                    MissPercent = 0;
00657	                    MyWeaponIsAGrenad = true;
00658	                    MoveSpeed = MaxMoveSpeed;
00659	                    Pawn.SightRadius = 2500;
00660	                    break;
00661	//        case 6 :    // Arbalete
00662	//                    HeadShotModificator = 50 ;
00663	//                    MissPercent = 5;
00664	//                    MyWeaponIsAGrenad = false;
00665	//                    MoveSpeed = MaxMoveSpeed;
00666	//                    break;
00667	//        case 7 :    // Arbalete x3
00668	//                    HeadShotModificator = 50 ;
00669	//                    MissPercent = 5;
00670	//                    MyWeaponIsAGrenad = false;
00671	//                    MoveSpeed = MaxMoveSpeed;
00672	//                    break;
00673	//        case 8 :    // Harpon
00674	//                    HeadShotModificator = 40 ;
00675	//                    MissPercent = 5;
00676	//                    MyWeaponIsAGrenad = false;
00677	//                    MoveSpeed = MaxMoveSpeed;
00678	//                    break;
00679	        case 9 :    // Pompe
00680	                    HeadShotModificator = -10 ;
00681	                    MissPercent = 5;
00682	                    MyWeaponIsAGrenad = false;
00683	                    MoveSpeed = MaxMoveSpeed;
00684	                    Pawn.SightRadius = 2500;
00685	                    break;
00686	        case 10 :   // Chasse
00687	                    HeadShotModificator = 10 ;
00688	                    MissPercent = 5;
00689	                    MyWeaponIsAGrenad = false;
00690	                    MoveSpeed = MaxMoveSpeed;
00691	                    break;
00692	        case 11 :   // M16
00693	                    HeadShotModificator = 0 ;
00694	                    MissPercent = 6;
00695	                    MyWeaponIsAGrenad = false;
00696	                    MoveSpeed = MaxMoveSpeed;
00697	                    Pawn.SightRadius = 2500;
00698	                    break;
00699	        case 12 :   // Kalash
00700	                    HeadShotModificator = 0 ;
00701	                    MissPercent = 8;
00702	                    MyWeaponIsAGrenad = false;
00703	                    MoveSpeed = MaxMoveSpeed;
00704	                    Pawn.SightRadius = 2500;
00705	                    break;
00706	        case 13 :   // UZI
00707	                    HeadShotModificator = 5 ;
00708	                    MissPercent = 7;
00709	                    MyWeaponIsAGrenad = false;
00710	                    MoveSpeed = MaxMoveSpeed;
00711	                    Pawn.SightRadius = 2500;
00712	                    break;
00713	        case 14 :   // Snipe
00714	                    HeadShotModificator = 50 ;
00715	                    MissPercent = 2;
00716	                    MyWeaponIsAGrenad = false;
00717	                    MoveSpeed = MaxMoveSpeed;
00718	                    Pawn.SightRadius = 5000;
00719	                    break;
00720	        case 15 :   // Bazook
00721	                    HeadShotModificator = -20 ;
00722	                    MissPercent = 2;
00723	                    MyWeaponIsAGrenad = false;
00724	                    MoveSpeed = MaxMoveSpeed * 0.66;
00725	                    Pawn.SightRadius = 2500;
00726	                    break;
00727	        case 16 :   // M60
00728	                    HeadShotModificator = -20 ;
00729	                    MissPercent = 9;
00730	                    MyWeaponIsAGrenad = false;
00731	                    MoveSpeed = MaxMoveSpeed * 0.66;
00732	                    Pawn.SightRadius = 2500;
00733	                    break;
00734	        case 21 :   // FlashBang
00735	                    HeadShotModificator = 50 ;
00736	                    MissPercent = 0;
00737	                    MyWeaponIsAGrenad = true;
00738	                    MoveSpeed = MaxMoveSpeed;
00739	                    Pawn.SightRadius = 2500;
00740	                    break;
00741	    }
00742	}
00743	
00744	//__________________________________________________________________
00745	
00746	function SwitchWeapon()
00747	{
00748	     local float rating;
00749	     local Weapon W;
00750	
00751	    if (Pawn == None )
00752	        return;
00753	
00754	    if (Pawn.Inventory == None )
00755	        return;
00756	
00757	    Pawn.PendingWeapon = Pawn.Inventory.RecommendWeapon(rating);
00758	
00759	    //if( DBugBot ) Log("[ BOT"@ID@"] : SwitchWeapon to"@Pawn.PendingWeapon@"with rating of"@Rating);
00760	
00761	    if (Pawn.PendingWeapon == None )
00762	        return;
00763	
00764	    if (Pawn.PendingWeapon == Pawn.Weapon )
00765	        Pawn.PendingWeapon = None;
00766	
00767	    if (Pawn.Weapon == None )
00768	        Pawn.ChangedWeapon();
00769	    else if ( Pawn.Weapon != Pawn.PendingWeapon )
00770	        Pawn.Weapon.PutDown();
00771	
00772	    InitWeaponParam();
00773	}
00774	
00775	//__________________________________________________________________
00776	
00777	function PawnDied()
00778	{
00779	    if ( Pawn != None )
00780		{
00781			SetLocation(Pawn.Location);
00782			Pawn.UnPossessed();
00783		}
00784	
00785		Pawn = None;
00786		PendingMover = None;
00787	
00788	    //log("");
00789	    //Log("[ BOT"@ID@"] : PawnDied"@self);
00790	
00791	    GotoState('Dead');
00792	}
00793	
00794	//__________________________________________________________________
00795	
00796	function bool IsEnemy( Pawn Target )
00797	{
00798	    return True;
00799	}
00800	
00801	//__________________________________________________________________
00802	
00803	function SomeoneWantKillMe( Pawn Agressor )
00804	{
00805	    if( ! PathErrorToAllLife )
00806	    {
00807	        if( FindOrder( Order_Life ) )
00808	            ModifyOrder( Order_Life, GetLifePriority() );
00809	        else
00810	            AddOrder(GetLifePriority(),Order_Life,"Life",0);
00811	    }
00812	
00813	    if( Agressor == Pawn )
00814	        return;
00815	
00816	    if( Agressor == Enemy )
00817	    {
00818	        bFireMove = true;
00819	        return;
00820	    }
00821	
00822	    if( ! IsEnemy( Agressor ) )
00823	        return;
00824	
00825	    if( ( Enemy == none ) || ( IsNearest( Enemy,Agressor) )  )
00826	    {
00827	        Enemy = Agressor;
00828	
00829	        if( !FindOrder( Order_Kill ) )
00830	            AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
00831	        else
00832	        {
00833	            WaitBeforeFire = true;
00834	            bFire=0;
00835	            bFireMove = false;
00836	            SetTimer(0.0,false);
00837	            SetTimer2(0.0,false);
00838	        }
00839	    }
00840	}
00841	
00842	//__________________________________________________________________
00843	
00844	function bool CheckThePowerOfTheEnemy( Pawn Other )
00845	{
00846	    local int MyPower,EnemyPower;
00847	    local Inventory AlreadyHas;
00848	
00849	    AlreadyHas = Other.FindInventoryType(Class'XIII.Casque');
00850	
00851	    If( AlreadyHas != none )
00852	    {
00853	        log("Has Casque");
00854	        EnemyPower++;
00855	    }
00856	
00857	    AlreadyHas = Other.FindInventoryType(Class'XIII.GiletMk1');
00858	
00859	    If( AlreadyHas != none )
00860	    {
00861	        log("Has Gilet");
00862	        EnemyPower++;
00863	    }
00864	
00865	    switch( Other.Weapon.InventoryGroup )
00866	    {
00867	        case 2 :    // Beretta
00868	                    break;
00869	        case 3 :    // Magnum
00870	                    EnemyPower++;
00871	                    break;
00872	        case 4 :    // Grenad
00873	                    break;
00874	        case 5 :    // Grenad Frag
00875	                    break;
00876	        case 9 :    // Pompe
00877	                    EnemyPower++;
00878	                    break;
00879	        case 11 :   // M16
00880	                    EnemyPower+=2;
00881	                    break;
00882	        case 12 :   // Kalash
00883	                    EnemyPower+=2;
00884	                    break;
00885	        case 13 :   // UZI
00886	                    EnemyPower++;
00887	                    break;
00888	        case 14 :   // Snipe
00889	                    EnemyPower++;
00890	                    break;
00891	        case 15 :   // Bazook
00892	                    EnemyPower+=3;
00893	                    break;
00894	        case 16 :   // M60
00895	                    EnemyPower+=3;
00896	                    break;
00897	        case 21 :   // FlashBang
00898	                    break;
00899	    }
00900	
00901	    AlreadyHas = Pawn.FindInventoryType(Class'XIII.Casque');
00902	
00903	    If( AlreadyHas != none )
00904	    {
00905	        log("Has Casque");
00906	        MyPower++;
00907	    }
00908	
00909	    AlreadyHas = Pawn.FindInventoryType(Class'XIII.GiletMk1');
00910	
00911	    If( AlreadyHas != none )
00912	    {
00913	        log("Has Gilet");
00914	        MyPower++;
00915	    }
00916	
00917	    switch( Pawn.Weapon.InventoryGroup )
00918	    {
00919	        case 2 :    // Beretta
00920	                    break;
00921	        case 3 :    // Magnum
00922	                    MyPower++;
00923	                    break;
00924	        case 4 :    // Grenad
00925	                    break;
00926	        case 5 :    // Grenad Frag
00927	                    break;
00928	        case 9 :    // Pompe
00929	                    MyPower++;
00930	                    break;
00931	        case 11 :   // M16
00932	                    MyPower+=2;
00933	                    break;
00934	        case 12 :   // Kalash
00935	                    MyPower+=2;
00936	                    break;
00937	        case 13 :   // UZI
00938	                    MyPower++;
00939	                    break;
00940	        case 14 :   // Snipe
00941	                    MyPower++;
00942	                    break;
00943	        case 15 :   // Bazook
00944	                    MyPower+=3;
00945	                    break;
00946	        case 16 :   // M60
00947	                    MyPower+=3;
00948	                    break;
00949	        case 21 :   // FlashBang
00950	                    break;
00951	    }
00952	
00953	    if( (  MyPower >= EnemyPower ) || ( Rand(100) > ( EnemyPower - MyPower )*20 ) )
00954	        return true;
00955	    else
00956	        return false;
00957	}
00958	
00959	
00960	//__________________________________________________________________
00961	
00962	function bool GetNumberOfEnemyInTheGrenadArea(BotGrenadTarget Target)
00963	{
00964	//    return true;
00965	
00966	    if( Rand( 100 ) < 50 )
00967	        return true;
00968	    else
00969	        return false;
00970	
00971	//    local BotController BOT;
00972	//
00973	//    foreach DynamicActors(class'BotController', BOT)
00974	//    {
00975	//        if( ( BOT != self ) && ( VSize( Target.Location - Bot.Pawn.Location ) < Max(Target.AreaSize,600) ) )
00976	//            return true;
00977	//    }
00978	//
00979	//    return false;
00980	}
00981	
00982	//__________________________________________________________________
00983	
00984	function GrenadPossibility( GrenadPathNode GrenadNode )
00985	{
00986	    local weapon MyGrenad;
00987	    local int Loop;
00988	
00989	    if( GrenadNode.LastUsedTime == -1 )
00990	        GrenadNode.LastUsedTime = Level.TimeSeconds;
00991	    else if( Level.TimeSeconds - GrenadNode.LastUsedTime > 10 )
00992	        GrenadNode.LastUsedTime = Level.TimeSeconds;
00993	    else
00994	        return;
00995	
00996	
00997	
00998	    MyGrenad = Weapon(Pawn.FindInventoryType(class'FGrenad') );
00999	
01000	    if( ( MyGrenad == none ) || (  MyGrenad.AmmoType.AmmoAmount == 0 ) )
01001	    {
01002	        MyGrenad = Weapon(Pawn.FindInventoryType(class'FlashBangBot') );
01003	
01004	        if( ( MyGrenad == none ) || (  MyGrenad.AmmoType.AmmoAmount == 0 ) )
01005	        {
01006	            return;
01007	        }
01008	    }
01009	
01010	
01011	
01012	    MyGrenadTarget = GrenadNode;
01013	
01014	    if( GetNumberOfEnemyInTheGrenadArea(GrenadNode.Target) )
01015	    {
01016	        if( ( ! FindOrder( Order_GrenadLauncher ) ) && ( ! FindOrder( Order_Kill ) ) )
01017	        {
01018	            MyGrenad.AIRating = 2.0;
01019	            SwitchWeapon();
01020	
01021	            GrenadIsLauched = false;
01022	            AddOrder(79,Order_GrenadLauncher,"GrenadLauncher",0);
01023	        }
01024	    }
01025	}
01026	
01027	//__________________________________________________________________
01028	
01029	event HearNoise( float Loudness, Actor NoiseMaker)
01030	{
01031	    if( NoiseMaker.IsA('GrenadFlying') )
01032	    {
01033	//        if( ( Rand( 100 ) < 30 + Skill*20 ) || ( ForceFear ) )
01034	        if( ( Rand( 100 ) < 90 ) || ( ForceFear ) )
01035	        {
01036	            if( FastTrace( NoiseMaker.Location, Pawn.Location ) )
01037	            {
01038	                if( VSize( NoiseMaker.Location - Pawn.Location ) < 600 )
01039	                {
01040	                    FearActor = NoiseMaker;
01041	                    AddOrder( 90 ,Order_Fear , "Fear" , 0 );
01042	                }
01043	            }
01044	        }
01045	    }
01046	}
01047	
01048	//__________________________________________________________________
01049	
01050	event SeePlayer( Pawn Seen )
01051	{
01052	    local float Dist;
01053	
01054	    if( MyWeaponIsAGrenad )
01055	    {
01056	        Dist = VSize( Seen.Location - Pawn.Location );
01057	
01058	        If( Dist > 1200 )
01059	            return;
01060	
01061	        if( Dist < 800 )
01062	        {
01063	            Pawn.Weapon.AIRating = 0.11;
01064	            SwitchWeapon();
01065	        }
01066	    }
01067	
01068	    if( ( ! IsEnemy( Seen ) ) || DamnedImFlashed )
01069	        return;
01070	
01071	    if( Seen.DrawType == DT_None )
01072	        return;
01073	
01074	    if( Enemy == none )
01075	    {
01076	        //if( CheckThePowerOfTheEnemy( Seen ) )
01077	        //{
01078	            Enemy = Seen;
01079	
01080	            if( IsShootable( Seen ) )
01081	                AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
01082	            else
01083	                AddOrder(70,Order_Seek,"Seek",0);
01084	        //}
01085	    }
01086	    else if( IsNearest( Enemy,Seen) )
01087	    {
01088	        Enemy = Seen;
01089	    }
01090	}
01091	
01092	//__________________________________________________________________
01093	
01094	event MayFall()
01095	{
01096	    if( ! IsInState('Kill') )
01097	        return;
01098	
01099	    StopMvtWhenMayFall();
01100	    Pawn.velocity=vect(0,0,0);
01101	    Pawn.acceleration=vect(0,0,0);
01102	}
01103	
01104	//__________________________________________________________________
01105	
01106	function bool IsShootable( Pawn ShootTarget )
01107	{
01108	    if( MyWeaponIsAGrenad )
01109	        return ( FastTrace( ShootTarget.Location+ShootTarget.EyePosition(), Pawn.Location+Pawn.EyePosition() ) && ( ! Pawn.bIsCrouched ) );
01110	    else
01111	        return FastTrace( ShootTarget.Location, Pawn.Location + Pawn.EyePosition() + Pawn.Weapon.FireOffset )  ;
01112	}
01113	
01114	//__________________________________________________________________
01115	
01116	function InitPickUpList()
01117	{
01118	    local PickUp A;
01119	    local NavigationPoint Nav;
01120	    local Pawn P;
01121	
01122	    bInitPickUpList = true;
01123	
01124	    Nav = Level.NavigationPointList;
01125	
01126	    while( Nav != none)
01127	    {
01128	        if( Nav.IsA('SnipePathNode') )
01129	        {
01130	            SnipeSpotList.Length = SnipeSpotList.Length+1;
01131	            SnipeSpotList[ SnipeSpotList.Length-1 ] = Nav;
01132	        }
01133	
01134	        if( Nav.IsA('TrakNarPathNode') )
01135	        {
01136	            TrakNarSpotList.Length = TrakNarSpotList.Length+1;
01137	            TrakNarSpotList[ TrakNarSpotList.Length-1 ] = Nav;
01138	        }
01139	
01140	        Nav = Nav.NextNavigationPoint;
01141	    }
01142	
01143	    MarioMode = false;
01144	
01145	    foreach DynamicActors(class'PickUp', A)
01146	    {
01147	
01148	        FullPickUpList.Length = FullPickUpList.Length+1;
01149	        FullPickUpList[ FullPickUpList.Length-1 ] = A;
01150	
01151	        if ( A.IsA('MultiPlayerMedPickUp') )
01152	        {
01153	            MedKitList.Length = MedKitList.Length+1;
01154	            MedKitList[ MedKitList.Length-1 ] = A;
01155	        }
01156	        else if( A.IsA('XIIIWeaponPickUp') )
01157	        {
01158	            WeaponList.Length = WeaponList.Length+1;
01159	            WeaponList[ WeaponList.Length-1 ] = A;
01160	        }
01161	        else if( A.IsA('XIIIArmorPickUp') )
01162	        {
01163	            ArmorList.Length = ArmorList.Length+1;
01164	            ArmorList[ ArmorList.Length-1 ] = A;
01165	        }
01166	        else if (A.IsA('MarioPickUp'))
01167	        {
01168	            MarioMode = true;
01169	
01170	            FullPickUpList.Length = FullPickUpList.Length+1;
01171	                FullPickUpList[ FullPickUpList.Length-1 ] = A;
01172	
01173	                if ( A.IsA('MarioArmorAndMedKitPickUp'))
01174	            {
01175	                MedKitList.Length = MedKitList.Length+1;
01176	                    MedKitList[ MedKitList.Length-1 ] = A;
01177	            }
01178	                else if( ( A.IsA('MarioHeavyWeaponPickUp') ) || ( A.IsA('MarioSmallWeaponPickUp') ) )
01179	            {
01180	                WeaponList.Length = WeaponList.Length+1;
01181	                    WeaponList[ WeaponList.Length-1 ] = A;
01182	            }
01183	        }
01184	        else if (A.IsA('MarioSuperBonusPickUp'))
01185	        {
01186	            FullPickUpList.Length = FullPickUpList.Length+1;
01187	            FullPickUpList[ FullPickUpList.Length-1 ] = A;
01188	
01189	            ArmorList.Length = ArmorList.Length+1;
01190	            ArmorList[ ArmorList.Length-1 ] = A;
01191	        }
01192	    }
01193	
01194	    if( DBugBot )
01195	    {
01196	        Log("");
01197	        Log("[ BOT"@ID@"] : PickUpList Construction");
01198	        log("    > MedKit="$MedKitList.Length);
01199	        log("    > Weapon="$WeaponList.Length);
01200	        log("    > Armor="$ArmorList.Length);
01201	        log("    > SnipePoint="$SnipeSpotList.Length);
01202	        log("    > TrakNarPoint="$TrakNarSpotList.Length);
01203	        log("    > MarioMode="$MarioMode);
01204	    }
01205	}
01206	
01207	//__________________________________________________________________
01208	
01209	function InitBotJump( int V , int H , NavigationPoint T )
01210	{
01211	    JumpSpeed = V;
01212	    JumpHeight = H;
01213	    JumpTarget = T;
01214	
01215	    if( MoveSpeed != MaxMoveSpeed )
01216	    {
01217	        JumpSpeed *= 1.7;
01218	        JumpHeight *= 1.7;
01219	    }
01220	
01221	    bIsJumping = true;
01222	    GotoState('Jumping');
01223	}
01224	
01225	//__________________________________________________________________
01226	
01227	function InitSnipe()
01228	{
01229	    Sniping = true;
01230	    GotoState('Sniping');
01231	}
01232	
01233	//__________________________________________________________________
01234	
01235	function Flashed()
01236	{
01237	    DamnedImFlashed = true;
01238	}
01239	
01240	//__________________________________________________________________
01241	
01242	
01243	event Timer()
01244	{
01245	}
01246	/*
01247	event tick (float delta)
01248	{
01249		super.tick(delta);
01250		if (pawn==none && !isinstate('dead') && !isinstate('gameended')) log(self@getstatename()@"PAWN== NONE NONE NONE NONE");
01251	}   */
01252	//__________________________________________________________________
01253	//__________________________________________________________________
01254	//                            Weapon
01255	//__________________________________________________________________
01256	//__________________________________________________________________
01257	
01258	state Weapon
01259	{
01260	    event BeginState()
01261	    {
01262	        if( DBugBot )
01263	        {
01264	            Log("");
01265	            Log("[ BOT"@ID@"] : *STATE* ---> Weapon");
01266	        }
01267	
01268	        Enemy = none;
01269	        Pawn.ControllerPitch = 0;
01270	
01271	        Pawn.ShouldCrouch( false );
01272	    }
01273	
01274	    event SeePlayer( Pawn Seen )
01275	    {
01276	        if( ( GetDistToMyTarget() > 800 ) && ( VSize( Pawn.Location - Seen.Location ) > VSize( PathCache[ PathIndex ].Location - Seen.Location ) ) )
01277	            global.SeePlayer( Seen );
01278	    }
01279	
01280	    function SomeoneWantKillMe( Pawn Agressor )
01281	    {
01282	        if( Agressor == Pawn )
01283	            return;
01284	
01285	        if( ( GetDistToMyTarget() > 800 ) && ( VSize( Pawn.Location - Agressor.Location ) > VSize( PathCache[ PathIndex ].Location - Agressor.Location ) ) )
01286	            global.SomeoneWantKillMe( Agressor );
01287	    }
01288	
01289	Begin:
01290	
01291	    if( Pawn.Physics == PHYS_Falling )
01292	    {
01293	        while( true )
01294	        {
01295	            sleep( 0.1 );
01296	
01297	            if ( Pawn.Physics != PHYS_Falling )
01298	               break;
01299	        }
01300	    }
01301	
01302	    if( ( Skill == 0 ) || FirstWeaponPickUp )
01303	    {
01304	        FindNearestWeapon();
01305	        FirstWeaponPickUp = false;
01306	    }
01307	    else
01308	        FindBestWeapon();
01309	
01310	    if( Item == none )
01311	    {
01312	        Sleep( 0.5 );
01313	        RemoveOrder( Order_Weapon );
01314	    }
01315	    else
01316	    {
01317	        while( true )
01318	        {
01319	            PickUpPathStorage(Item);
01320	
01321	            for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
01322	            {
01323	                if( ( PathIndex == PathCacheSize-1 ) && ( ! PickUp(Item).ReadyToPickUp(0) ) )
01324	                    Goto('begin');
01325	
01326	                MoveTarget = PathCache[ PathIndex ];
01327	                Focus=MoveTarget;
01328	
01329	                Pawn.ShouldCrouch( false );
01330	                MoveToward( MoveTarget, Focus , MoveSpeed );
01331	            }
01332	
01333	            if( FullPath )
01334	                break;
01335	        }
01336	
01337	        SwitchWeapon();
01338	
01339	        if( ( Pawn.Weapon.InventoryGroup == 14) && ( SnipeSpotList.Length != 0 ) )
01340	        {
01341	            Pawn.SetAnimStatus('Alert');
01342	            AddOrder(50,Order_SnipeSpot,"Snipe",0);
01343	        }
01344	
01345	        RemoveOrder( Order_Weapon );
01346	    }
01347	}
01348	
01349	//__________________________________________________________________
01350	//__________________________________________________________________
01351	//                            Fear
01352	//__________________________________________________________________
01353	//__________________________________________________________________
01354	
01355	state Fear
01356	{
01357	    event BeginState()
01358	    {
01359	        if( DBugBot )
01360	        {
01361	            Log("");
01362	            Log("[ BOT"@ID@"] : *STATE* ---> Fear");
01363	        }
01364	
01365	        Pawn.ControllerPitch = 0;
01366	
01367	        if( Pawn.bIsCrouched )
01368	            Pawn.ShouldCrouch( false );
01369	
01370	        ForceFear = false;
01371	
01372	        if( FindOrder( Order_Kill ) )
01373	            RemoveOrder( Order_Kill );
01374	    }
01375	
01376	    event HearNoise( float Loudness, Actor NoiseMaker);
01377	
01378	    event SeePlayer( Pawn Seen )
01379	    {
01380	        if( ! IsEnemy( Seen ) )
01381	            return;
01382	
01383	        if( ! IsShootable( Seen ) )
01384	            return;
01385	
01386	        if( ( VSize( FearActor.Location - Pawn.Location ) < 1200 - (3-Skill)*100 ) && ( VSize( Seen.Location - Pawn.Location ) > 300 ) )
01387	            return;
01388	
01389	        Enemy = Seen;
01390	
01391	        AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
01392	        RemoveOrder( Order_Fear );
01393	    }
01394	
01395	    function SomeoneWantKillMe( Pawn Agressor );
01396	
01397	Begin:
01398	
01399	    if( Pawn.Physics == PHYS_Falling )
01400	    {
01401	        while( true )
01402	        {
01403	            sleep( 0.1 );
01404	
01405	            if ( Pawn.Physics != PHYS_Falling )
01406	               break;
01407	        }
01408	    }
01409	
01410	    Pawn.ShouldCrouch( false );
01411	
01412	    Sleep( 1.0 - 0.3*Skill );
01413	
01414	    SearchHidePoint();
01415	
01416	    if( HidePoint == none )
01417	        RemoveOrder( Order_Fear );
01418	    else
01419	    {
01420	        while( true )
01421	        {
01422	            if( HidePoint.IsA('PickUp') )
01423	                PickUpPathStorage(HidePoint);
01424	            else
01425	                NavPathStorage(NavigationPoint(HidePoint));
01426	
01427	            for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
01428	            {
01429	                MoveTarget = PathCache[ PathIndex ];
01430	                Focus=MoveTarget;
01431	
01432	                Pawn.ShouldCrouch( false );
01433	                MoveToward( MoveTarget, Focus , MoveSpeed );
01434	
01435	                if( FearActor == none )
01436	                {
01437	                    if( DBugBot )
01438	                    {
01439	                        Log("");
01440	                        Log("[ BOT"@ID@"] : Fear ---> Grenad Explosed");
01441	                    }
01442	
01443	                    break;
01444	                }
01445	                else if( VSize( FearActor.Location - Pawn.Location ) > 1500 - (3-Skill)*100 )
01446	                     RemoveOrder( Order_Fear );
01447	            }
01448	
01449	            if( FullPath )
01450	                break;
01451	
01452	            if( FearActor == none )
01453	                break;
01454	        }
01455	
01456	        if( FearActor != none )
01457	        {
01458	            if( DBugBot )
01459	            {
01460	                Log("");
01461	                Log("[ BOT"@ID@"] : Fear ---> Safe Point");
01462	            }
01463	
01464	            Pawn.ShouldCrouch( true );
01465	
01466	            if( FearActor.IsA('GrenadFlying') )
01467	                Sleep( 2 );
01468	            else
01469	            {
01470	                while( FearActor != none )
01471	                {
01472	                    Sleep( 0.5 );
01473	                }
01474	            }
01475	
01476	            Pawn.ShouldCrouch( false );
01477	        }
01478	
01479	        RemoveOrder( Order_Fear );
01480	    }
01481	}
01482	
01483	//__________________________________________________________________
01484	//__________________________________________________________________
01485	//                            Life
01486	//__________________________________________________________________
01487	//__________________________________________________________________
01488	
01489	state Life
01490	{
01491	    event BeginState()
01492	    {
01493	        if( DBugBot )
01494	        {
01495	            Log("");
01496	            Log("[ BOT"@ID@"] : *STATE* ---> Life("$GetLifePriority()$")");
01497	        }
01498	
01499	        Enemy = none;
01500	        Pawn.ControllerPitch = 0;
01501	
01502	        Pawn.ShouldCrouch( false );
01503	
01504	        if( FindOrder( Order_Kill ) )
01505	            RemoveOrder( Order_Kill );
01506	    }
01507	
01508	    event SeePlayer( Pawn Seen )
01509	    {
01510	        if( ! IsEnemy( Seen ) )
01511	            return;
01512	
01513	        if( ! ForceAttack( Seen ) )
01514	            return;
01515	
01516	        if( ! IsShootable( Seen ) )
01517	            return;
01518	
01519	        if( ! FindOrder( Order_Kill ) )
01520	        {
01521	            Enemy = Seen;
01522	            AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
01523	            ModifyOrder( Order_Life,KillOrderPriority-1 );
01524	        }
01525	    }
01526	
01527	    function SomeoneWantKillMe( Pawn Agressor )
01528	    {
01529	        if( Agressor == Pawn )
01530	            return;
01531	
01532	        SeePlayer( Agressor );
01533	    }
01534	
01535	    function bool ForceAttack( Pawn Other )
01536	    {
01537	        local float DistToOther, DistToLife, DistToTarget;
01538	
01539	        if ( (Other == none) || (MoveTarget == none) )
01540	          return false;
01541	
01542	        DistToOther = VSize( Pawn.Location - Other.Location );
01543	//        DistToLife = VSize( Pawn.Location - Item.Location );
01544	        DistToTarget = VSize( MoveTarget.Location - Other.Location );
01545	
01546	        if( DistToOther < 500 )
01547	            return true;
01548	
01549	        if( DistToOther > DistToTarget )
01550	            return true;
01551	
01552	        return false;
01553	    }
01554	
01555	Begin:
01556	
01557	    if( Pawn.Physics == PHYS_Falling )
01558	    {
01559	        while( true )
01560	        {
01561	            sleep( 0.1 );
01562	
01563	            if ( Pawn.Physics != PHYS_Falling )
01564	               break;
01565	        }
01566	    }
01567	
01568	    FindMedKit();
01569	
01570	    if( Item == none )
01571	    {
01572	        Sleep( 0.5 );
01573	        RemoveOrder( Order_Life );
01574	    }
01575	    else
01576	    {
01577	        while( true )
01578	        {
01579	            PickUpPathStorage(Item);
01580	
01581	            for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
01582	            {
01583	                if( ( PathIndex == PathCacheSize-1 ) && ( ! PickUp(Item).ReadyToPickUp(0) ) )
01584	                    Goto('begin');
01585	
01586	                MoveTarget = PathCache[ PathIndex ];
01587	                Focus=MoveTarget;
01588	
01589	                Pawn.ShouldCrouch( false );
01590	                MoveToward( MoveTarget, Focus , MoveSpeed );
01591	            }
01592	
01593	            if( FullPath )
01594	                break;
01595	        }
01596	
01597	        if( GetLifePriority() == 0 )
01598	            RemoveOrder( Order_Life );
01599	        else
01600	            ModifyOrder( Order_Life , GetLifePriority() );
01601	    }
01602	}
01603	//__________________________________________________________________
01604	//__________________________________________________________________
01605	//                            Armor
01606	//__________________________________________________________________
01607	//__________________________________________________________________
01608	
01609	state Armor
01610	{
01611	    event BeginState()
01612	    {
01613	        if( DBugBot )
01614	        {
01615	            Log("");
01616	            Log("[ BOT"@ID@"] : *STATE* ---> Armor");
01617	        }
01618	
01619	        Enemy = none;
01620	        Pawn.ControllerPitch = 0;
01621	
01622	        Pawn.ShouldCrouch( false );
01623	    }
01624	
01625	Begin:
01626	
01627	    if( Pawn.Physics == PHYS_Falling )
01628	    {
01629	        while( true )
01630	        {
01631	            sleep( 0.1 );
01632	
01633	            if ( Pawn.Physics != PHYS_Falling )
01634	               break;
01635	        }
01636	    }
01637	
01638	    if( Rand( 100 ) < 40 + Skill*20 )
01639	        FindBestArmor();
01640	    else
01641	        FindNearestArmor();
01642	
01643	
01644	    if( Item == none )
01645	    {
01646	        Sleep( 0.5 );
01647	        RemoveOrder( Order_Armor );
01648	    }
01649	    else
01650	    {
01651	        while( true )
01652	        {
01653	            PickUpPathStorage(Item);
01654	
01655	            for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
01656	            {
01657	                if( ( PathIndex == PathCacheSize-1 ) && ( ! PickUp(Item).ReadyToPickUp(0) ) )
01658	                    Goto('begin');
01659	
01660	                MoveTarget = PathCache[ PathIndex ];
01661	                Focus=MoveTarget;
01662	
01663	                Pawn.ShouldCrouch( false );
01664	                MoveToward( MoveTarget, Focus , MoveSpeed );
01665	            }
01666	
01667	            if( FullPath )
01668	                break;
01669	        }
01670	
01671	        RemoveOrder( Order_Armor );
01672	    }
01673	}
01674	
01675	//__________________________________________________________________
01676	//__________________________________________________________________
01677	//                            Kill
01678	//__________________________________________________________________
01679	//__________________________________________________________________
01680	
01681	state Kill
01682	{
01683	    event BeginState()
01684	    {
01685	        if( DBugBot )
01686	        {
01687	            Log("");
01688	            Log("[ BOT"@ID@"] : *STATE* ---> Kill");
01689	            Log("    > Enemy :"@Enemy);
01690	        }
01691	
01692	        if( ! IsEnemy( Enemy ) )
01693	        {
01694	            Enemy = none ;
01695	            RemoveOrder( Order_Kill );
01696	            return;
01697	        }
01698	
01699	        if( Enemy == Pawn )
01700	        {
01701	            Enemy = none ;
01702	            RemoveOrder( Order_Kill );
01703	            return;
01704	        }
01705	
01706	        if( FindOrder( Order_TrakNar ) )
01707	            RemoveOrder( Order_TrakNar );
01708	
01709	        if( FindOrder( Order_GrenadLauncher ) )
01710	            RemoveOrder( Order_GrenadLauncher );
01711	
01712	        FocalPoint = vect(0,0,0);
01713	        Focus = Enemy;
01714	        Pawn.velocity=vect(0,0,0);
01715	        Pawn.acceleration=vect(0,0,0);
01716	        bFireMove = false;
01717	
01718	        WaitBeforeFire = true;
01719	
01720	        bFire=0;
01721	        SetTimer(0.0,false);
01722	        SetTimer2(0.0,false);
01723	        SetTimer3(0.5,true);
01724	
01725	        SetRotation( rotator(Enemy.GetBoneCoords('X Spine1').Origin-(Pawn.Location+Pawn.EyePosition()) ) );
01726	        TimePassedBeforeSeeingMyEnemy = Level.TimeSeconds;
01727	    }
01728	
01729	    //--------------------------------------------------------------
01730	
01731	    event EndState()
01732	    {
01733	        NbStraffe = 0;
01734	        bFireMove = false;
01735	
01736	        bFire=0;
01737	        bFireMove = false;
01738	        SetTimer(0.0,false);
01739	        SetTimer2(0.0,false);
01740	        SetTimer3(0.0,false);
01741	
01742	        if( Pawn != none )
01743	        {
01744	            Pawn.ShouldCrouch( false );
01745	            Pawn.Weapon.ForceReload();
01746	        }
01747	    }
01748	
01749	    //--------------------------------------------------------------
01750	
01751	    event SeePlayer( Pawn Seen )
01752	    {
01753	        local vector MyVect,OtherVect;
01754	
01755	        if( ( WaitBeforeFire ) && ( Seen == Enemy ) )
01756	        {
01757	            MyVect = Pawn.Location;
01758	            OtherVect = Seen.Location;
01759	            OtherVect.Z = MyVect.Z;
01760	
01761	            if( ( normal( OtherVect - MyVect ) dot ( vector( Pawn.Rotation ) ) ) > 0.85 )
01762	            {
01763	                WaitBeforeFire = false;
01764	
01765	                if( Rand( 100 ) < 10 + Skill*10 )
01766	                {
01767	                    Pawn.ShouldCrouch( true );
01768	                    InitShotError(True);
01769	                }
01770	                else
01771	                    InitShotError(false);
01772	
01773	                if( Pawn.WeaponMode == 'FM_Snipe' )
01774	                {
01775	                    SetTimer( 1.0 + FRand()/2, false );
01776	                }
01777	                else
01778	                    SetTimer( (4-Skill)*0.2+FRand()/2 ,False );
01779	            }
01780	        }
01781	
01782	        if( bFireMove )
01783	            return;
01784	
01785	        if( ! IsEnemy( Seen ) )
01786	            return;
01787	
01788	        else if( IsNearest( Enemy,Seen) )
01789	        {
01790	            Enemy = Seen;
01791	        }
01792	    }
01793	
01794	    //--------------------------------------------------------------
01795	
01796	    event EnemyNotVisible()
01797	    {
01798	        if( WaitBeforeFire )
01799	            return;
01800	
01801	        if( Pawn.bIsCrouched )
01802	            Pawn.ShouldCrouch( false );
01803	
01804	        SetTimer(0.0,false);
01805	        SetTimer2(0.0,false);
01806	
01807	        bFireMove = false;
01808	        NbStraffe = 0;
01809	
01810	        if( ( Rand( 100 ) < 100 - Skill*10 ) || ( Enemy.Health < 70 ) )
01811	        {
01812	            bFire=0;
01813	            AddOrder( 70 ,Order_Seek,"Seek", 0);
01814	            RemoveOrder( Order_Kill );
01815	        }
01816	        else
01817	        {
01818	            bFire=0;
01819	            Enemy = none;
01820	
01821	            RemoveOrder( Order_Kill );
01822	        }
01823	    }
01824	
01825	    //--------------------------------------------------------------
01826	
01827	    event Timer()
01828	    {
01829	        if( MyWeaponIsAGrenad )
01830	        {
01831	            bFire=1;
01832	            Pawn.Weapon.Fire(0);
01833	            bFire=0;
01834	
01835	            SetTimer2(0.5,false);
01836	            SetTimer(0.0,false);
01837	
01838	            ForceFear = true;
01839	        }
01840	        else if( Pawn.Weapon.WeaponMode == WM_SemiAuto )
01841	        {
01842	            bFire=1;
01843	            Pawn.Weapon.Fire(0);
01844	            bFire=0;
01845	
01846	            SetTimer2( Pawn.Weapon.ShotTime + ( 3 - Skill )*0.25,false );
01847	            SetTimer(0.0,false);
01848	        }
01849	        else if ( ( ( Pawn.WeaponMode == 'FM_M16' ) && ( Pawn.Weapon.HasAltAmmo() ) ) && ( VSize( Enemy.Location - Pawn.Location ) < 1600 ) )
01850	        {
01851	            bFire=1;
01852	            Pawn.Weapon.AltFire(0);
01853	            bFire=0;
01854	
01855	            SetTimer2( 0.5,false );
01856	            SetTimer(0.0,false);
01857	        }
01858	        else
01859	        {
01860	            bFire=1;
01861	            Pawn.Weapon.Fire(0);
01862	
01863	            SetTimer2( 2.5 - skill/2,false );
01864	            SetTimer(0.0,false);
01865	        }
01866	    }
01867	
01868	    //--------------------------------------------------------------
01869	
01870	    event Timer2()
01871	    {
01872	        if( MyWeaponIsAGrenad )
01873	        {
01874	            Pawn.Weapon.AIRating = 0.11;
01875	            SwitchWeapon();
01876	            SetTimer(1.0,false);
01877	            SetTimer2(0.0,false);
01878	        }
01879	        else if( Pawn.Weapon.WeaponMode == WM_SemiAuto )
01880	        {
01881	            if( Pawn.WeaponMode == 'FM_Snipe' )
01882	                SetTimer(0.01 + FRand()/2,false);
01883	            else
01884	                SetTimer(0.01,false);
01885	
01886	            SetTimer2(0.0,false);
01887	        }
01888	        else if ( ( ( Pawn.WeaponMode == 'FM_M16' ) && ( Pawn.Weapon.HasAltAmmo() ) ) && ( VSize( Enemy.Location - Pawn.Location ) < 1600 ) )
01889	        {
01890	            SetTimer(0.1,false);
01891	            SetTimer2(0.0,false);
01892	        }
01893	        else
01894	        {
01895	            bFire=0;
01896	            SetTimer(0.01,false);
01897	            SetTimer2(0.0,false);
01898	        }
01899	
01900	        if( ! Pawn.Weapon.HasAmmo() )
01901	            SwitchWeapon();
01902	
01903	        if( ( Enemy == none ) || ( Enemy.bIsDead ) )
01904	        {
01905	            Pawn.ShouldCrouch( false );
01906	
01907	            bFire=0;
01908	            Enemy = none;
01909	
01910	            RemoveOrder( Order_Kill );
01911	        }
01912	    }
01913	
01914	    //--------------------------------------------------------------
01915	
01916	    event Timer3()
01917	    {
01918	        if( ( Enemy == none ) || (Pawn == none ) || ( Enemy.bIsDead ) )
01919	        {
01920	            if ( Pawn != none )
01921	              Pawn.ShouldCrouch( false );
01922	
01923	            bFire=0;
01924	            Enemy = none;
01925	
01926	            RemoveOrder( Order_Kill );
01927	            return;
01928	        }
01929	
01930	        if( WaitBeforeFire && ( Level.TimeSeconds - TimePassedBeforeSeeingMyEnemy > 1.5 ) )
01931	        {
01932	            AddOrder( 70 ,Order_Seek,"Seek", 0);
01933	            RemoveOrder( Order_Kill );
01934	        }
01935	
01936	        SetRotation( rotator(Enemy.GetBoneCoords('X Spine1').Origin-(Pawn.Location+Pawn.EyePosition()) ) );
01937	
01938	        if( ( bFireMove ) || ( bBackMove ) )
01939	           return;
01940	
01941	        if( VSize( Pawn.Location - Enemy.Location ) < 200 )
01942	            bBackMove = true;
01943	    }
01944	
01945	    //--------------------------------------------------------------
01946	
01947	    function int CheckStraffe( int Direction )
01948	    {
01949	        local vector              HitLocation;
01950	        local vector              HitNormal;
01951	        local actor               ColActor;
01952	        local int                 StarffeDist;
01953	
01954	        if( Direction == 0 )
01955	            NextPosition = Pawn.Location + ( vector(pawn.rotation) cross (vect(0,0,1)) )*10000;
01956	        else
01957	            NextPosition = Pawn.Location + ( vector(pawn.rotation) cross (vect(0,0,1)) )*(-10000);
01958	
01959	        ColActor=Trace( HitLocation,HitNormal,NextPosition,Pawn.Location, true);
01960	
01961	        StarffeDist = VSize( HitLocation - Pawn.Location );
01962	        return StarffeDist;
01963	    }
01964	
01965	    //--------------------------------------------------------------
01966	
01967	    function int CheckBackMove()
01968	    {
01969	        local vector              HitLocation;
01970	        local vector              HitNormal;
01971	        local actor               ColActor;
01972	        local int                 StarffeDist;
01973	
01974	        ColActor=Trace( HitLocation,HitNormal,NextPosition,Pawn.Location, true);
01975	
01976	        StarffeDist = VSize( HitLocation - Pawn.Location );
01977	        return StarffeDist;
01978	    }
01979	
01980	    //--------------------------------------------------------------
01981	
01982	Begin:
01983	
01984	
01985	    while( true )
01986	    {
01987	        Sleep( ( 4-skill)*StraffeDelay );
01988	
01989	        if( bFireMove )
01990	        {
01991	            if( ( Pawn.bIsCrouched ) && ( Rand( 100 ) < (Skill+1)*20 ) )
01992	                Pawn.ShouldCrouch( false );
01993	
01994	
01995	            if( ( LastStraffeDir == -1 ) || ( Rand( 100 ) < 50 ) )
01996	                LastStraffeDir = Rand( 2 );
01997	
01998	            StraffeValue = CheckStraffe( LastStraffeDir );
01999	
02000	            if( StraffeValue > 100 )
02001	            {
02002	                if( LastStraffeDir == 0 )
02003	                    StraffeValue = Min(100+Rand(200),StraffeValue);
02004	                else
02005	                    StraffeValue = Max(-100-Rand(200),-StraffeValue);
02006	
02007	                if( Rand(2)==0 )
02008	                    NextPosition = Pawn.Location + ( vector(pawn.rotation) cross (vect(0,0,1)) )*StraffeValue + vector(pawn.rotation)*StraffeValue*FRand()*(-1);
02009	                else
02010	                    NextPosition = Pawn.Location + ( vector(pawn.rotation) cross (vect(0,0,1)) )*StraffeValue + vector(pawn.rotation)*StraffeValue*FRand();
02011	            }
02012	            else
02013	            {
02014	                if( LastStraffeDir == 0 )
02015	                    LastStraffeDir =1;
02016	                else
02017	                    LastStraffeDir =0;
02018	
02019	                StraffeValue = CheckStraffe( LastStraffeDir );
02020	
02021	                if( StraffeValue > 100 )
02022	                {
02023	                    if( LastStraffeDir == 0 )
02024	                        StraffeValue = Min(100+Rand(200),StraffeValue);
02025	                    else
02026	                        StraffeValue = Max(-100-Rand(200),-StraffeValue);
02027	
02028	                    if( Rand(2)==0 )
02029	                        NextPosition = Pawn.Location + ( vector(pawn.rotation) cross (vect(0,0,1)) )*StraffeValue + vector(pawn.rotation)*StraffeValue*FRand()*(-1);
02030	                    else
02031	                        NextPosition = Pawn.Location + ( vector(pawn.rotation) cross (vect(0,0,1)) )*StraffeValue + vector(pawn.rotation)*StraffeValue*FRand();
02032	                }
02033	                else
02034	                    bFireMove = false;
02035	            }
02036	
02037	
02038	            if( bFireMove )
02039	            {
02040	                MoveTo( NextPosition, Enemy );
02041	                Pawn.velocity=vect(0,0,0);
02042	                Pawn.acceleration=vect(0,0,0);
02043	            }
02044	
02045	            if( ( Rand( 100 ) > 30 + Skill*20 ) || ( NbStraffe == Skill+1 ) )
02046	            {
02047	                bFireMove = false;
02048	                NbStraffe = 0;
02049	            }
02050	            else
02051	                NbStraffe++;
02052	
02053	            if( Rand( 100 ) < 10 + Skill*10 )
02054	            {
02055	                if( Pawn.bIsCrouched )
02056	                    Pawn.ShouldCrouch( false );
02057	                else
02058	                    Pawn.ShouldCrouch( true );
02059	            }
02060	        }
02061	
02062	        else if( bBackMove )
02063	        {
02064	            NextPosition = vector(Pawn.rotation)*(-1000)+Pawn.Location;
02065	
02066	            StraffeValue = CheckBackMove();
02067	
02068	            if( StraffeValue > 100 )
02069	            {
02070	                StraffeValue = Max(-100-Rand(200),-StraffeValue);
02071	            }
02072	            else
02073	            {
02074	                bBackMove = false;
02075	            }
02076	
02077	            NextPosition = vector(Pawn.rotation)*StraffeValue+Pawn.Location;
02078	
02079	            if( bBackMove )
02080	            {
02081	                MoveTo( NextPosition, Enemy );
02082	                Pawn.velocity=vect(0,0,0);
02083	                Pawn.acceleration=vect(0,0,0);
02084	                bBackMove = false;
02085	            }
02086	
02087	        }
02088	    }
02089	}
02090	
02091	//__________________________________________________________________
02092	//__________________________________________________________________
02093	//                            Seek
02094	//__________________________________________________________________
02095	//__________________________________________________________________
02096	
02097	state Seek
02098	{
02099	    event BeginState()
02100	    {
02101	        if( DBugBot )
02102	        {
02103	            Log("");
02104	            Log("[ BOT"@ID@"] : *STATE* ---> Seek");
02105	
02106	        }
02107	
02108	        Pawn.ControllerPitch = 0;
02109	
02110	        SeekTime = Level.TimeSeconds;
02111	
02112	        Pawn.ShouldCrouch( false );
02113	    }
02114	
02115	    function SomeoneWantKillMe( Pawn Agressor )
02116	    {
02117	        if( ! PathErrorToAllLife )
02118	        {
02119	            if( FindOrder( Order_Life ) )
02120	                ModifyOrder( Order_Life, GetLifePriority() );
02121	            else
02122	                AddOrder(GetLifePriority(),Order_Life,"Life",0);
02123	        }
02124	
02125	        if( ! IsEnemy( Agressor ) )
02126	            return;
02127	
02128	        if( Agressor == Pawn )
02129	            return;
02130	
02131	        if( ( Agressor == Enemy ) || ( IsNearest( Enemy,Agressor ) ) )
02132	        {
02133	            Enemy = Agressor;
02134	            AddOrder(KillOrderPriority,Order_Kill,"Kill",Order_Seek);
02135	        }
02136	    }
02137	
02138	    event SeePlayer( Pawn Seen )
02139	    {
02140	        if( ! IsEnemy( Seen ) )
02141	            return;
02142	
02143	        if( ( MyWeaponIsAGrenad ) && ( VSize( Seen.Location - Pawn.Location ) > 1200 ) )
02144	           return;
02145	
02146	        if( Seen == Enemy )
02147	        {
02148	            if( IsShootable( Seen ) )
02149	                AddOrder(KillOrderPriority,Order_Kill,"Kill",Order_Seek);
02150	        }
02151	        else if( IsNearest( Enemy,Seen) )
02152	        {
02153	            Enemy = Seen;
02154	
02155	            if( IsShootable(Seen) )
02156	                AddOrder(KillOrderPriority,Order_Kill,"Kill",Order_Seek);
02157	            else
02158	                FindPathToMyEnemy();
02159	        }
02160	    }
02161	
02162	    function FindPathToMyEnemy()
02163	    {
02164	        local actor Path;
02165	
02166	        if( DBugBot )
02167	        {
02168	            Log("");
02169	            Log("[ BOT"@ID@"] : Search for"@Enemy);
02170	        }
02171	
02172	        Path = ExtendFindPathToward(Enemy);
02173	
02174	//        if( Path == none )
02175	//            Path = FindPathToward(Enemy);
02176	
02177	        if( Path == none )
02178	        {
02179	            if( DBugBot ) Log("    > Failed ....");
02180	            Enemy = none;
02181	        }
02182	        else
02183	        {
02184	            MoveTarget = Path;
02185	
02186	            if( DBugBot )
02187	                Log("    > Ok");
02188	        }
02189	    }
02190	
02191	Begin:
02192	
02193	    if( Pawn.Physics == PHYS_Falling )
02194	    {
02195	        while( true )
02196	        {
02197	            sleep( 0.1 );
02198	
02199	            if ( Pawn.Physics != PHYS_Falling )
02200	               break;
02201	        }
02202	    }
02203	
02204	    Pawn.ShouldCrouch( false );
02205	
02206	    if( Enemy != none )
02207	        FindPathToMyEnemy();
02208	    else
02209	    {
02210	        sleep(0.5);
02211	        RemoveOrder( Order_Seek );
02212	    }
02213	
02214	    if( Enemy == none )
02215	    {
02216	        if( DBugBot )
02217	            Log("[ BOT"@ID@"] : Enemy Lost");
02218	
02219	        sleep(0.5);
02220	        RemoveOrder( Order_Seek );
02221	    }
02222	    else
02223	    {
02224	        ActorPathStorage( Enemy);
02225	
02226	        for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
02227	        {
02228	            MoveTarget = PathCache[ PathIndex ];
02229	            Focus=MoveTarget;
02230	
02231	            if( Level.TimeSeconds - SeekTime > MaxSeekTime )
02232	                Enemy = none;
02233	
02234	            if( ( Enemy == none ) || ( Enemy.bIsDead ) )
02235	                RemoveOrder( Order_Seek );
02236	
02237	            Pawn.ShouldCrouch( false );
02238	            MoveToward( MoveTarget, Focus , MoveSpeed );
02239	        }
02240	    }
02241	
02242	    if( ( Enemy == none ) || ( Enemy.bIsDead ) )
02243	        RemoveOrder( Order_Seek );
02244	    else
02245	        Goto('Begin');
02246	}
02247	
02248	//__________________________________________________________________
02249	//__________________________________________________________________
02250	//                            Dead
02251	//__________________________________________________________________
02252	//__________________________________________________________________
02253	
02254	state Dead
02255	{
02256	    event BeginState()
02257	    {
02258	        if( DBugBot )
02259	        {
02260	            Log("");
02261	            Log("[ BOT"@ID@"] : *STATE* ---> Dead");
02262	            Log("    > ReSpawnTime"@RespawnTime$"sec");
02263	        }
02264	
02265	        bFire = 0;
02266	
02267	        if( NavToUpDate != none )
02268	        {
02269	            NavToUpDate.bSpecialCost=false;
02270	            NavToUpDate = none;
02271	        }
02272	
02273	        if( CheckGameEnded() )
02274	        {
02275	            if( DBugBot )
02276	                Log("[ AntiBug ][ BOT"@ID@"] : Dead --> GameEnded");
02277	
02278	            GotoState('GameEnded');
02279	        }
02280	        else
02281	            SetTimer( RespawnTime + 6 , false);
02282	    }
02283	
02284	    event EndState()
02285	    {
02286	       SetTimer(0.0, false );
02287	    }
02288	
02289	
02290	    event HearNoise( float Loudness, Actor NoiseMaker);
02291	    event SeePlayer( Pawn Seen );
02292	    function SomeoneWantKillMe( Pawn Agressor );
02293	
02294	    event Timer( )
02295	    {
02296	        Log("[ BOT"@ID@"] : Force ReInit");
02297	        SetTimer(0.0,false);
02298	        SetTimer2(0.0,false);
02299	        Initialize( ID,Skill,MyName );
02300	    }
02301	
02302	    function bool CheckGameEnded()
02303	    {
02304	    	local Controller C;
02305	    	local bool IsGameEnded;
02306	
02307	    	IsGameEnded = false;
02308	
02309	    	for ( C=Level.ControllerList; C!=None; C= C.NextController )
02310	    	{
02311	            if( C.IsInState('GameEnded') )
02312	            {
02313	            	IsGameEnded = true;
02314	            	break;
02315	            }
02316	    	}
02317	
02318	    	return IsGameEnded;
02319	    }
02320	
02321	Begin:
02322	
02323	    sleep( 0.5 );
02324	
02325	    if( CheckGameEnded() )
02326	    {
02327	        if( DBugBot )
02328	            Log("[ AntiBug ][ BOT"@ID@"] : Dead --> GameEnded");
02329	
02330	        GotoState('GameEnded');
02331	    }
02332	
02333	    Sleep(RespawnTime);
02334	
02335	    if( CheckGameEnded() )
02336	    {
02337	        if( DBugBot )
02338	            Log("[ AntiBug ][ BOT"@ID@"] : Dead --> GameEnded");
02339	
02340	        GotoState('GameEnded');
02341	    }
02342	    super.ServerReStartPlayer();
02343	    Initialize( ID,Skill,MyName );
02344	}
02345	
02346	//__________________________________________________________________
02347	//__________________________________________________________________
02348	//                            Jumping
02349	//__________________________________________________________________
02350	//__________________________________________________________________
02351	
02352	state Jumping
02353	{
02354	    event BeginState()
02355	    {
02356	        if( DBugBot )
02357	        {
02358	            Log("");
02359	            Log("[ BOT"@ID@"] : *STATE* ---> Jumping");
02360	        }
02361	    }
02362	
02363	    event HearNoise( float Loudness, Actor NoiseMaker);
02364	    event SeePlayer( Pawn Seen );
02365	    function SomeoneWantKillMe( Pawn Agressor );
02366	
02367	begin:
02368	
02369	    if( JumpTarget != none )
02370	    {
02371	        Focus = none;
02372	        FocalPoint = (JumpTarget.Location-Pawn.Location)*10000+Pawn.Location;
02373	        Pawn.Velocity = vector( rotator(JumpTarget.Location-Pawn.Location ) )*JumpSpeed;
02374	    }
02375	    else
02376	        Pawn.Velocity = vector( Pawn.Rotation)*JumpSpeed;
02377	
02378	    Pawn.JumpZ = JumpHeight;
02379	    Pawn.DoJump( true );
02380	
02381	    while( bIsJumping )
02382	    {
02383	       sleep(0.1);
02384	    }
02385	
02386	    FindMostImportantOrder();
02387	    ChangeState();
02388	}
02389	
02390	//__________________________________________________________________
02391	//__________________________________________________________________
02392	//                            Blind
02393	//__________________________________________________________________
02394	//__________________________________________________________________
02395	
02396	state Blind
02397	{
02398	    event BeginState()
02399	    {
02400	        if( DBugBot )
02401	        {
02402	            Log("");
02403	            Log("[ BOT"@ID@"] : *STATE* ---> @#$#%$ I'm Flashed");
02404	        }
02405	
02406	        Pawn.ShouldCrouch( true );
02407	        Enemy = none;
02408	
02409	        if( MyWeaponIsAGrenad )
02410	            SwitchWeapon();
02411	    }
02412	
02413	    function rotator AdjustAim(Ammunition FiredAmmunition, vector projStart, int aimerror)
02414	    {
02415	    	local rotator RotatorError;
02416	    	local float ErrorDelay, ErrorFactor, ShotError;
02417	
02418	    	if( Enemy == none )
02419	        	return ( Rotation );
02420	
02421	        if( Rand( 100 ) > (Skill+1)*5 )
02422	        {
02423	            ShotError = 200 + Rand( 400 ) - Skill*50;
02424	
02425	            if( Rand( 2 ) == 1 )
02426	                RotatorError.Yaw = ShotError;
02427	            else
02428	                RotatorError.Yaw = 65535-ShotError;
02429	        }
02430	
02431	        SetRotation( rotator(Enemy.GetBoneCoords('X Spine1').Origin-(Pawn.Location+Pawn.EyePosition()) ) );
02432	        Pawn.ControllerPitch = Rotation.Pitch / 256;
02433	
02434	        return ( Rotation + RotatorError );
02435	    }
02436	
02437	    event HearNoise( float Loudness, Actor NoiseMaker)
02438	    {
02439	        if( Enemy != none )
02440	            return;
02441	
02442	        if( Pawn( NoiseMaker ) != none )
02443	        {
02444	            Enemy = Pawn( NoiseMaker );
02445	            Focus = Enemy;
02446	        }
02447	    }
02448	
02449	    event SeePlayer( Pawn Seen );
02450	    function SomeoneWantKillMe( Pawn Agressor );
02451	
02452	begin:
02453	
02454	    while( DamnedImFlashed )
02455	    {
02456	        if( ( Enemy != none ) && ( ! MyWeaponIsAGrenad ) )
02457	        {
02458	            Focus = Enemy;
02459	
02460	            if( Pawn.Weapon.WeaponMode == WM_SemiAuto )
02461	            {
02462	                bFire=1;
02463	                Pawn.Weapon.Fire(0);
02464	                bFire=0;
02465	
02466	                Sleep( Pawn.Weapon.ShotTime );
02467	            }
02468	            else
02469	            {
02470	                bFire=1;
02471	                Pawn.Weapon.Fire(0);
02472	                Sleep( 2.5 - skill/2 );
02473	                bFire=0;
02474	            }
02475	
02476	            Sleep( 2.5 - skill/2 );
02477	        }
02478	        else
02479	            sleep(0.1);
02480	    }
02481	
02482	    FindMostImportantOrder();
02483	    ChangeState();
02484	}
02485	
02486	//__________________________________________________________________
02487	//__________________________________________________________________
02488	//                            SnipeSpot
02489	//__________________________________________________________________
02490	//__________________________________________________________________
02491	
02492	state SnipeSpot
02493	{
02494	    event BeginState()
02495	    {
02496	        if( DBugBot )
02497	        {
02498	            Log("");
02499	            Log("[ BOT"@ID@"] : *STATE* ---> Go To Good Snipe Spot");
02500	        }
02501	
02502	        Enemy = none;
02503	        Pawn.ControllerPitch = 0;
02504	        Pawn.ShouldCrouch( false );
02505	    }
02506	
02507	    event HearNoise( float Loudness, Actor NoiseMaker);
02508	
02509	    event SeePlayer( Pawn Seen )
02510	    {
02511	        if( ! IsEnemy( Seen ) )
02512	            return;
02513	
02514	        if( IsShootable( Seen ) )
02515	        {
02516	            Enemy = Seen;
02517	
02518	            AddOrder(KillOrderPriority,Order_Kill,"Kill",Order_SnipeSpot);
02519	        }
02520	    }
02521	
02522	    function SomeoneWantKillMe( Pawn Agressor )
02523	    {
02524	        if( Agressor == Pawn )
02525	            return;
02526	
02527	        if( ! IsEnemy( Agressor ) )
02528	            return;
02529	
02530	        Enemy = Agressor;
02531	        AddOrder(KillOrderPriority,Order_Kill,"Kill",Order_SnipeSpot);
02532	    }
02533	
02534	    function FindGoodSnipeSpot()
02535	    {
02536	        if( SnipeSpotList.Length == 0 )
02537	            SnipePoint = none;
02538	        else
02539	            SnipePoint = SnipeSpotList[Rand( SnipeSpotList.Length)];
02540	    }
02541	
02542	Begin:
02543	
02544	    FindGoodSnipeSpot();
02545	
02546	    if( SnipePoint != none )
02547	    {
02548	        while( true )
02549	        {
02550	            NavPathStorage(SnipePoint);
02551	
02552	            for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
02553	            {
02554	                MoveTarget = PathCache[ PathIndex ];
02555	                Focus=MoveTarget;
02556	
02557	                MoveToward( MoveTarget, Focus , MoveSpeed );
02558	            }
02559	
02560	            if( FullPath )
02561	                break;
02562	        }
02563	    }
02564	
02565	    AddOrder(KillOrderPriority,Order_SnipeAndKill,"Order_SnipeAndKill",Order_SnipeSpot);
02566	}
02567	
02568	
02569	//__________________________________________________________________
02570	//__________________________________________________________________
02571	//                            SnipeAndKill
02572	//__________________________________________________________________
02573	//__________________________________________________________________
02574	
02575	state SnipeAndKill
02576	{
02577	    event BeginState()
02578	    {
02579	        if( DBugBot )
02580	        {
02581	            Log("");
02582	            Log("[ BOT"@ID@"] : *STATE* ---> SnipeAndKill");
02583	        }
02584	
02585	        Pawn.velocity=vect(0,0,0);
02586	        Pawn.acceleration=vect(0,0,0);
02587	        Focus = none;
02588	        FocalPoint = vector(SnipePoint.rotation)+Pawn.Location;
02589	
02590	        if( SnipePathNode(SnipePoint).bDoNotCrouch )
02591	            Pawn.ShouldCrouch( false );
02592	        else
02593	            Pawn.ShouldCrouch( true );
02594	
02595	        SnipeTime = Level.TimeSeconds;
02596	        MaxSnipeTime = 30 + Rand( 30 );
02597	    }
02598	
02599	    event EndState()
02600	    {
02601	        bFire=0;
02602	    }
02603	
02604	    event EnemyNotVisible()
02605	    {
02606	        Enemy = none;
02607	        SetRotation( SnipePoint.Rotation );
02608	        Pawn.ControllerPitch = Rotation.Pitch / 256;
02609	    }
02610	
02611	    event SeePlayer( Pawn Seen )
02612	    {
02613	        if( ! IsEnemy( Seen ) )
02614	            return;
02615	
02616	        if( Enemy == none )
02617	        {
02618	            if( IsShootable(Seen) )
02619	                Enemy = Seen;
02620	        }
02621	        else if( Seen == Enemy )
02622	        {
02623	            if( ! IsShootable(Seen) )
02624	                Enemy = none;
02625	        }
02626	    }
02627	
02628	    function rotator AdjustAim(Ammunition FiredAmmunition, vector projStart, int aimerror)
02629	    {
02630	    	local rotator RotatorError;
02631	    	local float ShotError;
02632	    	local int HeadShotPercent;
02633	
02634	    	if( Enemy == none )
02635	        	return ( Rotation );
02636	
02637	        if( MissTheShoot() )
02638	        {
02639	            // Miss
02640	
02641	            ShotError = 200 + Rand(400);
02642	
02643	            if( Rand( 2 ) == 1 )
02644	                RotatorError.Yaw = ShotError;
02645	            else
02646	                RotatorError.Yaw = 65535-ShotError;
02647	        }
02648	        else
02649	            HeadShotPercent = 60 + Skill*10 ;
02650	
02651	
02652	        if( Rand( 100 ) < HeadShotPercent )
02653	        {
02654	            SetRotation( rotator(Enemy.GetBoneCoords('X Head').Origin-(Pawn.Location+Pawn.EyePosition()) ) );
02655	            Pawn.ControllerPitch = Rotation.Pitch / 256;
02656	        }
02657	        else
02658	        {
02659	            SetRotation( rotator(Enemy.GetBoneCoords('X Spine1').Origin-(Pawn.Location+Pawn.EyePosition()) ) );
02660	            Pawn.ControllerPitch = Rotation.Pitch / 256;
02661	        }
02662	
02663	        return ( Rotation + RotatorError );
02664	    }
02665	
02666	    function SomeoneWantKillMe( Pawn Agressor )
02667	    {
02668	        if( ! PathErrorToAllLife )
02669	        {
02670	            if( FindOrder( Order_Life ) )
02671	                ModifyOrder( Order_Life, GetLifePriority() );
02672	            else
02673	                AddOrder(GetLifePriority(),Order_Life,"Life",0);
02674	        }
02675	
02676	        if( ! IsEnemy( Agressor ) )
02677	            return;
02678	
02679	        if( Agressor == Enemy )
02680	            return;
02681	
02682	        if( Agressor == Pawn )
02683	            return;
02684	
02685	        if( ( Enemy == none ) || ( IsNearest( Enemy,Agressor) )  )
02686	            Enemy = Agressor;
02687	    }
02688	
02689	Begin:
02690	
02691	    if( Pawn.WeaponMode != 'FM_Snipe' )
02692	        RemoveOrder( Order_SnipeAndKill );
02693	
02694	    while( true )
02695	    {
02696	        if( Enemy != none )
02697	        {
02698	            Focus = enemy;
02699	
02700	            AimTime = 0.5 + FRand();
02701	            Sleep( AimTime );
02702	
02703	            bFire=1;
02704	
02705	            sleep( Pawn.Weapon.ShotTime );
02706	
02707	            Pawn.Weapon.Fire(0);
02708	            bFire=0;
02709	
02710	            if( ! Pawn.Weapon.HasAmmo() )
02711	                RemoveOrder( Order_SnipeAndKill );
02712	        }
02713	        else
02714	            Sleep( 0.2 );
02715	
02716	        if( ( Enemy == none ) || ( Enemy.bIsDead ) )
02717	        {
02718	            Enemy = none;
02719	            bFire=0;
02720	
02721	            if( Level.TimeSeconds - SnipeTime > MaxSnipeTime )
02722	                RemoveOrder( Order_SnipeAndKill );
02723	        }
02724	    }
02725	}
02726	
02727	
02728	//__________________________________________________________________
02729	//__________________________________________________________________
02730	//                            UnBlock
02731	//__________________________________________________________________
02732	//__________________________________________________________________
02733	
02734	state UnBlock
02735	{
02736	    event BeginState()
02737	    {
02738	        if( DBugBot )
02739	        {
02740	            Log("");
02741	            Log("[ BOT"@ID@"] : *STATE* ---> UnBlock");
02742	        }
02743	
02744	        Enemy = none;
02745	        Pawn.ControllerPitch = 0;
02746	        Pawn.ShouldCrouch( false );
02747	    }
02748	
02749	    //--------------------------------------------------------------
02750	
02751	    event EndState()
02752	    {
02753	        TrakNarPoint = none;
02754	    }
02755	
02756	    //--------------------------------------------------------------
02757	
02758	    function GetRandomUnblockPoint()
02759	    {
02760	        local NavigationPoint Nav;
02761	        local Array<NavigationPoint> UseablePoint;
02762	
02763	        Nav = Level.NavigationPointList;
02764	
02765	        while( Nav != none)
02766	        {
02767	            if( Nav.IsA('PlayerStart') )
02768	            {
02769	                UseablePoint.Length = UseablePoint.Length+1;
02770	                UseablePoint[ UseablePoint.Length-1 ] = Nav;
02771	            }
02772	
02773	            Nav = Nav.NextNavigationPoint;
02774	        }
02775	
02776	        TrakNarPoint = UseablePoint[ Rand(UseablePoint.Length) ];
02777	    }
02778	
02779	    //--------------------------------------------------------------
02780	
02781	Begin:
02782	
02783	    if( Pawn.Physics == PHYS_Falling )
02784	    {
02785	        while( true )
02786	        {
02787	            sleep( 0.1 );
02788	
02789	            if ( Pawn.Physics != PHYS_Falling )
02790	               break;
02791	        }
02792	    }
02793	
02794	    Pawn.ShouldCrouch( false );
02795	
02796	    GetRandomUnblockPoint();
02797	
02798	    if( TrakNarPoint == none )
02799	    {
02800	        log("!!! OUPS !!!");
02801	        Sleep(3.0);
02802	        RemoveOrder( Order_UnBlock );
02803	    }
02804	
02805	    while( true )
02806	    {
02807	        NavPathStorage(TrakNarPoint);
02808	
02809	        for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
02810	        {
02811	            MoveTarget = PathCache[ PathIndex ];
02812	            Focus=MoveTarget;
02813	
02814	            MoveToward( MoveTarget, Focus , MoveSpeed );
02815	        }
02816	
02817	        if( FullPath )
02818	            break;
02819	    }
02820	
02821	    RemoveOrder( Order_UnBlock );
02822	}
02823	
02824	
02825	
02826	//__________________________________________________________________
02827	//__________________________________________________________________
02828	//                            TrakNar
02829	//__________________________________________________________________
02830	//__________________________________________________________________
02831	
02832	state TrakNar
02833	{
02834	    event BeginState()
02835	    {
02836	        if( DBugBot )
02837	        {
02838	            Log("");
02839	            Log("[ BOT"@ID@"] : *STATE* ---> TrakNar");
02840	        }
02841	
02842	        Enemy = none;
02843	        Pawn.ControllerPitch = 0;
02844	
02845	        Pawn.ShouldCrouch( false );
02846	    }
02847	
02848	    event EndState()
02849	    {
02850	        if( Pawn != none )
02851	            Pawn.SpineYawControl(false,3000, 1.2);
02852	    }
02853	
02854	    event HearNoise( float Loudness, Actor NoiseMaker);
02855	
02856	    function FindGoodTrakNarSpot()
02857	    {
02858	        if( TrakNarSpotList.Length == 0 )
02859	            TrakNarPoint = none;
02860	        else
02861	            TrakNarPoint = TrakNarSpotList[Rand( TrakNarSpotList.Length)];
02862	    }
02863	
02864	Begin:
02865	
02866	    if( Pawn.Physics == PHYS_Falling )
02867	    {
02868	        while( true )
02869	        {
02870	            sleep( 0.1 );
02871	
02872	            if ( Pawn.Physics != PHYS_Falling )
02873	               break;
02874	        }
02875	    }
02876	
02877	    Pawn.ShouldCrouch( false );
02878	
02879	    FindGoodTrakNarSpot();
02880	
02881	    if( TrakNarPoint != none )
02882	    {
02883	        while( true )
02884	        {
02885	            NavPathStorage(TrakNarPoint);
02886	
02887	            for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
02888	            {
02889	                MoveTarget = PathCache[ PathIndex ];
02890	                Focus=MoveTarget;
02891	
02892	                Pawn.ShouldCrouch( false );
02893	                MoveToward( MoveTarget, Focus , MoveSpeed );
02894	            }
02895	
02896	            if( FullPath )
02897	                break;
02898	        }
02899	    }
02900	
02901	    if( Beretta(Pawn.Weapon) == none )
02902	    {
02903	        Pawn.velocity=vect(0,0,0);
02904	        Pawn.acceleration=vect(0,0,0);
02905	        Focus = none;
02906	        FocalPoint = vector(TrakNarPoint.Rotation)+Pawn.Location;
02907	
02908	        if( ( Rand( 100 ) < 20 + Skill*20 ) || ( TrakNarPathNode(TrakNarPoint).bShouldCrouch ) )
02909	        {
02910	            Pawn.ShouldCrouch( true );
02911	            InitShotError(True);
02912	        }
02913	        else
02914	            InitShotError(false);
02915	
02916	        Pawn.SpineYawControl(true,3000, 1.2);
02917	
02918	        Sleep( 10 + Rand( 5 ) );
02919	    }
02920	
02921	    RemoveOrder(Order_TrakNar);
02922	}
02923	
02924	
02925	//__________________________________________________________________
02926	//__________________________________________________________________
02927	//                            GameEnded
02928	//__________________________________________________________________
02929	//__________________________________________________________________
02930	
02931	state GameEnded
02932	{
02933	    event BeginState()
02934	    {
02935	        if( DBugBot )
02936	        {
02937	            Log("");
02938	            Log("[ BOT"@ID@"] : *STATE* ---> GameEnded");
02939	        }
02940	
02941	        bFire=0;
02942	        Enemy = none;
02943	
02944			if (pawn!=none)
02945			{
02946	        Pawn.ControllerPitch = 0;
02947	        Pawn.ShouldCrouch( false );
02948	        Pawn.velocity=vect(0,0,0);
02949	        Pawn.acceleration=vect(0,0,0);
02950			}
02951	
02952	        SetTimer(0.0,false);
02953	        SetTimer2(0.0,false);
02954	        SetTimer3(0.0,false);
02955	
02956	        if( NavToUpDate != none )
02957	        {
02958	            NavToUpDate.bSpecialCost=false;
02959	            NavToUpDate = none;
02960	        }
02961	    }
02962	
02963	    event HearNoise( float Loudness, Actor NoiseMaker);
02964	    event SeePlayer( Pawn Seen );
02965	    function SomeoneWantKillMe( Pawn Agressor );
02966	
02967	    event Timer();
02968	    event Timer2();
02969	    event Timer3();
02970	}
02971	
02972	//__________________________________________________________________
02973	//__________________________________________________________________
02974	//                            GrenadLauncher
02975	//__________________________________________________________________
02976	//__________________________________________________________________
02977	
02978	state GrenadLauncher
02979	{
02980	    event BeginState()
02981	    {
02982	        if( DBugBot )
02983	        {
02984	            Log("");
02985	            Log("[ BOT"@ID@"] : *STATE* ---> Grenad Launcher");
02986	            Log("    > Target :"@MyGrenadTarget.Target);
02987	        }
02988	
02989	        Focus = MyGrenadTarget.Target;
02990	        Pawn.velocity=vect(0,0,0);
02991	        Pawn.acceleration=vect(0,0,0);
02992	
02993	        if( GrenadIsLauched )
02994	            RemoveOrder( Order_GrenadLauncher );
02995	    }
02996	
02997	    //--------------------------------------------------------------
02998	
02999	    event EndState()
03000	    {
03001	        bFire=0;
03002	        SetTimer(0.0,false);
03003	        SetTimer2(0.0,false);
03004	        GrenadIsLauched = true;
03005	    }
03006	
03007	    //--------------------------------------------------------------
03008	
03009	    event SeePlayer( Pawn Seen )
03010	    {
03011	        if( Focus == none )
03012	            global.SeePlayer( Seen );
03013	    }
03014	
03015	    //--------------------------------------------------------------
03016	
03017	    event EnemyNotVisible();
03018	
03019	    //--------------------------------------------------------------
03020	
03021	    event HearNoise( float Loudness, Actor NoiseMaker);
03022	
03023	    //--------------------------------------------------------------
03024	
03025	    event Timer()
03026	    {
03027	        bFire=1;
03028	        Pawn.Weapon.Fire(0);
03029	
03030	        SetTimer2(0.5,false);
03031	        SetTimer(0.0,false);
03032	    }
03033	
03034	    //--------------------------------------------------------------
03035	
03036	    event Timer2()
03037	    {
03038	        bFire=0;
03039	        Pawn.Weapon.AIRating = 0.11;
03040	        SwitchWeapon();
03041	
03042	        SetTimer2(0.0,false);
03043	
03044	        gotostate('GrenadLauncher','GoToHide');
03045	    }
03046	
03047	    //--------------------------------------------------------------
03048	
03049	    function SomeoneWantKillMe( Pawn Agressor )
03050	    {
03051	        if( Focus == none )
03052	            global.SomeoneWantKillMe( Agressor );
03053	    }
03054	
03055	
03056	    //--------------------------------------------------------------
03057	
03058	Begin:
03059	
03060	    While( true )
03061	    {
03062	        Sleep( 0.5 );
03063	
03064	        if( ( FlashBangBot(Pawn.Weapon) != none ) || ( Grenad(Pawn.Weapon) != none ) )
03065	        {
03066	            SetTimer( 0.5, false );
03067	            gotostate('GrenadLauncher','WaitToLauch');
03068	        }
03069	    }
03070	
03071	WaitToLauch:
03072	
03073	    While( true )
03074	    {
03075	        Sleep( 0.5 );
03076	    }
03077	
03078	GoToHide:
03079	
03080	    Pawn.ControllerPitch = 0;
03081	
03082	    while( true )
03083	    {
03084	        NavPathStorage(MyGrenadTarget.HidePoint);
03085	
03086	        for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
03087	        {
03088	            MoveTarget = PathCache[ PathIndex ];
03089	            Focus=MoveTarget;
03090	
03091	            MoveToward( MoveTarget, Focus , MoveSpeed );
03092	        }
03093	
03094	        if( FullPath )
03095	            break;
03096	    }
03097	
03098	    Enemy = none;
03099	
03100	    Pawn.velocity=vect(0,0,0);
03101	    Pawn.acceleration=vect(0,0,0);
03102	
03103	    Focus = none;
03104	    FocalPoint = vector(MyGrenadTarget.HidePoint.Rotation)*1000+Pawn.Location;
03105	
03106	    Sleep( 2.0 );
03107	
03108	    if ( DBugOrder ) log("RemoveOrder Order_GrenadLauncher");
03109	
03110	    RemoveOrder( Order_GrenadLauncher );
03111	}
03112	
03113	//__________________________________________________________________
03114	
03115	
03116	
03117	
03118	defaultproperties
03119	{
03120	     Id=-1
03121	     MaxShotErrorTime=4.000000
03122	     RespawnTime=4
03123	     MaxSeekDist_Life=1500
03124	     MaxSeekDist_Weapon=1500
03125	     MaxSeekDist_Armor=1500
03126	     AttackArea=1000
03127	     MissPercent=5.000000
03128	     StraffeDelay=0.150000
03129	     bIsPlayer=True
03130	     PlayerReplicationInfoClass=Class'XIII.XIIIPlayerReplicationInfo'
03131	}

End Source Code