private static void ComputeBranchCountsLocal(Random randomStream, DungeonProxy proxyDungeon, ref int[] mainPathBranches)
        {
            for (int i = 0; i < mainPathBranches.Length; i++)
            {
                var tile = proxyDungeon.MainPathTiles[i];

                if (tile.Placement.Archetype == null)
                {
                    continue;
                }

                int branchCount = tile.Placement.Archetype.BranchCount.GetRandom(randomStream);
                branchCount = Mathf.Min(branchCount, tile.UnusedDoorways.Count());

                mainPathBranches[i] = branchCount;
            }
        }
Esempio n. 2
0
        public void FromProxy(DungeonProxy proxyDungeon, DungeonGenerator generator)
        {
            Clear();

            var proxyToTileMap = new Dictionary <TileProxy, Tile>();

            foreach (var tileProxy in proxyDungeon.AllTiles)
            {
                // Instantiate & re-position tile
                var tileObj = GameObject.Instantiate(tileProxy.Prefab, generator.Root.transform);
                tileObj.transform.localPosition = tileProxy.Placement.Position;
                tileObj.transform.localRotation = tileProxy.Placement.Rotation;

                // Add tile to lists
                var tile = tileObj.GetComponent <Tile>();
                tile.Dungeon              = this;
                tile.Placement            = new TilePlacementData(tileProxy.Placement);
                proxyToTileMap[tileProxy] = tile;
                allTiles.Add(tile);

                if (tile.Placement.IsOnMainPath)
                {
                    mainPathTiles.Add(tile);
                }
                else
                {
                    branchPathTiles.Add(tile);
                }

                // Place trigger volume
                if (generator.PlaceTileTriggers)
                {
                    tile.AddTriggerVolume();
                    tile.gameObject.layer = generator.TileTriggerLayer;
                }

                // Process doorways
                var allDoorways = tileObj.GetComponentsInChildren <Doorway>();

                foreach (var doorway in allDoorways)
                {
                    doorway.Tile = tile;
                    doorway.placedByGenerator      = true;
                    doorway.HideConditionalObjects = false;

                    tile.AllDoorways.Add(doorway);
                }

                foreach (var doorwayProxy in tileProxy.UsedDoorways)
                {
                    var doorway = allDoorways[doorwayProxy.Index];
                    tile.UsedDoorways.Add(doorway);

                    foreach (var obj in doorway.BlockerSceneObjects)
                    {
                        if (obj != null)
                        {
                            DestroyImmediate(obj, false);
                        }
                    }
                }

                foreach (var doorwayProxy in tileProxy.UnusedDoorways)
                {
                    var doorway = allDoorways[doorwayProxy.Index];
                    tile.UnusedDoorways.Add(doorway);

                    foreach (var obj in doorway.ConnectorSceneObjects)
                    {
                        if (obj != null)
                        {
                            DestroyImmediate(obj, false);
                        }
                    }

                    // If there is at least one blocker prefab, select one and spawn it as a child of the doorway
                    if (doorway.BlockerPrefabWeights.HasAnyViableEntries())
                    {
                        GameObject blocker = GameObject.Instantiate(doorway.BlockerPrefabWeights.GetRandom(generator.RandomStream)) as GameObject;
                        blocker.transform.parent        = doorway.gameObject.transform;
                        blocker.transform.localPosition = Vector3.zero;
                        blocker.transform.localScale    = Vector3.one;

                        if (!doorway.AvoidRotatingBlockerPrefab)
                        {
                            blocker.transform.localRotation = Quaternion.identity;
                        }
                    }
                }
            }

            // Add doorway connections
            foreach (var proxyConn in proxyDungeon.Connections)
            {
                var tileA = proxyToTileMap[proxyConn.A.TileProxy];
                var tileB = proxyToTileMap[proxyConn.B.TileProxy];

                var doorA = tileA.AllDoorways[proxyConn.A.Index];
                var doorB = tileB.AllDoorways[proxyConn.B.Index];

                doorA.ConnectedDoorway = doorB;
                doorB.ConnectedDoorway = doorA;

                var conn = new DoorwayConnection(doorA, doorB);
                connections.Add(conn);

                SpawnDoorPrefab(doorA, doorB, generator.RandomStream);
            }
        }
        private static void ComputeBranchCountsGlobal(DungeonFlow dungeonFlow, Random randomStream, DungeonProxy proxyDungeon, ref int[] mainPathBranches)
        {
            int   globalBranchCount    = dungeonFlow.BranchCount.GetRandom(randomStream);
            int   totalBranchableRooms = proxyDungeon.MainPathTiles.Count(t => t.Placement.Archetype != null);
            float branchesPerTile      = globalBranchCount / (float)totalBranchableRooms;

            float branchChance      = branchesPerTile;
            int   branchesRemaining = globalBranchCount;

            for (int i = 0; i < mainPathBranches.Length; i++)
            {
                if (branchesRemaining <= 0)
                {
                    break;
                }

                var tile = proxyDungeon.MainPathTiles[i];

                if (tile.Placement.Archetype == null)
                {
                    continue;
                }

                int availableDoorways = tile.UnusedDoorways.Count();
                int branchCount       = Mathf.FloorToInt(branchChance);
                branchCount = Mathf.Min(branchCount, availableDoorways, tile.Placement.Archetype.BranchCount.Max);

                branchChance -= branchCount;

                if (branchCount < availableDoorways &&
                    randomStream.Next() < branchChance)
                {
                    branchCount++;
                    branchChance = 0f;
                }

                branchChance      += branchesPerTile;
                branchesRemaining -= branchCount;

                mainPathBranches[i] = branchCount;
            }
        }
        public static void ComputeBranchCounts(DungeonFlow dungeonFlow, Random randomStream, DungeonProxy proxyDungeon, ref int[] mainPathBranches)
        {
            switch (dungeonFlow.BranchMode)
            {
            case BranchMode.Local:
                ComputeBranchCountsLocal(randomStream, proxyDungeon, ref mainPathBranches);
                break;

            case BranchMode.Global:
                ComputeBranchCountsGlobal(dungeonFlow, randomStream, proxyDungeon, ref mainPathBranches);
                break;

            default:
                throw new NotImplementedException(string.Format("{0}.{1} is not implemented", typeof(BranchMode).Name, dungeonFlow.BranchMode));
            }
        }