Decompiled source of LoopVariantConfig v1.0.1

VariantConfig.dll

Decompiled 2 weeks ago
using 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+a6edeca9ec4c9ba06b811404335a2dd1a5de98e3")]
[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) / Run.stagesPerLoop;
		}
	}

	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;
	}
}