XIII
Class XIIITransientACreature

source: C:\XIII\XIII\Classes\XIIITransientACreature.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Controller
         |
         +--Engine.AIController
            |
            +--XIII.XIIITransientACreature
Direct Known Subclasses:XIIIBirds

class XIIITransientACreature
extends Engine.AIController

//-----------------------------------------------------------
Variables
 class AltPredatorType
           who eats my pawns (optional)
 float FlockRadius
           radius in which to spawn slaves
 class LocationTypeForSpawn
           the points where the creatures should be spawned
 float MaxSpawnDist
           maximum distance for spawning in player's line of sight
 float MinSpawnDist
           minimum distance for spawning in player's line of sight
 XIIICreatureManager MyManager
 XIIITransientACreature NextCreature
           transient ambient creature list managed by AmbientCreatureManager
 int NumSlaves
           number of slave pawns
 class PawnTypes[8]
           pawns which can be controlled by this controller on land - pick one when spawning
 class PickedClass
           if true, my pawns are meant for underwater
 class PredatorType
           who eats my pawns (optional)
 XIIITransientACreature Prey
           if hunter, what I'm hunting
 XIIITransientACreature Replacement
           replacement if destroyed because of wrong zone
 Keypoint StartingSpot
           Starting Spot to turn/move around if needed
 class UnderWaterType
           who to replace me with underwater (optional)
 bool bOffCameraSpawns
           if true, use off camera spawns
 bool bUnderWaterCreatures
           if true, my pawns are meant for underwater

States
Wandering

Function Summary
 void AddPawn()
     
//_____________________________________________________________________________
 void AddSlaves(XIIITransientAPawn Last, int SpawnNum)
     
//_____________________________________________________________________________
 void Destroyed()
     
//_____________________________________________________________________________
 vector FindGround(PlayerController Viewer, vector StartLoc)
     
//_____________________________________________________________________________
 vector FindSpawnLocation(float Dist, vector SpawnDir, PlayerController Viewer)
     
/* FindSpawnLocation()
Find a suitable spawn location for the ambient creature (far enough away from the player)
if none can be found, returns vect(0,0,0)
*/
 vector InitialLocation(vector CurrentLocation)
     
//_____________________________________________________________________________
 float MaxHiddenTime()
     
//_____________________________________________________________________________
 void NotVisible()
     
//_____________________________________________________________________________
 void PawnDied()
     
//_____________________________________________________________________________
 vector PickDestination(XIIITransientAPawn P)
     
//_____________________________________________________________________________
 void PickSlaveDestination(XIIITransientAPawn P)
     
//_____________________________________________________________________________
 void PostBeginPlay()
     
//_____________________________________________________________________________
 void SlavePawnDied(Pawn P)
     
//_____________________________________________________________________________
 Rotator SpawnRotation()
     
//_____________________________________________________________________________
 XIIITransientAPawn SpawnSlave()
     
//_____________________________________________________________________________


State Wandering Function Summary



Source Code


