예제 #1
0
        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);
        }