## XIII
Class XIIICreatureManager

source: C:\XIII\XIII\Classes\XIIICreatureManager.uc

    Core.Object
       |
       +--Engine.Actor
          |
          +--Engine.Info
             |
             +--XIII.XIIICreatureManager

Direct Known Subclasses:MouettesManager

class XIIICreatureManager
extends Engine.Info

    //-----------------------------------------------------------
    //
    //-----------------------------------------------------------

Variables
`PlayerController` | `LocalPlayer` number of TransientAmbientCreature classes (determined in postbeginplay)
`int` | `MaxCreatures` Number of creatures controlled
`XIIITransientACreature` | `MyCreatures` Ambient creature list
`int` | `NumClasses` number of TransientAmbientCreature classes (determined in postbeginplay)
`int` | `NumCreatures` Number of creatures controlled
`XIIITransientACreature` | `Prey` last spawned creature - could be prey for next spawn
`int` | `SpawnRadius` radius of area to spawn creatures
`class` | `TransientCreatures[8]` allowable TransientAmbientCreature classes
`int` | `TriggerRadius` radius of area to be triggered by player

Function Summary
`bool` | `InSpawnRange()`
    //_____________________________________________________________________________
`void` | `PostBeginPlay()`
    //_____________________________________________________________________________
`void` | `RemoveCreature(XIIITransientACreature Remove)`
    //_____________________________________________________________________________
`void` | `SpawnAllCreaturesFromSpots()`
    //_____________________________________________________________________________
`void` | `Timer()`
    //_____________________________________________________________________________
    // check if should spawn or destroy temporary ambient creatures

