예제 #1
0
 /// <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);
 }
예제 #2
0
        /// <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);
                }
            }
        }