Exemple #1
0
        // Initialize KnownFlows array with custom + official flows.

        public static void InitBossRooms()
        {
            Dungeon CathedralPrefab = DungeonDatabase.GetOrLoadByName("Base_Cathedral");

            CathedralInjectionData = CathedralPrefab.PatternSettings.flows[0].sharedInjectionData[1];

            BossBishopRoom = new ProceduralFlowModifierData()
            {
                annotation        = "The Bishop's Chapel",
                DEBUG_FORCE_SPAWN = false,
                OncePerRun        = false,
                placementRules    = new List <ProceduralFlowModifierData.FlowModifierPlacementType>()
                {
                    ProceduralFlowModifierData.FlowModifierPlacementType.RANDOM_NODE_CHILD
                },
                // exactRoom = SewersInjectionData.InjectionData[0].exactRoom,
                exactRoom              = dungeonRoom,
                RequiresMasteryToken   = false,
                chanceToLock           = 0,
                selectionWeight        = 1,
                chanceToSpawn          = 1,
                RequiredValidPlaceable = null,
                prerequisites          = new DungeonPrerequisite[0],
                CanBeForcedSecret      = true,
                RandomNodeChildMinDistanceFromEntrance = 0,
                exactSecondaryRoom = null,
                framedCombatNodes  = 0,
            };
            CathedralInjectionData.InjectionData.Add(BossBishopRoom);

            CathedralPrefab = null;
        }
        public static void Init()
        {
            AssetBundles = new Dictionary <string, AssetBundle>();
            foreach (var name in assetBundleNames)
            {
                try
                {
                    var bundle = ResourceManager.LoadAssetBundle(name);
                    if (bundle == null)
                    {
                        Tools.PrintError($"Failed to load asset bundle: {name}");
                        continue;
                    }
                    AssetBundles.Add(name, ResourceManager.LoadAssetBundle(name));
                }
                catch (Exception e)
                {
                    Tools.PrintError($"Failed to load asset bundle: {name}");
                    Tools.PrintException(e);
                }
            }

            RoomTables = new Dictionary <string, GenericRoomTable>();
            foreach (var entry in roomTableMap)
            {
                try
                {
                    var table = DungeonDatabase.GetOrLoadByName($"base_{entry.Key}").PatternSettings.flows[0].fallbackRoomTable;
                    RoomTables.Add(entry.Key, table);
                }
                catch (Exception e)
                {
                    Tools.PrintError($"Failed to load room table: {entry.Key}:{entry.Value}");
                    Tools.PrintException(e);
                }
            }

            foreach (var entry in specialRoomTableMap)
            {
                try
                {
                    var table = GetAsset <GenericRoomTable>(entry.Value);
                    RoomTables.Add(entry.Key, table);
                }
                catch (Exception e)
                {
                    Tools.PrintError($"Failed to load special room table: {entry.Key}:{entry.Value}");
                    Tools.PrintException(e);
                }
            }

            subShopTable = AssetBundles["shared_auto_001"].LoadAsset <SharedInjectionData>("_global injected subshop table");

            //foreach(var data in subShopTable.InjectionData)
            //{
            //    Tools.LogPropertiesAndFields(data, data.annotation);
            //}

            Tools.Print("Static references initialized.");
        }
        public static void DungeonFlowInit(bool refreshFlows = false)
        {
            LoopItemRoomPrefab = ExpandTheGungeon.ExpandUtilities.RoomFactory.BuildFromResource("Items/Resources/LoopItemRoom.room");
            sharedAssets2      = ResourceManager.LoadAssetBundle("shared_auto_002");

            Dungeon ForgePrefab = DungeonDatabase.GetOrLoadByName("Base_Forge");

            ForgeData    = ForgePrefab.PatternSettings.flows[0].sharedInjectionData[1];
            LoopItemRoom = new ProceduralFlowModifierData()
            {
                annotation        = "Loop Item Room",
                DEBUG_FORCE_SPAWN = false,
                OncePerRun        = false,
                placementRules    = new List <ProceduralFlowModifierData.FlowModifierPlacementType>()
                {
                    ProceduralFlowModifierData.FlowModifierPlacementType.END_OF_CHAIN
                },
                roomTable              = null,
                exactRoom              = LoopItemRoomPrefab,
                IsWarpWing             = false,
                RequiresMasteryToken   = false,
                chanceToLock           = 0,
                selectionWeight        = 1,
                chanceToSpawn          = 1,
                RequiredValidPlaceable = null,
                prerequisites          = new DungeonPrerequisite[] {
                    new DungeonPrerequisite()
                    {
                        prerequisiteOperation      = DungeonPrerequisite.PrerequisiteOperation.EQUAL_TO,
                        prerequisiteType           = DungeonPrerequisite.PrerequisiteType.TILESET,
                        requiredTileset            = GlobalDungeonData.ValidTilesets.FORGEGEON,
                        requireTileset             = true,
                        comparisonValue            = 1,
                        encounteredObjectGuid      = string.Empty,
                        maxToCheck                 = TrackedMaximums.MOST_KEYS_HELD,
                        requireDemoMode            = false,
                        requireCharacter           = false,
                        requiredCharacter          = PlayableCharacters.Pilot,
                        requireFlag                = false,
                        useSessionStatValue        = false,
                        encounteredRoom            = null,
                        requiredNumberOfEncounters = -1,
                        saveFlagToCheck            = GungeonFlags.TUTORIAL_COMPLETED,
                        statToCheck                = TrackedStats.GUNBERS_MUNCHED
                    }
                },
                CanBeForcedSecret = true,
                RandomNodeChildMinDistanceFromEntrance = 0,
                exactSecondaryRoom = null,
                framedCombatNodes  = 0,
            };
            ExpandTheGungeon.ExpandObjects.ExpandObjectDatabase objectDatabase = new ExpandTheGungeon.ExpandObjects.ExpandObjectDatabase();


            BaseSharedInjectionData.InjectionData.Add(LoopItemRoom);
            ExpandTheGungeon.ExpandUtilities.RoomBuilder.AddObjectToRoom(LoopItemRoomPrefab, new Vector2(5, 7), objectDatabase.GodRays);
            ExpandTheGungeon.ExpandUtilities.RoomBuilder.AddObjectToRoom(LoopItemRoomPrefab, new Vector2(7, 8), ExpandTheGungeon.ExpandUtilities.ExpandUtility.GenerateDungeonPlacable(TimeItemStand, useExternalPrefab: true));
            objectDatabase = null;
            ForgePrefab    = null;
        }
