Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LoopVariantConfig v1.0.3
VariantConfig.dll
Decompiled 5 months agousing System; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HG; using IL.RoR2; using Mono.Cecil.Cil; using MonoMod.Cil; using On.RoR2; using RiskOfOptions; using RiskOfOptions.Options; using RoR2; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("VariantConfig")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+b4e36a2994d14295e7503284f061d2c3ba78aea1")] [assembly: AssemblyProduct("VariantConfig")] [assembly: AssemblyTitle("VariantConfig")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace VariantConfig; public static class WConfig { public static ConfigFile ConfigFileSTAGES = new ConfigFile(Paths.ConfigPath + "\\Wolfo.LoopVariantConfig.cfg", true); public static ConfigEntry<bool> Preset; public static ConfigEntry<bool> LakesNightSpawnPool; public static ConfigEntry<bool> VillageNight_Credits; public static ConfigEntry<float> Chance_PreLoop; public static ConfigEntry<float> Chance_Loop; public static ConfigEntry<float> Chance_Loop_2; public static ConfigEntry<bool> Alternate_Chances; public static void InitConfig() { Preset = ConfigFileSTAGES.Bind<bool>("Preset", "Simple 50/50 pre/post loop", false, "Sets chance config values to 50/50 or 0/100"); Preset.SettingChanged += Preset_SettingChanged; Chance_PreLoop = ConfigFileSTAGES.Bind<float>("Config", "Chance pre-loop", 0f, "% Chance for a loop weather to happen pre-loop\n(Stages 1 - 5)"); Chance_Loop = ConfigFileSTAGES.Bind<float>("Config", "Chance post-loop", 100f, "% Chance for a loop weather to happen loop 1\n(Stages 6 - 10)"); Chance_Loop_2 = ConfigFileSTAGES.Bind<float>("Config", "Chance consecutive-loops", 100f, "% Chance for a loop weather to happen loop 2+\n(Stage 11+)\n-1 will just use loop 1 Chance instead"); Alternate_Chances = ConfigFileSTAGES.Bind<bool>("Config", "Alternate Chances between loops", false, "Weather sets alternate between loops.\nGo standard, loop, standard, loop.\nIgnores consecutive loop setting."); LakesNightSpawnPool = ConfigFileSTAGES.Bind<bool>("Stage 1 Loop Variants", "Friendlier spawnpools", true, "Change Viscious Falls & Disturbed Impact to be more Stage 1 friendly.\n\nViscious Fall content now Loop Exclusive\nImp Overlord\nGrovetender\nHalcyonite\nVoid Reaver\nElder Lemurian\nVoid Seed\n\nDisturbed Impact content now Loop Exclusive\nGrovetender"); VillageNight_Credits = ConfigFileSTAGES.Bind<bool>("Stage 1 Loop Variants", "Credits Nerfs", true, "Nerf Disturbed Impact Credits to 280 - 30(flat), if it's Stage 1\nDisturbed Impact has 310 Credits and a guaranteed Large Chest.\n\nThis would make it the best stage 1 by far if not changed."); } private static void Preset_SettingChanged(object sender, EventArgs e) { if (Preset.Value) { Chance_PreLoop.Value = 50f; Chance_Loop.Value = 50f; Chance_Loop_2.Value = -1f; } if (!Preset.Value) { Chance_PreLoop.Value = 0f; Chance_Loop.Value = 100f; Chance_Loop_2.Value = -1f; } } public static void RiskConfig() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown ModSettingsManager.SetModDescription("Config for when Loop Variants happen"); Texture2D val = Addressables.LoadAssetAsync<Texture2D>((object)"RoR2/DLC2/lakesnight/texLakesNightPreview.png").WaitForCompletion(); ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(-0.5f, -0.5f))); ConfigEntryBase[] configEntries = ConfigFileSTAGES.GetConfigEntries(); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Preset)); ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(Chance_PreLoop)); ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(Chance_Loop)); ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(Chance_Loop_2)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Alternate_Chances)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(LakesNightSpawnPool, true)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(VillageNight_Credits)); } } public class OfficialVariant { public static void Awake() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown Run.PickNextStageScene += new hook_PickNextStageScene(Teleporter_PickLoopVariant); SceneExitController.GetLoopedStageOrDefault += new hook_GetLoopedStageOrDefault(GreenPortal_PickLoopVariant); BazaarController.IsUnlockedBeforeLooping += new hook_IsUnlockedBeforeLooping(SeerStationVariants); } public static SceneDef VariantToPreLoop(SceneDef loopedScene) { for (int i = 0; i < SceneCatalog._stageSceneDefs.Length; i++) { if ((Object)(object)SceneCatalog._stageSceneDefs[i].loopedSceneDef == (Object)(object)loopedScene) { return SceneCatalog._stageSceneDefs[i]; } } return null; } public static bool SeerStationVariants(orig_IsUnlockedBeforeLooping orig, BazaarController self, SceneDef sceneDef) { if ((Object)(object)sceneDef.loopedSceneDef != (Object)null) { return !SyncLoopWeather.instance.NextStage_LoopVariant; } if (sceneDef.isLockedBeforeLooping) { return SyncLoopWeather.instance.NextStage_LoopVariant; } return orig.Invoke(self, sceneDef); } public static void Teleporter_PickLoopVariant(orig_PickNextStageScene orig, Run self, WeightedSelection<SceneDef> choices) { orig.Invoke(self, choices); if (!Object.op_Implicit((Object)(object)self.nextStageScene)) { return; } if (SyncLoopWeather.instance.NextStage_LoopVariant) { if ((Object)(object)self.nextStageScene.loopedSceneDef != (Object)null && self.CanPickStage(self.nextStageScene.loopedSceneDef)) { self.nextStageScene = self.nextStageScene.loopedSceneDef; } } else if (self.nextStageScene.isLockedBeforeLooping) { SceneDef val = VariantToPreLoop(self.nextStageScene); if ((Object)(object)val != (Object)null) { self.nextStageScene = val; } } } public static SceneDef GreenPortal_PickLoopVariant(orig_GetLoopedStageOrDefault orig, SceneExitController self, SceneDef sceneDef) { SceneDef val = null; if (Object.op_Implicit((Object)(object)sceneDef.loopedSceneDef) && SyncLoopWeather.instance.NextStage_LoopVariant) { val = sceneDef.loopedSceneDef; } else if (sceneDef.isLockedBeforeLooping) { val = VariantToPreLoop(sceneDef); } if ((Object)(object)val != (Object)null) { return val; } return sceneDef; } } public class Stage1_Changes { public static void EditDccs() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (WConfig.LakesNightSpawnPool.Value) { DirectorCardCategorySelection val = Addressables.LoadAssetAsync<DirectorCardCategorySelection>((object)"RoR2/DLC2/lakesnight/dccsLakesnightMonsters.asset").WaitForCompletion(); DirectorCardCategorySelection val2 = Addressables.LoadAssetAsync<DirectorCardCategorySelection>((object)"RoR2/DLC2/lakesnight/dccsLakesnightInteractables_DLC1.asset").WaitForCompletion(); DirectorCardCategorySelection val3 = Addressables.LoadAssetAsync<DirectorCardCategorySelection>((object)"2751f6d6bca27a44a9e45d87c5bbee1c").WaitForCompletion(); DirectorCardCategorySelection val4 = Addressables.LoadAssetAsync<DirectorCardCategorySelection>((object)"RoR2/DLC2/villagenight/dccsVillageNightMonsters_Additional.asset").WaitForCompletion(); val.categories[0].cards[2].minimumStageCompletions = 2; val.categories[0].cards[4].minimumStageCompletions = 2; val.categories[0].cards[5].minimumStageCompletions = 2; val.categories[1].cards[2].minimumStageCompletions = 2; val.categories[1].cards[3].minimumStageCompletions = 4; val2.categories[0].cards[0].minimumStageCompletions = 1; val4.categories[0].cards[1].minimumStageCompletions = 1; } } public static void OfficialVariantStage1Friendly(DirectorCardCategorySelection dccs) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) string baseSceneName = SceneInfo.instance.sceneDef.baseSceneName; string text = baseSceneName; if (!(text == "lakesnight")) { if (text == "villagenight" && WConfig.VillageNight_Credits.Value && Run.instance.stageClearCount == 0) { ClassicStageInfo.instance.sceneDirectorInteractibleCredits = 280; ref BonusInteractibleCreditObject[] bonusInteractibleCreditObjects = ref ClassicStageInfo.instance.bonusInteractibleCreditObjects; BonusInteractibleCreditObject val = new BonusInteractibleCreditObject { points = -10, objectThatGrantsPointsIfEnabled = ((Component)Run.instance).gameObject }; ArrayUtils.ArrayAppend<BonusInteractibleCreditObject>(ref bonusInteractibleCreditObjects, ref val); } } else if (WConfig.LakesNightSpawnPool.Value) { LakesNight_AddStage1FriendlyMonsters(dccs); } } public static void LakesNight_AddStage1FriendlyMonsters(DirectorCardCategorySelection dccs) { if (!((Object)(object)dccs == (Object)null)) { } } } [BepInPlugin("Wolfo.LoopVariantConfig", "LoopVariantConfig", "1.5.1")] public class VariantConfig : BaseUnityPlugin { public class SendSyncLoopWeather : ChatMessageBase { public bool CURRENT; public bool NEXT; public bool HostPing = false; public override string ConstructChatString() { if (!NetworkServer.active) { SyncLoopWeather.instance.Next_Host = NEXT; SyncLoopWeather.instance.Current_Host = CURRENT; Debug.Log((object)("Current Stage Loop Variant : " + (object)SyncLoopWeather.instance)); Debug.Log((object)("Next Stage Loop Variant : " + (object)SyncLoopWeather.instance)); if (SyncLoopWeather.instance.CurrentStage_LoopVariant) { Action<SyncLoopWeather> applyWeatherVisuals = VariantConfig.applyWeatherVisuals; if (applyWeatherVisuals != null) { applyWeatherVisuals(SyncLoopWeather.instance); } else { Debug.Log((object)"applyWeatherVisuals action Null"); } } } return null; } public override void Serialize(NetworkWriter writer) { ((ChatMessageBase)this).Serialize(writer); writer.Write(HostPing); writer.Write(CURRENT); writer.Write(NEXT); } public override void Deserialize(NetworkReader reader) { ((ChatMessageBase)this).Deserialize(reader); HostPing = reader.ReadBoolean(); if (HostPing) { HostHasMod = true; return; } CURRENT = reader.ReadBoolean(); NEXT = reader.ReadBoolean(); } } public static bool HostHasMod_; public static bool HostHasMod { get { return HostHasMod_ || NetworkServer.active; } set { HostHasMod_ = value; } } public static event Action<SyncLoopWeather> applyWeatherVisuals; public static event Action<DirectorCardCategorySelection> applyWeatherDCCS; public void Start() { WConfig.RiskConfig(); } public void Awake() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown WConfig.InitConfig(); OfficialVariant.Awake(); Run.Awake += new hook_Awake(AskHostIfHasMod); Run.Start += new hook_Start(AddRoll_StartOfRun); Stage.Start += new hook_Start(Global_RollForNextStage); ClassicStageInfo.RebuildCards += new Manipulator(ApplyVariantDCCSChanges); ChatMessageBase.chatMessageTypeToIndex.Add(typeof(SendSyncLoopWeather), (byte)ChatMessageBase.chatMessageIndexToType.Count); ChatMessageBase.chatMessageIndexToType.Add(typeof(SendSyncLoopWeather)); Stage1_Changes.EditDccs(); applyWeatherDCCS += Stage1_Changes.OfficialVariantStage1Friendly; } private IEnumerator Global_RollForNextStage(orig_Start orig, Stage self) { IEnumerator result = orig.Invoke(self); SyncLoopWeather.instance.nameTokenOverride = string.Empty; SyncLoopWeather.instance.AppliedToCurrentStage = false; SyncLoopWeather.instance.RollForLoopWeather(runStart: false); if ((!HostHasMod || NetworkServer.active) && SyncLoopWeather.instance.CurrentStage_LoopVariant) { VariantConfig.applyWeatherVisuals?.Invoke(SyncLoopWeather.instance); } return result; } private void AskHostIfHasMod(orig_Awake orig, Run self) { orig.Invoke(self); if (NetworkServer.active) { Chat.SendBroadcastChat((ChatMessageBase)(object)new SendSyncLoopWeather { HostPing = true }); } } private void AddRoll_StartOfRun(orig_Start orig, Run self) { SyncLoopWeather.instance.RollForLoopWeather(runStart: true); orig.Invoke(self); } private void ApplyVariantDCCSChanges(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchStfld(x, "RoR2.ClassicStageInfo", "modifiableMonsterCategories") })) { val.EmitDelegate<Func<DirectorCardCategorySelection, DirectorCardCategorySelection>>((Func<DirectorCardCategorySelection, DirectorCardCategorySelection>)delegate(DirectorCardCategorySelection dccs) { if (SyncLoopWeather.instance.NextStage_LoopVariant && ShouldAddLoopEnemies(dccs)) { Action<DirectorCardCategorySelection> action = VariantConfig.applyWeatherDCCS; if (action != null) { action(dccs); } else { Debug.Log((object)"applyWeatherDCCS action Null"); } } return dccs; }); } else { Debug.LogWarning((object)"IL Failed: AddVariantExclusiveMonsters"); } } public static bool ShouldAddLoopEnemies(DirectorCardCategorySelection dccs) { if ((Object)(object)dccs == (Object)null) { return false; } if (Object.op_Implicit((Object)(object)RunArtifactManager.instance) && RunArtifactManager.instance.IsArtifactEnabled(Artifacts.mixEnemyArtifactDef)) { return false; } if (Object.op_Implicit((Object)(object)dccs) && dccs is FamilyDirectorCardCategorySelection) { return false; } return true; } } public class SyncLoopWeather : MonoBehaviour { public static SyncLoopWeather _instance; public bool AppliedToCurrentStage; public string nameTokenOverride; public string descTokenOverride; public bool Next_Client; public bool Next_Host; public bool Current_Client; public bool Current_Host; public static int loopClearCountPlusOne { get { if (!Object.op_Implicit((Object)(object)Run.instance)) { return 0; } return (Run.instance.stageClearCount + 1) / 5; } } public static SyncLoopWeather instance { get { if ((Object)(object)_instance == (Object)null) { _instance = ((Component)Run.instance).gameObject.AddComponent<SyncLoopWeather>(); } return _instance; } } public static bool RandomStageOrder { get { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 if (!Object.op_Implicit((Object)(object)Run.instance)) { return false; } return (int)Run.instance.ruleBook.stageOrder == 1; } } public bool CurrentStage_LoopVariant { get { if (VariantConfig.HostHasMod) { return Current_Host; } return Current_Client; } } public bool NextStage_LoopVariant { get { if (VariantConfig.HostHasMod) { return Next_Host; } return Next_Client; } set { if (NetworkServer.active) { Current_Host = Next_Host; Next_Host = value; } Current_Client = Next_Client; Next_Client = value; } } public void RollForLoopWeather(bool runStart) { bool flag = false; bool flag2 = false; if (RandomStageOrder) { flag = Util.CheckRoll(50f, (CharacterMaster)null); } else if (WConfig.Alternate_Chances.Value) { if (loopClearCountPlusOne % 2 == 1) { flag = true; } } else if (loopClearCountPlusOne > 1 && WConfig.Chance_Loop_2.Value != -1f) { flag2 = true; } else { flag = loopClearCountPlusOne > 0; } if (flag2) { NextStage_LoopVariant = Util.CheckRoll(WConfig.Chance_Loop_2.Value, (CharacterMaster)null); } else if (flag) { NextStage_LoopVariant = Util.CheckRoll(WConfig.Chance_Loop.Value, (CharacterMaster)null); } else { NextStage_LoopVariant = Util.CheckRoll(WConfig.Chance_PreLoop.Value, (CharacterMaster)null); } if (NetworkServer.active) { Chat.SendBroadcastChat((ChatMessageBase)(object)new VariantConfig.SendSyncLoopWeather { NEXT = Next_Host, CURRENT = Current_Host }); if (runStart) { Debug.Log((object)("Stage 1 | Loop Variant : " + NextStage_LoopVariant)); return; } Debug.Log((object)("Current Stage | Loop Variant : " + CurrentStage_LoopVariant)); Debug.Log((object)(" Next Stage | Loop Variant : " + NextStage_LoopVariant)); } } public void Awake() { _instance = this; } }