public IEnumerable <SpawnPoint> GetSpawnPoints(SpawnerStateSetting setting, Location location, WIGroup spawnGroup, PlayerBase player, System.Random random) { //figure out how many we need setting.NumAttempts = 0; setting.NumFailedAttempts = 0; int numExistingObjects = spawnGroup.NumChildItemsByCategory(setting.CategoryName, setting.MaxSpawnedObjects); //TODO make sure this works int numObjectsToSpawn = random.Next(setting.MinSpawnedObjects, setting.MaxSpawnedObjects) - numExistingObjects; if (numObjectsToSpawn <= 0) { //we don't need any more right now #if UNITY_EDITOR Debug.Log("Skipping spawning in " + name + " because num objects to spawn is <= 0"); #endif yield break; } bool succeededThisAttempt = false; switch (setting.Type) { case SpawnerType.Characters: //when we're spawning characters, we need action nodes WorldChunk chunk = spawnGroup.GetParentChunk(); List <ActionNodeState> nodeStates = null; if (chunk.GetNodesForLocation(location.worlditem.StaticReference.FullPath, out nodeStates)) { for (int i = 0; i < nodeStates.Count; i++) { mNextSpawnPoint.nodeState = nodeStates [i]; yield return(mNextSpawnPoint); } } else { nodeStates = new List <ActionNodeState> (); Debug.Log("Didn't find spawn points at location, so we're going to create some"); //if we can't find any nodes for this location //that means we've never spawned here before //we need to create some nodes for (int i = 0; i < numObjectsToSpawn; i++) { //are we totally done? if (setting.NumFailedAttempts >= setting.MaxFailedAttempts) { yield break; } //if not, try to get another spawn point if (spawnGroup.Props.Interior) { succeededThisAttempt = GetInteriorSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup); } else if (spawnGroup.Props.TerrainType == LocationTerrainType.AboveGround) { succeededThisAttempt = GetAboveGroundSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup); } else { succeededThisAttempt = GetBelowGroundSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup); } //did we do it? if (succeededThisAttempt) { //hooray we created a new action node setting.NumAttempts++; //turn this spawn point into an action node ActionNodeState nodeState = new ActionNodeState(); nodeState.Name = location.worlditem.FileName + "-Spawn-" + nodeStates.Count.ToString(); nodeState.Type = ActionNodeType.Generic; nodeState.Users = ActionNodeUsers.AnyOccupant; nodeState.Transform.CopyFrom(mNextSpawnPoint.Transform); mNextSpawnPoint.nodeState = nodeState; ActionNode node = chunk.SpawnActionNode(spawnGroup, nodeState, location.worlditem.tr); yield return(mNextSpawnPoint); } else { //boo, we failed setting.NumFailedAttempts++; } } } nodeStates.Clear(); nodeStates = null; break; default: //when we're spawning other things, we just need spawn points //ok, try to spawn this stuff for (int i = 0; i < numObjectsToSpawn; i++) { //are we totally done? if (setting.NumFailedAttempts >= setting.MaxFailedAttempts) { yield break; } //if not, try to get another spawn point if (spawnGroup.Props.Interior) { succeededThisAttempt = GetInteriorSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup); } else if (spawnGroup.Props.TerrainType == LocationTerrainType.AboveGround) { succeededThisAttempt = GetAboveGroundSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup); } else { succeededThisAttempt = GetBelowGroundSpawnPoint(ref mNextSpawnPoint, setting, location, spawnGroup); } //did we do it? if (succeededThisAttempt) { //hooray, we got another spawn point setting.NumAttempts++; yield return(mNextSpawnPoint); } else { //boo, we failed setting.NumFailedAttempts++; yield return(SpawnPoint.Empty); } } break; } yield break; }