private bool GenerateConnector(Level nextLevel, int3 exitPosition, LiminalBlock exit, List <int3> liminalBlocksGenerated) { List <int3> blocksToIgnore = new List <int3> (liminalBlocksGenerated); foreach (int3 pos in whitelist) { blocksToIgnore.Add(pos + position); } List <int3> liminalBlocksToAdd = new List <int3> (); for (int i = 0; i < nextLevels.Count; i++) { exitPosition += directions [exit.dir]; liminalBlocksToAdd.Add(exitPosition); } LiminalBlock entrance = nextLevel.GenerateLiminalBlock(nextLevel.startBlocks); int3[] entranceBlocks = new int3[LEVEL_BORDER]; int3 entrancePosition = entrance.pos; for (int n = 0; n < LEVEL_BORDER + 1; n++) { if (n > 0) { entranceBlocks [n - 1] = entrancePosition; } entrancePosition += directions[entrance.dir]; } List <int3> tempDirections = new List <int3> (directions); List <int3> directionPriority = new List <int3> (); for (int j = 4; j > 0; j--) { int index = Random.Range(0, j); directionPriority.Add(tempDirections[index]); tempDirections.RemoveAt(index); } Dictionary <int3, int3> parents = new Dictionary <int3, int3> (); List <int3> squaresChecked = new List <int3> (); Queue <int3> squaresToCheck = new Queue <int3> (); squaresToCheck.Enqueue(exitPosition); parents.Add(exitPosition, exitPosition); int3 successBlock = null; while (squaresToCheck.Count > 0) { int3 currentSquare = squaresToCheck.Dequeue(); squaresChecked.Add(currentSquare); List <int3> extraBlocks = Chain(new List <int3> (), parents, currentSquare); if (!WorldManager.regionIntersect(currentSquare - entrancePosition, nextLevel.min, nextLevel.max, nextLevel.visualMin, nextLevel.visualMax, LEVEL_BORDER * 2, extraBlocks)) { successBlock = currentSquare; break; } foreach (int3 d in directionPriority) { int3 newSquare = currentSquare + d; if (!squaresChecked.Contains(newSquare) && !squaresToCheck.Contains(newSquare) && !WorldManager.blockIntersect(newSquare, blocksToIgnore, LEVEL_BORDER * 2)) { squaresToCheck.Enqueue(newSquare); parents.Add(newSquare, currentSquare); } } } if (successBlock == null) { return(false); } nextLevel.position = successBlock - entrancePosition; Chain(liminalBlocksToAdd, parents, successBlock); WorldManager.levelsSpawned.Add(nextLevel); foreach (int3 pos in entranceBlocks) { liminalBlocksToAdd.Add(pos + nextLevel.position); } foreach (int3 pos in liminalBlocksToAdd) { AddLiminalBlock(pos); liminalBlocksGenerated.Add(pos); } return(true); }
public void GenerateConnectors() { if (nextLevels.Count == 0) { return; } List <int3> liminalBlocksGenerated = new List <int3>(); List <Level> toRemove = new List <Level> (); for (int i = 0; i < nextLevels.Count; i++) { Level nextLevel = nextLevels [i]; bool success = false; for (int n = 0; n < 6; n++) { LiminalBlock exit = GenerateLiminalBlock(endBlocks); int3 exitPosition = exit.pos + position; if (GenerateConnector(nextLevel, exitPosition, exit, liminalBlocksGenerated)) { success = true; break; } } if (!success) { toRemove.Add(nextLevel); } } foreach (Level l in toRemove) { nextLevels.Remove(l); WorldManager.extraLevels.Enqueue(l); WorldManager.shortcuts.Add(l, this); } if (nextLevels.Count == 0) { return; } List <int3> liminalWhitelist = new List <int3> (liminalBlocksGenerated); foreach (int3 b in whitelist) { liminalWhitelist.Add(b + position); //GameObject.Instantiate (WorldManager.blockTypes [2].prefab, (b + position).ToVector(), Quaternion.identity); } foreach (Level l in nextLevels) { foreach (int3 b in l.whitelist) { liminalWhitelist.Add(b + l.position); //GameObject.Instantiate (WorldManager.blockTypes [2].prefab, (b + l.position).ToVector(), Quaternion.identity); } } int extraBlockCount = 100; //liminalBlocksGenerated.Count * 2; List <Level> allLevels = new List <Level> (nextLevels); allLevels.Add(this); for (int n = 0; n < extraBlockCount; n++) { int3 pos = liminalBlocksGenerated [Random.Range(0, liminalBlocksGenerated.Count)]; pos += directions [Random.Range(0, 4)]; if (!WorldManager.blockIntersect(pos, liminalWhitelist, LEVEL_BORDER * 2, allLevels) && !liminalBlocksGenerated.Contains(pos)) { AddLiminalBlock(pos); liminalBlocksGenerated.Add(pos); liminalWhitelist.Add(pos); } } for (int n = 0; n < LEVEL_BORDER; n++) { int len = liminalBlocksGenerated.Count; for (int i = 0; i < len; i++) { int3 b = liminalBlocksGenerated [i]; foreach (int3 d in directions) { if (!WorldManager.liminalBlocks.Contains(b + d)) { WorldManager.liminalBlocks.Add(b + d); liminalBlocksGenerated.Add(b + d); } } } } }