예제 #1
0
    // Use this for initialization
    void Start()
    {
        ProbabilityList <char> list = new ProbabilityList <char>();

        list.Add('A', 1, false);    // Normal Probability
        list.Add('B', 2, false);    // Double normal probability
        list.Add('C', .5, false);   // Half normal probability
        list.Add('Z', .001, false); // very rare
        Test(list, Max, false);

        // Make a func that sets customized probability modifiers based on level
        LeveledPool <char> leveled = new LeveledPool <char>((playerLevel, itemLevel) =>
        {
            int diff = Math.Abs(itemLevel - playerLevel);
            // Return the probability multiplier we want for this current itemLevel
            if (diff > 10)
            {
                return(-1);
            }
            return(Math.Pow(2, -diff));
        });

        leveled.Add('A', 1, false, 5);    // level 5 entry with normal prob
        leveled.Add('B', 2, false, 4);    // level 4 entry with double prob
        leveled.Add('C', .5, false, 7);   // level 7 entry with half prob
        leveled.Add('Z', .001, false, 6); // level 6 entry rare
        leveled.Add('X', 1, false, 20);   // Should be cut out
        Test(leveled, Max, false, 5);     // Testing against level 5
    }
예제 #2
0
 public ProbabilityList(ProbabilityList <T> rhs)
 {
     this.Max = rhs.Max;
     foreach (ProbContainer cont in rhs.itemList)
     {
         itemList.Add(new ProbContainer(cont));
     }
 }
예제 #3
0
        public override void Initialize(InitializeParameters p)
        {
            base.Initialize(p);

            if (!string.IsNullOrWhiteSpace(this.Probabilities))
            {
                probabilities = new ProbabilityList(this.random, this.Probabilities.Split(',').Select(s => double.Parse(s)));

                if (probabilities.Count != runnables.Count)
                {
                    throw new InvalidOperationException(string.Format("Number of probabilities must match the number of runnables - {0} != {1}", probabilities.Count, runnables));
                }
            }
        }
예제 #4
0
    public override ProbabilityPool <T> Filter(System.Func <T, bool> filter)
    {
        ProbabilityList <T>  ret      = new ProbabilityList <T>();
        List <ProbContainer> filtered = new List <ProbContainer>();

        foreach (ProbContainer cont in itemList)
        {
            if (filter(cont.Item))
            {
                filtered.Add(cont);
            }
        }
        ret.Add(filtered);
        return(ret);
    }
예제 #5
0
    public static List <Value2D <GenSpace> > PlaceSomeDoors(this Container2D <GenSpace> arr, IEnumerable <Point> points, Theme theme, System.Random rand, int desiredWallToDoorRatio = -1, Point shift = null)
    {
        if (desiredWallToDoorRatio < 0)
        {
            desiredWallToDoorRatio = LevelGenerator.desiredWallToDoorRatio;
        }
        var     acceptablePoints   = new MultiMap <GenSpace>();
        Counter numPoints          = new Counter();
        DrawAction <GenSpace> call = Draw.Count <GenSpace>(numPoints).And(Draw.CanDrawDoor().IfThen(Draw.AddTo(acceptablePoints)));

        if (shift != null)
        {
            call = call.Shift <GenSpace>(shift.x, shift.y);
        }
        arr.DrawPoints(points, call);
        if (DoorRatioPicker == null)
        {
            DoorRatioPicker = new ProbabilityList <int>();
            DoorRatioPicker.Add(-2, .25);
            DoorRatioPicker.Add(-1, .5);
            DoorRatioPicker.Add(0, 1);
            DoorRatioPicker.Add(1, .5);
            DoorRatioPicker.Add(2, .25);
        }
        int numDoors = numPoints / desiredWallToDoorRatio;

        numDoors += DoorRatioPicker.Get(rand);
        if (numDoors <= 0)
        {
            numDoors = 1;
        }
        List <Value2D <GenSpace> > pickedPts = acceptablePoints.GetRandom(rand, numDoors, 1);

        foreach (Point picked in pickedPts)
        {
            arr.SetTo(picked, GridType.Door, theme);
        }
        return(pickedPts);
    }
