/// <summary> /// Removes an <see cref="HutPivot"/> after discovery. /// </summary> /// <param name="hut">The hut to remove.</param> internal void RemoveHut(HutPivot hut) { _huts.Remove(hut); }
/// <summary> /// Constructor. /// </summary> /// <param name="mapSize"><see cref="SizePivot"/></param> /// <param name="mapShape"><see cref="LandShapePivot"/></param> /// <param name="landCoverage"><see cref="LandCoveragePivot"/></param> /// <param name="temperature"><see cref="TemperaturePivot"/></param> /// <param name="age"><see cref="AgePivot"/></param> /// <param name="humidity"><see cref="HumidityPivot"/></param> internal MapPivot(SizePivot mapSize, LandShapePivot mapShape, LandCoveragePivot landCoverage, TemperaturePivot temperature, AgePivot age, HumidityPivot humidity) { var continentCount = mapShape == LandShapePivot.Pangaea ? 1 : ( mapShape == LandShapePivot.Continent ? Tools.Randomizer.Next(CONTINENT_COUNT_MIN, CONTINENT_COUNT_MAX + 1) : Tools.Randomizer.Next(ISLAND_COUNT_MIN, ISLAND_COUNT_MAX + 1) ); var landRatio = LAND_COVERAGE_RATIOS[landCoverage]; _huts = new List <HutPivot>(); Height = MINIMAL_HEIGHT * (int)mapSize; Width = Height * RATIO_WIDTH_HEIGHT; GlobalTemperature = temperature; _mapSquareList = new MapSquarePivot[Height, Width]; var continentInfos = new List <List <MapSquarePivot> >(); var boundaries = new List <ContinentBlueprint>(); Action <ContinentBlueprint> SplitX = delegate(ContinentBlueprint contPick) { var splitX = Tools.Randomizer.Next((int)Math.Floor(MIN_SPLIT_RATIO * contPick.Width), (int)Math.Floor(MAX_SPLIT_RATIO * contPick.Width)); boundaries.Add(new ContinentBlueprint(splitX, contPick.Height, contPick.StartX, contPick.StartY)); boundaries.Add(new ContinentBlueprint(contPick.Width - splitX, contPick.Height, contPick.StartX + splitX, contPick.StartY)); }; Action <ContinentBlueprint> SplitY = delegate(ContinentBlueprint contPick) { var splitY = Tools.Randomizer.Next((int)Math.Floor(MIN_SPLIT_RATIO * contPick.Height), (int)Math.Floor(MAX_SPLIT_RATIO * contPick.Height)); boundaries.Add(new ContinentBlueprint(contPick.Width, splitY, contPick.StartX, contPick.StartY)); boundaries.Add(new ContinentBlueprint(contPick.Width, contPick.Height - splitY, contPick.StartX, contPick.StartY + splitY)); }; Action <int, bool> Split = delegate(int pickIndex, bool inY) { var contPick = boundaries[pickIndex]; if (inY) { SplitY(contPick); } else { SplitX(contPick); } boundaries.Remove(contPick); }; List <int> ranges = new List <int>(); var cpt = ISLAND_COUNT_MAX; while (cpt > 1) { ranges.Add(cpt); cpt /= 2; } for (int i = 1; i <= continentCount; i++) { if (boundaries.Count == 0) { boundaries.Add(new ContinentBlueprint(Width, Height, 0, 0)); } else { var nextTypeI = ranges.Where(x => x > boundaries.Count).Min(); Split( Tools.Randomizer.Next(0, nextTypeI - boundaries.Count), ranges.Any(x => x == Math.Sqrt(nextTypeI)) ); } } var cIndex = 0; foreach (var boundary in boundaries) { continentInfos.Add(ConvertContinentBlueprintToMapSquares(landRatio, boundary, cIndex)); cIndex++; } // sets chunks var chunksByType = BiomePivot.ChunkAppearanceBiomes.ToDictionary(b => b, b => new List <List <Tuple <int, int> > >()); var rivers = new List <List <Tuple <int, int> > >(); var huts = new List <Tuple <int, int> >(); foreach (var fullLand in continentInfos) { fullLand.ForEach(msloc => _mapSquareList[msloc.Row, msloc.Column] = msloc); var continentLand = fullLand.Where(ms => !ms.Biome.IsSeaType).ToList(); var chunksCountByType = BiomePivot.ChunkAppearanceBiomes .ToDictionary(b => b, b => b.ChunkSquaresCount(continentLand.Count, CHUNK_SIZE_RATIO, humidity, age)); var topY = continentLand.Min(x => x.Row); var leftX = continentLand.Min(x => x.Column); var bottomY = continentLand.Max(x => x.Row); var rightX = continentLand.Max(x => x.Column); // Squares count in height for one square in width var ratioHeightWidth = (int)Math.Round((bottomY - topY + 1) / (double)(rightX - leftX + 1)); foreach (var chunkType in chunksByType.Keys) { chunksByType[chunkType].AddRange(FiilContinentBlueprintWithBiomeChunks( chunksCountByType[chunkType], chunkType.SizeInt * CHUNK_SIZE_RATIO, topY, leftX, bottomY, rightX, ratioHeightWidth, chunkType.Temperatures)); } // Rivers count on the continent. var riversCount = (int)Math.Round(continentLand.Count * BiomePivot.River.AppearanceRate); for (int i = 0; i < riversCount; i++) { var river = new List <Tuple <int, int> >(); // Random river starting point. var riverPt = new Tuple <int, int>( Tools.Randomizer.Next(topY, bottomY), Tools.Randomizer.Next(leftX, rightX) ); // The river can go in two directions [(bottom or top) and (left or right)] var forbiddenDirection1 = (DirectionPivot)Tools.Randomizer.Next(2, 4); var forbiddenDirection2 = (DirectionPivot)Tools.Randomizer.Next(0, 2); // Loops until the river reachs the coast, or another river. while (riverPt.Item1 >= topY && riverPt.Item1 <= bottomY && riverPt.Item2 >= leftX && riverPt.Item2 <= rightX && !rivers.Any(r => r.Any(rsquare => rsquare.Item1 == riverPt.Item1 && rsquare.Item2 == riverPt.Item2))) { river.Add(riverPt); DirectionPivot currentDirection; do { // Picks a random direction, which can't be a forbidden one. currentDirection = (DirectionPivot)Tools.Randomizer.Next(0, 4); }while (currentDirection == forbiddenDirection1 || currentDirection == forbiddenDirection2); riverPt = new Tuple <int, int>( riverPt.Item1 + (currentDirection == DirectionPivot.Bottom ? 1 : (currentDirection == DirectionPivot.Top ? -1 : 0)), riverPt.Item2 + (currentDirection == DirectionPivot.Right ? 1 : (currentDirection == DirectionPivot.Left ? -1 : 0)) ); } rivers.Add(river); } // Huts count on the continent. var hutsCount = (int)Math.Round(continentLand.Count * HUT_APPEARANCE_RATE); // Creates hut locations. for (int i = 0; i < hutsCount; i++) { Tuple <int, int> hutPoint; do { hutPoint = new Tuple <int, int>( Tools.Randomizer.Next(topY, bottomY), Tools.Randomizer.Next(leftX, rightX) ); }while (huts.Any(h => h.Item1 == hutPoint.Item1 && h.Item2 == hutPoint.Item2)); huts.Add(hutPoint); } } foreach (var type in chunksByType.Keys) { foreach (var chunkOfType in chunksByType[type]) { foreach (var ofType in chunkOfType) { var currSq = _mapSquareList[ofType.Item1, ofType.Item2]; currSq.ChangeBiome(type); } } } // Overrides chunks with river squares. rivers.ForEach(r => r.ForEach(rSquare => _mapSquareList[rSquare.Item1, rSquare.Item2].ChangeBiome(BiomePivot.River))); // Add huts. foreach (var hSquare in huts) { HutPivot hut = null; var location = _mapSquareList[hSquare.Item1, hSquare.Item2]; var typeHut = Tools.Randomizer.Next(0, 6); switch (typeHut) { case 0: hut = HutPivot.EmptyHut(location); break; case 1: hut = HutPivot.AdvanceHut(location); break; case 2: hut = HutPivot.BarbariansHut(location); break; case 3: hut = HutPivot.SettlerHut(location); break; case 4: hut = HutPivot.FriendlyCavalryUnitHut(location); break; case 5: hut = HutPivot.GoldHut(location); break; } if (hut != null) { _huts.Add(hut); } } }