public void SolveSymmetry()
 {
     if (this.mirror)
     {
         if (this.leftSymmetric)
         {
             if (this.left == null || this.left.data == null || this.right == null)
             {
                 return;
             }
             this.right.data = this.left.data.Flipped();
             this.right.symmetricalPartner = this.left;
             this.left.symmetricalPartner  = this.right;
         }
         else
         {
             if (this.right == null || this.right.data == null || this.left == null)
             {
                 return;
             }
             this.left.data = this.right.data.Flipped();
             this.right.symmetricalPartner = this.left;
             this.left.symmetricalPartner  = this.right;
         }
     }
     else
     {
         if (this.data == null)
         {
             return;
         }
         if (this.removeRight && this.right != null)
         {
             this.right.data = this.data.Flipped();
             this.right.symmetricalPartner = this;
             this.symmetricalPartner       = this.right;
         }
         if (!this.removeLeft || this.left == null)
         {
             return;
         }
         this.left.data = this.data.Flipped();
         this.left.symmetricalPartner = this;
         this.symmetricalPartner      = this.left;
     }
 }
Esempio n. 2
0
        private static bool TryReroll(
            RandomLevelData combined,
            List <RandomLevelNode> available,
            Func <RandomLevelData, bool> problem,
            Func <RandomLevelData, bool> solution,
            RandomLevelNode specific = null)
        {
            if (available.Count == 0 && specific == null)
            {
                return(false);
            }
            if (problem(combined))
            {
                List <RandomLevelNode> randomLevelNodeList = new List <RandomLevelNode>();
                if (specific != null)
                {
                    randomLevelNodeList.Add(specific);
                }
                else
                {
                    randomLevelNodeList.AddRange((IEnumerable <RandomLevelNode>)available);
                }
                do
                {
                    RandomLevelNode randomLevelNode = randomLevelNodeList[Rando.Int(randomLevelNodeList.Count - 1)];
                    if (randomLevelNode.Reroll(solution))
                    {
                        available.Remove(randomLevelNode);
                        goto label_10;
                    }
                    else
                    {
                        randomLevelNodeList.Remove(randomLevelNode);
                    }
                }while (randomLevelNodeList.Count != 0);
                return(false);
            }
label_10:
            return(true);
        }
        private void GenerateTilesRecurse(RandomLevelData tile, LevGenType type = LevGenType.Any)
        {
            this.visited = true;
            if (tile == null)
            {
                return;
            }
            this.data            = tile;
            this.connectionUp    = this.data.up;
            this.connectionDown  = this.data.down;
            this.connectionLeft  = this.data.left;
            this.connectionRight = this.data.right;
            if (this.symmetric)
            {
                if (this.kingTile)
                {
                    if (this.connectionLeft && this.connectionRight || !this.connectionLeft && !this.connectionRight)
                    {
                        this.mirror = true;
                    }
                    else
                    {
                        if (!this.connectionLeft)
                        {
                            if (this.up != null)
                            {
                                this.up.left        = (RandomLevelNode)null;
                                this.up.removeRight = true;
                            }
                            if (this.down != null)
                            {
                                this.down.left        = (RandomLevelNode)null;
                                this.down.removeRight = true;
                            }
                            this.removeRight = true;
                            this.left        = (RandomLevelNode)null;
                        }
                        if (!this.connectionRight)
                        {
                            if (this.up != null)
                            {
                                this.up.right      = (RandomLevelNode)null;
                                this.up.removeLeft = true;
                            }
                            if (this.down != null)
                            {
                                this.down.right      = (RandomLevelNode)null;
                                this.down.removeLeft = true;
                            }
                            this.removeLeft = true;
                            this.right      = (RandomLevelNode)null;
                        }
                    }
                }
                if (this.mirror)
                {
                    this.connectionRight = this.data.left;
                }
                if (this.up != null)
                {
                    this.up.mirror = this.mirror;
                }
                if (this.down != null)
                {
                    this.down.mirror = this.mirror;
                }
            }
            List <TileConnection> source = new List <TileConnection>()
            {
                TileConnection.Right,
                TileConnection.Left,
                TileConnection.Up,
                TileConnection.Down
            };

            if (this.removeLeft)
            {
                source.Remove(TileConnection.Left);
            }
            if (this.removeRight)
            {
                source.Remove(TileConnection.Right);
            }
            foreach (TileConnection tileConnection in (IEnumerable <TileConnection>)source.OrderBy <TileConnection, float>((Func <TileConnection, float>)(x => Rando.Float(1f))))
            {
                switch (tileConnection)
                {
                case TileConnection.Left:
                    if (this.connectionLeft && this.left != null && this.left.data == null && (!this.mirror || !this.symmetric || !this.rightSymmetric))
                    {
                        if (this.mirror && this.symmetric)
                        {
                            this.leftSymmetric = true;
                            if (this.down != null)
                            {
                                this.down.leftSymmetric = this.leftSymmetric;
                                if (this.down.down != null)
                                {
                                    this.down.down.leftSymmetric = this.leftSymmetric;
                                }
                            }
                            if (this.up != null)
                            {
                                this.up.leftSymmetric = this.leftSymmetric;
                                if (this.up.up != null)
                                {
                                    this.up.up.leftSymmetric = this.leftSymmetric;
                                }
                            }
                        }
                        this.left.leftSymmetric  = this.leftSymmetric;
                        this.left.rightSymmetric = this.rightSymmetric;
                        this.left.symmetric      = this.symmetric;
                        this.left.GenerateTilesRecurse(LevelGenerator.GetTile(TileConnection.Right, tile, type: type, mirror: this.left.mirror, filter: this.left.GetFilter()), type);
                        continue;
                    }
                    continue;

                case TileConnection.Right:
                    if (this.connectionRight && this.right != null && this.right.data == null && (!this.mirror || !this.symmetric || !this.leftSymmetric))
                    {
                        if (this.mirror && this.symmetric)
                        {
                            this.rightSymmetric = true;
                            if (this.down != null)
                            {
                                this.down.rightSymmetric = this.rightSymmetric;
                                if (this.down.down != null)
                                {
                                    this.down.down.rightSymmetric = this.rightSymmetric;
                                }
                            }
                            if (this.up != null)
                            {
                                this.up.rightSymmetric = this.rightSymmetric;
                                if (this.up.up != null)
                                {
                                    this.up.up.rightSymmetric = this.rightSymmetric;
                                }
                            }
                        }
                        this.right.leftSymmetric  = this.leftSymmetric;
                        this.right.rightSymmetric = this.rightSymmetric;
                        this.right.symmetric      = this.symmetric;
                        this.right.GenerateTilesRecurse(LevelGenerator.GetTile(TileConnection.Left, tile, type: type, mirror: this.right.mirror, filter: this.right.GetFilter()), type);
                        continue;
                    }
                    continue;

                case TileConnection.Up:
                    if (this.connectionUp && this.up != null && this.up.data == null)
                    {
                        this.up.leftSymmetric  = this.leftSymmetric;
                        this.up.rightSymmetric = this.rightSymmetric;
                        this.up.symmetric      = this.symmetric;
                        this.up.GenerateTilesRecurse(LevelGenerator.GetTile(TileConnection.Down, tile, type: type, mirror: this.mirror, filter: this.up.GetFilter()), type);
                        continue;
                    }
                    continue;

                case TileConnection.Down:
                    if (this.connectionDown && this.down != null && this.down.data == null)
                    {
                        this.down.leftSymmetric  = this.leftSymmetric;
                        this.down.rightSymmetric = this.rightSymmetric;
                        this.down.symmetric      = this.symmetric;
                        this.down.GenerateTilesRecurse(LevelGenerator.GetTile(TileConnection.Up, tile, type: type, mirror: this.mirror, filter: this.down.GetFilter()), type);
                        continue;
                    }
                    continue;

                default:
                    continue;
                }
            }
            if (!this.kingTile || !this.symmetric)
            {
                return;
            }
            this.SolveSymmetry();
            if (this.up != null)
            {
                this.up.SolveSymmetry();
            }
            if (this.down == null)
            {
                return;
            }
            this.down.SolveSymmetry();
        }
        public void LoadParts(float x, float y, Level level, int seed = 0)
        {
            Random generator = Rando.generator;

            if (seed != 0)
            {
                Rando.generator = new Random(seed);
            }
            Level.InitChanceGroups();
            this.LoadPartsRecurse(x, y, level);
            this.ClearFlags();
            Rando.generator = generator;
            for (int index1 = -1; index1 < this.tilesWide + 1; ++index1)
            {
                for (int index2 = -1; index2 < this.tilesHigh + 1; ++index2)
                {
                    RandomLevelNode randomLevelNode = (RandomLevelNode)null;
                    if (index1 >= 0 && index1 < this.tilesWide && (index2 >= 0 && index2 < this.tilesHigh))
                    {
                        randomLevelNode = this.tiles[index1, index2];
                    }
                    if (randomLevelNode == null || randomLevelNode.data == null)
                    {
                        level.AddThing((Thing) new PyramidWall((float)(index1 * 192 - 192 - 8), (float)(index2 * 144 - 144 - 8)));
                    }
                }
            }
            level.things.RefreshState();
            foreach (PyramidDoor pyramidDoor in level.things[typeof(PyramidDoor)])
            {
                switch (level.CollisionLine <Block>(pyramidDoor.position + new Vec2(-16f, 0.0f), pyramidDoor.position + new Vec2(16f, 0.0f), (Thing)pyramidDoor))
                {
                case null:
                case PyramidDoor _:
                case Door _:
                    continue;

                default:
                    level.RemoveThing((Thing)pyramidDoor);
                    Level.Add((Thing) new PyramidTileset(pyramidDoor.x, pyramidDoor.y - 16f));
                    Level.Add((Thing) new PyramidTileset(pyramidDoor.x, pyramidDoor.y));
                    continue;
                }
            }
            foreach (Door door in level.things[typeof(Door)])
            {
                switch (level.CollisionLine <Block>(door.position + new Vec2(-16f, 0.0f), door.position + new Vec2(16f, 0.0f), (Thing)door))
                {
                case null:
                case PyramidDoor _:
                case Door _:
                    continue;

                default:
                    level.RemoveThing((Thing)door);
                    Level.Add((Thing) new PyramidTileset(door.x, door.y - 16f));
                    Level.Add((Thing) new PyramidTileset(door.x, door.y));
                    continue;
                }
            }
            LightingTwoPointOH lightingTwoPointOh = new LightingTwoPointOH();

            lightingTwoPointOh.visible = false;
            level.AddThing((Thing)lightingTwoPointOh);
        }
