Ejemplo n.º 1
0
        private static StageSettings GetStageSettings(ClassicStageInfo self)
        {
            StageSettings set = new StageSettings
            {
                sceneDirectorInteractableCredits = self.sceneDirectorInteractibleCredits,
                sceneDirectorMonsterCredits      = self.sceneDirectorMonsterCredits
            };

            set.bonusCreditObjects = new Dictionary <GameObject, int>();
            for (int i = 0; i < self.bonusInteractibleCreditObjects.Length; i++)
            {
                var bonusObj = self.bonusInteractibleCreditObjects[i];
                set.bonusCreditObjects[bonusObj.objectThatGrantsPointsIfEnabled] = bonusObj.points;
            }

            set.interactableCategoryWeights = new Dictionary <InteractableCategory, float>();
            var interCats = self.GetFieldValue <DirectorCardCategorySelection>("interactableCategories");

            for (int i = 0; i < interCats.categories.Length; i++)
            {
                var cat = interCats.categories[i];
                set.interactableCategoryWeights[GetInteractableCategory(cat.name)] = cat.selectionWeight;
            }

            set.monsterCategoryWeights = new Dictionary <MonsterCategory, float>();
            var monstCats = self.GetFieldValue <DirectorCardCategorySelection>("monsterCategories");

            for (int i = 0; i < monstCats.categories.Length; i++)
            {
                var cat = monstCats.categories[i];
                set.monsterCategoryWeights[GetMonsterCategory(cat.name)] = cat.selectionWeight;
            }

            return(set);
        }
Ejemplo n.º 2
0
        private static StageSettings GetStageSettings(ClassicStageInfo self)
        {
            var set = new StageSettings {
                SceneDirectorInteractableCredits = self.sceneDirectorInteractibleCredits,
                SceneDirectorMonsterCredits      = self.sceneDirectorMonsterCredits,
                BonusCreditObjects = new Dictionary <GameObject, int>()
            };

            foreach (var bonusObj in self.bonusInteractibleCreditObjects)
            {
                set.BonusCreditObjects[bonusObj.objectThatGrantsPointsIfEnabled] = bonusObj.points;
            }
            set.InteractableCategoryWeights = new Dictionary <InteractableCategory, float>();
            var interCats = self.GetFieldValue <DirectorCardCategorySelection>("interactableCategories");

            foreach (var cat in interCats.categories)
            {
                set.InteractableCategoryWeights[GetInteractableCategory(cat.name)] = cat.selectionWeight;
            }
            set.MonsterCategoryWeights = new Dictionary <MonsterCategory, float>();
            var monstCats = self.GetFieldValue <DirectorCardCategorySelection>("monsterCategories");

            foreach (var cat in monstCats.categories)
            {
                set.MonsterCategoryWeights[GetMonsterCategory(cat.name)] = cat.selectionWeight;
            }
            return(set);
        }
Ejemplo n.º 3
0
        private static void SpawnsCore_familyEdits1(ClassicStageInfo stageInfo, Run runInstance, ClassicStageInfo.MonsterFamily[] possibleFamilies)
        {
            if (runInstance.selectedDifficulty < DifficultyIndex.Hard && runInstance is not EclipseRun)
            {
                return;
            }
            for (Int32 i = 0; i < possibleFamilies.Length; ++i)
            {
                var family = possibleFamilies[i];
                if (family.familySelectionChatString != "FAMILY_WISP")
                {
                    continue;
                }
                var startCount = family.monsterFamilyCategories.categories.Length;
                for (Int32 j = 0; j < startCount; ++j)
                {
                    var category = family.monsterFamilyCategories.categories[j];
                    if (category.name.ToLower() != "minibosses")
                    {
                        continue;
                    }
                    var ind = category.cards.Length;
                    Array.Resize <DirectorCard>(ref category.cards, ind + 1);
                    category.cards[ind] = ArW_dirCard;

                    family.monsterFamilyCategories.categories[j] = category;
                    break;
                }
                possibleFamilies[i] = family;
                break;
            }
        }
Ejemplo n.º 4
0
        private static void SetStageSettings(ClassicStageInfo self, StageSettings set)
        {
            self.sceneDirectorInteractibleCredits = set.SceneDirectorInteractableCredits;
            self.sceneDirectorMonsterCredits      = set.SceneDirectorMonsterCredits;
            var keys    = set.BonusCreditObjects.Keys.ToArray();
            var bonuses = new ClassicStageInfo.BonusInteractibleCreditObject[keys.Length];

            for (int i = 0; i < keys.Length; i++)
            {
                bonuses[i] = new ClassicStageInfo.BonusInteractibleCreditObject {
                    objectThatGrantsPointsIfEnabled = keys[i],
                    points = set.BonusCreditObjects[keys[i]]
                };
            }
            self.bonusInteractibleCreditObjects = bonuses;
            var interCats = self.GetFieldValue <DirectorCardCategorySelection>("interactableCategories");

            for (int i = 0; i < interCats.categories.Length; i++)
            {
                var cat = interCats.categories[i];
                InteractableCategory intCat = GetInteractableCategory(cat.name);
                cat.selectionWeight     = set.InteractableCategoryWeights[intCat];
                interCats.categories[i] = cat;
            }
            var monstCats = self.GetFieldValue <DirectorCardCategorySelection>("monsterCategories");

            for (int i = 0; i < monstCats.categories.Length; i++)
            {
                var             cat    = monstCats.categories[i];
                MonsterCategory monCat = GetMonsterCategory(cat.name);
                cat.selectionWeight     = set.MonsterCategoryWeights[monCat];
                monstCats.categories[i] = cat;
            }
        }
Ejemplo n.º 5
0
        private static void ApplySettingsChanges(ClassicStageInfo self, StageInfo stageInfo)
        {
            StageSettings settings = GetStageSettings(self);

            StageSettingsActions?.Invoke(settings, stageInfo);
            SetStageSettings(self, settings);
        }
