Esempio n. 1
0
        public void GivenЕстьСундукIdВЯчейкеСоСлучайнымЛутом(int chestId, int chestPosX, int chestPosY, Table table)
        {
            var schemeService       = Context.ServiceProvider.GetRequiredService <ISchemeService>();
            var sectorManager       = Context.ServiceProvider.GetRequiredService <ISectorManager>();
            var staticObjectManager = sectorManager.CurrentSector.StaticObjectManager;

            var nodeCoords = new OffsetCoords(chestPosX, chestPosY);
            var node       = sectorManager.CurrentSector.Map.Nodes.SelectByHexCoords(nodeCoords.X, nodeCoords.Y);

            var dropProps = new List <IProp>();

            foreach (var tableRow in table.Rows)
            {
                tableRow.TryGetValue("prop", out var propSchemeSid);
                tableRow.TryGetValue("count", out var resourceCount);

                var propScheme = schemeService.GetScheme <IPropScheme>(propSchemeSid);

                dropProps.Add(new Resource(propScheme, int.Parse(resourceCount)));
            }

            var dropResolverMock = new Mock <IDropResolver>();

            dropResolverMock.Setup(x => x.Resolve(It.IsAny <IEnumerable <IDropTableScheme> >()))
            .Returns(dropProps.ToArray());
            var dropResolver = dropResolverMock.Object;

            var chest        = new DropTablePropChest(System.Array.Empty <DropTableScheme>(), dropResolver);
            var staticObject = new StaticObject(node, chest.Purpose, chestId);

            staticObject.AddModule <IPropContainer>(chest);

            staticObjectManager.Add(staticObject);
        }
Esempio n. 2
0
        private bool TryRollInteriorCoord(OffsetCoords[] openCoords,
                                          IEnumerable <OffsetCoords> passableRegionCoords,
                                          bool checkPass,
                                          out OffsetCoords rolledCoords)
        {
            var supposedRolledCoords = _dice.RollFromList(openCoords);

            if (!checkPass)
            {
                rolledCoords = supposedRolledCoords;
                return(true);
            }

            // Проверяем, что элемент декора не перекрывает проход.
            var isNotBlockPass = CheckMapPassable(passableRegionCoords, supposedRolledCoords);

            if (!isNotBlockPass)
            {
                rolledCoords = supposedRolledCoords;
                return(false);
            }

            rolledCoords = supposedRolledCoords;
            return(true);
        }
Esempio n. 3
0
        public void GivenЕстьСундукIdВЯчейкеСоСлучайнымЛутом(int chestId, int chestPosX, int chestPosY, Table table)
        {
            var schemeService    = Context.Container.GetInstance <ISchemeService>();
            var containerManager = Context.Container.GetInstance <IPropContainerManager>();
            var sectorManager    = Context.Container.GetInstance <ISectorManager>();

            var nodeCoords = new OffsetCoords(chestPosX, chestPosY);
            var node       = sectorManager.CurrentSector.Map.Nodes.Cast <HexNode>().SelectBy(nodeCoords.X, nodeCoords.Y);

            var dropProps = new List <IProp>();

            foreach (var tableRow in table.Rows)
            {
                tableRow.TryGetValue("prop", out var propSchemeSid);
                tableRow.TryGetValue("count", out var resourceCount);

                var propScheme = schemeService.GetScheme <IPropScheme>(propSchemeSid);

                dropProps.Add(new Resource(propScheme, int.Parse(resourceCount)));
            }

            var dropResolverMock = new Mock <IDropResolver>();

            dropResolverMock.Setup(x => x.Resolve(It.IsAny <IEnumerable <IDropTableScheme> >()))
            .Returns(dropProps.ToArray());
            var dropResolver = dropResolverMock.Object;

            var chest = new DropTablePropChest(node, new DropTableScheme[0], dropResolver, chestId);

            containerManager.Add(chest);
        }
