//TODO Постараться объединить GetStartProvinceCoords и GetHomeProvinceCoords private TerrainCell GetHomeProvinceCoords(Globe globe, TerrainCell startProvince) { // Выбираем основной город, являющийся стартовым. // По городу определяем провинцию. var currentCubeCoords = HexHelper.ConvertToCube(startProvince.Coords); var availableLocalities = globe.Localities .Where(x => x.Cell != startProvince) .Where(x => HexHelper.ConvertToCube(x.Cell.Coords).DistanceTo(currentCubeCoords) > 2) .Where(x => HexHelper.ConvertToCube(x.Cell.Coords).DistanceTo(currentCubeCoords) <= 5) .ToArray(); Locality selectedLocality; if (availableLocalities.Any()) { var localityIndex = _dice.Roll(0, availableLocalities.Count() - 1); selectedLocality = availableLocalities[localityIndex]; } else { selectedLocality = globe.Localities.LastOrDefault(); } if (selectedLocality == null) { //TODO Создать отдельный класс исключений GlobeGenerationException. throw new InvalidOperationException("Не удалось выбрать локацию для дома."); } return(selectedLocality.Cell); }
/// <summary> /// Создание /// </summary> /// <param name="globe">Объект игрового мира, для которого создаётся локация.</param> /// <param name="cell">Провинция игрового мира из указанного выше <see cref="Globe" />, /// для которого создаётся локация.</param> /// <returns> /// Возвращает граф локация для провинции. /// </returns> public Task <GlobeRegion> GenerateRegionAsync(Globe globe, TerrainCell cell) { var locationSchemeSids = new[] { "rat-hole", "rat-kingdom", "demon-dungeon", "demon-lair", "crypt", "elder-place", "genomass-cave" }; var region = new GlobeRegion(LocationBaseSize); for (var x = 0; x < LocationBaseSize; x++) { for (var y = 0; y < LocationBaseSize; y++) { //var hasNodeRoll = _dice.Roll(6); //if (hasNodeRoll <= 2) //{ // continue; //} var hasDundeonRoll = _dice.Roll(100); if (hasDundeonRoll > 90) { var locationSidIndex = _dice.Roll(0, locationSchemeSids.Length - 1); var locationSid = locationSchemeSids[locationSidIndex]; var locationScheme = _schemeService.GetScheme <ILocationScheme>(locationSid); var node = new GlobeRegionNode(x, y, locationScheme); region.AddNode(node); } else { var hasCityRoll = _dice.Roll(100); if (hasCityRoll > 90) { var locationScheme = _schemeService.GetScheme <ILocationScheme>("city"); var node = new GlobeRegionNode(x, y, locationScheme) { IsTown = true }; region.AddNode(node); } else { var locationScheme = _schemeService.GetScheme <ILocationScheme>("forest"); var node = new GlobeRegionNode(x, y, locationScheme); region.AddNode(node); } } } } return(Task.FromResult(region)); }
/// <summary> /// Создание /// </summary> /// <param name="globe">Объект игрового мира, для которого создаётся локация.</param> /// <param name="cell">Провинция игрового мира из указанного выше <see cref="Globe" />, /// для которого создаётся локация.</param> /// <returns> /// Возвращает граф локация для провинции. /// </returns> public Task <GlobeRegion> GenerateRegionAsync(Globe globe, TerrainCell cell) { var region = new GlobeRegion(LocationBaseSize); // Сейчас допускаем, что паттерны квадратные, меньше размера провинции. // Пока не вращаем и не искажаем. // Там, где может быть объект, гарантированно создаём один город и два подземелья. var regionDraft = new GlobeRegionDraftValue[LocationBaseSize, LocationBaseSize]; var startPattern = GlobeRegionPatterns.Start; var homePattern = GlobeRegionPatterns.Home; // Расчитываем размер паттернов. // Исходим из того, что пока все паттерны квадратные и одинаковые по размеру. // Поэтому размер произвольного паттерна будет справедлив для всех остальных. // Паттерн старта выбран произвольно. var patternSize = startPattern.Values.GetUpperBound(0) - startPattern.Values.GetLowerBound(0) + 1; // Вставляем паттерны в указанные области ApplyRegionPattern(ref regionDraft, GetDefaultPattrn(), 1, 1); ApplyRegionPattern(ref regionDraft, GetDefaultPattrn(), LocationBaseSize - patternSize - 1, 1); ApplyRegionPattern(ref regionDraft, GetDefaultPattrn(), 1, LocationBaseSize - patternSize - 1); ApplyRegionPattern(ref regionDraft, GetDefaultPattrn(), LocationBaseSize - patternSize - 1, LocationBaseSize - patternSize - 1); if (globe.StartProvince == cell) { ApplyRegionPattern(ref regionDraft, startPattern, (LocationBaseSize - patternSize) / 2, (LocationBaseSize - patternSize) / 2); } else if (globe.HomeProvince == cell) { ApplyRegionPattern(ref regionDraft, homePattern, (LocationBaseSize - patternSize) / 2, (LocationBaseSize - patternSize) / 2); } else { ApplyRegionPattern(ref regionDraft, GetDefaultPattrn(), (LocationBaseSize - patternSize) / 2, (LocationBaseSize - patternSize) / 2); } for (var x = regionDraft.GetLowerBound(0); x <= regionDraft.GetUpperBound(0); x++) { for (var y = regionDraft.GetLowerBound(1); y <= regionDraft.GetUpperBound(1); y++) { ValidateRegion(region, regionDraft, x, y); } } return(Task.FromResult(region)); }
public static void AddAgentToCell(Dictionary <TerrainCell, List <Agent> > cells, TerrainCell cell, Agent agent) { if (cells.TryGetValue(cell, out var list)) { list.Add(agent); } else { list = new List <Agent> { agent }; cells[cell] = list; } }
public static void RemoveAgentToCell(Dictionary <TerrainCell, List <Agent> > cells, TerrainCell cell, Agent agent) { if (cells.TryGetValue(cell, out var list)) { list.Remove(agent); } }
public static void RemoveAgentFromCell(Dictionary <TerrainCell, List <Agent> > cellDict, TerrainCell cell, Agent agent) { if (cellDict.TryGetValue(cell, out var list)) { list.Remove(agent); if (!list.Any()) { cellDict.Remove(cell); } } }