private static void ApplyRegionPatternInner(GlobeRegionDraftValue[,] regionDraft, GlobeRegionPatternValue[,] patternValues, int insertX, int insertY, int townIndex) { var interestObjectCounter = 0; for (var x = patternValues.GetLowerBound(0); x <= patternValues.GetUpperBound(0); x++) { for (var y = patternValues.GetLowerBound(1); y <= patternValues.GetUpperBound(1); y++) { GlobeRegionDraftValue draftValue = null; // TODO Для диких секторов нужно ввести отдельное значение шаблона. // Потому что в шаблонах планируются ещё пустые (непроходимые) узлы. Но и для них будет специальное значение. // А пустота (null) будет означать, что ничего делать не нужно (transparent). // Потому что будут ещё шаблоны, накладываемые поверх всех в случайные места, чтобы генерировать дополнительные // мусорные объекты. var patternValue = patternValues[x, y]; if (patternValue == null) { draftValue = new GlobeRegionDraftValue(GlobeRegionDraftValueType.Wild); } else if (patternValue.IsStart) { draftValue = new GlobeRegionDraftValue(GlobeRegionDraftValueType.Dungeon) { IsStart = true }; } else if (patternValue.IsHome) { draftValue = new GlobeRegionDraftValue(GlobeRegionDraftValueType.Town) { IsHome = true }; } else if (patternValue.HasObject) { if (interestObjectCounter == townIndex) { draftValue = new GlobeRegionDraftValue(GlobeRegionDraftValueType.Town); } else { draftValue = new GlobeRegionDraftValue(GlobeRegionDraftValueType.Dungeon); } interestObjectCounter++; } regionDraft[x + insertX, y + insertY] = draftValue; } } }
/// <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)); }