public GenerationStats Clone() { GenerationStats newStats = new GenerationStats(); newStats.MainPathRoomCount = MainPathRoomCount; newStats.BranchPathRoomCount = BranchPathRoomCount; newStats.TotalRoomCount = TotalRoomCount; newStats.MaxBranchDepth = MaxBranchDepth; newStats.TotalRetries = TotalRetries; newStats.PreProcessTime = PreProcessTime; newStats.MainPathGenerationTime = MainPathGenerationTime; newStats.BranchPathGenerationTime = BranchPathGenerationTime; newStats.PostProcessTime = PostProcessTime; newStats.TotalTime = TotalTime; return(newStats); }
public DungeonGenerator() { GenerationStats = new GenerationStats(); }
protected virtual IEnumerator InnerGenerate(bool isRetry) { if (isRetry) { ChosenSeed = RandomStream.Next(); RandomStream = new Random(ChosenSeed); if (retryCount >= MaxAttemptCount && Application.isEditor) { string errorText = "Failed to generate the dungeon " + MaxAttemptCount + " times.\n" + "This could indicate a problem with the way the tiles are set up. Try to make sure most rooms have more than one doorway and that all doorways are easily accessible.\n" + "Here are a list of all reasons a tile placement had to be retried:"; foreach (var pair in tilePlacementResultCounters) { if (pair.Value > 0) { errorText += "\n" + pair.Key + " (x" + pair.Value + ")"; } } Debug.LogError(errorText); ChangeStatus(GenerationStatus.Failed); yield break; } retryCount++; GenerationStats.IncrementRetryCount(); if (Retrying != null) { Retrying(); } } else { retryCount = 0; GenerationStats.Clear(); } currentDungeon = Root.GetComponent <Dungeon>(); if (currentDungeon == null) { currentDungeon = Root.AddComponent <Dungeon>(); } currentDungeon.DebugRender = DebugRender; currentDungeon.PreGenerateDungeon(this); Clear(false); targetLength = Mathf.RoundToInt(DungeonFlow.Length.GetRandom(RandomStream) * LengthMultiplier); targetLength = Mathf.Max(targetLength, 2); // Tile Injection GenerationStats.BeginTime(GenerationStatus.TileInjection); if (tilesPendingInjection == null) { tilesPendingInjection = new List <InjectedTile>(); } else { tilesPendingInjection.Clear(); } injectedTiles.Clear(); GatherTilesToInject(); // Pre-Processing GenerationStats.BeginTime(GenerationStatus.PreProcessing); PreProcess(); // Main Path Generation GenerationStats.BeginTime(GenerationStatus.MainPath); yield return(Wait(GenerateMainPath())); // We may have had to retry when generating the main path, if so, the status will be either Complete or Failed and we should exit here if (Status == GenerationStatus.Complete || Status == GenerationStatus.Failed) { yield break; } // Branch Paths Generation GenerationStats.BeginTime(GenerationStatus.Branching); yield return(Wait(GenerateBranchPaths())); // If there are any required tiles missing from the tile injection stage, the generation process should fail foreach (var tileInjection in tilesPendingInjection) { if (tileInjection.IsRequired) { yield return(Wait(InnerGenerate(true))); yield break; } } // We may have missed some required injected tiles and have had to retry, if so, the status will be either Complete or Failed and we should exit here if (Status == GenerationStatus.Complete || Status == GenerationStatus.Failed) { yield break; } // Post-Processing yield return(Wait(PostProcess())); // Waiting one frame so objects are in their expected state yield return(null); ChangeStatus(GenerationStatus.Complete); // Let DungenCharacters know that they should re-check the Tile they're in foreach (var character in Component.FindObjectsOfType <DungenCharacter>()) { character.ForceRecheckTile(); } }
protected virtual IEnumerator PostProcess() { // Waiting one frame so objects are in their expected state yield return(null); GenerationStats.BeginTime(GenerationStatus.PostProcessing); ChangeStatus(GenerationStatus.PostProcessing); // Order post-process steps by priority postProcessSteps.Sort((a, b) => { return(b.Priority.CompareTo(a.Priority)); }); // Apply any post-process to be run BEFORE built-in post-processing is run foreach (var step in postProcessSteps) { if (ShouldSkipFrame(false)) { yield return(null); } if (step.Phase == PostProcessPhase.BeforeBuiltIn) { step.PostProcessCallback(this); } } // Waiting one frame so objects are in their expected state yield return(null); foreach (var tile in currentDungeon.AllTiles) { tile.gameObject.SetActive(true); } int length = currentDungeon.MainPathTiles.Count; // // Need to sort list manually to avoid compilation problems on iOS int maxBranchDepth = 0; if (currentDungeon.BranchPathTiles.Count > 0) { List <Tile> branchTiles = currentDungeon.BranchPathTiles.ToList(); branchTiles.Sort((a, b) => { return(b.Placement.BranchDepth.CompareTo(a.Placement.BranchDepth)); } ); maxBranchDepth = branchTiles[0].Placement.BranchDepth; } // End calculate max branch depth // if (!IsAnalysis) { ConnectOverlappingDoorways(DungeonFlow.DoorwayConnectionChance); foreach (var tile in currentDungeon.AllTiles) { if (ShouldSkipFrame(false)) { yield return(null); } tile.Placement.NormalizedPathDepth = tile.Placement.PathDepth / (float)(length - 1); tile.Placement.ProcessDoorways(RandomStream); } currentDungeon.PostGenerateDungeon(this); if (DungeonFlow.KeyManager != null) { PlaceLocksAndKeys(); } // Process random props foreach (var tile in currentDungeon.AllTiles) { foreach (var prop in tile.GetComponentsInChildren <RandomProp>()) { if (ShouldSkipFrame(false)) { yield return(null); } prop.Process(RandomStream, tile); } } ProcessGlobalProps(); } GenerationStats.SetRoomStatistics(currentDungeon.MainPathTiles.Count, currentDungeon.BranchPathTiles.Count, maxBranchDepth); ClearPreProcessData(); // Waiting one frame so objects are in their expected state yield return(null); // Apply any post-process to be run AFTER built-in post-processing is run foreach (var step in postProcessSteps) { if (ShouldSkipFrame(false)) { yield return(null); } if (step.Phase == PostProcessPhase.AfterBuiltIn) { step.PostProcessCallback(this); } } // Finalise GenerationStats.EndTime(); // Activate all door gameobjects that were added to doorways foreach (var door in currentDungeon.Doors) { if (door != null) { door.SetActive(true); } } }