Exemple #4
0
 // Token: 0x06000013 RID: 19 RVA: 0x00002C30 File Offset: 0x00000E30
 public static GenericRoomTable GetSpecialRoomTable()
 {
     foreach (MetaInjectionDataEntry metaInjectionDataEntry in GameManager.Instance.GlobalInjectionData.entries)
     {
         SharedInjectionData injectionData = metaInjectionDataEntry.injectionData;
         bool flag = ((injectionData != null) ? injectionData.InjectionData : null) != null;
         if (flag)
         {
             foreach (ProceduralFlowModifierData proceduralFlowModifierData in metaInjectionDataEntry.injectionData.InjectionData)
             {
                 bool flag2 = proceduralFlowModifierData.roomTable != null && proceduralFlowModifierData.roomTable.name.ToLower().Contains("basic special rooms");
                 if (flag2)
                 {
                     return(proceduralFlowModifierData.roomTable);
                 }
             }
         }
     }
     return(null);
 }
Exemple #5
0
        public static void InitDungeonFlows(bool refreshFlows = false)
        {
            try {
                Dungeon TutorialPrefab       = DungeonDatabase.GetOrLoadByName("Base_Tutorial");
                Dungeon CastlePrefab         = DungeonDatabase.GetOrLoadByName("Base_Castle");
                Dungeon SewerPrefab          = DungeonDatabase.GetOrLoadByName("Base_Sewer");
                Dungeon GungeonPrefab        = DungeonDatabase.GetOrLoadByName("Base_Gungeon");
                Dungeon CathedralPrefab      = DungeonDatabase.GetOrLoadByName("Base_Cathedral");
                Dungeon MinesPrefab          = DungeonDatabase.GetOrLoadByName("Base_Mines");
                Dungeon ResourcefulRatPrefab = DungeonDatabase.GetOrLoadByName("Base_ResourcefulRat");
                Dungeon CatacombsPrefab      = DungeonDatabase.GetOrLoadByName("Base_Catacombs");
                Dungeon NakatomiPrefab       = DungeonDatabase.GetOrLoadByName("Base_Nakatomi");
                Dungeon ForgePrefab          = DungeonDatabase.GetOrLoadByName("Base_Forge");
                Dungeon BulletHellPrefab     = DungeonDatabase.GetOrLoadByName("Base_BulletHell");

                BaseSharedInjectionData = ModPrefabs.shared_auto_002.LoadAsset <SharedInjectionData>("Base Shared Injection Data");
                GungeonInjectionData    = GungeonPrefab.PatternSettings.flows[0].sharedInjectionData[1];
                SewersInjectionData     = SewerPrefab.PatternSettings.flows[0].sharedInjectionData[1];
                HollowsInjectionData    = CatacombsPrefab.PatternSettings.flows[0].sharedInjectionData[1];
                CastleInjectionData     = CastlePrefab.PatternSettings.flows[0].sharedInjectionData[0];



                // Don't build/add flows until injection data is created!
                Foyer_Flow = FlowHelpers.DuplicateDungeonFlow(ModPrefabs.shared_auto_002.LoadAsset <DungeonFlow>("Foyer Flow"));

                // List<DungeonFlow> m_knownFlows = new List<DungeonFlow>();
                KnownFlows = new List <DungeonFlow>();

                //we will add our custom flow here soon.


                // Fix issues with nodes so that things other then MainMenu can load Foyer flow
                Foyer_Flow.name = "Foyer_Flow";
                Foyer_Flow.AllNodes[1].handlesOwnWarping = true;
                Foyer_Flow.AllNodes[2].handlesOwnWarping = true;
                Foyer_Flow.AllNodes[3].handlesOwnWarping = true;

                KnownFlows.Add(Foyer_Flow);
                KnownFlows.Add(f1b_Hat_flow_01.F1b_Hat_flow_01());
                // Add official flows to list (flows found in Dungeon asset bundles after AG&D)
                for (int i = 0; i < TutorialPrefab.PatternSettings.flows.Count; i++)
                {
                    KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(TutorialPrefab.PatternSettings.flows[i]));
                }
                for (int i = 0; i < CastlePrefab.PatternSettings.flows.Count; i++)
                {
                    KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(CastlePrefab.PatternSettings.flows[i]));
                }
                for (int i = 0; i < SewerPrefab.PatternSettings.flows.Count; i++)
                {
                    KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(SewerPrefab.PatternSettings.flows[i]));
                }
                for (int i = 0; i < GungeonPrefab.PatternSettings.flows.Count; i++)
                {
                    KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(GungeonPrefab.PatternSettings.flows[i]));
                }
                for (int i = 0; i < MinesPrefab.PatternSettings.flows.Count; i++)
                {
                    KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(MinesPrefab.PatternSettings.flows[i]));
                }
                for (int i = 0; i < ResourcefulRatPrefab.PatternSettings.flows.Count; i++)
                {
                    KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(ResourcefulRatPrefab.PatternSettings.flows[i]));
                }
                for (int i = 0; i < CatacombsPrefab.PatternSettings.flows.Count; i++)
                {
                    KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(CatacombsPrefab.PatternSettings.flows[i]));
                }
                for (int i = 0; i < NakatomiPrefab.PatternSettings.flows.Count; i++)
                {
                    KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(NakatomiPrefab.PatternSettings.flows[i]));
                }
                for (int i = 0; i < ForgePrefab.PatternSettings.flows.Count; i++)
                {
                    KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(ForgePrefab.PatternSettings.flows[i]));
                }
                for (int i = 0; i < BulletHellPrefab.PatternSettings.flows.Count; i++)
                {
                    KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(BulletHellPrefab.PatternSettings.flows[i]));
                }

                for (int i = 0; i < CathedralPrefab.PatternSettings.flows.Count; i++)
                {
                    KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(CathedralPrefab.PatternSettings.flows[i]));
                }


                TutorialPrefab       = null;
                CastlePrefab         = null;
                SewerPrefab          = null;
                GungeonPrefab        = null;
                CathedralPrefab      = null;
                MinesPrefab          = null;
                ResourcefulRatPrefab = null;
                CatacombsPrefab      = null;
                CathedralPrefab      = null;
                NakatomiPrefab       = null;
                ForgePrefab          = null;
                BulletHellPrefab     = null;
            }
            catch (Exception e)
            {
                Tools.Print(e);
            }
        }