예제 #6
0
        public override void Initialize()
        {
            //************************* INIT TEXTURES(needs to be init before map) ************************//

            //Load in bullet texture
            ProjectileConfig.BULLET_TEXTURE =
                director.Content.Load <Texture2D>(MainConfig.PIPELINE_GRAPHICS_DIRECTORY + "Bullet");
            ProjectileConfig.BULLET_SIZE = new Vector3(ProjectileConfig.BULLET_TEXTURE.Width / 1.5f,
                                                       ProjectileConfig.BULLET_TEXTURE.Height / 1.5f, 0f);//new Vector3(ProjectileConfig.BULLET_TEXTURE.Width/2f, ProjectileConfig.BULLET_TEXTURE.Height/2f, 0);

            //Load in dart texture
            ProjectileConfig.DART_TEXTURE =
                director.Content.Load <Texture2D>(MainConfig.PIPELINE_GRAPHICS_DIRECTORY + "Dart");
            ProjectileConfig.DART_SIZE = new Vector3(ProjectileConfig.DART_TEXTURE.Width,
                                                     ProjectileConfig.DART_TEXTURE.Height, 0f);

            //Init all treasure and ammo crate textures into the ItemsConfig class
            ItemsConfig.LOOT_TEXTURE = new List <Texture2D>();
            string treasurePrefix = "Treasure0";

            for (var i = 0; i < numOfTreasureTypes; i++)
            {
                ItemsConfig.LOOT_TEXTURE.Add(
                    director.Content.Load <Texture2D>(MainConfig.PIPELINE_GRAPHICS_DIRECTORY + treasurePrefix + (i + 1)));
            }

            ItemsConfig.AMMO_CRATE_TEXTURE =
                director.Content.Load <Texture2D>(MainConfig.PIPELINE_GRAPHICS_DIRECTORY + "NewCrate");

            for (var i = 0; i < maxAmmoCount + 1; i++)
            {
                ItemsConfig.AMMO_COUNT_TEXTURES.Add(
                    director.Content.Load <Texture2D>(MainConfig.PIPELINE_GRAPHICS_DIRECTORY + "Ammo" + i));
            }

            ItemsConfig.TRAP_CLOSED_TEXTURE =
                director.Content.Load <Texture2D>(MainConfig.PIPELINE_GRAPHICS_DIRECTORY + "TrapClosed");

            ItemsConfig.TRAP_OPEN_TEXTURE =
                director.Content.Load <Texture2D>(MainConfig.PIPELINE_GRAPHICS_DIRECTORY + "TrapOpen");

            ParticleConfig.WHITE_CIRCLE =
                director.Content.Load <Texture2D>(MainConfig.PIPELINE_GRAPHICS_DIRECTORY + "whiteCircle");

            ParticleConfig.RAIN_DROP =
                director.Content.Load <Texture2D>(MainConfig.PIPELINE_GRAPHICS_DIRECTORY + "raindrop");

            int    numOfFootstepTextures = 3;
            string texturePrefix         = "FootstepParticle0";

            for (var i = 0; i < numOfFootstepTextures; i++)
            {
                ParticleConfig.FOOTSTEP_TEXTURE.Add(new Sprite(director.Content.Load <Texture2D>(MainConfig.PIPELINE_GRAPHICS_DIRECTORY + texturePrefix + i)));
            }

            int numOfFoliageTextures = 5;

            texturePrefix = "UndergrowthParticle0";
            for (var i = 0; i < numOfFoliageTextures; i++)
            {
                ParticleConfig.FOLIAGE_CUT_TEXTURE.Add(new Sprite(director.Content.Load <Texture2D>(MainConfig.PIPELINE_GRAPHICS_DIRECTORY + texturePrefix + (i + 1))));
            }

            LightningConfig.LIGHTNING_TEXTURES[0] = director.Content.Load <Texture2D>(MainConfig.PIPELINE_GRAPHICS_DIRECTORY + "Half Circle");
            LightningConfig.LIGHTNING_TEXTURES[1] = director.Content.Load <Texture2D>(MainConfig.PIPELINE_GRAPHICS_DIRECTORY + "Lightning Segment");

            //************************* INIT MAP(map needs to be initialized before player) ************************//

            //Import a simple test level
            TiledMap tiledMap = new TiledMap(MainConfig.CONTENT_MAP_DIRECTORY + "FinalLevel.xml", director.Content, MainConfig.PIPELINE_GRAPHICS_DIRECTORY, scene);

            this.BaseScreenSize = tiledMap.MapSize;


            //************************* INIT SHOP KEEPER ************************//
            Character shopkeeper = CharacterImporter.ImportCharacter(
                MainConfig.CONTENT_CHARACTERS_DIRECTORY + MainConfig.CONTENT_SHOPKEEPER_FILE, director.Content, scene);

            scene.RegisterObject(shopkeeper);



            //************************* INIT AI GRAPH ************************//
            NavGraph navGraph = new NavGraph(scene);

            //************************* INIT FOLIAGE (after the characters!!) ************************//


            // Initialize the foliage events
            // Initialize treasures and ammo crates
            int foliageCount    = scene.GetFoliage().Count;
            int treasureCount   = selectedPlayers.Length * MatchConfig.TreasuresPerPlayer;                    //(int)(foliageCount * MatchConfig.TreasureFactor);
            int ammoCrateCount  = (int)(foliageCount * MatchConfig.AmmoCrateFactor);
            int indigenousCount = (int)Math.Ceiling(selectedPlayers.Length * MatchConfig.IndPeoplePerPlayer); //(foliageCount * MatchConfig.IndigenousFactor);
            int snakeCount      = (int)(foliageCount * MatchConfig.SnakeSpawnFactor);

            scene.TreasuresLeft = treasureCount;

            List <Foliage> undecidedFoliage = new List <Foliage>();

            undecidedFoliage.AddRange(scene.GetFoliage());

            // Favor higher distances to the shopkeeper
            ProbabilityList <Foliage, double> undecidedFoliageProbabilityList =
                new ProbabilityList <Foliage, double>(MatchConfig.TreasureDistanceProbabilityMeanFactor, MatchConfig.TreasureDistanceProbabilityVarianceFactor, foliage =>
                                                      Math.Sqrt(
                                                          Math.Pow(foliage.GetPosition().X - shopkeeper.GetPosition().X, 2) +
                                                          Math.Pow(foliage.GetPosition().Y - shopkeeper.GetPosition().Y, 2) +
                                                          Math.Pow(foliage.GetPosition().Z - shopkeeper.GetPosition().Z, 2))
                                                      , scene.Random);


            Random random = scene.Random;


            // WARNING: Order of hiding matters! 1. AI, 2. Snakes, 3. Rest
            // This way, snakes can be hidden with other things.

            // Hide Indigenous AI
            for (int i = 0; i < indigenousCount; i++)
            {
                Foliage currentFoliage;
                SpawnAiPossessedCharacterEvent currentSpawnAiPossessedCharacterEvent;
                Character currentIndigenousCharacter;
                // Select one random foliage to put treasure inside
                currentFoliage = undecidedFoliage[random.Next(undecidedFoliage.Count)];
                undecidedFoliage.Remove(currentFoliage);
                currentIndigenousCharacter = CharacterImporter.ImportCharacter(MainConfig.CONTENT_CHARACTERS_DIRECTORY + "IndigenousChar.xml", director.Content, scene);
                currentIndigenousCharacter.InitCharacter(new Vector3(currentFoliage.PositionForContent.X, currentFoliage.PositionForContent.Y - 150, 0f));
                currentSpawnAiPossessedCharacterEvent = new SpawnAiPossessedCharacterEvent(currentIndigenousCharacter, scene);
                currentFoliage.CharacterCutEventList.EventList.Add(currentSpawnAiPossessedCharacterEvent);
            }

            //Hide snakes
            for (int i = 0; i < snakeCount; i++)
            {
                Foliage         currentFoliage;
                SpawnSnakeEvent currentSpawnSnakeEvent;
                currentFoliage = undecidedFoliage[random.Next(undecidedFoliage.Count)];

                // Don't remove currentfoliage from undecidedfoliage because snakes should appear in any foliage (except foliage with AI)

                Tuple <Spritesheet, Rectangle> snakeData = SpritesheetImporter.ImportSpritesheet(MainConfig.CONTENT_CHARACTERS_DIRECTORY + "Snake.xml", director.Content, scene);

                Snake snake = new Snake(snakeData.Item1, new Vector2(currentFoliage.PositionForContent.X, currentFoliage.PositionForContent.Y - 70), snakeData.Item2);
                scene.RegisterObject(snake);
                currentSpawnSnakeEvent = new SpawnSnakeEvent(snake, scene);
                //test
                var rand = random.Next(1, 4);                //1,2,3

                if (rand < 2)
                {
                    Foliage movingFoliage = CreateMovingFoliage(currentFoliage);

                    movingFoliage.CharacterCutEventList.EventList.Add(currentSpawnSnakeEvent);
                    scene.RegisterObject(movingFoliage);
                    scene.RemoveActor(currentFoliage);

                    // Make sure that things hidden later are hidden in foliage that is accessible and visible
                    undecidedFoliage.Remove(currentFoliage);
                    undecidedFoliage.Add(movingFoliage);
                }
                else
                {
                    currentFoliage.CharacterCutEventList.EventList.Add(currentSpawnSnakeEvent);
                }
            }


            // Hide treasures
            undecidedFoliageProbabilityList.AddRange(undecidedFoliage);
            undecidedFoliageProbabilityList.LockList(true);

            for (int i = 0; i < treasureCount; i++)
            {
                Foliage           currentFoliage;
                TreasureDropEvent currentTreasureDropEvent;
                // Select one random foliage to put treasure inside
                currentFoliage = undecidedFoliageProbabilityList.DrawItem();
                //test
                var rand = random.Next(1, 4);

                if (rand < 2)
                {
                    Foliage movingFoliage = CreateMovingFoliage(currentFoliage);

                    currentTreasureDropEvent = new TreasureDropEvent(random, currentFoliage.PositionForContent, scene);
                    movingFoliage.CharacterCutEventList.EventList.Add(currentTreasureDropEvent);
                    scene.RegisterObject(movingFoliage);
                    scene.RemoveActor(currentFoliage);
                }
                else
                {
                    currentTreasureDropEvent = new TreasureDropEvent(random, currentFoliage.PositionForContent, scene);
                    currentFoliage.CharacterCutEventList.EventList.Add(currentTreasureDropEvent);
                }

                undecidedFoliage.Remove(currentFoliage);
            }

            // Hide ammo crates
            for (int i = 0; i < ammoCrateCount; i++)
            {
                Foliage       currentFoliage;
                AmmoDropEvent currentAmmoDropEvent;
                // Select one random foliage to put an ammo crate inside
                currentFoliage = undecidedFoliage[random.Next(undecidedFoliage.Count)];
                undecidedFoliage.Remove(currentFoliage);
                currentAmmoDropEvent = new AmmoDropEvent(ItemsConfig.AMMO_CRATE_TEXTURE, currentFoliage.PositionForContent, scene);
                currentFoliage.CharacterCutEventList.EventList.Add(currentAmmoDropEvent);
            }



            //************************* INIT PLAYERS ************************//

            // Creating as many players, as there are connected gamepads (up to four)
            // Player 1 and 2 are always created.
            Character defaultCharacter = null;

            for (var i = 0; i < maxNumOfPlayers; i++)
            {
                if (!selectedPlayers[i])
                {
                    continue;
                }

                Player player;
                if (i == 1 || i == 2)
                {
                    player = new Player((PlayerIndex)i, new MatchInputMapper(true, i), scene);
                    scene.RegisterPlayer(player);
                }
                else
                {
                    player = new Player((PlayerIndex)i, new MatchInputMapper(false, -1), scene);
                    scene.RegisterPlayer(player);
                }


                defaultCharacter = CharacterImporter.ImportCharacter(
                    MainConfig.CONTENT_CHARACTERS_DIRECTORY + MainConfig.CONTENT_CHARACTER_FILE_XML(i + 1), director.Content, scene);
                player.Possess(defaultCharacter);
                //Character can only be initialized after the possesing player has been set.
                defaultCharacter.InitCharacter();
                scene.Characters.Add(defaultCharacter);
                //scene.RegisterObject(defaultCharacter);
            }

            //Correct walkable areas of each walkable polygons(MinX and MaxX may overlap)
            var character = (DefaultCharacter)defaultCharacter;

            if (character != null)
            {
                //TODO:DELTAY is only a crude approximation. Find better way
                float deltaY = 2 * character.HitboxOffset.Height;

                foreach (var c1 in scene.WalkableCollidables)
                {
                    foreach (var c2 in scene.WalkableCollidables)
                    {
                        if (c1 == c2)
                        {
                            continue;
                        }
                        float centerDistY = Math.Abs(c1.Center.Y - c2.Center.Y);
                        if (centerDistY > deltaY)
                        {
                            continue;
                        }
                        //If centerDistY < deltaY, then one walkable polygon may overlap another walkable
                        if (c1.WalkableMinMax.X < c2.WalkableMinMax.X && c1.WalkableMinMax.Y > c2.WalkableMinMax.X)
                        {
                            if (c1.Center.Y < c2.Center.Y)
                            {
                                //c1 is overlapping(above) c2 => adjust walkables positions of c2
                                c2.WalkableMinMax.X = c1.WalkableMinMax.Y;
                            }
                            else
                            {
                                //c2 is overlapping(above) c1 => adjust walkables positions of c2
                                c1.WalkableMinMax.Y = c2.WalkableMinMax.X;
                            }
                        }
                    }
                }
            }

            //************************* INIT SCORE ************************//

            // Initialize the score
            scene.Scores = new Dictionary <Player, Score>();
            foreach (Player p in scene.GetPlayers())
            {
                scene.Scores.Add(p, new Score());
            }


            //************************* INIT PARTICLE EFFECTS ************************//

            /*Rectangle startPosRec = scene.ShopKeeperStartPos[0];
             * Vector3 firePos = new Vector3(startPosRec.X, startPosRec.Y, 0f);
             * ParticleEffectFactory fireParticleEffectFactory = new FireParticleEffectFactory(FireParticleEffectType.Default, new Vector2(firePos.X, firePos.Y), 10);
             * //ParticleEffectFactory fireParticleEffectFactory = new FireParticleEffectFactory(new Vector2(firePos.X, firePos.Y), 10, 3000, new Vector2(0.5f,0f),
             * // new Vector2(0f, 200), 0.5f, -0.3f, Color.Red, Color.LightYellow, 2750);
             * ParticleEffectManager fireParticleEffectManager = new ParticleEffectManager(new Sprite(ParticleConfig.WHITE_CIRCLE),fireParticleEffectFactory, 10, 16, true, BlendState.Additive);
             * scene.RegisterParticleEffect(fireParticleEffectManager);*/


            weatherSystem           = new WeatherSystem(scene, BaseScreenSize);
            scene.CurrWeatherSystem = weatherSystem;

            //************************* PLAY INGAME THEME ************************//
            scene.MatchSoundManager.PlaySong(SongEnumeration.InGame);
        }