Source Code

    00001	//-----------------------------------------------------------
    00002	//
    00003	//-----------------------------------------------------------
    00004	class XIIICreatureManager extends Info
    00005	     abstract
    00006	     placeable;
    00007
    00008	var XIIITransientACreature MyCreatures;   // Ambient creature list
    00009	var int NumCreatures;                     // Number of creatures controlled
    00010	var() int MaxCreatures;
    00011	var() class<XIIITransientACreature> TransientCreatures[8];  // allowable TransientAmbientCreature classes
    00012	var int NumClasses;                       // number of TransientAmbientCreature classes (determined in postbeginplay)
    00013	var PlayerController LocalPlayer;
    00014	var() int SpawnRadius;                    // radius of area to spawn creatures
    00015	var() int TriggerRadius;                  // radius of area to be triggered by player
    00016	var XIIITransientACreature Prey;          // last spawned creature - could be prey for next spawn
    00017
    00018	//_____________________________________________________________________________
    00019	function PostBeginPlay()
    00020	{
    00021	    local int i;
    00022
    00023	    log(self$" starting up!!!");
    00024	    Super.PostBeginPlay();
    00025
    00026	    if (Level.NetMode == NM_DedicatedServer )
    00027	    {
    00028	      Destroy();
    00029	      return;
    00030	    }
    00031
    00032	    For ( i=0; i<ArrayCount(TransientCreatures); i++ )
    00033	      if ( TransientCreatures[NumClasses] != None )
    00034	        NumClasses++;
    00035
    00036	    log(self$" started up w/ "$NumClasses$" TransientCreatures types");
    00037
    00038	    if ( TransientCreatures[0].default.LocationTypeForSpawn != none )
    00039	    {
    00040	      // We do spawn creatures on specific spots.
    00041	      SpawnAllCreaturesFromspots();
    00042	      log("all Creature Spawns should be done now on the correct location...");
    00043	    }
    00044	    else
    00045	      SetTimer(1.0,true);
    00046	}
    00047
    00048	//_____________________________________________________________________________
    00049	function XIIITransientACreature AddCreature(Class<XIIITransientACreature> SpawnClass, vector SpawnLoc, rotator SpawnRot)
    00050	{
    00051	    local XIIITransientACreature A;
    00052
    00053	    A = spawn(SpawnClass,self,,SpawnLoc+SpawnClass.Default.CollisionHeight*vect(0,0,1), SpawnRot);
    00054
    00055
    00056	    if ( (A != None) && A.bDeleteMe )
    00057	      A = A.Replacement;
    00058	    if ( (A != None) && !A.bDeleteMe )
    00059	    {
    00060	      A.NextCreature = MyCreatures;
    00061	      MyCreatures = A;
    00062	      NumCreatures++;
    00063	      return A;
    00064	    }
    00065	    return none;
    00066	}
    00067
    00068	//_____________________________________________________________________________
    00069	function RemoveCreature(XIIITransientACreature Remove)
    00070	{
    00071	    local XIIITransientACreature A;
    00072
    00073	    // check if A is in my list
    00074	    if ( Remove == MyCreatures )
    00075	      MyCreatures = Remove.NextCreature;
    00076	    else
    00077	    {
    00078	      for ( A=MyCreatures; A!=None; A=A.NextCreature )
    00079	        if ( A.NextCreature == Remove )
    00080	        {
    00081	          A.NextCreature = Remove.NextCreature;
    00082	          break;
    00083	        }
    00084	    }
    00085
    00086	    NumCreatures--;
    00087	}
    00088
    00089	//_____________________________________________________________________________
    00090	function bool InSpawnRange()
    00091	{
    00092	    return ( VSize(Location - LocalPlayer.Location) < SpawnRadius  );
    00093	}
    00094
    00095	//_____________________________________________________________________________
    00096	// check if should spawn or destroy temporary ambient creatures
    00097	function Timer()
    00098	{
    00099	    local XIIITransientACreature A;
    00100	    local Controller C;
    00101	    local class<XIIITransientACreature> SpawnClass;
    00102	    local float Dist;
    00103	    local vector SpawnLoc, SpawnDir, ViewPos;
    00104
    00105	    // make sure I know who my player is
    00106	    if ( LocalPlayer == None )
    00107	    {
    00108	      for ( C=Level.ControllerList; C!=None; C=C.NextController )
    00109	        if ( C.IsA('PlayerController')
    00110	          && (Viewport(PlayerController(C).Player) != None) )
    00111	        {
    00112	          LocalPlayer = PlayerController(C);
    00113	          break;
    00114	        }
    00115	    }
    00116
    00117	    for ( A=MyCreatures; A!=None; A=A.NextCreature )
    00118	      if ( Level.TimeSeconds - A.Pawn.LastRenderTime > 1 )
    00119	        A.NotVisible(); // after a few seconds, destroy
    00120
    00121	    // Add transient creature
    00122	    // Note - pawns will also inform me when they die, so I can spawn appropriate carrion feeders (after a little while)
    00123	    // and herd animals will ask for bugs
    00124	    // only add optional creatures if frame rate is high enough and there aren't too many
    00125	    // FIXME - add more initially, reduce maxcreatures if combat (how do you determine that?)
    00126	    log("Almost add creature, last render "$Region.Zone.LastRenderTime$" for "$Region.Zone);
    00127	    if ( Level.bDropDetail || (NumCreatures >= MaxCreatures)
    00128	//      || (Level.TimeSeconds - Region.Zone.LastRenderTime > 0.5)
    00129	      || (VSize(LocalPlayer.ViewTarget.Location - Location) > TriggerRadius) )
    00130	    {
    00131	      return;
    00132	    }
    00133
    00134	    // maybe wait a bit
    00135	    if ( VSize(LocalPlayer.ViewTarget.Velocity) < 200 )
    00136	    {
    00137	      if ( FRand() < 0.5 )
    00138	        return;
    00139	    }
    00140
    00141	    // pick what type of creature to spawn
    00142	    SpawnClass = TransientCreatures[Rand(NumClasses)];
    00143	    // add new creatures? - either beyond fog dist (if close) or far enough to be not visible (bugs)
    00144	    // or just off screen with AI to come on screen
    00145	    // bugs are added to their group one at a time
    00146	    // find a spot to spawn the creature
    00147	    log("try to spawn a "$SpawnClass);
    00148
    00149	    // pick spawn location
    00150	    Dist = SpawnClass.Default.MinSpawnDist + FRand() * (SpawnClass.Default.MaxSpawnDist - SpawnClass.Default.MinSpawnDist);
    00151	    SpawnDir = vector(LocalPlayer.Rotation);
    00152	    SpawnDir.Z = 0;
    00153	    SpawnLoc = LocalPlayer.ViewTarget.Location + Dist * Normal(SpawnDir);
    00154
    00155	    // make sure spawnlocation is within SpawnRadius
    00156	    if ( VSize(SpawnLoc - Location) > SpawnRadius )
    00157	      SpawnLoc = Location + SpawnRadius * Normal(SpawnLoc - Location);
    00158
    00159	    // check if now too close to player
    00160	    Dist = VSize(LocalPlayer.ViewTarget.Location - SpawnLoc);
    00161	    if ( Dist < SpawnClass.Default.MinSpawnDist )
    00162	      return;
    00163
    00164	    SpawnLoc = SpawnClass.Static.FindSpawnLocation(Dist,SpawnDir,LocalPlayer);
    00165	    log("try to spawn a "$SpawnClass$" at "$SpawnLoc);
    00166	    if ( SpawnLoc == vect(0,0,0) )
    00167	      return;
    00168
    00169	    Prey = AddCreature(SpawnClass, SpawnLoc, rotator(Spawndir));
    00170	    if ( (Prey != None)
    00171	      && (FRand() < 0.3)
    00172	      && (Prey.PredatorType != None)
    00173	      && (Prey.PredatorType.Default.MinSpawnDist < Dist) )
    00174	    {
    00175	      // sometimes spawn predator in conjunction with prey
    00176	      A = AddCreature(Prey.PredatorType, SpawnLoc, rotator(SpawnDir));
    00177	    }
    00178	    Prey = None;
    00179	}
    00180
    00181	//_____________________________________________________________________________
    00182	function SpawnAllCreaturesFromSpots()
    00183	{
    00184	    local XIIITransientACreature A;
    00185	    local actor other;
    00186	    local vector SpawnLoc, SpawnDir, ViewPos;
    00187
    00188	    log(" BEGIN spawning "$TransientCreatures[0]);
    00189	    ForEach AllActors( TransientCreatures[0].default.LocationTypeForSpawn, other )
    00190	    {
    00191	      if (other != none)
    00192	      {
    00193	        SpawnLoc = Other.Location;
    00194	        A = AddCreature(TransientCreatures[0], SpawnLoc, Other.Rotation);
    00195	        log("    Spawned "$TransientCreatures[0]$" at "$Other$" w/ rotation="$Other.Rotation);
    00196	        A.StartingSpot = KeyPoint(Other);
    00197	        A.Pawn.Event = Other.Event;
    00198	        A.Pawn.Tag = Other.Tag;
    00199	        A.Event = Other.Event;
    00200	        A.Tag = Other.Tag;
    00201	      }
    00202	      else
    00203	      {
    00204	        log("    No Location to spawn "$TransientCreatures[0]);
    00205	      }
    00206	    }
    00207	    log(" END spawning "$TransientCreatures[0]);
    00208	}
    00209
    00210
    00211
    00212	defaultproperties
    00213	{
    00214	     MaxCreatures=10
    00215	     SpawnRadius=6000
    00216	     TriggerRadius=8000
    00217	}

End Source Code