public List <Character> RespawnMob() { List <Character> respawns = new List <Character>(); if (TeamSpawns.Count > 0) { bool[][] traversedGrid = new bool[Width][]; for (int xx = 0; xx < Width; xx++) { traversedGrid[xx] = new bool[Height]; } List <Loc> freeTiles = new List <Loc>(); Grid.FloodFill(new Rect(new Loc(), new Loc(Width, Height)), (Loc testLoc) => { if (traversedGrid[testLoc.X][testLoc.Y]) { return(true); } return(TileBlocked(testLoc)); }, (Loc testLoc) => { if (traversedGrid[testLoc.X][testLoc.Y]) { return(true); } return(TileBlocked(testLoc, true)); }, (Loc testLoc) => { traversedGrid[testLoc.X][testLoc.Y] = true; if (Grid.GetForkDirs(testLoc, TileBlocked, TileBlocked).Count >= 2) { return; } //must be walkable, not have a nonwalkable on at least 3 cardinal directions, not be within eyesight of any of the player characters foreach (Character character in ActiveTeam.Players) { if (character.IsInSightBounds(testLoc)) { return; } } foreach (Team team in AllyTeams) { foreach (Character character in team.EnumerateChars()) { if (!character.Dead && character.CharLoc == testLoc) { return; } } } foreach (Team team in MapTeams) { foreach (Character character in team.EnumerateChars()) { if (!character.Dead && character.CharLoc == testLoc) { return; } } } freeTiles.Add(testLoc); }, EntryPoints[0].Loc); if (freeTiles.Count > 0) { for (int ii = 0; ii < 10; ii++) { Team newTeam = TeamSpawns.Pick(Rand).Spawn(this); if (newTeam == null) { continue; } Loc trialLoc = freeTiles[Rand.Next(freeTiles.Count)]; //find a way to place all members- needs to fit all of them in, or else fail the spawn Grid.LocTest checkOpen = (Loc testLoc) => { if (TileBlocked(testLoc)) { return(false); } Character locChar = GetCharAtLoc(testLoc); if (locChar != null) { return(false); } return(true); }; Grid.LocTest checkBlock = (Loc testLoc) => { return(TileBlocked(testLoc, true)); }; Grid.LocTest checkDiagBlock = (Loc testLoc) => { return(TileBlocked(testLoc, true, true)); }; List <Loc> resultLocs = new List <Loc>(); foreach (Loc loc in Grid.FindClosestConnectedTiles(new Loc(), new Loc(Width, Height), checkOpen, checkBlock, checkDiagBlock, trialLoc, newTeam.Players.Count)) { resultLocs.Add(loc); } if (resultLocs.Count >= newTeam.Players.Count + newTeam.Guests.Count) { for (int jj = 0; jj < newTeam.Players.Count; jj++) { newTeam.Players[jj].CharLoc = resultLocs[jj]; } for (int jj = 0; jj < newTeam.Guests.Count; jj++) { newTeam.Guests[jj].CharLoc = resultLocs[newTeam.Players.Count + jj]; } MapTeams.Add(newTeam); foreach (Character member in newTeam.EnumerateChars()) { member.RefreshTraits(); respawns.Add(member); } break; } } } } return(respawns); }