예제 #7
0
    protected void ClusterAround(LayoutObjectContainer cluster, LayoutObject obj)
    {
        #region Debug
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            BigBoss.Debug.printHeader("Cluster Around");
        }
        #endregion
        obj.ShiftOutside(cluster, new Point(1, 0), null, false, false);
        obj.Shift(-1, 0); // Shift to overlapping slightly
        MultiMap <bool> visited = new MultiMap <bool>();
        visited[0, 0] = true;
        ProbabilityList <ClusterInfo> shiftOptions = new ProbabilityList <ClusterInfo>();
        Queue <Point> shiftQueue = new Queue <Point>();
        shiftQueue.Enqueue(new Point());
        Container2D <GenSpace> clusterGrid = cluster.GetGrid();
        Container2D <GenSpace> objGrid     = obj.GetGrid();
        #region Debug
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            var tmp = new MultiMap <GenSpace>();
            tmp.PutAll(obj.GetGrid());
            tmp.PutAll(cluster.GetGrid());
            tmp.ToLog(Logs.LevelGen, "Starting placement");
        }
        #endregion
        while (shiftQueue.Count > 0)
        {
            Point curShift = shiftQueue.Dequeue();
            #region Debug
            if (BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps) && BigBoss.Debug.logging(Logs.LevelGen))
            {
                var tmpMap = new MultiMap <GenSpace>();
                tmpMap.PutAll(clusterGrid);
                tmpMap.PutAll(objGrid, curShift);
                tmpMap.ToLog(Logs.LevelGen, "Analyzing at shift " + curShift);
            }
            #endregion
            // Test if pass
            List <Point> intersectPoints = new List <Point>();
            if (objGrid.DrawAll((arr, x, y) =>
            {
                if (GridTypeEnum.EdgeType(arr[x, y].GetGridType()))
                {
                    GridType clusterType = clusterGrid[x + curShift.x, y + curShift.y].GetGridType();
                    if (clusterType == GridType.NULL)
                    {
                        return(true);
                    }
                    intersectPoints.Add(new Point(x, y));
                    return(GridTypeEnum.EdgeType(clusterType));
                }
                else
                {
                    return(!clusterGrid.Contains(x + curShift.x, y + curShift.y));
                }
            }) &&
                intersectPoints.Count > 0)
            { // Passed test
                // queue surrounding points
                visited.DrawAround(curShift.x, curShift.y, true, Draw.Not(Draw.EqualTo(true)).IfThen(Draw.AddTo <bool>(shiftQueue).And(Draw.SetTo(true))));

                #region Debug
                if (BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps) && BigBoss.Debug.logging(Logs.LevelGen))
                {
                    BigBoss.Debug.w(Logs.LevelGen, "passed with " + intersectPoints.Count);
                }
                #endregion
                shiftOptions.Add(new ClusterInfo()
                {
                    Shift = curShift, Intersects = intersectPoints
                }, Math.Pow(intersectPoints.Count, 3));
            }
        }
        #region Debug
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            shiftOptions.ToLog(Logs.LevelGen, "Shift options");
        }
        #endregion
        List <Point> clusterDoorOptions = new List <Point>();
        ClusterInfo  info;
        var          placed = new List <Value2D <GenSpace> >(0);
        while (shiftOptions.Take(Rand, out info))
        {
            clusterGrid.DrawPoints(info.Intersects, Draw.CanDrawDoor().IfThen(Draw.AddTo <GenSpace>(clusterDoorOptions)).Shift(info.Shift));
            #region Debug
            if (BigBoss.Debug.logging(Logs.LevelGen))
            {
                BigBoss.Debug.w(Logs.LevelGen, "selected " + info.Shift);
                var tmpMap = new MultiMap <GenSpace>();
                clusterGrid.DrawAll(Draw.CopyTo(tmpMap));
                objGrid.DrawAll(Draw.CopyTo(tmpMap, info.Shift));
                tmpMap.DrawPoints(info.Intersects, Draw.SetTo(GridType.INTERNAL_RESERVED_CUR, Theme).Shift(info.Shift));
                tmpMap.ToLog(Logs.LevelGen, "Intersect Points");
                tmpMap = new MultiMap <GenSpace>();
                clusterGrid.DrawAll(Draw.CopyTo(tmpMap));
                objGrid.DrawAll(Draw.CopyTo(tmpMap, info.Shift));
                tmpMap.DrawPoints(clusterDoorOptions, Draw.SetTo(GridType.Door, Theme));
                tmpMap.ToLog(Logs.LevelGen, "Cluster door options");
            }
            #endregion
            if (clusterDoorOptions.Count > 0)
            { // Cluster side has door options
                obj.Shift(info.Shift.x, info.Shift.y);
                placed = obj.PlaceSomeDoors(clusterDoorOptions, Theme, Rand);
                if (placed.Count != 0)
                { // Placed a door
                    foreach (Point p in placed)
                    {
                        LayoutObject clusterObj;
                        cluster.GetObjAt(p, out clusterObj);
                        obj.Connect(clusterObj);
                    }
                    break;
                }
                else
                {
                    #region Debug
                    if (BigBoss.Debug.logging(Logs.LevelGen))
                    {
                        BigBoss.Debug.w(Logs.LevelGen, "selected point failed to match " + info.Shift + ". Backing up");
                    }
                    #endregion
                    obj.Shift(-info.Shift.x, -info.Shift.y);
                }
            }
        }
        if (placed.Count == 0)
        {
            throw new ArgumentException("Could not cluster rooms");
        }
        #region Debug
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            var tmpMap = new MultiMap <GenSpace>();
            tmpMap.PutAll(clusterGrid);
            tmpMap.PutAll(obj.GetGrid());
            tmpMap.ToLog(Logs.LevelGen, "Final setup " + info.Shift);
            BigBoss.Debug.printFooter("Cluster Around");
        }
        #endregion
    }