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; } }
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); }
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); } }