示例#1
0
        private Point FindTrapDoorPosition(IAreaMap map, Point playerPosition)
        {
            const int maxIterations       = 100;
            var       iteration           = 0;
            var       minDistanceToPlayer = map.Width / 4;

            while (iteration < maxIterations)
            {
                iteration++;

                var x        = RandomHelper.GetRandomValue(1, map.Width - 2);
                var y        = RandomHelper.GetRandomValue(1, map.Height - 2);
                var position = new Point(x, y);

                if (Point.GetDistance(playerPosition, position) < minDistanceToPlayer)
                {
                    continue;
                }

                if (map.GetCell(position).BlocksMovement)
                {
                    continue;
                }

                return(position);
            }
            throw new MapGenerationException("Unable to find trap door position");
        }
示例#2
0
        private IPlaceConnectionObject GetWall(IAreaMap map, Point position, int relativeX, int relativeY)
        {
            var nearPosition = new Point(position.X + relativeX, position.Y + relativeY);
            var cell         = map.TryGetCell(nearPosition);

            return(cell?.Objects.OfType <IPlaceConnectionObject>().FirstOrDefault(obj => CanConnectTo(obj) || obj.CanConnectTo(this)));
        }
        private static void PlaceSquad(IAreaMap map, IMonsterConfiguration[] monsters, string group,
                                       bool[,] occupiedCells)
        {
            var squadMonsters = monsters.Where(monster => string.Equals(monster.SpawnConfiguration.Group, group))
                                .ToArray();

            var roomPoint  = FindEmptyRoom(map, occupiedCells);
            var roomPoints = CollectRoomPoints(map, roomPoint);

            foreach (var point in roomPoints)
            {
                occupiedCells[point.X, point.Y] = true;
            }

            var emptyRoomPoints = roomPoints.ToList();
            var leftForce       = GetSquadForce(map.Level);
            var monsterConfig   = GenerateMonster(squadMonsters, leftForce);

            while (monsterConfig != null && emptyRoomPoints.Count > 0)
            {
                leftForce -= monsterConfig.SpawnConfiguration.Force;

                var position = RandomHelper.GetRandomElement(emptyRoomPoints.ToArray());
                emptyRoomPoints.Remove(position);
                var monster = CreateMonster(monsterConfig);
                map.AddObject(position, monster);

                monsterConfig = GenerateMonster(squadMonsters, leftForce);
            }
        }
        private static bool IsEmptyBlock(IAreaMap map, bool[,] occupiedCells, Point position)
        {
            for (int shiftX = 0; shiftX < 3; shiftX++)
            {
                for (int shiftY = 0; shiftY < 3; shiftY++)
                {
                    var x = position.X + shiftX;
                    var y = position.Y + shiftY;

                    var cell = map.TryGetCell(x, y);
                    if (cell == null)
                    {
                        return(false);
                    }

                    if (occupiedCells[x, y])
                    {
                        return(false);
                    }

                    if (cell.BlocksMovement || cell.BlocksEnvironment)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
        public void GenerateMonsters(IAreaMap map, Point playerPosition)
        {
            var stopwatch = Stopwatch.StartNew();

            var squadsCount = GetSquadsCount(map);

            var possibleMonsters = ConfigurationManager.Current.Monsters.Monsters
                                   .Where(monster => map.Level >= monster.SpawnConfiguration.MinLevel).ToArray();
            var possibleGroups = possibleMonsters.Select(monster => monster.SpawnConfiguration.Group).Distinct()
                                 .ToArray();


            var occupiedCells    = new bool[map.Width, map.Height];
            var playerRoomPoints = CollectRoomPoints(map, playerPosition);

            foreach (var point in playerRoomPoints)
            {
                occupiedCells[point.X, point.Y] = true;
            }

            for (var counter = 0; counter < squadsCount; counter++)
            {
                var group = RandomHelper.GetRandomElement(possibleGroups);
                PlaceSquad(map, possibleMonsters, group, occupiedCells);
            }

            stopwatch.Stop();
            Log.Debug($"GenerateMonsters took {stopwatch.ElapsedMilliseconds} milliseconds.");
        }
示例#6
0
        private string GetCellSymbol(int x, int y, IAreaMap map, Point playerPosition)
        {
            if (playerPosition.X == x && playerPosition.Y == y)
            {
                return("+");
            }

            var cell = map.GetCell(x, y);

            if (cell.Objects.OfType <DoorBase>().Any())
            {
                return("▒");
            }

            if (cell.Objects.OfType <WallBase>().Any())
            {
                return("█");
            }

            if (cell.Objects.OfType <DungeonTrapDoor>().Any())
            {
                return("v");
            }

            if (cell.Objects.OfType <DungeonStairs>().Any())
            {
                return("^");
            }

            return(" ");
        }
示例#7
0
        private Point GetEndPosition(IAreaMap map, Point playerPosition)
        {
            const int maxIterations     = 100;
            const int minPlayerDistance = 10;

            var iteration = 0;

            while (true)
            {
                if (iteration >= maxIterations)
                {
                    throw new MapGenerationException("Unable to find suitable end point.");
                }

                iteration++;

                var x     = RandomHelper.GetRandomValue(0, map.Width - 1);
                var y     = RandomHelper.GetRandomValue(0, map.Height - 1);
                var point = new Point(x, y);

                if (Point.GetDistance(playerPosition, point) < minPlayerDistance)
                {
                    continue;
                }

                var cell = map.GetCell(point);

                if (cell.BlocksMovement)
                {
                    continue;
                }

                return(point);
            }
        }
示例#8
0
        public void ChangeMap(IAreaMap newMap, Point playerPosition)
        {
            log.Debug("Changing map");
            Map = newMap;
            Map.AddObject(playerPosition, Player);
            PlayerPosition = playerPosition;

            MapUpdated?.Invoke(this, EventArgs.Empty);
        }
示例#9
0
        private void CheckWallInDirection(IAreaMap map, Point position, int relativeX, int relativeY)
        {
            var wallUp = GetWall(map, position, relativeX, relativeY);

            if (wallUp != null)
            {
                connectedTiles.Add(new Point(relativeX, relativeY));
                wallUp.AddConnectedTile(new Point(relativeX * (-1), relativeY * (-1)));
            }
        }
示例#10
0
 public void ResetLightLevel(IAreaMap map)
 {
     for (int x = 0; x < map.Width; x++)
     {
         for (int y = 0; y < map.Height; y++)
         {
             var position = new Point(x, y);
             var cell     = map.GetCell(position);
             cell.LightLevel = LightLevel.Darkness;
         }
     }
 }
示例#11
0
 public void UpdateLightLevel(IAreaMap map)
 {
     for (int x = 0; x < map.Width; x++)
     {
         for (int y = 0; y < map.Height; y++)
         {
             var position = new Point(x, y);
             var cell     = map.GetCell(position);
             UpdateCellLightLevel(map, cell, position);
         }
     }
 }
示例#12
0
        public void OnPlaced(IAreaMap map, Point position)
        {
            CheckWallInDirection(map, position, -1, -1); // Top Left
            CheckWallInDirection(map, position, 0, -1);  // Top
            CheckWallInDirection(map, position, 1, -1);  // Top Right

            CheckWallInDirection(map, position, -1, 0);  // Left
            CheckWallInDirection(map, position, 1, 0);   // Right

            CheckWallInDirection(map, position, 1, 1);   // Bottom Left
            CheckWallInDirection(map, position, 0, 1);   // Bottom
            CheckWallInDirection(map, position, 1, 1);   // Bottom Right
        }
示例#13
0
        private bool TryAddPattern(IAreaMap map, Point playerPosition, ObjectsPattern pattern)
        {
            var x = RandomHelper.GetRandomValue(0, map.Width);
            var y = RandomHelper.GetRandomValue(0, map.Height);

            if (!map.ContainsCell(x, y))
            {
                return(false);
            }

            for (int cursorX = 0; cursorX < pattern.Width; cursorX++)
            {
                for (int cursorY = 0; cursorY < pattern.Height; cursorY++)
                {
                    var posX = cursorX + x;
                    var posY = cursorY + y;

                    if (posX == playerPosition.X && posY == playerPosition.Y)
                    {
                        return(false);
                    }

                    var cell = map.TryGetCell(posX, posY);
                    if (cell == null)
                    {
                        return(false);
                    }

                    if (!pattern.CheckRequirements(cursorX, cursorY, cell))
                    {
                        return(false);
                    }
                }
            }

            for (int cursorX = 0; cursorX < pattern.Width; cursorX++)
            {
                for (int cursorY = 0; cursorY < pattern.Height; cursorY++)
                {
                    var posX = cursorX + x;
                    var posY = cursorY + y;

                    foreach (var factory in pattern.Get(cursorX, cursorY))
                    {
                        map.AddObject(new Point(posX, posY), factory(map.Level));
                    }
                }
            }

            return(true);
        }
示例#14
0
        public GameCore(IAreaMap map, TPlayer player, Point playerPosition)
        {
            Map            = map;
            PlayerPosition = playerPosition;
            Player         = player;

            Map.AddObject(PlayerPosition, Player);

            Journal = new Journal();

            CurrentTurn = 1;

            cachedVisibleArea = null;
        }
示例#15
0
        private void ProcessDestroyableObjects(IAreaMap map, Point position)
        {
            var destroyableObjects = ObjectsCollection.OfType <IDestroyableObject>().ToArray();

            ProcessStatusesAndEnvironment(destroyableObjects, position);

            var deadObjects = destroyableObjects.Where(obj => obj.Health <= 0).ToArray();

            foreach (var deadObject in deadObjects)
            {
                map.RemoveObject(position, deadObject);
                deadObject.OnDeath(position);
            }
        }
示例#16
0
 private void WriteMapToFile(IAreaMap map, Point playerPosition)
 {
     using (var file = File.CreateText(@".\Map.txt"))
     {
         for (int y = 0; y < map.Height; y++)
         {
             var line = string.Empty;
             for (int x = 0; x < map.Width; x++)
             {
                 line += GetCellSymbol(x, y, map, playerPosition);
             }
             file.WriteLine(line);
         }
     }
 }
示例#17
0
        private void AddPattern(IAreaMap map, Point playerPosition, ObjectsPattern pattern)
        {
            const int maxAttempts = 100;
            var       attempt     = 0;

            while (attempt < maxAttempts)
            {
                attempt++;

                if (TryAddPattern(map, playerPosition, pattern))
                {
                    return;
                }
            }
        }
示例#18
0
        private static Point[] CollectRoomPoints(IAreaMap map, Point startPoint)
        {
            var markedPoints = new bool[map.Width, map.Height];

            var leftPoints = new Stack <Point>();

            leftPoints.Push(startPoint);
            while (leftPoints.Count > 0)
            {
                var point = leftPoints.Pop();
                if (markedPoints[point.X, point.Y])
                {
                    continue;
                }

                var cell = map.TryGetCell(point);
                if (cell == null)
                {
                    continue;
                }

                if (cell.BlocksMovement || cell.BlocksEnvironment)
                {
                    continue;
                }

                markedPoints[point.X, point.Y] = true;
                leftPoints.Push(Point.GetPointInDirection(point, Direction.East));
                leftPoints.Push(Point.GetPointInDirection(point, Direction.West));
                leftPoints.Push(Point.GetPointInDirection(point, Direction.North));
                leftPoints.Push(Point.GetPointInDirection(point, Direction.South));
            }

            var result = new List <Point>();

            for (int x = 0; x < map.Width; x++)
            {
                for (int y = 0; y < map.Height; y++)
                {
                    if (markedPoints[x, y])
                    {
                        result.Add(new Point(x, y));
                    }
                }
            }

            return(result.ToArray());
        }
示例#19
0
        private static Point FindEmptyRoom(IAreaMap map, bool[,] occupiedCells)
        {
            for (int counter = 0; counter < 5000; counter++)
            {
                var pointX = RandomHelper.GetRandomValue(0, map.Width - 1);
                var pointY = RandomHelper.GetRandomValue(0, map.Height - 1);
                var point  = new Point(pointX, pointY);

                if (IsEmptyBlock(map, occupiedCells, point))
                {
                    return(point);
                }
            }

            throw new MapGenerationException("Unable to find empty room for squad.");
        }
示例#20
0
        public void GenerateObjects(IAreaMap map, Point playerPosition)
        {
            var stopwatch = Stopwatch.StartNew();

            foreach (var pattern in patterns)
            {
                var count = (int)Math.Floor(map.Width * map.Height * pattern.MaxCountMultiplier);
                for (int counter = 0; counter < count; counter++)
                {
                    AddPattern(map, playerPosition, pattern);
                }
            }

            stopwatch.Stop();
            Log.Debug($"GenerateObjects took {stopwatch.ElapsedMilliseconds} milliseconds.");
        }
示例#21
0
        private Point FindPlayerPosition(IAreaMap map)
        {
            const int maxIterations = 100;
            var       iteration     = 0;

            while (iteration < maxIterations)
            {
                var x = RandomHelper.GetRandomValue(1, map.Width - 1);
                var y = RandomHelper.GetRandomValue(1, map.Height - 1);

                var cell = map.GetCell(x, y);
                if (!cell.BlocksMovement && !cell.BlocksEnvironment)
                {
                    return(new Point(x, y));
                }

                iteration++;
            }

            throw new ApplicationException("Unable to find player position.");
        }
示例#22
0
        private static void UpdateCellLightLevel(IAreaMap map, IAreaMapCell cell, Point position)
        {
            var lights = cell.Objects.OfType <ILightObject>()
                         .SelectMany(lightObject => lightObject.LightSources)
                         .Where(source => source.IsLightOn && source.LightPower > LightLevel.Darkness)
                         .ToArray();

            if (lights.Length == 0)
            {
                return;
            }

            var maxLightPower = lights.Max(light => light.LightPower);

            cell.LightLevel = (LightLevel)Math.Max((int)cell.LightLevel, (int)maxLightPower);

            SpreadLightLevel(map, Point.GetPointInDirection(position, Direction.North), maxLightPower);
            SpreadLightLevel(map, Point.GetPointInDirection(position, Direction.South), maxLightPower);
            SpreadLightLevel(map, Point.GetPointInDirection(position, Direction.West), maxLightPower);
            SpreadLightLevel(map, Point.GetPointInDirection(position, Direction.East), maxLightPower);
        }
示例#23
0
        private static void SpreadLightLevel(IAreaMap map, Point position, LightLevel light)
        {
            if (light <= LightLevel.Darkness)
            {
                return;
            }

            var cell = map.TryGetCell(position);

            if (cell == null)
            {
                return;
            }

            if ((int)light < (int)cell.LightLevel)
            {
                return;
            }
            cell.LightLevel = light;

            if (cell.BlocksEnvironment)
            {
                return;
            }

            var lightPowerToSpread = (int)light - 1;

            if (lightPowerToSpread <= (int)LightLevel.Darkness)
            {
                return;
            }

            var lightToSpread = (LightLevel)lightPowerToSpread;

            SpreadLightLevel(map, Point.GetPointInDirection(position, Direction.North), lightToSpread);
            SpreadLightLevel(map, Point.GetPointInDirection(position, Direction.South), lightToSpread);
            SpreadLightLevel(map, Point.GetPointInDirection(position, Direction.West), lightToSpread);
            SpreadLightLevel(map, Point.GetPointInDirection(position, Direction.East), lightToSpread);
        }
示例#24
0
 public void PostUpdate(IAreaMap map, Point position)
 {
     ProcessDestroyableObjects(map, position);
 }
示例#25
0
 private void OnPathReached(IAreaMap map)
 {
     this.ticks  = 0;
     this.moving = false;
 }
示例#26
0
 private void OnPathFailed(IAreaMap map, OQ.MineBot.PluginBase.Movement.Geometry.IAreaCuboid cuboid)
 {
     this.ticks  = -10;
     this.moving = false;
 }
示例#27
0
 private void NestReached(IAreaMap map)
 {
     this.State = WorkerState.Mining;
 }
示例#28
0
        private static int GetSquadsCount(IAreaMap map)
        {
            var square = map.Width * map.Height;

            return((int)Math.Round(square * SquadsCountMultiplier));
        }
示例#29
0
 public static void Initialize <TPlayer>(IAreaMap map, TPlayer player, Point playerPosition)
     where TPlayer : class, IPlayer
 {
     Game = new GameCore <TPlayer>(map, player, playerPosition);
 }