00001	
00002	// TransientAmbientCreature
00003	// The base class of controllers for ambient creatures which are created an destroyed
00004	// on the client as the player walks around (small stuff like bugs, birds, etc.)
00005	
00006	//-----------------------------------------------------------
00007	class XIIITransientACreature extends AIController;
00008	
00009	var XIIICreatureManager MyManager;
00010	var XIIITransientACreature NextCreature;    // transient ambient creature list managed by AmbientCreatureManager
00011	var class<Pawn> PawnTypes[8];               // pawns which can be controlled by this controller on land - pick one when spawning
00012	var class<XIIITransientACreature> PredatorType;    // who eats my pawns (optional)
00013	var class<XIIITransientACreature> AltPredatorType; // who eats my pawns (optional)
00014	var class<XIIITransientACreature> UnderWaterType;  // who to replace me with underwater (optional)
00015	var float MinSpawnDist;                     // minimum distance for spawning in player's line of sight
00016	var float MaxSpawnDist;                     // maximum distance for spawning in player's line of sight
00017	var bool  bOffCameraSpawns;                 // if true, use off camera spawns
00018	var bool  bUnderWaterCreatures;             // if true, my pawns are meant for underwater
00019	var class<Pawn> PickedClass;
00020	var XIIITransientACreature Prey;            // if hunter, what I'm hunting
00021	var float FlockRadius;                      // radius in which to spawn slaves
00022	var int NumSlaves;                          // number of slave pawns
00023	var XIIITransientACreature Replacement;     // replacement if destroyed because of wrong zone
00024	var class<XIIICreaturePoint> LocationTypeForSpawn;  // the points where the creatures should be spawned
00025	var KeyPoint StartingSpot;                  // Starting Spot to turn/move around if needed
00026	
00027	
00028	//_____________________________________________________________________________
00029	function PostBeginPlay()
00030	{
00031	    Super.PostBeginPlay();
00032	
00033	    MyManager = XIIICreatureManager(Owner);
00034	    Prey = MyManager.Prey;
00035	
00036	    // make sure in an appropriate zone
00037	    if ( PhysicsVolume.bPainCausing )
00038	    {
00039	      Destroy();
00040	      return;
00041	    }
00042	    if ( PhysicsVolume.bWaterVolume != bUnderWaterCreatures )
00043	    {
00044	      // try to replace me with underwater alternative
00045	      if ( UnderWaterType != None )
00046	        Replacement = spawn(UnderWaterType, Owner);
00047	
00048	      Destroy();
00049	      return;
00050	    }
00051	
00052	    AddPawn();
00053	}
00054	
00055	//_____________________________________________________________________________
00056	function AddSlaves(XIIITransientAPawn Last, int SpawnNum)
00057	{
00058	    while (SpawnNum > 0)
00059	    {
00060	      SpawnNum--;
00061	      Last.NextSlave = SpawnSlave();
00062	      if ( Last.NextSlave != None )
00063	      {
00064	        NumSlaves--;
00065	        Last.NextSlave.Controller = self;
00066	        Last = Last.NextSlave;
00067	      }
00068	    }
00069	}
00070	
00071	//_____________________________________________________________________________
00072	function XIIITransientAPawn SpawnSlave()
00073	{
00074	    local vector V, HitNormal, HitLocation;
00075	    local actor HitActor;
00076	    local float HitTime;
00077	
00078	    V = InitialLocation(Pawn.Location);
00079	    // check trace
00080	    HitActor = Trace(HitLocation, HitNormal, V, Pawn.Location, false);
00081	    if ( HitActor != None )
00082	      V = HitLocation - (2 + Pawn.CollisionRadius) * Normal(V - Pawn.Location);
00083	    return XIIITransientAPawn(spawn(Pawn.Class,self,,V));
00084	}
00085	
00086	//_____________________________________________________________________________
00087	function vector InitialLocation(vector CurrentLocation)
00088	{
00089	    return (CurrentLocation + VRand() * FlockRadius);
00090	}
00091	
00092	//_____________________________________________________________________________
00093	function AddPawn()
00094	{
00095	    local int NumClasses;
00096	    local Pawn P;
00097	
00098	    // add an appropriate pawn
00099	    // note that I've been spawned at ground level
00100	    if ( PickedClass == None )
00101	    {
00102	      While ( NumClasses < ArrayCount(PawnTypes) )
00103	      {
00104	        if ( PawnTypes[NumClasses] != None )
00105	          NumClasses++;
00106	        else
00107	          break;
00108	      }
00109	      if ( NumClasses == 0 )
00110	      {
00111	        log(self$" have No pawn classes to spawn");
00112	        return;
00113	      }
00114	      PickedClass = PawnTypes[Rand(NumClasses)];
00115	    }
00116	    P = Spawn(PickedClass,self,,Location + (PickedClass.Default.CollisionHeight + 2) * Vect(0,0,1), SpawnRotation());
00117	    log("AddPawn : "$self$" Spawned his pawn "$P);
00118	    if ( P != None )
00119	      Possess(P);
00120	    if ( Pawn == None )
00121	      Destroy();
00122	    else
00123	    {
00124	      Pawn.LastRenderTime = Level.TimeSeconds;
00125	      if ( NumSlaves > 0 )
00126	        Pawn.SetTimer(0.2, true);
00127	    }
00128	}
00129	
00130	//_____________________________________________________________________________
00131	function Rotator SpawnRotation()
00132	{
00133	    local Rotator SpawnRot;
00134	
00135	    SpawnRot.Yaw = Rand(65535);
00136	    return SpawnRot;
00137	}
00138	
00139	//_____________________________________________________________________________
00140	function Destroyed()
00141	{
00142	    if ( MyManager != None )
00143	      MyManager.RemoveCreature(self);
00144	    Super.Destroyed();
00145	}
00146	
00147	//_____________________________________________________________________________
00148	function NotVisible()
00149	{
00150	    if ( Pawn == None )
00151	    {
00152	      PawnDied();
00153	      return;
00154	    }
00155	    XIIITransientAPawn(Pawn).VerifyLastRenderTime();
00156	    if ( Level.TimeSeconds - Pawn.LastRenderTime > MaxHiddenTime() )
00157	      XIIITransientAPawn(Pawn).DestroyAll();
00158	}
00159	
00160	//_____________________________________________________________________________
00161	function float MaxHiddenTime()
00162	{
00163	    return ( 10 + 5 * FRand() );
00164	}
00165	
00166	//_____________________________________________________________________________
00167	function SlavePawnDied(Pawn P)
00168	{
00169	    if ( P == Pawn )
00170	      PawnDied();
00171	}
00172	
00173	//_____________________________________________________________________________
00174	function PawnDied()
00175	{
00176	    if ( XIIITransientAPawn(Pawn).NextSlave != None )
00177	      Possess(XIIITransientAPawn(Pawn).NextSlave);
00178	    else
00179	      Destroy();
00180	}
00181	
00182	//_____________________________________________________________________________
00183	/* FindSpawnLocation()
00184	Find a suitable spawn location for the ambient creature (far enough away from the player)
00185	if none can be found, returns vect(0,0,0)
00186	*/
00187	static function vector FindSpawnLocation(float Dist, vector SpawnDir, PlayerController Viewer)
00188	{
00189	    local rotator SpawnRot;
00190	    local actor HitActor;
00191	    local vector HitLocation, HitNormal, SpawnLoc, StartLoc;
00192	    // FIXME - some creatures may look for fixed spawn points (e.g. bat cave)
00193	
00194	    // if off camera spawning, then modify spawndir
00195	    // FIXME - don't always if beyond max visible distance (where thing is less than one pixel)
00196	    if ( Default.bOffCameraSpawns && (!Viewer.Region.Zone.bDistanceFog || (Viewer.Region.Zone.DistanceFogEnd > Dist))  )
00197	    {
00198	      SpawnRot = Rotator(SpawnDir);
00199	      if ( FRand() < 0.5 )
00200	        SpawnRot.Yaw += Viewer.FOVAngle * 182; // 65536/360
00201	      else
00202	        SpawnRot.Yaw -= Viewer.FOVAngle * 182; // 65536/360
00203	
00204	      SpawnDir = Vector(SpawnRot);
00205	    }
00206	    SpawnLoc = Viewer.ViewTarget.Location + Dist * SpawnDir;
00207	    // find ground
00208	    HitActor = Viewer.Trace(HitLocation, HitNormal, SpawnLoc, Viewer.ViewTarget.Location + Viewer.ViewTarget.CollisionRadius * Vect(0,0,1), false);
00209	
00210	    if ( HitActor == None )
00211	      return FindGround(Viewer, SpawnLoc);
00212	
00213	    //  OK - try to go over obstacle
00214	    HitActor = Viewer.Trace(HitLocation, HitNormal, HitLocation - 50 * HitNormal, HitLocation, false);
00215	
00216	    if ( HitActor != None )
00217	    {
00218	      // give up?
00219	      if ( (HitNormal.Z < 0.8)
00220	        || (VSize(HitLocation - Viewer.ViewTarget.Location) < Default.MinSpawnDist) )
00221	        return vect(0,0,0);
00222	
00223	      return HitLocation;
00224	    }
00225	
00226	    // ok- go up
00227	    StartLoc = HitLocation - 100 * HitNormal + vect(0,0,500);
00228	    HitActor = Viewer.Trace(HitLocation, HitNormal, StartLoc, HitLocation - 100 * HitNormal, false);
00229	
00230	    if ( HitActor != None )
00231	      StartLoc = HitLocation;
00232	    Dist = VSize(HitLocation - SpawnLoc);
00233	    HitActor = Viewer.Trace(HitLocation, HitNormal, StartLoc + Dist * SpawnDir, StartLoc, false);
00234	
00235	    if ( HitActor == None )
00236	      return FindGround(Viewer, SpawnLoc);
00237	    else if ( HitNormal.Z >= 0.8 )
00238	      return HitLocation;
00239	
00240	    return vect(0,0,0);
00241	}
00242	
00243	//_____________________________________________________________________________
00244	static function vector FindGround(PlayerController Viewer, vector StartLoc)
00245	{
00246	    local actor HitActor;
00247	    local vector HitLocation, HitNormal;
00248	
00249	    // find ground
00250	    HitActor = Viewer.Trace(HitLocation, HitNormal, StartLoc - vect(0,0,10000), StartLoc, false);
00251	    if ( (HitActor == None) || (HitNormal.Z < 0.8) )
00252	      return Vect(0,0,0);
00253	
00254	    return HitLocation;
00255	}
00256	
00257	//_____________________________________________________________________________
00258	function vector PickDestination(XIIITransientAPawn P)
00259	{
00260	    return Pawn.Location;
00261	}
00262	
00263	//_____________________________________________________________________________
00264	function PickSlaveDestination(XIIITransientAPawn P);
00265	
00266	//_____________________________________________________________________________
00267	auto State Wandering
00268	{
00269	Begin:
00270	    Destination = PickDestination(XIIITransientAPawn(Pawn));
00271	    FocalPoint = Destination;
00272	    Sleep(XIIITransientAPawn(Pawn).MoveTimeTo(Destination));
00273	    if ( AmbientSound != None )
00274	      SetLocation(Pawn.Location);
00275	    Goto('Begin');
00276	}
00277	
00278	//     UnderWaterType=class'AmbientCreatures.FishSchool'
00279	
00280	
00281	defaultproperties
00282	{
00283	     MinSpawnDist=500.000000
00284	     MaxSpawnDist=3000.000000
00285	     bOffCameraSpawns=True
00286	     FlockRadius=200.000000
00287	     RemoteRole=ROLE_None
00288	}

End Source Code