//================================================================= // RandomHumanSpawner // // Places random humans around the map. // // USAGE: //================================================================= class RandomHumanSpawner extends KeyPoint; struct sOrdersInfo { var() name Orders; // Orders to give the pawn var() name OrderTag; // OrderTag to give the pawn var() int OrderTagSuffixMin; // Minimum number to append to the OrderTag var() int OrderTagSuffixMax; // Maximum number to append to the OrderTag var() int Amount; // Amount of pawns to receive this order var int Count; var int LastOrderTagSuffix; }; // Adjustable parameters var() int Amount; // Amount of pawns to spawn var() bool bNoCelebrities; // Exclude known faces var() sOrdersInfo PawnOrders[10]; // Orders to give pawns var() string Tags[10]; // Allowed style tags // Internal variables var Vector ValidLocations[100]; var int NumValidLocations; var ExtensionObject EO; // ------------------ // Init all locations // ------------------ function PostBeginPlay() { local int g, p; local PathNode aPathNode; // For converting strings to names EO = new class'ExtensionObject'; // Gather up all valid locations if(Event != '') { foreach AllActors(class'PathNode', aPathNode, Event) { ValidLocations[NumValidLocations] = aPathNode.Location; NumValidLocations++; } } // Spawn all the pawns for(p = 0; p < Amount; p++) { SpawnPawn(); } Super.PostBeginPlay(); } // ------------------------------------------------------ // Moves a pawn, and tries to place it nearby if it fails // ------------------------------------------------------ function MovePawn(ScriptedPawn aPawn, Vector Loc) { local Rotator HelpRotator; local int HelpDistance; local int LoopCount; HelpRotator = aPawn.Rotation; HelpDistance = 16; if(!aPawn.SetLocation(Loc)) { while (LoopCount < 32 && !aPawn.SetLocation(Loc + Normal(Vector(HelpRotator)) * HelpDistance)) { HelpRotator.Yaw += 8192; HelpDistance += 16; LoopCount++; } } } // ----------------------------------------------- // Issues orders to a pawn and place it in the map // ----------------------------------------------- function OrderAndPlacePawn(ScriptedPawn aPawn) { local int i; local string OrderTag; local int OrderTagSuffix; local Vector NewLocation; local PatrolPoint aPatrolPoint; local Actor aActor; if(aPawn == None) return; // Determine location if(NumValidLocations < 1) NewLocation = Location; else NewLocation = ValidLocations[Rand(NumValidLocations)]; // Get the next order in the queue for(i = 0; i < ArrayCount(PawnOrders); i++) { if(PawnOrders[i].Orders == '' || PawnOrders[i].Count >= PawnOrders[i].Amount) continue; PawnOrders[i].Count++; OrderTag = string(PawnOrders[i].OrderTag); // If specified, add a numerical suffix to the tag if(PawnOrders[i].OrderTagSuffixMin > 0 && PawnOrders[i].OrderTagSuffixMax > PawnOrders[i].OrderTagSuffixMin) { // Increment one since the last suffix OrderTagSuffix = PawnOrders[i].LastOrderTagSuffix + 1; // If we're below minimum or above maximum reset to minimum if(OrderTagSuffix < PawnOrders[i].OrderTagSuffixMin || OrderTagSuffix > PawnOrders[i].OrderTagSuffixMax) OrderTagSuffix = PawnOrders[i].OrderTagSuffixMin; PawnOrders[i].LastOrderTagSuffix = OrderTagSuffix; OrderTag = OrderTag $ OrderTagSuffix; } aPawn.Orders = PawnOrders[i].Orders; aPawn.OrderTag = EO.StringToName(OrderTag); break; } // If the pawn is patrolling, move it to the starting PatrolPoint if(aPawn.Orders == 'Patrolling' && aPawn.OrderTag != '') { foreach AllActors(class'PatrolPoint', aPatrolPoint, aPawn.OrderTag) { NewLocation = aPatrolPoint.Location; break; } } // If the pawn is standing, and an OrderTag has been specified, move it there else if(aPawn.Orders == 'Standing' && aPawn.OrderTag != '') { foreach AllActors(class'Actor', aActor, aPawn.OrderTag) { NewLocation = aActor.Location; break; } } // Move the pawn MovePawn(aPawn, NewLocation); } // ----------------- // Spawns a new pawn // ----------------- function SpawnPawn() { local int i, GroundSpeedModifier; local RandomHuman aPawn; local class SpawnClass; // Determine the class if(Rand(2) > 0) SpawnClass = class'MyPackage.RandomMale'; else SpawnClass = class'MyPackage.RandomFemale'; // Spawn the pawn aPawn = Spawn(SpawnClass); // Assign properties for(i = 0; i < ArrayCount(Tags); i++) { aPawn.Tags[i] = Tags[i]; } aPawn.bNoCelebrities = bNoCelebrities; // Issue orders and place the pawn OrderAndPlacePawn(aPawn); // Generate the pawn's appearance aPawn.StartGeneration(); // Include the FinalTag in the BindName, so the convo knows what this pawn looks like aPawn.BindName = aPawn.BindName $ aPawn.FinalTag; // Mess with the GroundSpeed a little, so not everyone is moving at the same pace GroundSpeedModifier = Rand(6); if(Rand(2) > 0) GroundSpeedModifier *= -1; aPawn.GroundSpeed += GroundSpeedModifier; } defaultproperties { bNoCelebrities=True Tags(0)="Normal" }