Ejemplo n.º 6
0
        private static void ApplyMonsterChanges(ClassicStageInfo self, StageInfo stage)
        {
            var monsters     = self.GetFieldValue <DirectorCardCategorySelection>("monsterCategories");
            var monsterCards = new List <DirectorCardHolder>();

            foreach (var cat in monsters.categories)
            {
                MonsterCategory      monstCat = GetMonsterCategory(cat.name);
                InteractableCategory interCat = GetInteractableCategory(cat.name);
                foreach (var t in cat.cards)
                {
                    monsterCards.Add(new DirectorCardHolder {
                        InteractableCategory = interCat,
                        MonsterCategory      = monstCat,
                        Card = t
                    });
                }
            }
            MonsterActions?.Invoke(monsterCards, stage);
            var monsterBasic = new List <DirectorCard>();
            var monsterSub   = new List <DirectorCard>();
            var monsterChamp = new List <DirectorCard>();

            foreach (var hold in monsterCards)
            {
                switch (hold.MonsterCategory)
                {
                case MonsterCategory.BasicMonsters:
                    monsterBasic.Add(hold.Card);
                    break;

                case MonsterCategory.Champions:
                    monsterChamp.Add(hold.Card);
                    break;

                case MonsterCategory.Minibosses:
                    monsterSub.Add(hold.Card);
                    break;
                }
            }
            for (int i = 0; i < monsters.categories.Length; i++)
            {
                DirectorCardCategorySelection.Category cat = monsters.categories[i];
                switch (cat.name)
                {
                case "Champions":
                    cat.cards = monsterChamp.ToArray();
                    break;

                case "Minibosses":
                    cat.cards = monsterSub.ToArray();
                    break;

                case "Basic Monsters":
                    cat.cards = monsterBasic.ToArray();
                    break;
                }
                monsters.categories[i] = cat;
            }
        }
Ejemplo n.º 7
0
        internal static void ApplyChanges(this ClassicStageInfo self)
        {
            var stageInfo = GetStageInfo(self);

            ApplySettingsChanges(self, stageInfo);
            ApplyMonsterChanges(self, stageInfo);
            ApplyInteractableChanges(self, stageInfo);
            ApplyFamilyChanges(self, stageInfo);
        }
Ejemplo n.º 8
0
        private static void ApplyFamilyChanges(ClassicStageInfo self, StageInfo stage)
        {
            var familyHolds = self.possibleMonsterFamilies.Select(GetMonsterFamilyHolder).ToList();

            FamilyActions?.Invoke(familyHolds, stage);
            self.possibleMonsterFamilies = new ClassicStageInfo.MonsterFamily[familyHolds.Count];
            for (int i = 0; i < familyHolds.Count; i++)
            {
                self.possibleMonsterFamilies[i] = GetMonsterFamily(familyHolds[i]);
            }
        }
Ejemplo n.º 9
0
 private void SpawnsCore_monsterEdits(ClassicStageInfo stageInfo, Run runInstance, DirectorCardCategorySelection monsterSelection)
 {
     Log.Warning("edits");
     Log.Warning(monsterSelection.name);
     if (monsterSelection.name == "dccsSkyMeadowMonsters")
     {
         Log.Warning("IsRightMap");
         //monsterSelection.RemoveCardsThatFailFilter( ( card ) => !( card.spawnCard.name.Contains( "Grandparent" ) ) );
         _ = monsterSelection.AddCard(0, this.dirCard);
         _ = monsterSelection.AddCard(1, this.dirCard);
         _ = monsterSelection.AddCard(2, this.dirCard);
     }
 }
Ejemplo n.º 10
0
        private static void StageAwake(On.RoR2.ClassicStageInfo.orig_Awake orig, ClassicStageInfo self)
        {
            var stage = GetStage(self);

            ApplySettingsChanges(self, stage);

            ApplyMonsterChanges(self, stage);
            ApplyInteractableChanges(self, stage);

            ApplyFamilyChanges(self, stage);

            orig(self);
        }