Esempio n. 4
0
        public void AddHumanActor(string personSid, OffsetCoords startCoords)
        {
            var playerState     = Container.GetInstance <IPlayerState>();
            var schemeService   = Container.GetInstance <ISchemeService>();
            var sector          = Container.GetInstance <ISector>();
            var humanTaskSource = Container.GetInstance <IHumanActorTaskSource>();
            var actorManager    = Container.GetInstance <IActorManager>();

            var personScheme = schemeService.GetScheme <PersonScheme>(personSid);

            // Подготовка актёров
            var humanStartNode = sector.Map.Nodes.Cast <HexNode>().SelectBy(startCoords.X, startCoords.Y);
            var humanActor     = CreateHumanActor(_humanPlayer, personScheme, humanStartNode);

            humanTaskSource.SwitchActor(humanActor);

            actorManager.Add(humanActor);

            var humanActroViewModelMock = new Mock <IActorViewModel>();

            humanActroViewModelMock.SetupGet(x => x.Actor).Returns(humanActor);
            var humanActroViewModel = humanActroViewModelMock.Object;

            playerState.ActiveActor = humanActroViewModel;
        }
        public void AddHumanActor(string personSid, ISector sector, OffsetCoords startCoords)
        {
            if (sector is null)
            {
                throw new ArgumentNullException(nameof(sector));
            }

            var humanPlayer = ServiceProvider.GetRequiredService <IPlayer>();

            var playerState  = ServiceProvider.GetRequiredService <ISectorUiState>();
            var actorManager = sector.ActorManager;
            var perkResolver = ServiceProvider.GetRequiredService <IPerkResolver>();

            // Подготовка актёров
            var humanStartNode = sector.Map.Nodes.SelectByHexCoords(startCoords.X, startCoords.Y);
            var humanActor     = CreateHumanActor(personSid, humanStartNode, perkResolver);

            humanPlayer.BindPerson(Globe, humanActor.Person);

            actorManager.Add(humanActor);

            var humanActroViewModelMock = new Mock <IActorViewModel>();

            humanActroViewModelMock.SetupGet(x => x.Actor).Returns(humanActor);
            var humanActroViewModel = humanActroViewModelMock.Object;

            playerState.ActiveActor = humanActroViewModel;
        }
        public void RollInteriorObjectsTest()
        {
            const int SQARE_SIZE = 12;

            // ARRANGE

            var diceMock = new Mock <IDice>();

            diceMock.Setup(x => x.Roll(It.IsAny <int>())).Returns(1);
            var dice = diceMock.Object;

            var interiorRandomSource = new InteriorObjectRandomSource(dice);

            var coords = new OffsetCoords[SQARE_SIZE * SQARE_SIZE];

            for (var i = 0; i < SQARE_SIZE; i++)
            {
                for (var j = 0; j < SQARE_SIZE; j++)
                {
                    coords[i + (j * SQARE_SIZE)] = new OffsetCoords(i, j);
                }
            }

            // ACT
            var factMetas = interiorRandomSource.RollInteriorObjects(coords, true);

            // ASSERT
            factMetas.Should().NotBeEmpty();
        }
Esempio n. 7
0
 /// <summary>
 /// Выполняет заливку области в поле шестиугольников с учётом размера в 7 узлов.
 /// </summary>
 /// <param name="matrix"> Поле шестиугольников. Будут заливаться ячейки со сзначением <b>true</b>. </param>
 /// <param name="point"> Точка, с которой начинается заливка. Должна указывать на ячейку со значением <b>true</b>. </param>
 /// <returns> Возвращает точки, которые были залиты. </returns>
 public static IEnumerable <OffsetCoords> FloodFill7(Matrix <bool> matrix, OffsetCoords point)
 {
     return(FloodFillInner(
                matrix,
                point,
                nextCoords => CheckAvailableFor7(nextCoords, matrix)));
 }
        private static void HandleMoveCommand(
            IServiceScope serviceScope,
            ISectorUiState uiState,
            ICommandPool commandManager,
            ISectorNode playerActorSectorNode,
            string inputText)
        {
            var components   = inputText.Split(' ');
            var x            = int.Parse(components[1], CultureInfo.InvariantCulture);
            var y            = int.Parse(components[2], CultureInfo.InvariantCulture);
            var offsetCoords = new OffsetCoords(x, y);

            ISectorMap map = playerActorSectorNode.Sector.Map;

            var targetNode = map.Nodes.OfType <HexNode>()
                             .SingleOrDefault(node => node.OffsetCoords == offsetCoords);

            var command = serviceScope.ServiceProvider.GetRequiredService <MoveCommand>();

            uiState.SelectedViewModel = new NodeViewModel {
                Node = targetNode
            };

            PushCommandToExecution(commandManager, command);
        }
