public static GameObject TypeToPrefab(Level level, GameVertex.Edge.Type type) { switch (type) { case GameVertex.Edge.Type.solid: return(level.settings.prefabs.solidLine); case GameVertex.Edge.Type.conveyer: return(level.settings.prefabs.conveyerLine); //case GameVertex.Edge.Type.transform: return level.settings.prefabs.solidLine; //case GameVertex.Edge.Type.magnet: return level.settings.prefabs.solidLine; //case GameVertex.Edge.Type.weld: return level.settings.prefabs.solidLine; //case GameVertex.Edge.Type.laser: return level.settings.prefabs.solidLine; //case GameVertex.Edge.Type.ice: return level.settings.prefabs.solidLine; //case GameVertex.Edge.Type.spring: return level.settings.prefabs.solidLine; case GameVertex.Edge.Type.None: default: Debug.LogError("Error: Unexpected type given to TypeToPrefab!"); return(null); } }
// Takes a level Instance and creates its runtime equivalent void InvokeLevel(LevelInstance inst) { List <HashSet <LineVec> > clusters = new List <HashSet <LineVec> >(4); // Generate index lists for each cluster of lines { // Get a new traversal index char traversalIndex = LevelInstance.GetNewTraversalIndex(); // on looping around we don't use 0 since it is our reset value if (traversalIndex == 0) { traversalIndex = LevelInstance.GetNewTraversalIndex(); } // Is index grid valid? if (LevelInstance.gridIndex == null || LevelInstance.gridIndex.GetLength(0) < inst.grid.GetLength(0) || LevelInstance.gridIndex.GetLength(1) < inst.grid.GetLength(1) || traversalIndex == 1) // looped around, reset gridIndexes to 0 always { LevelInstance.gridIndex = new char[inst.grid.GetLength(0), inst.grid.GetLength(1)]; } Vector2Int max = Vector2Int.zero; max.y = inst.grid.GetLength(0); max.x = inst.grid.GetLength(1); int clusterIndex = -1; Queue <Vector2Int> SearchList = new Queue <Vector2Int>(16); for (int y = 0; y < max.y; ++y) { for (int x = 0; x < max.x; ++x) { // have we visited this space before? if (LevelInstance.gridIndex[y, x] == traversalIndex) { continue; } // Any out bound connections means this is a part of a new cluster if (inst.grid[y, x].lines.AllToOne() != GameVertex.DirectionFlags.None) { ++clusterIndex; if (clusters.Count == clusterIndex) { clusters.Add(new HashSet <LineVec>()); } // Add point to search through SearchList.Enqueue(new Vector2Int(x, y)); } // traverse cluster while (SearchList.Count > 0) { // Get next item on the Vector2Int look = SearchList.Dequeue(); // already looked at item? if (LevelInstance.gridIndex[look.y, look.x] == traversalIndex) { continue; } // Mark node as looked at LevelInstance.gridIndex[look.y, look.x] = traversalIndex; // Get inbound Connections and enqueue them to add them to the cluster { Vector2Int c = Vector2Int.zero; c.y = y; c.x = x - 1; if (ValidPoint(c, max, inst.grid, traversalIndex, GameVertex.DirectionFlags.E)) { SearchList.Enqueue(c); } c.y = y - 1; c.x = x - 1; if (ValidPoint(c, max, inst.grid, traversalIndex, GameVertex.DirectionFlags.NE)) { SearchList.Enqueue(c); } c.y = y - 1; c.x = x; if (ValidPoint(c, max, inst.grid, traversalIndex, GameVertex.DirectionFlags.N)) { SearchList.Enqueue(c); } c.y = y - 1; c.x = x + 1; if (ValidPoint(c, max, inst.grid, traversalIndex, GameVertex.DirectionFlags.NW)) { SearchList.Enqueue(c); } c.y = y; c.x = x + 1; if (ValidPoint(c, max, inst.grid, traversalIndex, GameVertex.DirectionFlags.W)) { SearchList.Enqueue(c); } c.y = y + 1; c.x = x + 1; if (ValidPoint(c, max, inst.grid, traversalIndex, GameVertex.DirectionFlags.SW)) { SearchList.Enqueue(c); } c.y = y + 1; c.x = x; if (ValidPoint(c, max, inst.grid, traversalIndex, GameVertex.DirectionFlags.S)) { SearchList.Enqueue(c); } c.y = y + 1; c.x = x - 1; if (ValidPoint(c, max, inst.grid, traversalIndex, GameVertex.DirectionFlags.SE)) { SearchList.Enqueue(c); } } // Add outbound connections from the GridVertex { var cluster = clusters[clusterIndex]; GameVertex.DirectionFlags outDirs = inst.grid[look.y, look.x].lines.AllToOne(); LineVec lv; lv.pos = Vector2Int.zero; lv.pos.y = y; lv.pos.x = x; // Add connections to the cluster lv.dir = (GameVertex.Direction) 0; if ((outDirs & GameVertex.DirectionFlags.W) == GameVertex.DirectionFlags.W && !cluster.Contains(lv)) { cluster.Add(lv); } lv.dir = (GameVertex.Direction) 1; if ((outDirs & GameVertex.DirectionFlags.SW) == GameVertex.DirectionFlags.SW && !cluster.Contains(lv)) { cluster.Add(lv); } lv.dir = (GameVertex.Direction) 2; if ((outDirs & GameVertex.DirectionFlags.S) == GameVertex.DirectionFlags.S && !cluster.Contains(lv)) { cluster.Add(lv); } lv.dir = (GameVertex.Direction) 3; if ((outDirs & GameVertex.DirectionFlags.SE) == GameVertex.DirectionFlags.SE && !cluster.Contains(lv)) { cluster.Add(lv); } lv.dir = (GameVertex.Direction) 4; if ((outDirs & GameVertex.DirectionFlags.E) == GameVertex.DirectionFlags.E && !cluster.Contains(lv)) { cluster.Add(lv); } lv.dir = (GameVertex.Direction) 5; if ((outDirs & GameVertex.DirectionFlags.NE) == GameVertex.DirectionFlags.NE && !cluster.Contains(lv)) { cluster.Add(lv); } lv.dir = (GameVertex.Direction) 6; if ((outDirs & GameVertex.DirectionFlags.N) == GameVertex.DirectionFlags.N && !cluster.Contains(lv)) { cluster.Add(lv); } lv.dir = (GameVertex.Direction) 7; if ((outDirs & GameVertex.DirectionFlags.NW) == GameVertex.DirectionFlags.NW && !cluster.Contains(lv)) { cluster.Add(lv); } } } } } } // resolve the clusters into blocks foreach (var cluster in clusters) { // @TODO make exception for lines on the static cluster to use that cluster! // Make cluster root var clusterRoot = Instantiate(settings.prefabs.clusterRoot); var clusterRootTrans = clusterRoot.transform; clusterRootTrans.SetParent(runtimeRoot.transform); foreach (var line in cluster) { // Create lines with behaviors which are indexable from LevelRUNTIME or something! Vector2Int end = ARUtil.DirToOffset(line.dir); GameVertex.Edge.Type type = ARUtil.SnapToType(line.dir, ref inst.grid[line.pos.y, line.pos.x].lines); GameObject typePrefab = ARUtil.TypeToPrefab(this, type); GameObject lineGo = Instantiate(typePrefab); //FFMessageBoard<InitLine>.SendToLocal() } } }