Esempio n. 5
0
        public static RandomLevelNode MakeLevel(
            RandomLevelData tile       = null,
            bool allowSymmetry         = true,
            int seed                   = 0,
            LevGenType type            = LevGenType.Any,
            int varwide                = 0,
            int varhigh                = 0,
            int genX                   = 1,
            int genY                   = 1,
            List <GeneratorRule> rules = null)
        {
            Random generator = Rando.generator;

            if (seed == 0)
            {
                seed = Rando.Int(2147483646);
            }
            Rando.generator = new Random(seed);
            bool flag1 = true;
            int  num1  = 0;
            int  length1;
            int  length2;

            RandomLevelNode[,] randomLevelNodeArray;
            while (true)
            {
                LevelGenerator._used.Clear();
                length1 = varwide;
                length2 = varhigh;
                if (varwide == 0)
                {
                    length1 = (double)Rando.Float(1f) <= 0.800000011920929 ? 3 : 2;
                }
                if (varhigh == 0)
                {
                    float num2 = Rando.Float(1f);
                    if ((double)num2 > 0.800000011920929)
                    {
                        ;
                    }
                    length2 = (double)num2 <= 0.349999994039536 ? 3 : 2;
                }
                if (flag1)
                {
                    length1 = length2 = 3;
                }
                genX = length1 != 3 ? 0 : 1;
                genY = length2 != 3 ? 0 : 1;
                if (genX > length1 - 1)
                {
                    genX = length1 - 1;
                }
                if (genY > length2 - 1)
                {
                    genY = length2 - 1;
                }
                randomLevelNodeArray = new RandomLevelNode[length1, length2];
                for (int index1 = 0; index1 < length1; ++index1)
                {
                    for (int index2 = 0; index2 < length2; ++index2)
                    {
                        randomLevelNodeArray[index1, index2]     = new RandomLevelNode();
                        randomLevelNodeArray[index1, index2].map = randomLevelNodeArray;
                    }
                }
                for (int index1 = 0; index1 < length1; ++index1)
                {
                    for (int index2 = 0; index2 < length2; ++index2)
                    {
                        RandomLevelNode randomLevelNode = randomLevelNodeArray[index1, index2];
                        if (index1 > 0)
                        {
                            randomLevelNode.left = randomLevelNodeArray[index1 - 1, index2];
                        }
                        if (index1 < length1 - 1)
                        {
                            randomLevelNode.right = randomLevelNodeArray[index1 + 1, index2];
                        }
                        if (index2 > 0)
                        {
                            randomLevelNode.up = randomLevelNodeArray[index1, index2 - 1];
                        }
                        if (index2 < length2 - 1)
                        {
                            randomLevelNode.down = randomLevelNodeArray[index1, index2 + 1];
                        }
                    }
                }
                if (tile != null)
                {
                    LevelGenerator._used[tile.file] = 1;
                }
                randomLevelNodeArray[genX, genY].kingTile = true;
                randomLevelNodeArray[genX, genY].GenerateTiles(tile, type, (double)Rando.Float(1f) > 0.300000011920929);
                List <RandomLevelNode> available = new List <RandomLevelNode>();
                for (int index1 = 0; index1 < length1; ++index1)
                {
                    for (int index2 = 0; index2 < length2; ++index2)
                    {
                        RandomLevelNode randomLevelNode = randomLevelNodeArray[index1, index2];
                        if (randomLevelNode.data != null)
                        {
                            available.Add(randomLevelNode);
                        }
                    }
                }
                if (rules == null)
                {
                    rules = new List <GeneratorRule>();
                    rules.Add(new GeneratorRule((Func <RandomLevelData, bool>)(problem => problem.numPermanentFatalWeapons < 1), (Func <RandomLevelData, bool>)(solution => solution.numPermanentFatalWeapons > 0), varMandatory: true));
                    rules.Add(new GeneratorRule((Func <RandomLevelData, bool>)(problem => problem.numLockedDoors > 0 && problem.numKeys == 0), (Func <RandomLevelData, bool>)(solution => solution.numLockedDoors == 0 && solution.numKeys > 0)));
                }
                bool flag2 = false;
                foreach (GeneratorRule rule in rules)
                {
                    if ((double)rule.chance == 1.0 || (double)Rando.Float(1f) < (double)rule.chance)
                    {
                        RandomLevelNode specific = (RandomLevelNode)null;
                        if (rule.special == SpecialRule.AffectCenterTile && length1 == 3)
                        {
                            specific = randomLevelNodeArray[1, Rando.Int(length2 - 1)];
                        }
                        if (!LevelGenerator.TryReroll(randomLevelNodeArray[genX, genY].totalData, available, rule.problem, rule.solution, specific) && rule.mandatory)
                        {
                            flag2 = true;
                            break;
                        }
                    }
                }
                if (flag2 && num1 < 6)
                {
                    if (num1 > 3)
                    {
                        flag1 = true;
                    }
                    ++num1;
                }
                else
                {
                    break;
                }
            }
            Rando.generator = generator;
            randomLevelNodeArray[genX, genY].seed      = seed;
            randomLevelNodeArray[genX, genY].tilesWide = length1;
            randomLevelNodeArray[genX, genY].tilesHigh = length2;
            randomLevelNodeArray[genX, genY].tiles     = randomLevelNodeArray;
            return(randomLevelNodeArray[genX, genY]);
        }
 public override void Initialize()
 {
     Vote.ClearVotes();
     if (this.level == "RANDOM")
     {
         this._randomLevel = LevelGenerator.MakeLevel(seed: this.seed);
         this.seed         = this._randomLevel.seed;
     }
     base.Initialize();
     if (Network.isActive)
     {
         Level.core.gameInProgress = true;
     }
     if (this._randomLevel != null)
     {
         this._randomLevel.LoadParts(0.0f, 0.0f, (Level)this, this.seed);
         List <SpawnPoint> source1 = new List <SpawnPoint>();
         foreach (SpawnPoint spawnPoint in this.things[typeof(SpawnPoint)])
         {
             source1.Add(spawnPoint);
         }
         if (source1.Count == 0)
         {
             Level.current = (Level) new GameLevel("RANDOM");
             return;
         }
         List <SpawnPoint> chosenSpawns = new List <SpawnPoint>();
         for (int index = 0; index < 4; ++index)
         {
             if (chosenSpawns.Count == 0)
             {
                 chosenSpawns.Add(source1.ElementAt <SpawnPoint>(Rando.Int(source1.Count - 1)));
             }
             else
             {
                 IOrderedEnumerable <SpawnPoint> source2 = source1.OrderByDescending <SpawnPoint, int>((Func <SpawnPoint, int>)(x =>
                 {
                     int num = 9999999;
                     foreach (Transform transform in chosenSpawns)
                     {
                         num = (int)Math.Min((transform.position - x.position).length, (float)num);
                     }
                     return(num);
                 }));
                 chosenSpawns.Add(source2.First <SpawnPoint>());
             }
         }
         foreach (SpawnPoint spawnPoint in source1)
         {
             if (!chosenSpawns.Contains(spawnPoint))
             {
                 Level.Remove((Thing)spawnPoint);
             }
         }
         foreach (Thing thing in this.things)
         {
             if (Network.isActive && thing.isStateObject)
             {
                 GhostManager.context.MakeGhost(thing, initLevel: true);
                 thing.ghostType = Editor.IDToType[thing.GetType()];
             }
         }
         PyramidBackground pyramidBackground = new PyramidBackground(0.0f, 0.0f);
         pyramidBackground.visible = false;
         Level.Add((Thing)pyramidBackground);
         base.Initialize();
     }
     this.things.RefreshState();
     if (this._mode == null)
     {
         this._mode = (GameMode) new DM(this._validityTest, this._editorTestMode);
     }
     this._mode.DoInitialize();
     if (!Network.isServer)
     {
         return;
     }
     foreach (Duck prepareSpawn in this._mode.PrepareSpawns())
     {
         prepareSpawn.localSpawnVisible = false;
         prepareSpawn.immobilized       = true;
         Level.Add((Thing)prepareSpawn);
     }
 }