Esempio n. 9
0
        public static OffsetCoords GetFreeCell(RoomMatrix grid, OffsetCoords rolled)
        {
            for (var i = 0; i < grid.Size; i++)
            {
                for (var j = 0; j < grid.Size; j++)
                {
                    if (IsValidForRoom(grid, rolled, i, j, 1, 1))
                    {
                        return(new OffsetCoords(rolled.X + i * 1, rolled.Y + j * 1));
                    }

                    if (IsValidForRoom(grid, rolled, i, j, -1, 1))
                    {
                        return(new OffsetCoords(rolled.X + i * -1, rolled.Y + j * 1));
                    }

                    if (IsValidForRoom(grid, rolled, i, j, 1, -1))
                    {
                        return(new OffsetCoords(rolled.X + i * 1, rolled.Y + j * -1));
                    }

                    if (IsValidForRoom(grid, rolled, i, j, -1, -1))
                    {
                        return(new OffsetCoords(rolled.X + i * -1, rolled.Y + j * -1));
                    }
                }
            }

            return(null);
        }
        /// <summary>
        /// Преобразовывет черновые регионы в узлы реальной карты.
        /// </summary>
        private static void MapDraftRegionsToSectorMap(Matrix <bool> matrix, RegionDraft[] draftRegions, ISectorMap map)
        {
            var cellMap   = matrix.Items;
            var mapWidth  = matrix.Width;
            var mapHeight = matrix.Height;

            var regionNodeCoords = draftRegions.SelectMany(x => x.Coords);
            var hashSet          = new HashSet <OffsetCoords>(regionNodeCoords);

            for (var x = 0; x < mapWidth; x++)
            {
                for (var y = 0; y < mapHeight; y++)
                {
                    if (cellMap[x, y])
                    {
                        var offsetCoord = new OffsetCoords(x, y);

                        if (!hashSet.Contains(offsetCoord))
                        {
                            var node = new HexNode(x, y);
                            map.AddNode(node);
                        }
                    }
                }
            }
        }
Esempio n. 11
0
    //TODO Попробовать сделать загрузку всех провинций параллельно.
    // Выглядит так, что каждый запуск метода не зависит от предыдущих запусков.
    /// <summary>
    /// Создание соседних провинций.
    /// </summary>
    /// <param name="playerCoords"> Текущии координаты игрока. </param>
    /// <param name="worldManager"> Менеджер мира. </param>
    /// <param name="worldGenerator"> Генератор мира, используемый для создания новых провинций. </param>
    /// <returns> Возвращает объект Task. </returns>
    private static async System.Threading.Tasks.Task CreateNeighborRegionsAsync(OffsetCoords playerCoords,
                                                                                IWorldManager worldManager,
                                                                                IWorldGenerator worldGenerator,
                                                                                ProgressStorageService progressStorageService)
    {
        for (var offsetX = -1; offsetX <= 1; offsetX++)
        {
            for (var offsetY = -1; offsetY <= 1; offsetY++)
            {
                if (offsetX == 0 && offsetY == 0)
                {
                    // Это нулевое смещение от текущего элемента.
                    // Пропускаем, т.к. текущий элемент уже есть.
                    continue;
                }

                var terrainX = playerCoords.X + offsetX;
                var terrainY = playerCoords.Y + offsetY;

                if (worldManager.Globe.Terrain.GetLowerBound(0) <= terrainX &&
                    terrainX <= worldManager.Globe.Terrain.GetUpperBound(0) &&
                    worldManager.Globe.Terrain[0].GetLowerBound(0) <= terrainY &&
                    terrainY <= worldManager.Globe.Terrain[0].GetUpperBound(0))
                {
                    var terrainCell = worldManager.Globe.Terrain[terrainX][terrainY];
                    if (!worldManager.Regions.ContainsKey(terrainCell))
                    {
                        var createdNeiborRegion = await CreateRegionAsync(worldManager.Globe, terrainCell, worldGenerator, progressStorageService);

                        worldManager.Regions[terrainCell] = createdNeiborRegion;
                    }
                }
            }
        }
    }