Ejemplo n.º 11
0
 private void SpawnsCore_monsterEdits(ClassicStageInfo stageInfo, Run runInstance, DirectorCardCategorySelection monsterSelection)
 {
     for (Int32 i = 0; i < monsterSelection.categories.Length; ++i)
     {
         ref var cat = ref monsterSelection.categories[i];
         for (Int32 j = 0; j < cat.cards.Length; ++j)
         {
             var card = cat.cards[j];
             if (card.spawnCard is CharacterSpawnCard csc && csc.name?.ToLower() == "cscelectricworm")
             {
                 csc.noElites = false;
             }
         }
     }
Ejemplo n.º 12
0
        private static void ApplyFamilyChanges(ClassicStageInfo self, StageInfo stage)
        {
            List <MonsterFamilyHolder> familyHolds = new List <MonsterFamilyHolder>();

            for (int i = 0; i < self.possibleMonsterFamilies.Length; i++)
            {
                familyHolds.Add(GetMonsterFamilyHolder(self.possibleMonsterFamilies[i]));
            }
            familyActions?.Invoke(familyHolds, stage);
            self.possibleMonsterFamilies = new ClassicStageInfo.MonsterFamily[familyHolds.Count];
            for (int i = 0; i < familyHolds.Count; i++)
            {
                Debug.Log(i);
                self.possibleMonsterFamilies[i] = GetMonsterFamily(familyHolds[i]);
            }
        }
Ejemplo n.º 13
0
        public static GameObject CreateGameObject()
        {
            GameObject gameObject = null;

            if (NetworkServer.active)
            {
                ClassicStageInfo component    = SceneInfo.instance.GetComponent <ClassicStageInfo>();
                DirectorCard     directorCard = CommonUtil.SelectCard(component.interactableSelection, 100);
                while (!directorCard.spawnCard.name.Contains("Barrel"))
                {
                    directorCard = CommonUtil.SelectCard(component.interactableSelection, 100);
                }

                gameObject = directorCard.spawnCard.DoSpawn(Vector3.zero, Quaternion.identity);
            }
            return(gameObject);
        }
Ejemplo n.º 14
0
 private static void SceneDirector_Start(Action <RoR2.SceneDirector> orig, SceneDirector self)
 {
     if (NetworkServer.active)
     {
         ClassicStageInfo stageInfo = SceneInfo.instance.GetComponent <ClassicStageInfo>();
         foreach (InteractableInfo interactable in registeredInteractables)
         {
             if (interactable.multiplayerOnly && RoR2Application.isInMultiPlayer || !interactable.multiplayerOnly)
             {
                 //Debug.Log("Trying to add " + interactable.directorCard.spawnCard.prefab.name + " to " + SceneManager.GetActiveScene().name);
                 if (interactable.scenes.Contains(SceneManager.GetActiveScene().name))
                 {
                     stageInfo.interactableCategories.AddCard((int)interactable.category, interactable.directorCard);
                 }
             }
         }
     }
     orig(self);
 }
Ejemplo n.º 15
0
        static void DisableDefaultSpawn(On.RoR2.SceneDirector.orig_Start orig, SceneDirector self)
        {
            if (NetworkServer.active)
            {
                ClassicStageInfo sceneInfo = SceneInfo.instance.GetComponent <ClassicStageInfo>();

                //Disables default interactibles spawning
                if (VoteAPI.VoteResults.HasVote(Settings.CustomInteractablesSpawner.Item2))
                {
                    sceneInfo.sceneDirectorInteractibleCredits = 0;
                    sceneInfo.bonusInteractibleCreditObjects   = null;
                }

                //Disables default mob spawning
                if (!VoteAPI.VoteResults.HasVote(Settings.MobSpawn.Item2))
                {
                    sceneInfo.sceneDirectorMonsterCredits = 0;
                }
            }
            orig(self);
        }
Ejemplo n.º 16
0
        private static void SpawnsCore_monsterEdits1(ClassicStageInfo stageInfo, Run runInstance, DirectorCardCategorySelection monsterSelection)
        {
            if (runInstance.selectedDifficulty < DifficultyIndex.Hard && runInstance is not EclipseRun)
            {
                return;
            }
            for (Int32 i = 0; i < monsterSelection.categories.Length; ++i)
            {
                var category = monsterSelection.categories[i];
                if (category.name.ToLower() != "minibosses")
                {
                    continue;
                }

                var ind = category.cards.Length;
                Array.Resize <DirectorCard>(ref category.cards, ind + 1);
                category.cards[ind] = ArW_dirCard;

                monsterSelection.categories[i] = category;
                break;
            }
        }
Ejemplo n.º 17
0
            static bool Prefix(SceneDirector __instance, ref Xoroshiro128Plus ___rng, ref int ___interactableCredit, ref int ___monsterCredit)
            {
                ___rng = new Xoroshiro128Plus((ulong)Run.instance.stageRng.nextUint);
                float num = 0.5f + (float)Run.instance.participatingPlayerCount * 0.5f;

                num *= LevelIntrInVar.Stacks;
                ClassicStageInfo component = SceneInfo.instance.GetComponent <ClassicStageInfo>();

                if (component)
                {
                    ___interactableCredit = (int)((float)component.sceneDirectorInteractibleCredits * num);
                    Debug.LogFormat("Spending {0} credits on interactables...", new object[] {
                        ___interactableCredit
                    });
                    ___monsterCredit = (int)((float)component.sceneDirectorMonsterCredits * Run.instance.difficultyCoefficient) * LevelMonsterInVar.Stacks;
                }

                typeof(SceneDirector).Raise("onPrePopulateSceneServer", __instance);
                new Traverse(__instance).Method("PopulateScene").GetValue();
                typeof(SceneDirector).Raise("onPostPopulateSceneServer", __instance);
                return(false);
            }
Ejemplo n.º 18
0
 private void SpawnsCore_monsterEdits1(ClassicStageInfo stageInfo, Run runInstance, DirectorCardCategorySelection monsterSelection)
 {
     foreach (var m in monsterSelection.categories)
     {
         if (m.name.Contains("ions"))
         {
             foreach (var n in m.cards)
             {
                 //Main.LogW( n.spawnCard.name );
                 if (n.spawnCard.name != "cscBeetleQueen")
                 {
                     n.selectionWeight = 0;
                 }
                 else
                 {
                     var master = (n.spawnCard as CharacterSpawnCard).prefab;
                     foreach (var v in master.GetComponents <RoR2.CharacterAI.AISkillDriver>())
                     {
                         if (v.skillSlot == SkillSlot.Secondary)
                         {
                             v.maxUserHealthFraction = 0f;
                             v.minUserHealthFraction = 0f;
                         }
                     }
                     master.GetComponent <CharacterMaster>().bodyPrefab.AddComponent <TimeThing>();
                 }
             }
         }
         else
         {
             foreach (var n in m.cards)
             {
                 var body = n.spawnCard.prefab.GetComponent <CharacterMaster>().bodyPrefab.GetComponent <CharacterBody>();
                 body.baseDamage  = 0f;
                 body.levelDamage = 0f;
             }
         }
     }
 }
Ejemplo n.º 19
0
        private static void ApplyMonsterChanges(ClassicStageInfo self, StageInfo stage)
        {
            var monsters = self.GetFieldValue <DirectorCardCategorySelection>("monsterCategories");
            List <DirectorCardHolder> monsterCards = new List <DirectorCardHolder>();

            for (int i = 0; i < monsters.categories.Length; i++)
            {
                DirectorCardCategorySelection.Category cat = monsters.categories[i];
                MonsterCategory      monstCat = GetMonsterCategory(cat.name);
                InteractableCategory interCat = GetInteractableCategory(cat.name);
                for (int j = 0; j < cat.cards.Length; j++)
                {
                    monsterCards.Add(new DirectorCardHolder
                    {
                        interactableCategory = interCat,
                        monsterCategory      = monstCat,
                        card = cat.cards[j]
                    });
                }
            }

            monsterActions?.Invoke(monsterCards, stage);

            DirectorCard[] monsterBasic = new DirectorCard[0];
            DirectorCard[] monsterSub   = new DirectorCard[0];
            DirectorCard[] monsterChamp = new DirectorCard[0];

            for (int i = 0; i < monsterCards.Count; i++)
            {
                DirectorCardHolder hold = monsterCards[i];
                switch (hold.monsterCategory)
                {
                default:
                    Debug.Log("Wtf are you doing...");
                    break;

                case MonsterCategory.BasicMonsters:
                    AddToArray <DirectorCard>(ref monsterBasic, hold.card);
                    break;

                case MonsterCategory.Champions:
                    AddToArray <DirectorCard>(ref monsterChamp, hold.card);
                    break;

                case MonsterCategory.Minibosses:
                    AddToArray <DirectorCard>(ref monsterSub, hold.card);
                    break;
                }
            }
            for (int i = 0; i < monsters.categories.Length; i++)
            {
                DirectorCardCategorySelection.Category cat = monsters.categories[i];
                switch (cat.name)
                {
                default:
                    Debug.Log(cat.name);
                    break;

                case "Champions":
                    cat.cards = monsterChamp;
                    break;

                case "Minibosses":
                    cat.cards = monsterSub;
                    break;

                case "Basic Monsters":
                    cat.cards = monsterBasic;
                    break;
                }
                monsters.categories[i] = cat;
            }
        }
Ejemplo n.º 20
0
 internal static void ForceFamilyEvent(On.RoR2.ClassicStageInfo.orig_RebuildCards orig, ClassicStageInfo self)
 {
     var originalVal = ClassicStageInfo.monsterFamilyChance;
     ClassicStageInfo.monsterFamilyChance = 1;
     orig(self);
     ClassicStageInfo.monsterFamilyChance = originalVal;
     On.RoR2.ClassicStageInfo.RebuildCards -= ForceFamilyEvent;
 }
Ejemplo n.º 21
0
        private static void ApplyInteractableChanges(ClassicStageInfo self, StageInfo stage)
        {
            var interactables     = self.GetFieldValue <DirectorCardCategorySelection>("interactableCategories");
            var interactableCards = new List <DirectorCardHolder>();

            foreach (var cat in interactables.categories)
            {
                MonsterCategory      monstCat = GetMonsterCategory(cat.name);
                InteractableCategory interCat = GetInteractableCategory(cat.name);
                foreach (var t in cat.cards)
                {
                    interactableCards.Add(new DirectorCardHolder {
                        InteractableCategory = interCat,
                        MonsterCategory      = monstCat,
                        Card = t
                    });
                }
            }
            InteractableActions?.Invoke(interactableCards, stage);
            var interChests  = new List <DirectorCard>();
            var interBarrels = new List <DirectorCard>();
            var interShrines = new List <DirectorCard>();
            var interDrones  = new List <DirectorCard>();
            var interMisc    = new List <DirectorCard>();
            var interRare    = new List <DirectorCard>();
            var interDupe    = new List <DirectorCard>();

            foreach (var hold in interactableCards)
            {
                switch (hold.InteractableCategory)
                {
                case InteractableCategory.None:
                    R2API.Logger.LogWarning("InteractableCategory from DirectorCardHolder is None !");
                    break;

                case InteractableCategory.Chests:
                    interChests.Add(hold.Card);
                    break;

                case InteractableCategory.Barrels:
                    interBarrels.Add(hold.Card);
                    break;

                case InteractableCategory.Drones:
                    interDrones.Add(hold.Card);
                    break;

                case InteractableCategory.Duplicator:
                    interDupe.Add(hold.Card);
                    break;

                case InteractableCategory.Misc:
                    interMisc.Add(hold.Card);
                    break;

                case InteractableCategory.Rare:
                    interRare.Add(hold.Card);
                    break;

                case InteractableCategory.Shrines:
                    interShrines.Add(hold.Card);
                    break;
                }
            }
            for (int i = 0; i < interactables.categories.Length; i++)
            {
                DirectorCardCategorySelection.Category cat = interactables.categories[i];
                switch (cat.name)
                {
                case "Chests":
                    cat.cards = interChests.ToArray();
                    break;

                case "Barrels":
                    cat.cards = interBarrels.ToArray();
                    break;

                case "Shrines":
                    cat.cards = interShrines.ToArray();
                    break;

                case "Drones":
                    cat.cards = interDrones.ToArray();
                    break;

                case "Misc":
                    cat.cards = interMisc.ToArray();
                    break;

                case "Rare":
                    cat.cards = interRare.ToArray();
                    break;

                case "Duplicator":
                    cat.cards = interDupe.ToArray();
                    break;
                }
                interactables.categories[i] = cat;
            }
        }
Ejemplo n.º 22
0
        public static void AddHooks()
        {
            // Ugh.
            On.RoR2.CharacterAI.BaseAI.OnBodyLost += (orig, self, body) =>
            {
                if (self.name.Equals("PlayerBot"))
                {
                    // Reset player bot state when body is lost so errors dont pop up
                    self.stateMachine.SetNextState(EntityStateCatalog.InstantiateState(self.scanState));
                    return;
                }
                orig(self, body);
            };

            // Random fix to make captains spawnable without errors in PlayerMode, theres probably a better way of doing this too
            On.RoR2.CaptainDefenseMatrixController.OnServerMasterSummonGlobal += (orig, self, summonReport) =>
            {
                if (self.GetFieldValue <CharacterBody>("characterBody") == null)
                {
                    return;
                }
                orig(self, summonReport);
            };

            // Maybe there is a better way to do this
            if (PlayerBotManager.ShowNameplates.Value && !PlayerBotManager.PlayerMode.Value)
            {
                IL.RoR2.TeamComponent.SetupIndicator += il =>
                {
                    ILCursor c = new ILCursor(il);
                    c.GotoNext(x => x.MatchCallvirt <CharacterBody>("get_isPlayerControlled"));
                    bool isPlayerBot = false;
                    c.EmitDelegate <Func <CharacterBody, CharacterBody> >(x =>
                    {
                        isPlayerBot = x.master.name.Equals("PlayerBot");
                        return(x);
                    }
                                                                          );
                    c.Index += 1;
                    c.EmitDelegate <Func <bool, bool> >(x =>
                    {
                        if (isPlayerBot)
                        {
                            return(true);
                        }
                        return(x);
                    }
                                                        );
                };
            }

            if (!PlayerBotManager.PlayerMode.Value && PlayerBotManager.AutoPurchaseItems.Value)
            {
                // Give bots money
                On.RoR2.TeamManager.GiveTeamMoney += (orig, self, teamIndex, money) =>
                {
                    orig(self, teamIndex, money);

                    if (PlayerBotManager.playerbots.Count > 0)
                    {
                        int num = Run.instance ? Run.instance.livingPlayerCount : 0;
                        if (num != 0)
                        {
                            money = (uint)Mathf.CeilToInt(money / (float)num);
                        }
                        foreach (GameObject playerbot in PlayerBotManager.playerbots)
                        {
                            if (!playerbot)
                            {
                                continue;
                            }
                            CharacterMaster master = playerbot.GetComponent <CharacterMaster>();
                            if (master && !master.IsDeadAndOutOfLivesServer() && master.teamIndex == teamIndex)
                            {
                                master.GiveMoney(money);
                            }
                        }
                    }
                };
            }

            if (PlayerBotManager.AutoPurchaseItems.Value)
            {
                On.RoR2.Run.BeginStage += (orig, self) =>
                {
                    foreach (GameObject playerbot in PlayerBotManager.playerbots.ToArray())
                    {
                        if (!playerbot)
                        {
                            PlayerBotManager.playerbots.Remove(playerbot);
                            continue;
                        }

                        ItemManager itemManager = playerbot.GetComponent <ItemManager>();
                        if (itemManager)
                        {
                            itemManager.ResetPurchases();
                            itemManager.master.money = 0;
                        }
                    }
                    orig(self);
                };
            }

            On.RoR2.Stage.Start += (orig, self) =>
            {
                orig(self);
                if (NetworkServer.active)
                {
                    if (PlayerBotManager.PlayerMode.Value)
                    {
                        foreach (GameObject playerbot in PlayerBotManager.playerbots.ToArray())
                        {
                            if (!playerbot)
                            {
                                PlayerBotManager.playerbots.Remove(playerbot);
                                continue;
                            }

                            CharacterMaster master = playerbot.GetComponent <CharacterMaster>();
                            if (master)
                            {
                                Stage.instance.RespawnCharacter(master);
                            }
                        }
                    }
                    // Spawn starting bots
                    if (Run.instance.stageClearCount == 0)
                    {
                        if (PlayerBotManager.InitialRandomBots.Value > 0)
                        {
                            PlayerBotManager.SpawnRandomPlayerbots(NetworkUser.readOnlyInstancesList[0].master, PlayerBotManager.InitialRandomBots.Value);
                        }
                        for (int randomSurvivorsIndex = 0; randomSurvivorsIndex < PlayerBotManager.InitialBots.Length; randomSurvivorsIndex++)
                        {
                            if (PlayerBotManager.InitialBots[randomSurvivorsIndex].Value > 0)
                            {
                                PlayerBotManager.SpawnPlayerbots(NetworkUser.readOnlyInstancesList[0].master, PlayerBotManager.RandomSurvivorsList[randomSurvivorsIndex], PlayerBotManager.InitialBots[randomSurvivorsIndex].Value);
                            }
                        }
                    }
                }
            };

            // Fix custom targets
            On.RoR2.CharacterAI.BaseAI.Target.GetBullseyePosition += Hook_GetBullseyePosition;

            if (PlayerBotManager.PlayerMode.Value)
            {
                On.RoR2.SceneDirector.PlaceTeleporter += (orig, self) =>
                {
                    if (PlayerBotManager.DontScaleInteractables.Value)
                    {
                        int              count     = PlayerCharacterMasterController.instances.Count((PlayerCharacterMasterController v) => v.networkUser);
                        float            num       = 0.5f + (float)count * 0.5f;
                        ClassicStageInfo component = SceneInfo.instance.GetComponent <ClassicStageInfo>();
                        int              credit    = (int)((float)component.sceneDirectorInteractibleCredits * num);
                        if (component.bonusInteractibleCreditObjects != null)
                        {
                            for (int i = 0; i < component.bonusInteractibleCreditObjects.Length; i++)
                            {
                                ClassicStageInfo.BonusInteractibleCreditObject bonusInteractibleCreditObject = component.bonusInteractibleCreditObjects[i];
                                if (bonusInteractibleCreditObject.objectThatGrantsPointsIfEnabled.activeSelf)
                                {
                                    credit += bonusInteractibleCreditObject.points;
                                }
                            }
                        }
                        self.interactableCredit = credit;
                    }
                    else if (Run.instance.stageClearCount == 0 && PlayerBotManager.GetInitialBotCount() > 0)
                    {
                        int count = PlayerCharacterMasterController.instances.Count((PlayerCharacterMasterController v) => v.networkUser);
                        count += PlayerBotManager.GetInitialBotCount();
                        float            num       = 0.5f + (float)count * 0.5f;
                        ClassicStageInfo component = SceneInfo.instance.GetComponent <ClassicStageInfo>();
                        int credit = (int)((float)component.sceneDirectorInteractibleCredits * num);
                        if (component.bonusInteractibleCreditObjects != null)
                        {
                            for (int i = 0; i < component.bonusInteractibleCreditObjects.Length; i++)
                            {
                                ClassicStageInfo.BonusInteractibleCreditObject bonusInteractibleCreditObject = component.bonusInteractibleCreditObjects[i];
                                if (bonusInteractibleCreditObject.objectThatGrantsPointsIfEnabled.activeSelf)
                                {
                                    credit += bonusInteractibleCreditObject.points;
                                }
                            }
                        }
                        self.interactableCredit = credit;
                    }

                    orig(self);
                };

                // Required for bots to even move, maybe switch to il later
                On.RoR2.PlayerCharacterMasterController.Update += (orig, self) =>
                {
                    if (self.name.Equals("PlayerBot"))
                    {
                        //self.InvokeMethod("SetBody", new object[] { self.master.GetBodyObject() });
                        return;
                    }
                    orig(self);
                };

                IL.RoR2.UI.AllyCardManager.PopulateCharacterDataSet += il =>
                {
                    ILCursor c = new ILCursor(il);
                    c.GotoNext(x => x.MatchCallvirt <CharacterMaster>("get_playerCharacterMasterController"));
                    c.Index += 2;
                    c.EmitDelegate <Func <bool, bool> >(x => false);
                };

                // Spectator fix
                On.RoR2.CameraRigController.CanUserSpectateBody += (orig, viewer, body) =>
                {
                    return(body.isPlayerControlled || orig(viewer, body));
                };

                // Dont end game on dying
                if (PlayerBotManager.ContinueAfterDeath.Value)
                {
                    IL.RoR2.Stage.FixedUpdate += il =>
                    {
                        ILCursor c = new ILCursor(il);
                        c.GotoNext(x => x.MatchCallvirt <PlayerCharacterMasterController>("get_isConnected"));
                        c.Index += 1;
                        c.EmitDelegate <Func <bool, bool> >(x => true);
                    };
                }
            }
        }
Ejemplo n.º 23
0
 private static void Awake_On(HooksCore.RoR2.ClassicStageInfo.Awake.Orig orig, ClassicStageInfo self)
 {
     if (loaded)
     {
         monsterEdits?.Invoke(self, Run.instance, self.monsterCategories);
         interactableEdits?.Invoke(self, Run.instance, self.interactableCategories);
         familyEdits?.Invoke(self, Run.instance, self.possibleMonsterFamilies);
         miscEdits?.Invoke(self, Run.instance);
     }
     orig(self);
 }
Ejemplo n.º 24
0
        public void Awake()
        {
            SurvivorDict.Add("commando", SurvivorIndex.Commando);
            SurvivorDict.Add("mult", SurvivorIndex.Toolbot);
            SurvivorDict.Add("mul-t", SurvivorIndex.Toolbot);
            SurvivorDict.Add("toolbot", SurvivorIndex.Toolbot);
            SurvivorDict.Add("hunt", SurvivorIndex.Huntress);
            SurvivorDict.Add("huntress", SurvivorIndex.Huntress);
            SurvivorDict.Add("engi", SurvivorIndex.Engi);
            SurvivorDict.Add("engineer", SurvivorIndex.Engi);
            SurvivorDict.Add("mage", SurvivorIndex.Mage);
            SurvivorDict.Add("arti", SurvivorIndex.Mage);
            SurvivorDict.Add("artificer", SurvivorIndex.Mage);
            SurvivorDict.Add("merc", SurvivorIndex.Merc);
            SurvivorDict.Add("mercenary", SurvivorIndex.Merc);
            SurvivorDict.Add("rex", SurvivorIndex.Treebot);
            SurvivorDict.Add("treebot", SurvivorIndex.Treebot);
            SurvivorDict.Add("loader", SurvivorIndex.Loader);
            SurvivorDict.Add("acrid", SurvivorIndex.Croco);
            SurvivorDict.Add("croco", SurvivorIndex.Croco);

            // Config
            InitialRandomBots = Config.Wrap("Starting Bots", "StartingBots.Random", "Starting amount of bots to spawn at the start of a run. (Random)", 0);
            for (int i = 0; i < RandomSurvivors.Length; i++)
            {
                string name = RandomSurvivors[i].ToString();
                InitialBots[i] = Config.Wrap("Starting Bots", "StartingBots." + name, "Starting amount of bots to spawn at the start of a run. (" + name + ")", 0);
            }

            AutoPurchaseItems       = Config.Wrap("Bot Inventory", "AutoPurchaseItems", "Maximum amount of purchases a playerbot can do per stage. Items are purchased directly instead of from chests. (Default: true)", true);
            MaxBotPurchasesPerStage = Config.Wrap("Bot Inventory", "MaxBotPurchasesPerStage", "Maximum amount of putchases a playerbot can do per stage. (Default: 8)", 8);
            Tier1ChestBotWeight     = Config.Wrap("Bot Inventory", "Tier1ChestBotWeight", "Weight of a bot picking an item from a small chest's loot table. (Default: 0.8)", 0.8f);
            Tier2ChestBotWeight     = Config.Wrap("Bot Inventory", "Tier2ChestBotWeight", "Weight of a bot picking an item from a large chest's loot table. (Default: 0.2)", 0.2f);
            Tier3ChestBotWeight     = Config.Wrap("Bot Inventory", "Tier3ChestBotWeight", "Weight of a bot picking an item from a legendary chest's loot table. (Default: 0)", 0f);
            Tier1ChestBotCost       = Config.Wrap("Bot Inventory", "Tier1ChestBotCost", "Base price of a small chest for the bot. (Default: 25)", 25);
            Tier2ChestBotCost       = Config.Wrap("Bot Inventory", "Tier2ChestBotCost", "Base price of a large chest for the bot. (Default: 50)", 50);
            Tier3ChestBotCost       = Config.Wrap("Bot Inventory", "Tier3ChestBotCost", "Base price of a legendary chest for the bot. (Default: 400)", 400);
            EquipmentBuyChance      = Config.Wrap("Bot Inventory", "EquipmentBuyChance", "Chance between 0 and 100 for a bot to buy from an equipment barrel instead of a tier 1 chest. Only active while the bot does not have a equipment item. (Default: 15)", 15);

            HostOnlySpawnBots = Config.Wrap("Misc", "HostOnlySpawnBots", "Set true so that only the host may spawn bots", true);
            ShowNameplates    = Config.Wrap("Misc", "ShowNameplates", "Show player nameplates on playerbots if SpawnAsPlayers == false. (Host only)", true);

            PlayerMode             = Config.Wrap("Experimental", "SpawnAsPlayers", "Makes the game treat playerbots like how regular players are treated. The bots now show up on the scoreboard, can pick up items, influence the map scaling, etc.", false);
            TpFix                  = Config.Wrap("Player Mode", "Teleport Fix", "Fixes long teleporter charging times by making the bots count towards the charging timer. Only active is PlayerMode is true.", true);
            DontScaleInteractables = Config.Wrap("Player Mode", "DontScaleInteractables", "Prevents interactables spawn count from scaling with bots. Only active is PlayerMode is true.", false);

            R2API.Utils.CommandHelper.AddToConsoleWhenReady();

            // Ugh.
            On.RoR2.CharacterAI.BaseAI.OnBodyLost += (orig, self, body) =>
            {
                if (self.name.Equals("PlayerBot"))
                {
                    return;
                }
                orig(self, body);
            };

            // Maybe there is a better way to do this
            if (ShowNameplates.Value && !PlayerMode.Value)
            {
                IL.RoR2.TeamComponent.SetupIndicator += il =>
                {
                    ILCursor c = new ILCursor(il);
                    c.GotoNext(x => x.MatchCallvirt <CharacterBody>("get_isPlayerControlled"));
                    bool isPlayerBot = false;
                    c.EmitDelegate <Func <CharacterBody, CharacterBody> >(x =>
                    {
                        isPlayerBot = x.master.name.Equals("PlayerBot");
                        return(x);
                    }
                                                                          );
                    c.Index += 1;
                    c.EmitDelegate <Func <bool, bool> >(x =>
                    {
                        if (isPlayerBot)
                        {
                            return(true);
                        }
                        return(x);
                    }
                                                        );
                };
            }

            if (!PlayerMode.Value && AutoPurchaseItems.Value)
            {
                // Give bots money
                On.RoR2.TeamManager.GiveTeamMoney += (orig, self, teamIndex, money) =>
                {
                    orig(self, teamIndex, money);

                    if (playerbots.Count > 0)
                    {
                        int num = Run.instance ? Run.instance.livingPlayerCount : 0;
                        if (num != 0)
                        {
                            money = (uint)Mathf.CeilToInt(money / (float)num);
                        }
                        foreach (GameObject playerbot in playerbots)
                        {
                            if (!playerbot)
                            {
                                continue;
                            }
                            CharacterMaster master = playerbot.GetComponent <CharacterMaster>();
                            if (master && master.alive && master.teamIndex == teamIndex)
                            {
                                master.GiveMoney(money);
                            }
                        }
                    }
                };
            }

            if (AutoPurchaseItems.Value)
            {
                On.RoR2.Run.BeginStage += (orig, self) =>
                {
                    foreach (GameObject playerbot in playerbots.ToArray())
                    {
                        if (!playerbot)
                        {
                            playerbots.Remove(playerbot);
                            continue;
                        }

                        ItemManager itemManager = playerbot.GetComponent <ItemManager>();
                        if (itemManager)
                        {
                            itemManager.ResetPurchases();
                            itemManager.master.money = 0;
                        }
                    }
                    orig(self);
                };
            }

            if (PlayerMode.Value && TpFix.Value)
            {
                On.RoR2.TeleporterInteraction.GetPlayerCountInRadius += (orig, self) =>
                {
                    Vector3 position = self.gameObject.transform.position;
                    float   num2     = self.clearRadius * self.clearRadius;
                    return(PlayerCharacterMasterController.instances.Count((PlayerCharacterMasterController c) => c.master.alive && (c.master.GetBody().transform.position - position).sqrMagnitude <= num2));
                };
            }

            On.RoR2.Stage.Start += (orig, self) =>
            {
                orig(self);
                if (NetworkServer.active)
                {
                    if (PlayerMode.Value)
                    {
                        foreach (GameObject playerbot in playerbots.ToArray())
                        {
                            if (!playerbot)
                            {
                                playerbots.Remove(playerbot);
                                continue;
                            }

                            CharacterMaster master = playerbot.GetComponent <CharacterMaster>();
                            if (master)
                            {
                                Stage.instance.RespawnCharacter(master);
                            }
                        }
                    }
                    // Spawn starting bots
                    if (Run.instance.stageClearCount == 0)
                    {
                        if (InitialRandomBots.Value > 0)
                        {
                            SpawnRandomPlayerbots(NetworkUser.readOnlyInstancesList[0].master, InitialRandomBots.Value);
                        }
                        for (int randomSurvivorsIndex = 0; randomSurvivorsIndex < InitialBots.Length; randomSurvivorsIndex++)
                        {
                            if (InitialBots[randomSurvivorsIndex].Value > 0)
                            {
                                SpawnPlayerbots(NetworkUser.readOnlyInstancesList[0].master, RandomSurvivors[randomSurvivorsIndex], InitialBots[randomSurvivorsIndex].Value);
                            }
                        }
                    }
                }
            };

            if (PlayerMode.Value)
            {
                On.RoR2.SceneDirector.PlaceTeleporter += (orig, self) =>
                {
                    if (DontScaleInteractables.Value)
                    {
                        int              count     = PlayerCharacterMasterController.instances.Count((PlayerCharacterMasterController v) => v.networkUser);
                        float            num       = 0.5f + (float)count * 0.5f;
                        ClassicStageInfo component = SceneInfo.instance.GetComponent <ClassicStageInfo>();
                        self.SetFieldValue("interactableCredit", (int)((float)component.sceneDirectorInteractibleCredits * num));
                    }
                    else if (Run.instance.stageClearCount == 0 && GetInitialBotCount() > 0)
                    {
                        int count = PlayerCharacterMasterController.instances.Count((PlayerCharacterMasterController v) => v.networkUser);
                        count += GetInitialBotCount();
                        float            num       = 0.5f + (float)count * 0.5f;
                        ClassicStageInfo component = SceneInfo.instance.GetComponent <ClassicStageInfo>();
                        self.SetFieldValue("interactableCredit", (int)((float)component.sceneDirectorInteractibleCredits * num));
                    }

                    orig(self);
                };

                IL.RoR2.UI.AllyCardManager.PopulateCharacterDataSet += il =>
                {
                    ILCursor c = new ILCursor(il);
                    c.GotoNext(x => x.MatchCallvirt <CharacterMaster>("get_playerCharacterMasterController"));
                    c.Index += 2;
                    c.EmitDelegate <Func <bool, bool> >(x => false);
                };
            }
        }
Ejemplo n.º 25
0
        private static void ApplyInteractableChanges(ClassicStageInfo self, StageInfo stage)
        {
            var interactables = self.GetFieldValue <DirectorCardCategorySelection>("interactableCategories");
            List <DirectorCardHolder> interactableCards = new List <DirectorCardHolder>();

            for (int i = 0; i < interactables.categories.Length; i++)
            {
                DirectorCardCategorySelection.Category cat = interactables.categories[i];
                MonsterCategory      monstCat = GetMonsterCategory(cat.name);
                InteractableCategory interCat = GetInteractableCategory(cat.name);
                for (int j = 0; j < cat.cards.Length; j++)
                {
                    interactableCards.Add(new DirectorCardHolder
                    {
                        interactableCategory = interCat,
                        monsterCategory      = monstCat,
                        card = cat.cards[j]
                    });
                }
            }

            interactableActions?.Invoke(interactableCards, stage);

            DirectorCard[] interChests  = new DirectorCard[0];
            DirectorCard[] interBarrels = new DirectorCard[0];
            DirectorCard[] interShrines = new DirectorCard[0];
            DirectorCard[] interDrones  = new DirectorCard[0];
            DirectorCard[] interMisc    = new DirectorCard[0];
            DirectorCard[] interRare    = new DirectorCard[0];
            DirectorCard[] interDupe    = new DirectorCard[0];

            for (int i = 0; i < interactableCards.Count; i++)
            {
                DirectorCardHolder hold = interactableCards[i];
                switch (hold.interactableCategory)
                {
                default:
                    Debug.Log("Wtf are you doing...");
                    break;

                case InteractableCategory.Chests:
                    AddToArray <DirectorCard>(ref interChests, hold.card);
                    break;

                case InteractableCategory.Barrels:
                    AddToArray <DirectorCard>(ref interBarrels, hold.card);
                    break;

                case InteractableCategory.Drones:
                    AddToArray <DirectorCard>(ref interDrones, hold.card);
                    break;

                case InteractableCategory.Duplicator:
                    AddToArray <DirectorCard>(ref interDupe, hold.card);
                    break;

                case InteractableCategory.Misc:
                    AddToArray <DirectorCard>(ref interMisc, hold.card);
                    break;

                case InteractableCategory.Rare:
                    AddToArray <DirectorCard>(ref interRare, hold.card);
                    break;

                case InteractableCategory.Shrines:
                    AddToArray <DirectorCard>(ref interShrines, hold.card);
                    break;
                }
            }
            for (int i = 0; i < interactables.categories.Length; i++)
            {
                DirectorCardCategorySelection.Category cat = interactables.categories[i];
                switch (cat.name)
                {
                default:
                    Debug.Log(cat.name);
                    break;

                case "Chests":
                    cat.cards = interChests;
                    break;

                case "Barrels":
                    cat.cards = interBarrels;
                    break;

                case "Shrines":
                    cat.cards = interShrines;
                    break;

                case "Drones":
                    cat.cards = interDrones;
                    break;

                case "Misc":
                    cat.cards = interMisc;
                    break;

                case "Rare":
                    cat.cards = interRare;
                    break;

                case "Duplicator":
                    cat.cards = interDupe;
                    break;
                }
                interactables.categories[i] = cat;
            }
        }
Ejemplo n.º 26
0
        private static StageInfo GetStage(ClassicStageInfo stage)
        {
            StageInfo stageInfo = new StageInfo
            {
                stage           = Stage.Custom,
                customStageName = "",
            };
            SceneInfo info = stage.GetComponent <SceneInfo>();

            if (!info)
            {
                return(stageInfo);
            }
            SceneDef scene = info.sceneDef;

            if (!scene)
            {
                return(stageInfo);
            }

            switch (scene.sceneName)
            {
            case "golemplains":
                stageInfo.stage = Stage.TitanicPlains;
                break;

            case "blackbeach":
                stageInfo.stage = Stage.DistantRoost;
                break;

            case "goolake":
                stageInfo.stage = Stage.AbandonedAqueduct;
                break;

            case "foggyswamp":
                stageInfo.stage = Stage.WetlandAspect;
                break;

            case "frozenwall":
                stageInfo.stage = Stage.RallypointDelta;
                break;

            case "wispgraveyard":
                stageInfo.stage = Stage.ScorchedAcres;
                break;

            case "dampcavesimple":
                stageInfo.stage = Stage.AbyssalDepths;
                break;

            case "shipgraveyard":
                stageInfo.stage = Stage.SirensCall;
                break;

            case "goldshores":
                stageInfo.stage = Stage.GildedCoast;
                break;

            default:
                stageInfo.stage           = Stage.Custom;
                stageInfo.customStageName = scene.sceneName;
                break;
            }
            return(stageInfo);
        }
Ejemplo n.º 27
0
        private void ClassicStageInfo_Awake(On.RoR2.ClassicStageInfo.orig_Awake orig, ClassicStageInfo self)
        {
            var longTotal     = 0UL;
            var longLongTotal = 0UL;

            stageSorted.Clear();
            totalSorted.Clear();
            for (Int32 i = 0; i < hooks.Count; ++i)
            {
                var v = hooks[i];
                v.Gather();
                longTotal     += v.stageTime / Main.profilerLongDivisor;
                longLongTotal += v.longTime / Main.profilerLongDivisor;
                stageSorted.Add(v);
                totalSorted.Add(v);
                if (!history.ContainsKey(v.name))
                {
                    history[v.name] = new Histogram(v.name);
                }
                history[v.name].AddTime(v.stageTime);
            }


            stageSorted.OrderByDescending <ILHookProfile, UInt64>((prof) => prof.stageTime);
            totalSorted.OrderByDescending <ILHookProfile, UInt64>((prof) => prof.longTime);

            for (Int32 i = 0; i < Main.numToLog; ++i)
            {
                var v    = stageSorted[i];
                var val  = v.stageTime;
                var perc = (Double)(v.stageTime / Main.profilerLongDivisor) / (Double)longTotal;
                Main.LogW(v.name + String.Format(":::Time {0}:::Percent {1}", val, perc));
            }
            for (Int32 i = 0; i < Main.numToLog; ++i)
            {
                var v    = totalSorted[i];
                var val  = v.longTime;
                var perc = (Double)(v.longTime / Main.profilerLongDivisor) / (Double)longLongTotal;
                Main.LogE(v.name + String.Format(":::Time {0}:::Percent {1}", val, perc));
            }


            orig(self);
        }
Ejemplo n.º 28
0
 private static void ApplyChangesOnStart(On.RoR2.ClassicStageInfo.orig_Start orig, ClassicStageInfo classicStageInfo)
 {
     classicStageInfo.PortToNewSystem();
     classicStageInfo.ApplyChanges();
     orig(classicStageInfo);
 }
Ejemplo n.º 29
0
        private static StageInfo GetStageInfo(ClassicStageInfo stage)
        {
            StageInfo stageInfo = new StageInfo
            {
                stage           = Stage.Custom,
                CustomStageName = "",
            };
            var info = stage.GetComponent <SceneInfo>();

            if (!info)
            {
                return(stageInfo);
            }
            var scene = info.sceneDef;

            if (!scene)
            {
                return(stageInfo);
            }
            switch (scene.baseSceneName)
            {
            case "golemplains":
                stageInfo.stage = Stage.TitanicPlains;
                break;

            case "blackbeach":
                stageInfo.stage = Stage.DistantRoost;
                break;

            case "goolake":
                stageInfo.stage = Stage.AbandonedAqueduct;
                break;

            case "foggyswamp":
                stageInfo.stage = Stage.WetlandAspect;
                break;

            case "frozenwall":
                stageInfo.stage = Stage.RallypointDelta;
                break;

            case "wispgraveyard":
                stageInfo.stage = Stage.ScorchedAcres;
                break;

            case "dampcavesimple":
                stageInfo.stage = Stage.AbyssalDepths;
                break;

            case "shipgraveyard":
                stageInfo.stage = Stage.SirensCall;
                break;

            case "goldshores":
                stageInfo.stage = Stage.GildedCoast;
                break;

            case "arena":
                stageInfo.stage = Stage.VoidCell;
                break;

            case "limbo":
                stageInfo.stage = Stage.MomentWhole;
                break;

            case "skymeadow":
                stageInfo.stage = Stage.SkyMeadow;
                break;

            case "artifactworld":
                stageInfo.stage = Stage.ArtifactReliquary;
                break;

            default:
                stageInfo.stage           = Stage.Custom;
                stageInfo.CustomStageName = scene.baseSceneName;
                break;
            }
            return(stageInfo);
        }
Ejemplo n.º 30
0
 private static void OnStageInfoAwake(On.RoR2.ClassicStageInfo.orig_Awake orig, ClassicStageInfo self)
 {
     self.ApplyChanges();
     orig(self);
 }