Exemple #6
0
        // Initialize KnownFlows array with custom + official flows.
        public static void InitDungeonFlows(AssetBundle sharedAssets2, bool refreshFlows = false)
        {
            Dungeon TutorialPrefab       = DungeonDatabase.GetOrLoadByName("Base_Tutorial");
            Dungeon CastlePrefab         = DungeonDatabase.GetOrLoadByName("Base_Castle");
            Dungeon SewerPrefab          = DungeonDatabase.GetOrLoadByName("Base_Sewer");
            Dungeon GungeonPrefab        = DungeonDatabase.GetOrLoadByName("Base_Gungeon");
            Dungeon CathedralPrefab      = DungeonDatabase.GetOrLoadByName("Base_Cathedral");
            Dungeon MinesPrefab          = DungeonDatabase.GetOrLoadByName("Base_Mines");
            Dungeon ResourcefulRatPrefab = DungeonDatabase.GetOrLoadByName("Base_ResourcefulRat");
            Dungeon CatacombsPrefab      = DungeonDatabase.GetOrLoadByName("Base_Catacombs");
            Dungeon NakatomiPrefab       = DungeonDatabase.GetOrLoadByName("Base_Nakatomi");
            Dungeon ForgePrefab          = DungeonDatabase.GetOrLoadByName("Base_Forge");
            Dungeon BulletHellPrefab     = DungeonDatabase.GetOrLoadByName("Base_BulletHell");

            BaseSharedInjectionData = sharedAssets2.LoadAsset <SharedInjectionData>("Base Shared Injection Data");
            GungeonInjectionData    = GungeonPrefab.PatternSettings.flows[0].sharedInjectionData[1];
            SewersInjectionData     = SewerPrefab.PatternSettings.flows[0].sharedInjectionData[1];
            HollowsInjectionData    = CatacombsPrefab.PatternSettings.flows[0].sharedInjectionData[1];
            CastleInjectionData     = CastlePrefab.PatternSettings.flows[0].sharedInjectionData[0];

            JunkSecretRoomInjector = new ProceduralFlowModifierData()
            {
                annotation        = "Tiny Secret Room",
                DEBUG_FORCE_SPAWN = false,
                OncePerRun        = false,
                placementRules    = new List <ProceduralFlowModifierData.FlowModifierPlacementType>()
                {
                    ProceduralFlowModifierData.FlowModifierPlacementType.RANDOM_NODE_CHILD
                },
                roomTable              = null,
                exactRoom              = ExpandRoomPrefabs.Expand_TinySecret,
                IsWarpWing             = false,
                RequiresMasteryToken   = false,
                chanceToLock           = 0,
                selectionWeight        = 1,
                chanceToSpawn          = 1,
                RequiredValidPlaceable = null,
                prerequisites          = new DungeonPrerequisite[0],
                CanBeForcedSecret      = true,
                RandomNodeChildMinDistanceFromEntrance = 0,
                exactSecondaryRoom = null,
                framedCombatNodes  = 0,
            };

            BellySpecialEntranceRoomInjector = new ProceduralFlowModifierData()
            {
                annotation        = "Secret Belly Entrance Room",
                DEBUG_FORCE_SPAWN = false,
                OncePerRun        = false,
                placementRules    = new List <ProceduralFlowModifierData.FlowModifierPlacementType>()
                {
                    ProceduralFlowModifierData.FlowModifierPlacementType.END_OF_CHAIN
                },
                roomTable              = null,
                exactRoom              = ExpandRoomPrefabs.Expand_Gungeon_BellyEntranceRoom,
                IsWarpWing             = false,
                RequiresMasteryToken   = false,
                chanceToLock           = 0,
                selectionWeight        = 1,
                chanceToSpawn          = 1,
                RequiredValidPlaceable = null,
                prerequisites          = new DungeonPrerequisite[] {
                    new DungeonPrerequisite()
                    {
                        prerequisiteOperation      = DungeonPrerequisite.PrerequisiteOperation.EQUAL_TO,
                        prerequisiteType           = DungeonPrerequisite.PrerequisiteType.TILESET,
                        requiredTileset            = GlobalDungeonData.ValidTilesets.GUNGEON,
                        requireTileset             = true,
                        comparisonValue            = 1,
                        encounteredObjectGuid      = string.Empty,
                        maxToCheck                 = TrackedMaximums.MOST_KEYS_HELD,
                        requireDemoMode            = false,
                        requireCharacter           = false,
                        requiredCharacter          = PlayableCharacters.Pilot,
                        requireFlag                = false,
                        useSessionStatValue        = false,
                        encounteredRoom            = null,
                        requiredNumberOfEncounters = -1,
                        saveFlagToCheck            = GungeonFlags.TUTORIAL_COMPLETED,
                        statToCheck                = TrackedStats.GUNBERS_MUNCHED
                    }
                },
                CanBeForcedSecret = true,
                RandomNodeChildMinDistanceFromEntrance = 0,
                exactSecondaryRoom = null,
                framedCombatNodes  = 0,
            };

            BellySpecialMonsterRoomInjector = new ProceduralFlowModifierData()
            {
                annotation        = "Secret Belly Monster Room",
                DEBUG_FORCE_SPAWN = false,
                OncePerRun        = false,
                placementRules    = new List <ProceduralFlowModifierData.FlowModifierPlacementType>()
                {
                    ProceduralFlowModifierData.FlowModifierPlacementType.NO_LINKS
                },
                roomTable              = null,
                exactRoom              = ExpandRoomPrefabs.Expand_Gungeon_HiddenMonsterRoom,
                IsWarpWing             = true,
                RequiresMasteryToken   = false,
                chanceToLock           = 0,
                selectionWeight        = 1,
                chanceToSpawn          = 1,
                RequiredValidPlaceable = null,
                prerequisites          = new DungeonPrerequisite[] {
                    new DungeonPrerequisite()
                    {
                        prerequisiteOperation      = DungeonPrerequisite.PrerequisiteOperation.EQUAL_TO,
                        prerequisiteType           = DungeonPrerequisite.PrerequisiteType.TILESET,
                        requiredTileset            = GlobalDungeonData.ValidTilesets.GUNGEON,
                        requireTileset             = true,
                        comparisonValue            = 1,
                        encounteredObjectGuid      = string.Empty,
                        maxToCheck                 = TrackedMaximums.MOST_KEYS_HELD,
                        requireDemoMode            = false,
                        requireCharacter           = false,
                        requiredCharacter          = PlayableCharacters.Pilot,
                        requireFlag                = false,
                        useSessionStatValue        = false,
                        encounteredRoom            = null,
                        requiredNumberOfEncounters = -1,
                        saveFlagToCheck            = GungeonFlags.TUTORIAL_COMPLETED,
                        statToCheck                = TrackedStats.GUNBERS_MUNCHED
                    }
                },
                CanBeForcedSecret = true,
                RandomNodeChildMinDistanceFromEntrance = 0,
                exactSecondaryRoom = null,
                framedCombatNodes  = 0,
            };

            GungeonInjectionData.InjectionData.Add(BellySpecialEntranceRoomInjector);
            GungeonInjectionData.InjectionData.Add(BellySpecialMonsterRoomInjector);

            SewersInjectionData.InjectionData.Add(JunkSecretRoomInjector);


            SecretFloorEntranceInjector = new ProceduralFlowModifierData()
            {
                annotation        = "Secret Floor Entrance Room",
                DEBUG_FORCE_SPAWN = false,
                OncePerRun        = false,
                placementRules    = new List <ProceduralFlowModifierData.FlowModifierPlacementType>()
                {
                    ProceduralFlowModifierData.FlowModifierPlacementType.NO_LINKS
                },
                roomTable = null,
                // exactRoom = SewersInjectionData.InjectionData[0].exactRoom,
                exactRoom              = ExpandRoomPrefabs.SecretExitRoom2,
                IsWarpWing             = true,
                RequiresMasteryToken   = false,
                chanceToLock           = 0,
                selectionWeight        = 1,
                chanceToSpawn          = 1,
                RequiredValidPlaceable = null,
                prerequisites          = new DungeonPrerequisite[0],
                CanBeForcedSecret      = true,
                RandomNodeChildMinDistanceFromEntrance = 0,
                exactSecondaryRoom = null,
                framedCombatNodes  = 0,
            };

            SecretMiniElevatorInjector = new ProceduralFlowModifierData()
            {
                annotation        = "Secret MiniElevator Room with Glitched Rats",
                DEBUG_FORCE_SPAWN = false,
                OncePerRun        = false,
                placementRules    = new List <ProceduralFlowModifierData.FlowModifierPlacementType>()
                {
                    ProceduralFlowModifierData.FlowModifierPlacementType.RANDOM_NODE_CHILD
                },
                roomTable              = null,
                exactRoom              = ExpandRoomPrefabs.SecretRatEntranceRoom,
                IsWarpWing             = false,
                RequiresMasteryToken   = false,
                chanceToLock           = 0.25f,
                selectionWeight        = 1,
                chanceToSpawn          = 1,
                RequiredValidPlaceable = null,
                prerequisites          = new DungeonPrerequisite[0],
                CanBeForcedSecret      = true,
                RandomNodeChildMinDistanceFromEntrance = 0,
                exactSecondaryRoom = null,
                framedCombatNodes  = 0,
            };


            m_KeepJungleEntranceRooms = ScriptableObject.CreateInstance <GenericRoomTable>();
            m_KeepJungleEntranceRooms.includedRoomTables = new List <GenericRoomTable>(0);
            m_KeepJungleEntranceRooms.includedRooms      = new WeightedRoomCollection()
            {
                elements = new List <WeightedRoom>()
                {
                    ExpandRoomPrefabs.GenerateWeightedRoom(ExpandRoomPrefabs.Expand_Keep_TreeRoom, Weight: 0.5f),
                    ExpandRoomPrefabs.GenerateWeightedRoom(ExpandRoomPrefabs.Expand_Keep_TreeRoom2)
                }
            };


            SecretJungleEntranceInjector = new ProceduralFlowModifierData()
            {
                annotation        = "Secret Jungle Entrance Room",
                DEBUG_FORCE_SPAWN = false,
                OncePerRun        = false,
                placementRules    = new List <ProceduralFlowModifierData.FlowModifierPlacementType>()
                {
                    ProceduralFlowModifierData.FlowModifierPlacementType.RANDOM_NODE_CHILD
                },
                roomTable              = m_KeepJungleEntranceRooms,
                exactRoom              = null,
                IsWarpWing             = false,
                RequiresMasteryToken   = false,
                chanceToLock           = 0,
                selectionWeight        = 1,
                chanceToSpawn          = 1,
                RequiredValidPlaceable = null,
                prerequisites          = new DungeonPrerequisite[] {
                    new DungeonPrerequisite()
                    {
                        prerequisiteOperation      = DungeonPrerequisite.PrerequisiteOperation.EQUAL_TO,
                        prerequisiteType           = DungeonPrerequisite.PrerequisiteType.TILESET,
                        requiredTileset            = GlobalDungeonData.ValidTilesets.CASTLEGEON,
                        requireTileset             = true,
                        comparisonValue            = 1,
                        encounteredObjectGuid      = string.Empty,
                        maxToCheck                 = TrackedMaximums.MOST_KEYS_HELD,
                        requireDemoMode            = false,
                        requireCharacter           = false,
                        requiredCharacter          = PlayableCharacters.Pilot,
                        requireFlag                = false,
                        useSessionStatValue        = false,
                        encounteredRoom            = null,
                        requiredNumberOfEncounters = -1,
                        saveFlagToCheck            = GungeonFlags.TUTORIAL_COMPLETED,
                        statToCheck                = TrackedStats.GUNBERS_MUNCHED
                    }
                },
                CanBeForcedSecret = true,
                RandomNodeChildMinDistanceFromEntrance = 0,
                exactSecondaryRoom = null,
                framedCombatNodes  = 0,
            };

            HollowsInjectionData.InjectionData.Add(SecretFloorEntranceInjector);
            HollowsInjectionData.InjectionData.Add(SecretMiniElevatorInjector);
            CastleInjectionData.InjectionData.Add(SecretJungleEntranceInjector);


            RickRollSecretRoomInjector = new ProceduralFlowModifierData()
            {
                annotation        = "RickRoll Secret Room",
                DEBUG_FORCE_SPAWN = false,
                OncePerRun        = false,
                placementRules    = new List <ProceduralFlowModifierData.FlowModifierPlacementType>()
                {
                    ProceduralFlowModifierData.FlowModifierPlacementType.END_OF_CHAIN
                },
                roomTable              = null,
                exactRoom              = ExpandRoomPrefabs.Expand_RickRollSecret,
                IsWarpWing             = false,
                RequiresMasteryToken   = false,
                chanceToLock           = 0,
                selectionWeight        = 1,
                chanceToSpawn          = 0.25f,
                RequiredValidPlaceable = null,
                prerequisites          = new DungeonPrerequisite[0],
                CanBeForcedSecret      = true,
                RandomNodeChildMinDistanceFromEntrance = 1,
                exactSecondaryRoom = null,
                framedCombatNodes  = 0
            };

            CustomSecretFloorSharedInjectionData = ScriptableObject.CreateInstance <SharedInjectionData>();

            CustomSecretFloorSharedInjectionData.name          = "Rick Roll Secret Room Injection Data";
            CustomSecretFloorSharedInjectionData.InjectionData = new List <ProceduralFlowModifierData>()
            {
                RickRollSecretRoomInjector
            };
            CustomSecretFloorSharedInjectionData.UseInvalidWeightAsNoInjection = true;
            CustomSecretFloorSharedInjectionData.IsNPCCell = false;
            CustomSecretFloorSharedInjectionData.PreventInjectionOfFailedPrerequisites = false;
            CustomSecretFloorSharedInjectionData.OnlyOne               = false;
            CustomSecretFloorSharedInjectionData.ChanceToSpawnOne      = 1;
            CustomSecretFloorSharedInjectionData.AttachedInjectionData = new List <SharedInjectionData>(0);


            // Don't build/add flows until injection data is created!
            Foyer_Flow = FlowHelpers.DuplicateDungeonFlow(sharedAssets2.LoadAsset <DungeonFlow>("Foyer Flow"));

            // List<DungeonFlow> m_knownFlows = new List<DungeonFlow>();
            KnownFlows = new List <DungeonFlow>();

            // Build and add custom flows to list.
            BossrushFlows.InitBossrushFlows();

            KnownFlows.Add(custom_glitchchest_flow.Custom_GlitchChest_Flow());
            KnownFlows.Add(test_west_floor_03a_flow.TEST_West_Floor_03a_Flow());
            KnownFlows.Add(demo_stage_flow.DEMO_STAGE_FLOW());
            KnownFlows.Add(complex_flow_test.Complex_Flow_Test());
            KnownFlows.Add(custom_glitch_flow.Custom_Glitch_Flow());
            KnownFlows.Add(really_big_flow.Really_Big_Flow());
            KnownFlows.Add(fruit_loops.Fruit_Loops());
            KnownFlows.Add(custom_glitchchestalt_flow.Custom_GlitchChestAlt_Flow());
            KnownFlows.Add(test_traproom_flow.Test_TrapRoom_Flow());
            KnownFlows.Add(test_customroom_flow.Test_CustomRoom_Flow());
            KnownFlows.Add(apache_fucking_around_flow.Apache_Fucking_Around_Flow());
            KnownFlows.Add(f1b_jungle_flow_01.F1b_Jungle_Flow_01());
            KnownFlows.Add(f1b_jungle_flow_02.F1b_Jungle_Flow_02());
            KnownFlows.Add(f2b_belly_flow_01.F2b_Belly_Flow_01());
            KnownFlows.Add(f4c_west_flow_01.F4c_West_Flow_01());

            // Fix issues with nodes so that things other then MainMenu can load Foyer flow
            Foyer_Flow.name = "Foyer_Flow";
            Foyer_Flow.AllNodes[1].handlesOwnWarping = true;
            Foyer_Flow.AllNodes[2].handlesOwnWarping = true;
            Foyer_Flow.AllNodes[3].handlesOwnWarping = true;

            KnownFlows.Add(Foyer_Flow);
            KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(LoadOfficialFlow("npcparadise")));
            KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(LoadOfficialFlow("secret_doublebeholster_flow")));
            KnownFlows.Add(BossrushFlows.Bossrush_01_Castle);
            KnownFlows.Add(BossrushFlows.Bossrush_01a_Sewer);
            KnownFlows.Add(BossrushFlows.Bossrush_02_Gungeon);
            KnownFlows.Add(BossrushFlows.Bossrush_02a_Cathedral);
            KnownFlows.Add(BossrushFlows.Bossrush_03_Mines);
            KnownFlows.Add(BossrushFlows.Bossrush_04_Catacombs);
            KnownFlows.Add(BossrushFlows.Bossrush_05_Forge);
            KnownFlows.Add(BossrushFlows.Bossrush_06_BulletHell);
            KnownFlows.Add(BossrushFlows.MiniBossrush_01);

            // Add official flows to list (flows found in Dungeon asset bundles after AG&D)
            for (int i = 0; i < TutorialPrefab.PatternSettings.flows.Count; i++)
            {
                KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(TutorialPrefab.PatternSettings.flows[i]));
            }
            for (int i = 0; i < CastlePrefab.PatternSettings.flows.Count; i++)
            {
                KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(CastlePrefab.PatternSettings.flows[i]));
            }
            for (int i = 0; i < SewerPrefab.PatternSettings.flows.Count; i++)
            {
                KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(SewerPrefab.PatternSettings.flows[i]));
            }
            for (int i = 0; i < GungeonPrefab.PatternSettings.flows.Count; i++)
            {
                KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(GungeonPrefab.PatternSettings.flows[i]));
            }
            for (int i = 0; i < CathedralPrefab.PatternSettings.flows.Count; i++)
            {
                KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(CathedralPrefab.PatternSettings.flows[i]));
            }
            for (int i = 0; i < MinesPrefab.PatternSettings.flows.Count; i++)
            {
                KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(MinesPrefab.PatternSettings.flows[i]));
            }
            for (int i = 0; i < ResourcefulRatPrefab.PatternSettings.flows.Count; i++)
            {
                KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(ResourcefulRatPrefab.PatternSettings.flows[i]));
            }
            for (int i = 0; i < CatacombsPrefab.PatternSettings.flows.Count; i++)
            {
                KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(CatacombsPrefab.PatternSettings.flows[i]));
            }
            for (int i = 0; i < NakatomiPrefab.PatternSettings.flows.Count; i++)
            {
                KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(NakatomiPrefab.PatternSettings.flows[i]));
            }
            for (int i = 0; i < ForgePrefab.PatternSettings.flows.Count; i++)
            {
                KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(ForgePrefab.PatternSettings.flows[i]));
            }
            for (int i = 0; i < BulletHellPrefab.PatternSettings.flows.Count; i++)
            {
                KnownFlows.Add(FlowHelpers.DuplicateDungeonFlow(BulletHellPrefab.PatternSettings.flows[i]));
            }

            // Let's make things look cool and give all boss rush flows my new tiny exit room. :D
            BossrushFlows.Bossrush_01a_Sewer.AllNodes[2].overrideExactRoom     = ExpandPrefabs.tiny_exit;
            BossrushFlows.Bossrush_02_Gungeon.AllNodes[6].overrideExactRoom    = ExpandPrefabs.tiny_exit;
            BossrushFlows.Bossrush_02a_Cathedral.AllNodes[2].overrideExactRoom = ExpandPrefabs.oldbulletking_room_01;
            BossrushFlows.Bossrush_02a_Cathedral.AllNodes[3].overrideExactRoom = ExpandPrefabs.tiny_exit;
            BossrushFlows.Bossrush_03_Mines.AllNodes[6].overrideExactRoom      = ExpandPrefabs.tiny_exit;
            BossrushFlows.Bossrush_04_Catacombs.AllNodes[6].overrideExactRoom  = ExpandPrefabs.tiny_exit;
            // Fix Forge Bossrush so it uses the correct boss foyer room for Dragun.
            // Using the same foyer room for previous floors looks odd so I fixed it. :P
            BossrushFlows.Bossrush_05_Forge.AllNodes[1].overrideExactRoom = ExpandPrefabs.DragunBossFoyerRoom;
            BossrushFlows.Bossrush_05_Forge.AllNodes[3].overrideExactRoom = ExpandPrefabs.tiny_exit;

            TutorialPrefab       = null;
            CastlePrefab         = null;
            SewerPrefab          = null;
            GungeonPrefab        = null;
            CathedralPrefab      = null;
            MinesPrefab          = null;
            ResourcefulRatPrefab = null;
            CatacombsPrefab      = null;
            NakatomiPrefab       = null;
            ForgePrefab          = null;
            BulletHellPrefab     = null;
        }