Esempio n. 12
0
        public static bool IsAvailableFor7(Matrix <bool> matrix, OffsetCoords coords)
        {
            if (matrix is null)
            {
                throw new ArgumentNullException(nameof(matrix));
            }

            if (!IsAvailableFor(matrix, coords))
            {
                return(false);
            }

            var neighbors = HexHelper.GetNeighbors(coords.X, coords.Y);

            foreach (var neightbor in neighbors)
            {
                if (!matrix.IsIn(neightbor.X, neightbor.Y))
                {
                    return(false);
                }

                if (!matrix[neightbor.X, neightbor.Y])
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 13
0
        private static void HandleMoveCommand(IServiceScope serviceScope, ISectorUiState uiState,
                                              ISectorNode playerActorSectorNode, string inputText)
        {
            var components   = inputText.Split(' ');
            var x            = int.Parse(components[1], CultureInfo.InvariantCulture);
            var y            = int.Parse(components[2], CultureInfo.InvariantCulture);
            var offsetCoords = new OffsetCoords(x, y);

            ISectorMap map = playerActorSectorNode.Sector.Map;

            var targetNode = map.Nodes.OfType <HexNode>()
                             .SingleOrDefault(node => node.OffsetCoords == offsetCoords);

            var command = serviceScope.ServiceProvider.GetRequiredService <MoveCommand>();

            uiState.SelectedViewModel = new NodeViewModel {
                Node = targetNode
            };

            if (command.CanExecute())
            {
                command.Execute();
            }
            else
            {
                Console.WriteLine(UiResource.CommandCantExecuteMessage);
            }
        }
Esempio n. 14
0
    public bool IsHexValid(Hex hex)
    {
        OffsetCoords o     = CubeToOffset(HexToCube(hex));
        bool         valid = (o.row >= 0 && o.row <= (rows - 1) && o.column >= 0 && o.column <= (columns - 1));

        return(valid);
    }
Esempio n. 15
0
    public OffsetCoords HexToOffset(Hex hex)
    {
        Cube         cube   = HexToCube(hex);
        OffsetCoords coords = CubeToOffset(cube);

        return(coords);
    }
Esempio n. 16
0
        /// <summary>
        /// Соединяет две комнаты коридором.
        /// </summary>
        /// <param name="map"> Карта, над которой идёт работа. </param>
        /// <param name="room"> Комната, которую соединяем. </param>
        /// <param name="selectedRoom"> Целевая комната для соединения. </param>
        /// <param name="edgeHash"> Хэш рёбер (для оптимизации). </param>
        protected static void ConnectRoomsWithCorridor(IMap map, Room room, Room selectedRoom, HashSet <string> edgeHash)
        {
            if (room is null)
            {
                throw new System.ArgumentNullException(nameof(room));
            }

            if (selectedRoom is null)
            {
                throw new System.ArgumentNullException(nameof(selectedRoom));
            }

            var currentNode = GetRoomCenterNode(room);
            var targetNode  = GetRoomCenterNode(selectedRoom);

            var points = CubeCoordsHelper.CubeDrawLine(currentNode.CubeCoords, targetNode.CubeCoords);

            foreach (var point in points)
            {
                var offsetCoords = HexHelper.ConvertToOffset(point);

                // Это происходит, потому что если при нулевом Х для обеих комнат
                // попытаться отрисовать линию коридора, то она будет змейкой заходить за 0.
                // Нужно искать решение получше.
                offsetCoords = new OffsetCoords(offsetCoords.X < 0 ? 0 : offsetCoords.X,
                                                offsetCoords.Y < 0 ? 0 : offsetCoords.Y);

                var node = RoomHelper.CreateCorridorNode(map, edgeHash, currentNode, offsetCoords.X, offsetCoords.Y);
                currentNode = node;
            }
        }
Esempio n. 17
0
        public void GetNeighborNodes_NodeFromTopLeftCorner_NodesFromFourSegments()
        {
            // ARRANGE
            const int segmentSize = 4;

            var map        = new LazyHexMap(segmentSize);
            var zeroOffset = new OffsetCoords(0, 0);
            var zeroNode   = map.Nodes.Single(x => x.Offset.Equals(zeroOffset));


            // ACT
            var nodes     = map.GetNeighborNodes(zeroNode);
            var nodeArray = nodes.ToArray();


            // ASSERT
            nodeArray[0].Offset.Should().Be(new OffsetCoords(-1, 0));

            nodeArray[1].Offset.Should().Be(new OffsetCoords(-1, 1));
            nodeArray[2].Offset.Should().Be(new OffsetCoords(0, 1));

            nodeArray[3].Offset.Should().Be(new OffsetCoords(1, 0));

            nodeArray[4].Offset.Should().Be(new OffsetCoords(0, -1));
            nodeArray[5].Offset.Should().Be(new OffsetCoords(-1, -1));
        }
Esempio n. 18
0
    HexCell GetHexCell(Hex hex)
    {
        OffsetCoords o       = CubeToOffset(HexToCube(hex));
        GameObject   thisHex = hexArray[o.column, o.row];
        HexCell      hexCell = thisHex.GetComponent <HexCell>();

        return(hexCell);
    }
Esempio n. 19
0
    public static OffsetCoords GetOffsetCoords(int x, int y, int z)
    {
        OffsetCoords convertedCoords = new OffsetCoords();

        convertedCoords.col = x + (int)((z - (z & 1)) / 2);
        convertedCoords.row = z;
        return(convertedCoords);
    }
Esempio n. 20
0
        /// <summary>
        /// Выполняет заливку области в поле шестиугольников.
        /// </summary>
        /// <param name="matrix"> Поле шестиугольников. Будут заливаться ячейки со сзначением <b>true</b>. </param>
        /// <param name="point"> Точка, с которой начинается заливка. Должна указывать на ячейку со значением <b>true</b>. </param>
        /// <returns> Возвращает точки, которые были залиты. </returns>
        public static IEnumerable <OffsetCoords> FloodFill(Matrix <bool> matrix, OffsetCoords point)
        {
            if (matrix is null)
            {
                throw new ArgumentNullException(nameof(matrix));
            }

            var snapshotCellmap = (bool[, ])matrix.Items.Clone();

            var regionPoints = new List <OffsetCoords>();

            var openPoints = new HashSet <OffsetCoords>
            {
                point
            };

            while (openPoints.Count > 0)
            {
                var currentCell = openPoints.First();
                openPoints.Remove(currentCell);

                var isInBound = IsInBounds(currentCell, matrix.Width, matrix.Height);

                if (!isInBound)
                {
                    // Если текущая точка указывает за край карты, то не пытаемся её заливать.
                    // Пропускаем.
                    continue;
                }

                if (!snapshotCellmap[currentCell.X, currentCell.Y])
                {
                    // Заливаем только живые клетки.
                    // Мертвые клетки являются границей, они не попадают в заливку.
                    continue;
                }

                regionPoints.Add(currentCell);
                snapshotCellmap[currentCell.X, currentCell.Y] = false;

                var cubeCoords       = HexHelper.ConvertToCube(currentCell);
                var clockwiseOffsets = HexHelper.GetOffsetClockwise();

                foreach (var offset in clockwiseOffsets)
                {
                    var neighbourCubeCoords = cubeCoords + offset;

                    var neighbourCoords = HexHelper.ConvertToOffset(neighbourCubeCoords);

                    if (!openPoints.Contains(neighbourCoords))
                    {
                        openPoints.Add(neighbourCoords);
                    }
                }
            }

            return(regionPoints);
        }
Esempio n. 21
0
        public HexNode(OffsetCoords coords)
        {
            OffsetCoords = coords;

            var x = coords.X;
            var y = coords.Y;

            CubeCoords = HexHelper.ConvertToCube(x, y);
        }
Esempio n. 22
0
    // TODO: fix this so that it calculates around the world properly.
    public int HexDistance(Hex a, Hex b)
    {
        OffsetCoords fullOffset = new OffsetCoords(columns, 0);
        Hex          b2         = OffsetToHex(HexToOffset(b) + fullOffset);
        Hex          b3         = OffsetToHex(HexToOffset(b) - fullOffset);
        int          dist       = System.Math.Min(System.Math.Min(Hex.Distance(a, b), Hex.Distance(a, b2)), Hex.Distance(a, b3));

        return(dist);
    }
Esempio n. 23
0
    public override bool Equals(object obj)
    {
        WorldTile otherTile = obj as WorldTile;

        if (otherTile == null)
        {
            return(false);
        }

        return(OffsetCoords.Equals(otherTile.OffsetCoords));
    }
Esempio n. 24
0
        public void ConvertToOffsetTest(int offsetX, int offsetY, int cubeX, int cubeY, int cubeZ)
        {
            // ARRANGE
            var cubeCoords     = new CubeCoords(cubeX, cubeY, cubeZ);
            var expectedOffset = new OffsetCoords(offsetX, offsetY);

            // ACT
            var factOffsetCoords = HexHelper.ConvertToOffset(cubeCoords);

            // ASSERT
            factOffsetCoords.Should().BeEquivalentTo(expectedOffset);
        }
        public void Restore(HumanPlayer humanPlayer, Globe globe, IWorldManager worldManager)
        {
            var terrainCoords = new OffsetCoords(TerrainX, TerrainY);
            var terrainCell   = globe.Terrain.SelectMany(x => x).Single(x => x.Coords == terrainCoords);

            humanPlayer.Terrain   = terrainCell;
            humanPlayer.SectorSid = SectorSid;

            var globeRegion = worldManager.Regions[terrainCell];

            humanPlayer.GlobeNode = globeRegion.RegionNodes.Single(x => x.OffsetX == CurrentGlobeNodeX && x.OffsetY == CurrentGlobeNodeY);
        }
Esempio n. 26
0
        public IPropContainer AddChest(int id, OffsetCoords nodeCoords)
        {
            var containerManager = Container.GetInstance <IPropContainerManager>();

            var sector = Container.GetInstance <ISector>();
            var node   = sector.Map.Nodes.Cast <HexNode>().SelectBy(nodeCoords.X, nodeCoords.Y);
            var chest  = new FixedPropChest(node, new IProp[0], id);

            containerManager.Add(chest);

            return(chest);
        }
Esempio n. 27
0
        public void ThenАктёрНаходитсяВЯчейке(int expectedOffsetX, int expectedOffsetY)
        {
            var actor = Context.GetActiveActor();

            var node = actor.Node;

            var hexNode = (HexNode)node;

            var expectedOffsetCoords = new OffsetCoords(expectedOffsetX, expectedOffsetY);
            var factOffsetCoords     = hexNode.OffsetCoords;

            factOffsetCoords.Should().Be(expectedOffsetCoords);
        }
        /// <summary>
        /// Выбрасывает случайный набор уникальных координат в матрице комнат указаной длины.
        /// </summary>
        /// <param name="roomGridSize">Размер матрицы комнат.</param>
        /// <param name="roomCount">Количество комнат в секторе.</param>
        /// <returns>
        /// Возвращает массив координат из матрицы комнат.
        /// </returns>
        public IEnumerable <OffsetCoords> RollRoomMatrixPositions(int roomGridSize, int roomCount)
        {
            var result = new OffsetCoords[20];

            for (var y = 0; y < 4; y++)
            {
                for (var x = 0; x < 5; x++)
                {
                    result[x + y * 5] = new OffsetCoords(x, y);
                }
            }

            return(result);
        }
Esempio n. 29
0
        private static bool IsInBounds(OffsetCoords coords, int width, int height)
        {
            if (!ValueInRange(value: coords.X, min: 0, max: width - 1))
            {
                return(false);
            }

            if (!ValueInRange(value: coords.Y, min: 0, max: height - 1))
            {
                return(false);
            }

            return(true);
        }
Esempio n. 30
0
        public static bool IsAvailableFor(Matrix <bool> matrix, OffsetCoords coords)
        {
            if (matrix is null)
            {
                throw new ArgumentNullException(nameof(matrix));
            }

            if (!matrix[coords.X, coords.Y])
            {
                return(false);
            }

            return(true);
        }