using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using DiskCardGame; using GBC; using HarmonyLib; using InscryptionAPI.Ascension; using InscryptionAPI.Helpers; using InscryptionAPI.Slots; using OLD_SA.Dialogue; using OLD_SA.Incorporal; using OLD_SA.Random; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("OldSa_Challenge")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("OldSa_Challenge")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("7bddb5c6-b65b-44d7-8bf7-754e15af94f3")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace OldSa_Challenge; [HarmonyPatch(typeof(AscensionSaveData), "NewRun")] public static class BadThingsChallengePatch { private const string BrokenPeltName = "OLD_SA_BROKEN_PELT"; [HarmonyPrefix] private static void Prefix(List starterDeck) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!SaveFile.IsAscension || starterDeck == null || starterDeck.Count == 0) { return; } int numChallengesOfTypeActive = AscensionSaveData.Data.GetNumChallengesOfTypeActive(ChallengeRegistry.BadThingsChallengeType); if (numChallengesOfTypeActive <= 0) { return; } CardInfo cardByName = CardLoader.GetCardByName("OLD_SA_BROKEN_PELT"); if ((Object)(object)cardByName == (Object)null) { Plugin.Log.LogError((object)"[OldSa Challenge] Bad Things: Could not find card: OLD_SA_BROKEN_PELT"); return; } List list = starterDeck.Where((CardInfo card) => (Object)(object)card != (Object)null && !card.HasTrait((Trait)13) && ((Object)card).name != "OLD_SA_BROKEN_PELT").ToList(); if (list.Count == 0) { Plugin.Log.LogWarning((object)"[OldSa Challenge] Bad Things: No valid starter cards found."); return; } int num = Math.Min(numChallengesOfTypeActive, list.Count); for (int num2 = 0; num2 < num; num2++) { int index = Random.Range(0, list.Count); CardInfo val = list[index]; if (!((Object)(object)val == (Object)null)) { int num3 = starterDeck.IndexOf(val); if (num3 >= 0) { starterDeck[num3] = cardByName; list.RemoveAt(index); Plugin.Log.LogInfo((object)("[OldSa Challenge] Bad Things: Replaced starter card " + (num2 + 1) + "/" + num + " (" + ((Object)val).name + ") with OLD_SA_BROKEN_PELT")); } } } if (numChallengesOfTypeActive > num) { Plugin.Log.LogWarning((object)("[OldSa Challenge] Bad Things: Challenge activated " + numChallengesOfTypeActive + " times, but only " + num + " valid starter cards were available.")); } } } [HarmonyPatch(typeof(GainConsumablesSequencer), "ReplenishConsumables")] public static class BrokenBackpackPatch { private static readonly FieldInfo BackpackField = AccessTools.Field(typeof(GainConsumablesSequencer), "backpack"); private static readonly MethodInfo FullConsumablesSequenceMethod = AccessTools.Method(typeof(GainConsumablesSequencer), "FullConsumablesSequence", (Type[])null, (Type[])null); private static readonly MethodInfo TutorialGainConsumablesMethod = AccessTools.Method(typeof(GainConsumablesSequencer), "TutorialGainConsumables", (Type[])null, (Type[])null); private static readonly MethodInfo RegularGainConsumablesMethod = AccessTools.Method(typeof(GainConsumablesSequencer), "RegularGainConsumables", (Type[])null, (Type[])null); [HarmonyPrefix] public static bool Prefix(GainConsumablesSequencer __instance, GainConsumablesNodeData nodeData, ref IEnumerator __result) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ChallengeRegistry.BrokenBagChallenge == (Object)null || AscensionSaveData.Data == null || !AscensionSaveData.Data.ChallengeIsActive(ChallengeRegistry.BrokenBagChallengeType)) { return true; } __result = ReplenishConsumablesWithDialogue(__instance, nodeData); return false; } private static IEnumerator ReplenishConsumablesWithDialogue(GainConsumablesSequencer instance, GainConsumablesNodeData nodeData) { Singleton.Instance.SwitchToView((View)1, false, true); yield return (object)new WaitForEndOfFrame(); Singleton.Instance.SetHandLightRange(17f, 0.25f); Singleton.Instance.SetHangingLightRange(7f, 0.25f); GameObject backpack = GetBackpack(instance); if ((Object)(object)backpack != (Object)null) { backpack.SetActive(true); } yield return (object)new WaitForSeconds(0.25f); if ((Object)(object)Singleton.Instance != (Object)null) { yield return (object)new WaitUntil((Func)(() => !Singleton.Instance.Transitioning)); } ChallengeActivationUI.TryShowActivation(ChallengeRegistry.BrokenBagChallengeType); yield return ChallengeDialogueManager.ShowFirstTime("Broken Bag", "Not much for you to choose from this time."); if (RunState.Run.consumables.Count == RunState.Run.MaxConsumables) { yield return InvokeCoroutine(FullConsumablesSequenceMethod, instance); } else if (!ProgressionData.LearnedMechanic((MechanicsConcept)33)) { yield return InvokeCoroutine(TutorialGainConsumablesMethod, instance); ProgressionData.SetMechanicLearned((MechanicsConcept)33); } else { yield return InvokeCoroutine(RegularGainConsumablesMethod, instance, nodeData); ProgressionData.SetMechanicLearned((MechanicsConcept)34); } Singleton.Instance.ResetHandLightRange(0.25f); Singleton.Instance.ResetHangingLightRange(0.25f); if ((Object)(object)backpack != (Object)null) { Animator animator = backpack.GetComponentInChildren(); if ((Object)(object)animator != (Object)null) { animator.SetTrigger("exit"); } CustomCoroutine.WaitThenExecute(0.25f, (Action)delegate { backpack.SetActive(false); }, false); } if ((Object)(object)Singleton.Instance != (Object)null) { Singleton.Instance.TransitionToGameState((GameState)1, (NodeData)null); } } private static GameObject GetBackpack(GainConsumablesSequencer instance) { if ((Object)(object)instance == (Object)null || BackpackField == null) { return null; } object? value = BackpackField.GetValue(instance); return (GameObject)((value is GameObject) ? value : null); } private static IEnumerator InvokeCoroutine(MethodInfo method, object instance, params object[] parameters) { if (method == null) { yield break; } object result = method.Invoke(instance, parameters); if (result is IEnumerator sequence) { while (sequence.MoveNext()) { yield return sequence.Current; } } } } public static class BrokenBagPatch { private static readonly HashSet ForbiddenConsumables = new HashSet { "Hourglass", "Scissors", "CuckooClock" }; public static void Apply(Harmony harmony) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(GainConsumablesSequencer), "GenerateItemChoices", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BrokenBagPatch), "GenerateItemChoices_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(ItemsUtil), "GetRandomUnlockedConsumable", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BrokenBagPatch), "GetRandomUnlockedConsumable_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(BuyPeltsSequencer), "BuyPelts", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(BrokenBagPatch), "BuyPelts_Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(BuyPeltsSequencer), "OnPurchaseKnifePressed", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BrokenBagPatch), "OnPurchaseKnifePressed_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)"[OldSa Challenge] Broken Bag patches applied."); } private static bool IsBrokenBagActive() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return AscensionSaveData.Data.ChallengeIsActive(ChallengeRegistry.BrokenBagChallengeType); } private static void GenerateItemChoices_Postfix(ref List __result, int randomSeed) { if (!IsBrokenBagActive() || __result == null) { return; } for (int i = 0; i < __result.Count; i++) { ConsumableItemData val = __result[i]; if (!((Object)(object)val == (Object)null) && IsForbidden(((Object)val).name)) { ConsumableItemData replacementConsumable = GetReplacementConsumable(randomSeed + i); if ((Object)(object)replacementConsumable != (Object)null) { __result[i] = replacementConsumable; } } } } private static void GetRandomUnlockedConsumable_Postfix(ref ConsumableItemData __result, int randomSeed) { if (IsBrokenBagActive() && !((Object)(object)__result == (Object)null) && IsForbidden(((Object)__result).name)) { __result = GetReplacementConsumable(randomSeed); } } private static ConsumableItemData GetReplacementConsumable(int randomSeed) { List unlockedConsumables = ItemsUtil.GetUnlockedConsumables(); unlockedConsumables.RemoveAll((ConsumableItemData item) => (Object)(object)item == (Object)null || item.notRandomlyGiven || IsForbidden(((Object)item).name)); if (unlockedConsumables.Count == 0) { return ItemsUtil.GetConsumableByName("SquirrelBottle"); } int index = SeededRandom.Range(0, unlockedConsumables.Count, randomSeed); return unlockedConsumables[index]; } private static bool IsForbidden(string itemName) { return !string.IsNullOrEmpty(itemName) && ForbiddenConsumables.Contains(itemName); } private static IEnumerable BuyPelts_Transpiler(IEnumerable instructions) { //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown List list = new List(instructions); FieldInfo fieldInfo = AccessTools.Field(typeof(RunState), "trapperKnifeBought"); MethodInfo methodInfo = AccessTools.Method(typeof(BrokenBagPatch), "IsBrokenBagActive", (Type[])null, (Type[])null); if (fieldInfo == null) { Plugin.Log.LogError((object)"[OldSa Challenge] Could not find RunState.trapperKnifeBought."); return list; } if (methodInfo == null) { Plugin.Log.LogError((object)"[OldSa Challenge] Could not find IsBrokenBagActive."); return list; } for (int i = 0; i < list.Count - 1; i++) { if (!(list[i].opcode != OpCodes.Ldfld) && list[i].operand is FieldInfo fieldInfo2 && !(fieldInfo2 != fieldInfo) && IsBrtrue(list[i + 1].opcode) && list[i + 1].operand is Label label) { list.Insert(i + 2, new CodeInstruction(OpCodes.Call, (object)methodInfo)); list.Insert(i + 3, new CodeInstruction(OpCodes.Brtrue, (object)label)); Plugin.Log.LogInfo((object)"[OldSa Challenge] Trapper Knife purchase option disabled."); return list; } } Plugin.Log.LogWarning((object)"[OldSa Challenge] Could not locate trapperKnifeBought check in BuyPelts()."); return list; } private static bool IsBrtrue(OpCode opcode) { return opcode == OpCodes.Brtrue || opcode == OpCodes.Brtrue_S; } private static bool OnPurchaseKnifePressed_Prefix() { if (!IsBrokenBagActive()) { return true; } Plugin.Log.LogInfo((object)"[OldSa Challenge] Broken Bag prevented Trapper Knife purchase."); return false; } } public static class BrokenStartPatch { [HarmonyPatch(typeof(AscensionSaveData), "NewRun", new Type[] { typeof(List) })] private static class NewRunPatch { [HarmonyPrefix] private static void Prefix(AscensionSaveData __instance) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) remainingReplacements = 0; if (__instance != null && SaveFile.IsAscension) { int numChallengesOfTypeActive = __instance.GetNumChallengesOfTypeActive(ChallengeRegistry.BrokenStartChallengeType); if (numChallengesOfTypeActive > 0) { remainingReplacements = numChallengesOfTypeActive; Plugin.Log.LogInfo((object)("[OldSa Challenge] Broken Start: Starting pelt replacement enabled. Remaining replacements = " + remainingReplacements)); } } } [HarmonyPostfix] private static void Postfix() { if (remainingReplacements > 0) { Plugin.Log.LogInfo((object)("[OldSa Challenge] Broken Start: NewRun finished with " + remainingReplacements + " replacement(s) unused.")); } remainingReplacements = 0; Plugin.Log.LogInfo((object)"[OldSa Challenge] Broken Start: Starting pelt replacement disabled."); } } [HarmonyPatch(typeof(CardLoader), "GetCardByName", new Type[] { typeof(string) })] private static class GetCardByNamePatch { [HarmonyPrefix] private static bool Prefix(ref string name) { if (remainingReplacements <= 0) { return true; } if (name != "PeltHare") { return true; } Plugin.Log.LogInfo((object)("[OldSa Challenge] Broken Start: Intercepted PeltHare -> OLD_SA_BROKEN_PELT (" + remainingReplacements + " replacement(s) before this one)")); name = "OLD_SA_BROKEN_PELT"; remainingReplacements--; return true; } } private const string BrokenPeltName = "OLD_SA_BROKEN_PELT"; private static int remainingReplacements; } public static class ChallengeIncompatibilities { public static void RegisterAll() { RegisterMutual(ChallengeRegistry.ElephantModeChallenge, (AscensionChallenge)13); RegisterMutual(ChallengeRegistry.BadThingsChallenge, ChallengeRegistry.DizzyStartersChallenge); RegisterMutual(ChallengeRegistry.BadThingsChallenge, (AscensionChallenge)9); } private static void RegisterMutual(AscensionChallengeInfo customChallenge, AscensionChallenge vanillaChallenge) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected I4, but got Unknown //IL_0025: 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_003a: Expected I4, but got Unknown if (!((Object)(object)customChallenge == (Object)null)) { ChallengeManager.GetFullChallenge(customChallenge).SetIncompatibleChallengeGetterStatic((AscensionChallenge[])(object)new AscensionChallenge[1] { (AscensionChallenge)(int)vanillaChallenge }); ChallengeManager.GetFullChallenge(vanillaChallenge).SetIncompatibleChallengeGetterStatic((AscensionChallenge[])(object)new AscensionChallenge[1] { (AscensionChallenge)(int)customChallenge.challengeType }); } } private static void RegisterMutual(AscensionChallengeInfo first, AscensionChallengeInfo second) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected I4, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected I4, but got Unknown if (!((Object)(object)first == (Object)null) && !((Object)(object)second == (Object)null)) { ChallengeManager.GetFullChallenge(first).SetIncompatibleChallengeGetterStatic((AscensionChallenge[])(object)new AscensionChallenge[1] { (AscensionChallenge)(int)second.challengeType }); ChallengeManager.GetFullChallenge(second).SetIncompatibleChallengeGetterStatic((AscensionChallenge[])(object)new AscensionChallenge[1] { (AscensionChallenge)(int)first.challengeType }); } } } public static class ChallengeDialogueAPI { public static IEnumerator ShowFirstTime(string challengeName, string dialogue) { if (!string.IsNullOrEmpty(challengeName) && !string.IsNullOrEmpty(dialogue) && !ChallengeDialogueSaveData.HasTriggered(challengeName)) { ChallengeDialogueSaveData.AddTriggered(challengeName); OLD_SA_SaveManager.Save(); TextDisplayer textDisplayer = Singleton.Instance; if (!((Object)(object)textDisplayer == (Object)null)) { yield return textDisplayer.ShowUntilInput(dialogue, -2.5f, 0.5f, (Emotion)0, (LetterAnimation)0, (Speaker)0, (string[])null, true); } } } } public static class ChallengeDialogueConfig { public const string NoGrowthDialogue = "NoGrowthChallenge"; public const string NoWoodcarverDialogue = "NoWoodcarverChallenge"; public const string DizzyStartersDialogue = "DizzyStartersChallenge"; public const string DoubleTrialDialogue = "DoubleTrialChallenge"; public const string BrokenStartDialogue = "BrokenStartChallenge"; public const string BadThingsDialogue = "BadThingsChallenge"; public const string ElephantModeDialogue = "ElephantModeChallenge"; public const string BrokenBagDialogue = "BrokenBagChallenge"; public const string NeverStarvationDialogue = "NeverStarvationChallenge"; public const string GhostForestDialogue = "GhostForestChallenge"; } public static class ChallengeDialogueManager { public static IEnumerator ShowFirstTime(string challengeName, string dialogue) { if (string.IsNullOrEmpty(challengeName) || string.IsNullOrEmpty(dialogue) || ChallengeDialogueSaveData.HasTriggered(challengeName)) { yield break; } ChallengeDialogueSaveData.AddTriggered(challengeName); OLD_SA_SaveManager.Save(); if ((Object)(object)Singleton.Instance != (Object)null) { Singleton.Instance.Controller.LockState = (ViewLockState)1; } if ((Object)(object)Singleton.Instance != (Object)null) { Singleton.Instance.PlayingLocked = true; } try { if ((Object)(object)Singleton.Instance != (Object)null) { yield return Singleton.Instance.ShowUntilInput(dialogue, -2.5f, 0.5f, (Emotion)0, (LetterAnimation)0, (Speaker)0, (string[])null, true); } } finally { if ((Object)(object)Singleton.Instance != (Object)null) { Singleton.Instance.PlayingLocked = false; } if ((Object)(object)Singleton.Instance != (Object)null) { Singleton.Instance.Controller.LockState = (ViewLockState)0; } } } } public static class ChallengeDialogueSaveData { private static readonly HashSet TriggeredChallenges = new HashSet(); public static bool HasTriggered(string challengeName) { if (string.IsNullOrEmpty(challengeName)) { return false; } return TriggeredChallenges.Contains(challengeName); } public static void AddTriggered(string challengeName) { if (!string.IsNullOrEmpty(challengeName)) { TriggeredChallenges.Add(challengeName); } } public static List GetSaveList() { return new List(TriggeredChallenges); } public static void LoadFromList(List list) { TriggeredChallenges.Clear(); if (list == null) { return; } foreach (string item in list) { if (!string.IsNullOrEmpty(item)) { TriggeredChallenges.Add(item); } } } } public static class ChallengeRegistry { public static AscensionChallengeInfo NoGrowthChallenge; public const string NoGrowthName = "No Growth"; public const string NoGrowthDescription = "Fledgling sigils no longer evolve. They only grant +1 Power and +1 Health."; public static AscensionChallengeInfo NoWoodcarverChallenge; public const string NoWoodcarverName = "No Woodcarver"; public const string NoWoodcarverDescription = "You will no longer encounter Woodcarver choice nodes."; public static AscensionChallengeInfo DizzyStartersChallenge; public const string DizzyStartersName = "Dizzy Starters"; public const string DizzyStartersDescription = "All creatures in your starting deck gain the Random sigil."; public static AscensionChallengeInfo DoubleTrialChallenge; public const string DoubleTrialName = "Double Trial"; public const string DoubleTrialDescription = "All Totem battles in this run have bases with the Double Strike sigil."; public static AscensionChallengeInfo BrokenStartChallenge; public const string BrokenStartName = "Broken Start"; public const string BrokenStartDescription = "One of your starting pelts is replaced with a Broken Pelt."; public static AscensionChallengeInfo BadThingsChallenge; public const string BadThingsName = "Bad Things"; public const string BadThingsDescription = "One of your starting creatures is replaced with a Broken Pelt."; public static AscensionChallengeInfo ElephantModeChallenge; public const string ElephantModeName = "Elephant Bosses"; public const string ElephantModeDescription = "On the second turn, the Boss will fill the board with Elephants."; public static AscensionChallengeInfo BrokenBagChallenge; public const string BrokenBagName = "Broken Bag"; public const string BrokenBagDescription = "You will not encounter the Hourglass, Skinning Knife, Scissors, or CuckooClock."; public static AscensionChallengeInfo NeverStarvationChallenge; public const string NeverStarvationName = "Never Starvation"; public const string NeverStarvationDescription = "You will never encounter starvation, even when there are no cards left to draw."; public static AscensionChallengeInfo GhostForestChallenge; public const string GhostForestName = "Ghost Forest"; public const string GhostForestDescription = "One of your squares will turn into the Netherworld."; public static AscensionChallenge NoGrowthChallengeType => (AscensionChallenge)(((Object)(object)NoGrowthChallenge != (Object)null) ? ((int)NoGrowthChallenge.challengeType) : 0); public static AscensionChallenge NoWoodcarverChallengeType => (AscensionChallenge)(((Object)(object)NoWoodcarverChallenge != (Object)null) ? ((int)NoWoodcarverChallenge.challengeType) : 0); public static AscensionChallenge DizzyStartersChallengeType => (AscensionChallenge)(((Object)(object)DizzyStartersChallenge != (Object)null) ? ((int)DizzyStartersChallenge.challengeType) : 0); public static AscensionChallenge DoubleTrialChallengeType => (AscensionChallenge)(((Object)(object)DoubleTrialChallenge != (Object)null) ? ((int)DoubleTrialChallenge.challengeType) : 0); public static AscensionChallenge BrokenStartChallengeType => (AscensionChallenge)(((Object)(object)BrokenStartChallenge != (Object)null) ? ((int)BrokenStartChallenge.challengeType) : 0); public static AscensionChallenge BadThingsChallengeType => (AscensionChallenge)(((Object)(object)BadThingsChallenge != (Object)null) ? ((int)BadThingsChallenge.challengeType) : 0); public static AscensionChallenge ElephantModeChallengeType => (AscensionChallenge)(((Object)(object)ElephantModeChallenge != (Object)null) ? ((int)ElephantModeChallenge.challengeType) : 0); public static AscensionChallenge BrokenBagChallengeType => (AscensionChallenge)(((Object)(object)BrokenBagChallenge != (Object)null) ? ((int)BrokenBagChallenge.challengeType) : 0); public static AscensionChallenge NeverStarvationChallengeType => (AscensionChallenge)(((Object)(object)NeverStarvationChallenge != (Object)null) ? ((int)NeverStarvationChallenge.challengeType) : 0); public static AscensionChallenge GhostForestChallengeType => (AscensionChallenge)(((Object)(object)GhostForestChallenge != (Object)null) ? ((int)GhostForestChallenge.challengeType) : 0); public static void Register() { Plugin.Log.LogInfo((object)"[OldSa Challenge] Registering challenges..."); NoGrowthChallenge = FullChallenge.op_Implicit(ChallengeManager.Add("OLD_SA.Challenge", "No Growth", "Fledgling sigils no longer evolve. They only grant +1 Power and +1 Health.", 30, TextureHelper.GetImageAsTexture("NoGrowth.png", (FilterMode)0), TextureHelper.GetImageAsTexture("NoGrowth_Activated.png", (FilterMode)0), 0, false)); Plugin.Log.LogInfo((object)("[OldSa Challenge] Registered: No Growth | ID: " + ((object)Unsafe.As(ref NoGrowthChallenge.challengeType)/*cast due to .constrained prefix*/).ToString())); NoWoodcarverChallenge = FullChallenge.op_Implicit(ChallengeManager.Add("OLD_SA.Challenge", "No Woodcarver", "You will no longer encounter Woodcarver choice nodes.", 30, TextureHelper.GetImageAsTexture("NoWoodcarver.png", (FilterMode)0), TextureHelper.GetImageAsTexture("NoWoodcarver_Activated.png", (FilterMode)0), 0, false)); Plugin.Log.LogInfo((object)("[OldSa Challenge] Registered: No Woodcarver | ID: " + ((object)Unsafe.As(ref NoWoodcarverChallenge.challengeType)/*cast due to .constrained prefix*/).ToString())); DizzyStartersChallenge = FullChallenge.op_Implicit(ChallengeManager.Add("OLD_SA.Challenge", "Dizzy Starters", "All creatures in your starting deck gain the Random sigil.", 30, TextureHelper.GetImageAsTexture("DizzyStarters.png", (FilterMode)0), TextureHelper.GetImageAsTexture("DizzyStarters_Activated.png", (FilterMode)0), 0, false)); Plugin.Log.LogInfo((object)("[OldSa Challenge] Registered: Dizzy Starters | ID: " + ((object)Unsafe.As(ref DizzyStartersChallenge.challengeType)/*cast due to .constrained prefix*/).ToString())); DoubleTrialChallenge = FullChallenge.op_Implicit(ChallengeManager.Add("OLD_SA.Challenge", "Double Trial", "All Totem battles in this run have bases with the Double Strike sigil.", 100, TextureHelper.GetImageAsTexture("DoubleTrial.png", (FilterMode)0), TextureHelper.GetImageAsTexture("DoubleTrial_Activated.png", (FilterMode)0), 0, false)); Plugin.Log.LogInfo((object)("[OldSa Challenge] Registered: Double Trial | ID: " + ((object)Unsafe.As(ref DoubleTrialChallenge.challengeType)/*cast due to .constrained prefix*/).ToString())); BrokenStartChallenge = FullChallenge.op_Implicit(ChallengeManager.AddSpecific("OLD_SA.Challenge", "Broken Start", "One of your starting pelts is replaced with a Broken Pelt.", 15, TextureHelper.GetImageAsTexture("BrokenStart.png", (FilterMode)0), TextureHelper.GetImageAsTexture("BrokenStart_Activated.png", (FilterMode)0), (Type)null, 0, (List)null, (Func>)null, (Func>)null, 2)); Plugin.Log.LogInfo((object)("[OldSa Challenge] Registered: Broken Start | ID: " + ((object)Unsafe.As(ref BrokenStartChallenge.challengeType)/*cast due to .constrained prefix*/).ToString() + " | Appearances: 2")); BadThingsChallenge = FullChallenge.op_Implicit(ChallengeManager.AddSpecific("OLD_SA.Challenge", "Bad Things", "One of your starting creatures is replaced with a Broken Pelt.", 20, TextureHelper.GetImageAsTexture("BadThings.png", (FilterMode)0), TextureHelper.GetImageAsTexture("BadThings_Activated.png", (FilterMode)0), (Type)null, 0, (List)null, (Func>)null, (Func>)null, 3)); Plugin.Log.LogInfo((object)("[OldSa Challenge] Registered: Bad Things | ID: " + ((object)Unsafe.As(ref BadThingsChallenge.challengeType)/*cast due to .constrained prefix*/).ToString() + " | Appearances: 3")); ElephantModeChallenge = FullChallenge.op_Implicit(ChallengeManager.AddSpecific("OLD_SA.Challenge", "Elephant Bosses", "On the second turn, the Boss will fill the board with Elephants.", 50, TextureHelper.GetImageAsTexture("ElephantMode.png", (FilterMode)0), TextureHelper.GetImageAsTexture("ElephantMode_Activated.png", (FilterMode)0), (Type)null, 0, (List)null, (Func>)null, (Func>)null, 1)); Plugin.Log.LogInfo((object)("[OldSa Challenge] Registered: Elephant Bosses | ID: " + ((object)Unsafe.As(ref ElephantModeChallenge.challengeType)/*cast due to .constrained prefix*/).ToString() + " | Appearances: 1")); BrokenBagChallenge = FullChallenge.op_Implicit(ChallengeManager.AddSpecific("OLD_SA.Challenge", "Broken Bag", "You will not encounter the Hourglass, Skinning Knife, Scissors, or CuckooClock.", 50, TextureHelper.GetImageAsTexture("BrokenBag.png", (FilterMode)0), TextureHelper.GetImageAsTexture("BrokenBag_Activated.png", (FilterMode)0), (Type)null, 0, (List)null, (Func>)null, (Func>)null, 1)); Plugin.Log.LogInfo((object)("[OldSa Challenge] Registered: Broken Bag | ID: " + ((object)Unsafe.As(ref BrokenBagChallenge.challengeType)/*cast due to .constrained prefix*/).ToString() + " | Appearances: 1")); NeverStarvationChallenge = FullChallenge.op_Implicit(ChallengeManager.AddSpecific("OLD_SA.Challenge", "Never Starvation", "You will never encounter starvation, even when there are no cards left to draw.", -15, TextureHelper.GetImageAsTexture("NeverStarvation.png", (FilterMode)0), TextureHelper.GetImageAsTexture("NeverStarvation_Activated.png", (FilterMode)0), (Type)null, 0, (List)null, (Func>)null, (Func>)null, 1)); Plugin.Log.LogInfo((object)("[OldSa Challenge] Registered: Never Starvation | ID: " + ((object)Unsafe.As(ref NeverStarvationChallenge.challengeType)/*cast due to .constrained prefix*/).ToString() + " | Appearances: 1")); GhostForestChallenge = FullChallenge.op_Implicit(ChallengeManager.AddSpecific("OLD_SA.Challenge", "Ghost Forest", "One of your squares will turn into the Netherworld.", 15, TextureHelper.GetImageAsTexture("GhostForest.png", (FilterMode)0), TextureHelper.GetImageAsTexture("GhostForest_Activated.png", (FilterMode)0), (Type)null, 0, (List)null, (Func>)null, (Func>)null, 4)); Plugin.Log.LogInfo((object)("[OldSa Challenge] Registered: Ghost Forest | ID: " + ((object)Unsafe.As(ref GhostForestChallenge.challengeType)/*cast due to .constrained prefix*/).ToString() + " | Appearances: 4")); Plugin.Log.LogInfo((object)"[OldSa Challenge] All challenges registered."); ChallengeIncompatibilities.RegisterAll(); } } [HarmonyPatch] public static class ChallengeIntroDialoguePatch { internal static bool InRunIntro; internal static bool IntroDeckShown; [HarmonyPatch(typeof(RunIntroSequencer), "RunIntroSequence")] [HarmonyPrefix] private static void RunIntroPrefix() { InRunIntro = true; IntroDeckShown = false; } [HarmonyPatch(typeof(RunIntroSequencer), "RunIntroSequence")] [HarmonyPostfix] private static void RunIntroPostfix(ref IEnumerator __result) { if (__result == null) { InRunIntro = false; } else { __result = WrapRunIntro(__result); } } private static IEnumerator WrapRunIntro(IEnumerator original) { while (original.MoveNext()) { yield return original.Current; } InRunIntro = false; } [HarmonyPatch(typeof(DeckReviewSequencer), "SetDeckReviewShown", new Type[] { typeof(bool), typeof(Transform), typeof(Vector3), typeof(bool), typeof(bool) })] [HarmonyPostfix] private static void SetDeckReviewShownPostfix(DeckReviewSequencer __instance, bool shown) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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) if (shown && InRunIntro && SaveFile.IsAscension && !IntroDeckShown) { IntroDeckShown = true; bool flag = IsChallengeActive(ChallengeRegistry.BadThingsChallengeType); bool flag2 = IsChallengeActive(ChallengeRegistry.BrokenStartChallengeType); bool flag3 = IsChallengeActive(ChallengeRegistry.DizzyStartersChallengeType); if ((flag || flag2 || flag3) && !((Object)(object)__instance == (Object)null)) { ((MonoBehaviour)__instance).StartCoroutine(ShowIntroDialogues(flag, flag2, flag3)); } } } private static bool IsChallengeActive(AscensionChallenge challenge) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (AscensionSaveData.Data == null) { return false; } return AscensionSaveData.Data.ChallengeIsActive(challenge); } private static IEnumerator ShowIntroDialogues(bool badThings, bool brokenStart, bool dizzyStarters) { yield return (object)new WaitForSeconds(0.3f); if (badThings) { yield return ChallengeDialogueManager.ShowFirstTime("Bad Things", "Your creature has left you.I kept this for you."); } if (brokenStart) { yield return ChallengeDialogueManager.ShowFirstTime("Broken Start", "Sorry,I don't have anything better.Good luck."); } if (dizzyStarters) { yield return ChallengeDialogueManager.ShowFirstTime("Dizzy Starters", "They have all lost their sense of direction."); } } } [HarmonyPatch(typeof(AscensionSaveData), "NewRun")] public static class DizzyStartersPatch { [HarmonyPostfix] public static void Postfix(AscensionSaveData __instance) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown if (!__instance.ChallengeIsActive(ChallengeRegistry.DizzyStartersChallengeType) || __instance.currentRun == null || __instance.currentRun.playerDeck == null) { return; } Ability randomAbility = RandomAPI.RandomAbility; if ((int)randomAbility == 0) { Plugin.Log.LogError((object)"[OldSa Challenge] Dizzy Starters: Random ability is invalid."); return; } foreach (CardInfo card in ((CardCollectionInfo)__instance.currentRun.playerDeck).Cards) { if (!((Object)(object)card == (Object)null) && !card.HasTrait((Trait)13) && !card.HasAbility(randomAbility)) { CardModificationInfo val = new CardModificationInfo(randomAbility); __instance.currentRun.playerDeck.ModifyCard(card, val); Plugin.Log.LogInfo((object)("[OldSa Challenge] Dizzy Starters: Added Random to " + ((Object)card).name)); } } } } [HarmonyPatch(typeof(TotemsUtil), "AssignAbilityToBottom")] public static class DoubleTrialPatch { [HarmonyPostfix] public static void Postfix(TotemBottomData bottom) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)bottom == (Object)null) && bottom.effectParams != null) { AscensionSaveData data = AscensionSaveData.Data; if (data != null && data.ChallengeIsActive(ChallengeRegistry.DoubleTrialChallengeType)) { bottom.effectParams.ability = (Ability)100; Plugin.Log.LogInfo((object)"[OldSa Challenge] Double Trial: Totem bottom ability changed to Double Strike."); } } } } [HarmonyPatch] public static class ElephantGrizzlyPhasePatch { private static MethodBase TargetMethod() { MethodInfo method = typeof(Part1BossOpponent).GetMethod("HasGrizzlyGlitchPhase", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { Plugin.Log.LogError((object)"[OLD SA Elephant] HasGrizzlyGlitchPhase NOT FOUND!"); return null; } Plugin.Log.LogInfo((object)("[OLD SA Elephant] Found HasGrizzlyGlitchPhase: " + method)); return method; } [HarmonyPostfix] private static void HasGrizzlyGlitchPhasePostfix(ref bool __result) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (AscensionSaveData.Data != null) { bool flag = AscensionSaveData.Data.ChallengeIsActive(ChallengeRegistry.ElephantModeChallengeType); Plugin.Log.LogInfo((object)("[OLD SA Elephant] HasGrizzlyGlitchPhase result = " + __result + ", Elephant Mode = " + flag)); if (flag) { Plugin.Log.LogInfo((object)"[OLD SA Elephant] Forcing Grizzly glitch phase."); __result = true; } } } } [HarmonyPatch] public static class ElephantBearGlitchPatch { private static MethodBase TargetMethod() { MethodInfo method = typeof(Tutorial4BattleSequencer).GetMethod("BearGlitchSequence", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { Plugin.Log.LogError((object)"[OLD SA Elephant] BearGlitchSequence NOT FOUND!"); return null; } Plugin.Log.LogInfo((object)("[OLD SA Elephant] Found BearGlitchSequence: " + method)); return method; } [HarmonyPrefix] private static bool BearGlitchSequencePrefix(ref IEnumerator __result) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) Plugin.Log.LogInfo((object)"[OLD SA Elephant] BearGlitchSequence PREFIX CALLED."); if (AscensionSaveData.Data == null) { Plugin.Log.LogWarning((object)"[OLD SA Elephant] AscensionSaveData.Data == null."); return true; } bool flag = AscensionSaveData.Data.ChallengeIsActive(ChallengeRegistry.ElephantModeChallengeType); Plugin.Log.LogInfo((object)("[OLD SA Elephant] Elephant Mode active = " + flag)); if (!flag) { return true; } Plugin.Log.LogInfo((object)"[OLD SA Elephant] Replacing BearGlitchSequence."); __result = ElephantGlitchSequence(); return false; } private static IEnumerator ElephantGlitchSequence() { Plugin.Log.LogInfo((object)"[OLD SA Elephant] ElephantGlitchSequence START."); ChallengeActivationUI.TryShowActivation(ChallengeRegistry.ElephantModeChallengeType); CardInfo elephantInfo = CardLoader.GetCardByName("OLD_SA_Elephant"); if ((Object)(object)elephantInfo == (Object)null) { Plugin.Log.LogError((object)"[OLD SA Elephant] OLD_SA_Elephant NOT FOUND!"); yield break; } Plugin.Log.LogInfo((object)"[OLD SA Elephant] OLD_SA_Elephant found."); ((ScreenEffect)Singleton.Instance.Effects.GetEffect()).SetIntensity(1f, 1f); Singleton.Instance.Shake(0.1f, 1f); AudioController.Instance.PlaySound2D("broken_hum", (MixerGroup)0, 1f, 0f, (Pitch)null, (Repetition)null, (Randomization)null, (Distortion)null, false); foreach (CardSlot slot in Singleton.Instance.OpponentSlotsCopy) { if (!Singleton.Instance.Opponent.QueuedSlots.Contains(slot)) { yield return Singleton.Instance.Opponent.QueueCard(elephantInfo, slot, false, false, false); } if ((Object)(object)slot.Card == (Object)null) { yield return Singleton.Instance.CreateCardInSlot(elephantInfo, slot, 0f, true); } if ((Object)(object)slot.Card != (Object)null) { GiveCardReachAndRedColor(slot.Card); } } foreach (PlayableCard playableCard in Singleton.Instance.Opponent.Queue) { if ((Object)(object)playableCard != (Object)null && (Object)(object)((Card)playableCard).Info != (Object)null && ((Object)((Card)playableCard).Info).name == "OLD_SA_Elephant") { GiveCardReachAndRedColor(playableCard); } } yield return (object)new WaitForSeconds(0.5f); Plugin.Log.LogInfo((object)"[OLD SA Elephant] ElephantGlitchSequence END."); } private static void GiveCardReachAndRedColor(PlayableCard card) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)card == (Object)null)) { CardModificationInfo val = new CardModificationInfo((Ability)23); val.fromTotem = true; if ((Object)(object)((Card)card).StatsLayer != (Object)null) { ((Card)card).StatsLayer.SetEmissionColor(GameColors.Instance.glowRed); } card.AddTemporaryMod(val); Plugin.Log.LogInfo((object)("[OLD SA Elephant] Reach applied to " + (((Object)(object)((Card)card).Info != (Object)null) ? ((Object)((Card)card).Info).name : "UNKNOWN"))); } } } public static class GhostForestChallenge { [HarmonyPatch(typeof(TurnManager), "SetupPhase")] private static class TurnManager_SetupPhase { [HarmonyPostfix] private static void Postfix(ref IEnumerator __result) { Plugin.Log.LogError((object)"[OldSa Challenge] TEST: TurnManager.SetupPhase PATCHED!"); IEnumerator original = __result; __result = SetupPhaseWithGhostForest(original); } } private static IEnumerator SetupPhaseWithGhostForest(IEnumerator original) { while (original?.MoveNext() ?? false) { yield return original.Current; } Plugin.Log.LogError((object)"[OldSa Challenge] TEST: SetupPhase finished!"); yield return ApplyGhostForest(); } private unsafe static IEnumerator ApplyGhostForest() { Plugin.Log.LogError((object)"[OldSa Challenge] TEST: ApplyGhostForest ENTERED!"); if (!SaveFile.IsAscension) { Plugin.Log.LogError((object)"[OldSa Challenge] Ghost Forest: Not Ascension."); yield break; } int activeCount = AscensionSaveData.Data.GetNumChallengesOfTypeActive(ChallengeRegistry.GhostForestChallengeType); Plugin.Log.LogError((object)("[OldSa Challenge] Ghost Forest active count = " + activeCount)); if (activeCount <= 0) { yield break; } BoardManager board = Singleton.Instance; if ((Object)(object)board == (Object)null) { Plugin.Log.LogError((object)"[OldSa Challenge] Ghost Forest: BoardManager NULL!"); yield break; } ModificationType modType = SlotModificationRegistry.NetherworldSlotModificationType; Plugin.Log.LogError((object)("[OldSa Challenge] Ghost Forest ModificationType = " + ((object)(*(ModificationType*)(&modType))/*cast due to .constrained prefix*/).ToString())); if ((int)modType == 0) { Plugin.Log.LogError((object)"[OldSa Challenge] Ghost Forest: ModificationType INVALID!"); yield break; } List slots = new List(board.PlayerSlotsCopy); Plugin.Log.LogError((object)("[OldSa Challenge] Player slot count = " + slots.Count)); if (slots.Count == 0) { yield break; } int convertCount = Mathf.Min(activeCount, slots.Count); for (int i = 0; i < convertCount; i++) { int randomIndex = Random.Range(0, slots.Count); CardSlot targetSlot = slots[randomIndex]; slots.RemoveAt(randomIndex); if (!((Object)(object)targetSlot == (Object)null)) { Plugin.Log.LogError((object)("[OldSa Challenge] Applying Netherworld to slot " + targetSlot.Index)); yield return SlotModificationExtensions.SetSlotModification(targetSlot, modType); ModificationType actual = SlotModificationExtensions.GetSlotModification(targetSlot); Plugin.Log.LogError((object)("[OldSa Challenge] Slot " + targetSlot.Index + " AFTER = " + ((object)(*(ModificationType*)(&actual))/*cast due to .constrained prefix*/).ToString())); if (actual == modType) { Plugin.Log.LogError((object)("[OldSa Challenge] SUCCESS slot " + targetSlot.Index)); continue; } Plugin.Log.LogError((object)("[OldSa Challenge] FAILED slot " + targetSlot.Index + " Expected=" + ((object)(*(ModificationType*)(&modType))/*cast due to .constrained prefix*/).ToString() + " Actual=" + ((object)(*(ModificationType*)(&actual))/*cast due to .constrained prefix*/).ToString())); } } } } public class NetherworldSlotModification : SlotModificationBehaviour { private PlayableCard currentCard; public override IEnumerator Setup() { currentCard = null; UpdateCurrentCard(); yield break; } public override bool RespondsToOtherCardAssignedToSlot(PlayableCard otherCard) { return (Object)(object)otherCard != (Object)null; } public override IEnumerator OnOtherCardAssignedToSlot(PlayableCard otherCard) { if (!((Object)(object)otherCard == (Object)null)) { if ((Object)(object)currentCard != (Object)null && (Object)(object)currentCard != (Object)(object)otherCard) { RemoveIncorporal(currentCard); } currentCard = otherCard; ApplyIncorporal(currentCard); } yield break; } private void Update() { if (!((Object)(object)((SlotModificationBehaviour)this).Slot == (Object)null)) { PlayableCard card = ((SlotModificationBehaviour)this).Slot.Card; if ((Object)(object)currentCard != (Object)null && (Object)(object)card != (Object)(object)currentCard) { PlayableCard card2 = currentCard; currentCard = null; RemoveIncorporal(card2); } if ((Object)(object)card != (Object)null && (Object)(object)card != (Object)(object)currentCard) { currentCard = card; ApplyIncorporal(currentCard); } } } private void ApplyIncorporal(PlayableCard card) { if (!((Object)(object)card == (Object)null)) { IncorporalState orCreate = IncorporalState.GetOrCreate(card); if (!((Object)(object)orCreate == (Object)null)) { orCreate.Apply((Component)(object)this); } } } private void RemoveIncorporal(PlayableCard card) { if (!((Object)(object)card == (Object)null)) { IncorporalState component = ((Component)card).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.Remove((Component)(object)this); } } } public override IEnumerator Cleanup(ModificationType replacement) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)currentCard != (Object)null) { PlayableCard oldCard = currentCard; currentCard = null; RemoveIncorporal(oldCard); } yield break; } private void UpdateCurrentCard() { if (!((Object)(object)((SlotModificationBehaviour)this).Slot == (Object)null)) { PlayableCard card = ((SlotModificationBehaviour)this).Slot.Card; if (!((Object)(object)card == (Object)null)) { currentCard = card; ApplyIncorporal(currentCard); } } } } public static class NeverHungryPatch { public static void Apply(Harmony harmony) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(CardDrawPiles), "ExhaustedSequence", (Type[])null, (Type[])null), new HarmonyMethod(typeof(NeverHungryPatch), "ExhaustedSequence_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)"[OldSa Challenge] Never Hungry patch applied."); } private static bool IsNeverHungryActive() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return AscensionSaveData.Data.ChallengeIsActive(ChallengeRegistry.NeverStarvationChallengeType); } private static bool ExhaustedSequence_Prefix() { if (!IsNeverHungryActive()) { return true; } Plugin.Log.LogInfo((object)"[OldSa Challenge] Never Hungry prevented starvation."); return false; } } [HarmonyPatch(typeof(Evolve), "OnUpkeep")] public static class NoGrowthPatch { private static readonly FieldRef NumTurnsInPlay = AccessTools.FieldRefAccess("numTurnsInPlay"); private static readonly MethodInfo PreSuccessfulTriggerSequenceMethod = AccessTools.Method(typeof(AbilityBehaviour), "PreSuccessfulTriggerSequence", (Type[])null, (Type[])null); private static readonly PropertyInfo CardProperty = AccessTools.Property(typeof(AbilityBehaviour), "Card"); private static readonly HashSet ProcessedEvolves = new HashSet(); [HarmonyPrefix] public static bool Prefix(Evolve __instance, bool playerUpkeep, ref IEnumerator __result) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return true; } if ((Object)(object)ChallengeRegistry.NoGrowthChallenge == (Object)null || AscensionSaveData.Data == null || !AscensionSaveData.Data.ChallengeIsActive(ChallengeRegistry.NoGrowthChallenge.challengeType)) { return true; } PlayableCard card = GetCard(__instance); if ((Object)(object)card == (Object)null || card.Dead) { return true; } if (card.OpponentCard) { return true; } if (ProcessedEvolves.Contains(__instance)) { __result = EmptySequence(); return false; } __result = NoGrowthOnUpkeep(__instance, card, playerUpkeep); return false; } private static IEnumerator EmptySequence() { yield break; } private static PlayableCard GetCard(Evolve evolve) { if ((Object)(object)evolve == (Object)null || CardProperty == null) { return null; } object? value = CardProperty.GetValue(evolve, null); return (PlayableCard)((value is PlayableCard) ? value : null); } private static IEnumerator NoGrowthOnUpkeep(Evolve evolve, PlayableCard card, bool playerUpkeep) { if ((Object)(object)evolve == (Object)null || (Object)(object)card == (Object)null || card.Dead || card.OpponentCard == playerUpkeep) { yield break; } int turnsToEvolve = ((!((Object)(object)((Card)card).Info != (Object)null) || ((Card)card).Info.evolveParams == null) ? 1 : ((Card)card).Info.evolveParams.turnsToEvolve); int numTurnsInPlay = NumTurnsInPlay.Invoke(evolve); numTurnsInPlay++; NumTurnsInPlay.Invoke(evolve) = numTurnsInPlay; int remaining = Mathf.Max(1, turnsToEvolve - numTurnsInPlay); ((Card)card).RenderInfo.OverrideAbilityIcon((Ability)5, ResourceBank.Get("Art/Cards/AbilityIcons/ability_evolve_" + remaining)); ((Card)card).RenderCard(); if (numTurnsInPlay >= turnsToEvolve) { ProcessedEvolves.Add(evolve); yield return InvokePreSuccessfulTriggerSequence(evolve); if (!((Object)(object)card == (Object)null) && !card.Dead) { Singleton.Instance.SwitchToView((View)4, false, false); yield return (object)new WaitForSeconds(0.15f); ((Card)card).Anim.PlayTransformAnimation(); yield return (object)new WaitForSeconds(0.15f); CardModificationInfo growth = new CardModificationInfo { attackAdjustment = 1, healthAdjustment = 1, singletonId = "OLD_SA_NoGrowth_StatIncrease" }; card.AddTemporaryMod(growth); HideEvolve(card); card.OnStatsChanged(); ((Card)card).RenderCard(); card.UpdateFaceUpOnBoardEffects(); yield return ChallengeDialogueManager.ShowFirstTime("No Growth", "They were meant to evolve... but only an echo answered."); } } } private static void HideEvolve(PlayableCard card) { if (!((Object)(object)card == (Object)null) && card.Status != null) { if (card.Status.hiddenAbilities == null) { card.Status.hiddenAbilities = new List(); } if (!card.Status.hiddenAbilities.Contains((Ability)5)) { card.Status.hiddenAbilities.Add((Ability)5); } ((Card)card).RenderInfo.OverrideAbilityIcon((Ability)5, (Texture)null); ((Card)card).RenderCard(); } } private static IEnumerator InvokePreSuccessfulTriggerSequence(Evolve evolve) { if ((Object)(object)evolve == (Object)null || PreSuccessfulTriggerSequenceMethod == null) { yield break; } object result = PreSuccessfulTriggerSequenceMethod.Invoke(evolve, null); if (result is IEnumerator sequence) { while (sequence.MoveNext()) { yield return sequence.Current; } } } } [HarmonyPatch(typeof(GameMap), "ShowMapSequence")] public static class NoWoodcarverDialoguePatch { private static readonly MethodInfo UnrollingSequenceMethod = AccessTools.Method(typeof(GameMap), "UnrollingSequence", (Type[])null, (Type[])null); [HarmonyPrefix] public static bool Prefix(GameMap __instance, float unrollSpeed, ref IEnumerator __result) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return true; } if ((Object)(object)ChallengeRegistry.NoWoodcarverChallenge == (Object)null || AscensionSaveData.Data == null || !AscensionSaveData.Data.ChallengeIsActive(ChallengeRegistry.NoWoodcarverChallenge.challengeType)) { return true; } __result = ShowMapSequenceWithDialogue(__instance, unrollSpeed); return false; } private static IEnumerator ShowMapSequenceWithDialogue(GameMap map, float unrollSpeed) { SetFullyUnrolled(map, value: false); IEnumerator sequence = InvokeUnrollingSequence(map, unrollSpeed); if (sequence != null) { while (sequence.MoveNext()) { yield return sequence.Current; } } ((AnimatedGameMapMarker)PlayerMarker.Instance).Show(); SetFullyUnrolled(map, value: true); yield return ChallengeDialogueManager.ShowFirstTime("No Woodcarver", "Sorry,she doesn't have enough wood."); } private static IEnumerator InvokeUnrollingSequence(GameMap map, float unrollSpeed) { if ((Object)(object)map == (Object)null || UnrollingSequenceMethod == null) { yield break; } object result = UnrollingSequenceMethod.Invoke(map, new object[1] { unrollSpeed }); if (result is IEnumerator sequence) { while (sequence.MoveNext()) { yield return sequence.Current; } } } private static void SetFullyUnrolled(GameMap map, bool value) { if (!((Object)(object)map == (Object)null)) { PropertyInfo propertyInfo = AccessTools.Property(typeof(GameMap), "FullyUnrolled"); if (!(propertyInfo == null)) { propertyInfo.SetValue(map, value, null); } } } } [HarmonyPatch(typeof(MapGenerator), "ChooseSpecialNodeFromPossibilities")] public static class NoWoodcarverPatch { [HarmonyPrefix] public static void Prefix(List possibilities) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (possibilities != null && !((Object)(object)ChallengeRegistry.NoWoodcarverChallenge == (Object)null) && SaveFile.IsAscension && AscensionSaveData.Data.ChallengeIsActive(ChallengeRegistry.NoWoodcarverChallenge.challengeType)) { possibilities.RemoveAll((NodeData node) => node is BuildTotemNodeData); } } } [BepInPlugin("OLD_SA.Challenge", "OLD SA Challenge", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "OLD_SA.Challenge"; public const string PluginName = "OLD SA Challenge"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; private void Awake() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"[OldSa Challenge] Plugin loaded."); SlotModificationRegistry.Register(); ChallengeRegistry.Register(); Harmony val = new Harmony("OLD_SA.Challenge"); val.PatchAll(); Log.LogInfo((object)"[OldSa Challenge] Harmony patches applied."); Log.LogInfo((object)"[OldSa Challenge] Initialization complete."); } public static Texture2D LoadTexture(string name) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("OldSa_Challenge.Resources." + name); if (stream == null) { Log.LogError((object)("[OldSa Challenge] Missing texture: " + name)); return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); Texture2D val = new Texture2D(2, 2); ImageConversion.LoadImage(val, array); ((Object)val).name = name; return val; } } public static class SlotModificationRegistry { public static ModificationType NetherworldSlotModificationType; private static Sprite netherworldRulebookSprite; public static void Register() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Invalid comparison between Unknown and I4 if ((int)NetherworldSlotModificationType > 0) { Plugin.Log.LogWarning((object)"[OldSa Challenge] Netherworld Slot Modification was already registered."); return; } SlotModificationManager.ModifySlotModificationList -= ModifySlotModificationList; SlotModificationManager.ModifySlotModificationList += ModifySlotModificationList; Plugin.Log.LogInfo((object)"[OldSa Challenge] Slot modification rulebook modifier registered."); Texture2D imageAsTexture = TextureHelper.GetImageAsTexture("OldSa_Netherworld.png", (FilterMode)0); if ((Object)(object)imageAsTexture == (Object)null) { Plugin.Log.LogError((object)"[OldSa Challenge] Failed to load OldSa_Netherworld.png."); return; } netherworldRulebookSprite = Sprite.Create(imageAsTexture, new Rect(0f, 0f, (float)((Texture)imageAsTexture).width, (float)((Texture)imageAsTexture).height), new Vector2(0.5f, 0.5f), 100f); if ((Object)(object)netherworldRulebookSprite == (Object)null) { Plugin.Log.LogError((object)"[OldSa Challenge] Failed to create Netherworld Rulebook Sprite."); return; } Plugin.Log.LogInfo((object)"[OldSa Challenge] Netherworld Rulebook Sprite created."); Dictionary dictionary = new Dictionary { { (CardTemple)0, imageAsTexture }, { (CardTemple)2, imageAsTexture }, { (CardTemple)1, imageAsTexture }, { (CardTemple)3, imageAsTexture } }; NetherworldSlotModificationType = SlotModificationManager.New("OLD_SA.Challenge", "Netherworld", typeof(NetherworldSlotModification), dictionary, (Dictionary)null); if ((int)NetherworldSlotModificationType == 0) { Plugin.Log.LogError((object)"[OldSa Challenge] FAILED to register Netherworld Slot Modification."); return; } Plugin.Log.LogInfo((object)"[OldSa Challenge] Registered Slot Modification: Netherworld"); Plugin.Log.LogInfo((object)("[OldSa Challenge] Netherworld ID = " + ((object)Unsafe.As(ref NetherworldSlotModificationType)/*cast due to .constrained prefix*/).ToString())); SlotModificationManager.SyncSlotModificationList(); Info val = SlotModificationManager.AllModificationInfos.Find((Info x) => x.ModificationType == NetherworldSlotModificationType); if (val == null) { Plugin.Log.LogError((object)"[OldSa Challenge] Netherworld Info was NOT found in AllModificationInfos."); return; } val.RulebookName = "Netherworld"; val.RulebookDescription = "When a creature enters this space, it becomes a ghost."; val.RulebookSprite = netherworldRulebookSprite; if ((Object)(object)val.RulebookSprite == (Object)null) { Plugin.Log.LogError((object)"[OldSa Challenge] RulebookSprite is STILL NULL!"); } else { Plugin.Log.LogInfo((object)"[OldSa Challenge] RulebookSprite assigned successfully."); } if (!val.MetaCategories.Contains((ModificationMetaCategory)0)) { val.MetaCategories.Add((ModificationMetaCategory)0); } SlotModificationManager.SyncSlotModificationList(); Info val2 = SlotModificationManager.AllModificationInfos.Find((Info x) => x.ModificationType == NetherworldSlotModificationType); if (val2 == null) { Plugin.Log.LogError((object)"[OldSa Challenge] Netherworld final Info was NOT found after Sync."); return; } Plugin.Log.LogInfo((object)"[OldSa Challenge] Netherworld Info found."); Plugin.Log.LogInfo((object)("[OldSa Challenge] RulebookName = " + val2.RulebookName)); Plugin.Log.LogInfo((object)("[OldSa Challenge] RulebookDescription = " + val2.RulebookDescription)); Plugin.Log.LogInfo((object)("[OldSa Challenge] RulebookSprite = " + (((Object)(object)val2.RulebookSprite != (Object)null) ? "VALID" : "NULL"))); Plugin.Log.LogInfo((object)("[OldSa Challenge] Part1Rulebook = " + val2.MetaCategories.Contains((ModificationMetaCategory)0))); } private static List ModifySlotModificationList(List infos) { Info val = infos.Find((Info x) => x.ModificationType == NetherworldSlotModificationType); if (val == null) { return infos; } val.RulebookName = "Netherworld"; val.RulebookDescription = "When a creature enters this space, it becomes a ghost."; if ((Object)(object)netherworldRulebookSprite != (Object)null) { val.RulebookSprite = netherworldRulebookSprite; } else { Plugin.Log.LogWarning((object)"[OldSa Challenge] Netherworld Rulebook Sprite is not available."); } if (!val.MetaCategories.Contains((ModificationMetaCategory)0)) { val.MetaCategories.Add((ModificationMetaCategory)0); } Plugin.Log.LogInfo((object)"[OldSa Challenge] Netherworld added to Part 1 Rulebook."); return infos; } }