private IPropContainer CreateContainerModuleByPurpose(IDropTableScheme[] trashDropTables, IDropTableScheme[] treasuresDropTable, PropContainerPurpose containerPurpose) { IPropContainer container; switch (containerPurpose) { case PropContainerPurpose.Trash: container = new DropTablePropChest(trashDropTables, _dropResolver) { Purpose = PropContainerPurpose.Trash }; break; case PropContainerPurpose.Treasures: container = new DropTablePropChest(treasuresDropTable, _dropResolver) { Purpose = PropContainerPurpose.Treasures }; break; default: throw new InvalidOperationException($"Не корректное назначение {containerPurpose}."); } return(container); }
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); }
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); }
public void AddModule_From() { // ARRANGE var dropResolverMock = new Mock <IDropResolver>(); var dropResolver = dropResolverMock.Object; var container = new DropTablePropChest(Array.Empty <IDropTableScheme>(), dropResolver); var nodeMock = new Mock <IGraphNode>(); var node = nodeMock.Object; var staticObject = new StaticObject(node, default, default);
private void CreateChests(Room[] rooms) { var defaultDropTable = _schemeService.GetScheme <DropTableScheme>("default"); var survivalDropTable = _schemeService.GetScheme <DropTableScheme>("survival"); foreach (var room in rooms) { var absNodeIndex = room.Nodes.Count(); var containerNode = room.Nodes[absNodeIndex / 2]; var container = new DropTablePropChest(containerNode, new[] { defaultDropTable, survivalDropTable }, _dropResolver); _propContainerManager.Add(container); } }
/// <summary> /// Создать сундуки в секторе. /// </summary> /// <param name="map">Карта сектора. Нужна для определения доступного места для сундука.</param> /// <param name="sectorSubScheme">Схема сектора. По сути - настройки для размещения сундуков.</param> /// <param name="regions">Регионы, в которых возможно размещение сундуков.</param> public void CreateChests(ISectorMap map, ISectorSubScheme sectorSubScheme, IEnumerable <MapRegion> regions) { var dropTables = GetDropTables(sectorSubScheme); var chestCounter = sectorSubScheme.TotalChestCount; //TODO В схемах хранить уже приведённое значение пропорции. var countChestRatioNormal = 1f / sectorSubScheme.RegionChestCountRatio; foreach (var region in regions) { var maxChestCountRaw = region.Nodes.Count() * countChestRatioNormal; var maxChestCount = (int)Math.Max(maxChestCountRaw, 1); var rolledCount = _chestGeneratorRandomSource.RollChestCount(maxChestCount); var availableNodes = from node in region.Nodes where !map.Transitions.Keys.Contains(node) select node; var openNodes = new List <IMapNode>(availableNodes); for (var i = 0; i < rolledCount; i++) { // Выбрать из коллекции доступных узлов var rollIndex = _chestGeneratorRandomSource.RollNodeIndex(openNodes.Count); var containerNode = MapRegionHelper.FindNonBlockedNode(openNodes[rollIndex], map, openNodes); if (containerNode == null) { // в этом случае будет сгенерировано на один сундук меньше. // узел, с которого не удаётся найти подходящий узел, удаляем, // чтобы больше его не анализировать, т.к. всё равно будет такой же исход. openNodes.Remove(openNodes[rollIndex]); continue; } openNodes.Remove(containerNode); var container = new DropTablePropChest(containerNode, dropTables, _dropResolver); _propContainerManager.Add(container); chestCounter--; if (chestCounter <= 0) { // лимит сундуков в секторе исчерпан. break; } } } }
public void DropTablePropContainerTest() { // ARRANGE var nodeMock = new Mock <IMapNode>(); var node = nodeMock.Object; var dropTableRecord = new TestDropTableRecordSubScheme { SchemeSid = "test-prop", Weight = 1, MinCount = 1, MaxCount = 1 }; var dropTable = new TestDropTableScheme(1, dropTableRecord); var testPropScheme = new PropScheme { Sid = "test-prop" }; var dropResolverMock = new Mock <IDropResolver>(); dropResolverMock.Setup(x => x.Resolve(It.IsAny <IEnumerable <IDropTableScheme> >())) .Returns(new IProp[] { new Resource(testPropScheme, 1) }); var dropResolver = dropResolverMock.Object; var container = new DropTablePropChest(node, new IDropTableScheme[] { dropTable }, dropResolver); // ACT var factProps = container.Content.CalcActualItems(); // ASSERT factProps.Length.Should().Be(1); factProps[0].Scheme.Should().BeSameAs(testPropScheme); ((Resource)factProps[0]).Count.Should().Be(1); }
/// <summary> /// Создать сундуки в секторе. /// </summary> /// <param name="map">Карта сектора. Нужна для определения доступного места для сундука.</param> /// <param name="sectorSubScheme">Схема сектора. По сути - настройки для размещения сундуков.</param> /// <param name="regions">Регионы, в которых возможно размещение сундуков.</param> public void CreateChests(ISectorMap map, ISectorSubScheme sectorSubScheme, IEnumerable <MapRegion> regions) { var trashDropTables = GetTrashDropTables(sectorSubScheme); var treasuresDropTable = GetTreasuresDropTable(); var chestCounter = sectorSubScheme.TotalChestCount; //TODO В схемах хранить уже приведённое значение пропорции. var countChestRatioNormal = 1f / sectorSubScheme.RegionChestCountRatio; foreach (var region in regions) { var maxChestCountRaw = region.Nodes.Count() * countChestRatioNormal; var maxChestCount = (int)Math.Max(maxChestCountRaw, 1); if (region.Nodes.Count() <= 1) { // Для регионов, где только один узел, // не создаём сундуки, иначе проход может быть загорожен. // Актуально для фабрики карт на основе клеточного автомата, // потому что он может генерить регионы из одного узла. //TODO Попробовать проверять соседей узла. // Возможно, одноклеточный регион находится в конце тупика. // Тогда в нём можно разместить сундук. // Критерий доступности такого региона - у узла только одни сосед. continue; } var rolledCount = _chestGeneratorRandomSource.RollChestCount(maxChestCount); var availableNodes = from node in region.Nodes where !map.Transitions.Keys.Contains(node) where map.IsPositionAvailableForContainer(node) select node; var openNodes = new List <IMapNode>(availableNodes); for (var i = 0; i < rolledCount; i++) { var containerPurpose = _chestGeneratorRandomSource.RollPurpose(); // Выбрать из коллекции доступных узлов var rollIndex = _chestGeneratorRandomSource.RollNodeIndex(openNodes.Count); var containerNode = MapRegionHelper.FindNonBlockedNode(openNodes[rollIndex], map, openNodes); if (containerNode == null) { // в этом случае будет сгенерировано на один сундук меньше. // узел, с которого не удаётся найти подходящий узел, удаляем, // чтобы больше его не анализировать, т.к. всё равно будет такой же исход. openNodes.Remove(openNodes[rollIndex]); continue; } // Проверка, что сундук не перегораживает проход. var isValid = CheckMap(map, (HexNode)containerNode); if (!isValid) { // в этом случае будет сгенерировано на один сундук меньше. // узел, с которого не удаётся найти подходящий узел, удаляем, // чтобы больше его не анализировать, т.к. всё равно будет такой же исход. openNodes.Remove(openNodes[rollIndex]); continue; } openNodes.Remove(containerNode); IPropContainer container; switch (containerPurpose) { case PropContainerPurpose.Trash: container = new DropTablePropChest(containerNode, trashDropTables, _dropResolver) { Purpose = PropContainerPurpose.Trash }; break; case PropContainerPurpose.Treasures: container = new DropTablePropChest(containerNode, treasuresDropTable, _dropResolver) { Purpose = PropContainerPurpose.Treasures }; break; default: throw new InvalidOperationException($"Не корректное назначение {containerPurpose}."); } _propContainerManager.Add(container); chestCounter--; if (chestCounter <= 0) { // лимит сундуков в секторе исчерпан. break; } } } }