Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of LoopVariantConfig v1.0.2
VariantConfig.dll
Decompiled 2 weeks 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 (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_00a3: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)("Loop Variant DCCS : " + SceneCatalog.mostRecentSceneDef.baseSceneName)); 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 = -20, 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.0")] public class VariantConfig : BaseUnityPlugin { public class HostHasModAlert : ChatMessageBase { public override string ConstructChatString() { if (!HostHasMod) { Debug.Log((object)"LoopWeather | Host has mod"); } HostHasMod = true; return null; } } public class SendSyncLoopWeather : ChatMessageBase { public bool CURRENT; public bool NEXT; public event Action<bool> onHostLoopChoice; 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(CURRENT); writer.Write(NEXT); } public override void Deserialize(NetworkReader reader) { ((ChatMessageBase)this).Deserialize(reader); 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)); ChatMessageBase.chatMessageTypeToIndex.Add(typeof(HostHasModAlert), (byte)ChatMessageBase.chatMessageIndexToType.Count); ChatMessageBase.chatMessageIndexToType.Add(typeof(HostHasModAlert)); 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) { Action<SyncLoopWeather> action = VariantConfig.applyWeatherVisuals; if (action != null) { action(SyncLoopWeather.instance); } else { Debug.Log((object)"applyWeatherVisuals action Null"); } } return result; } private void AskHostIfHasMod(orig_Awake orig, Run self) { orig.Invoke(self); if (NetworkServer.active) { Chat.SendBroadcastChat((ChatMessageBase)(object)new HostHasModAlert()); } } 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; } }