diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d72a40a..f0f3fd6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,17 @@
View Changelog +## 2.18.5 +- Added missing null checks +- Added PlayableCard.GetStatIconHealthBuffs() +- Added PlayableCard.TransformIntoCardAboveHand() - variant of TransformIntoCardInHand that incorporates MoveCardAboveHand +- Added FullAbility.SetExtendedProperty for setting an AbilityInfo's custom property during ability creation +- Fixed DrawCopyOnDeath creating warnings in the console +- Fixed talking cards locking the camera view when obtained during the Trapper boss's final phase +- Fixed ResourceDrone softlocking during Leshy's goodbye sequence if ConfigDefaultDrone is false +- Reverted change to resource drone preventing it from being parented to the scale outside of Act 1 +- Improved visual fix for the full pack Pack Rat sequence + ## 2.18.4 - Fixed Sniper sigil targeting the wrong side of the board - Fixed placeholder tribe choice icons being placed incorrectly diff --git a/InscryptionAPI/Card/AbilityExtensions.cs b/InscryptionAPI/Card/AbilityExtensions.cs index 9a22f159..acc63510 100644 --- a/InscryptionAPI/Card/AbilityExtensions.cs +++ b/InscryptionAPI/Card/AbilityExtensions.cs @@ -500,7 +500,7 @@ public static bool GetHideSingleStacks(this AbilityInfo abilityInfo) #region ExtendedProperties /// - /// Adds a custom property value to the ability. + /// Adds a custom property value to the AbilityInfo. /// /// Ability to access. /// The name of the property to set. @@ -511,6 +511,18 @@ public static AbilityInfo SetExtendedProperty(this AbilityInfo info, string prop info.GetAbilityExtensionTable()[propertyName] = value?.ToString(); return info; } + /// + /// Adds a custom property value to the FullAbility's AbilityInfo - intended as a shorthand for when modders are first adding abilities to the game. + /// + /// FullAbility object to access. + /// The name of the property to set. + /// The value of the property. + /// The same FullAbility so a chain can continue. + public static FullAbility SetExtendedProperty(this FullAbility fullAbility, string propertyName, object value) + { + fullAbility.Info.GetAbilityExtensionTable()[propertyName] = value?.ToString(); + return fullAbility; + } /// /// Gets a custom property value from the card. diff --git a/InscryptionAPI/Card/AbilityManager.cs b/InscryptionAPI/Card/AbilityManager.cs index 19b621b3..439fbd07 100644 --- a/InscryptionAPI/Card/AbilityManager.cs +++ b/InscryptionAPI/Card/AbilityManager.cs @@ -8,6 +8,7 @@ using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; +using System.Text; using UnityEngine; namespace InscryptionAPI.Card; @@ -411,7 +412,6 @@ private static void CleanUpParsedDescription(ref string __result) break; textToCheck = textToCheck.Substring(0, textToCheck.IndexOf("]") + 1); - __result = __result.Replace(textToCheck, textToCheck.Replace("[sigilcost:", "").Replace("]", "")); } } @@ -462,27 +462,27 @@ internal static string ParseAndUpdateDescription(string description, ExtendedAct int endIndex = textToChange.IndexOf("]"); textToChange = textToChange.Substring(0, endIndex + 1); - string allCosts = ""; + StringBuilder allCosts = new(); if (ability.BonesCost > 0) { - allCosts += ability.BonesCost.ToString() + " bone"; + allCosts.Append(ability.BonesCost.ToString() + " bone"); if (ability.BonesCost != 1) - allCosts += "s"; + allCosts.Append("s"); } if (ability.EnergyCost > 0) { - if (allCosts != "") - allCosts += ", "; - allCosts += ability.EnergyCost.ToString() + " energy"; + if (allCosts.ToString() != "") + allCosts.Append(", "); + allCosts.Append(ability.EnergyCost.ToString() + " energy"); } if (ability.HealthCost > 0) { - if (allCosts != "") - allCosts += ", "; - allCosts += ability.HealthCost.ToString() + " health"; + if (allCosts.ToString() != "") + allCosts.Append(", "); + allCosts.Append(ability.HealthCost.ToString() + " health"); } - return description.Replace(textToChange, allCosts == "" ? "nothing" : allCosts); + return description.Replace(textToChange, allCosts.ToString() == "" ? "nothing" : allCosts.ToString()); } string[] blocks = description.Split(' '); diff --git a/InscryptionAPI/Card/CardExtensionsHelpers.cs b/InscryptionAPI/Card/CardExtensionsHelpers.cs index e641188b..9de3474e 100644 --- a/InscryptionAPI/Card/CardExtensionsHelpers.cs +++ b/InscryptionAPI/Card/CardExtensionsHelpers.cs @@ -270,6 +270,21 @@ public static bool LacksAllCardMetaCategories(this CardInfo cardInfo, params Car #region PlayableCard /// + /// Gets the health adjustment given by a PlayableCard's Stat Icon. + /// + /// The PlayableCard to access. + /// How much Health the Stat Icon gives. + public static int GetStatIconHealthBuffs(this PlayableCard card) + { + int num = 0; + foreach (CardModificationInfo temporaryMod in card.TemporaryMods) + { + if (temporaryMod.singletonId == "VARIABLE_STAT") + num += temporaryMod.healthAdjustment; + } + return num; + } + /// /// Gets the number of Ability stacks a card has. /// /// The PlayableCard to access. @@ -592,7 +607,22 @@ public static IEnumerator TransformIntoCardInHand(this PlayableCard card, CardIn Singleton.Instance.SwitchToView(View.Hand); yield return new WaitForSeconds(0.15f); yield return card.Anim.FlipInAir(); + yield return new WaitForSeconds(0.1f); + preTransformCallback?.Invoke(); + card.SetInfo(evolvedInfo); + onTransformedCallback?.Invoke(); + } + /// + /// A version of TransformIntoCardInHand that incorporates MoveCardAboveHand. + /// + public static IEnumerator TransformIntoCardAboveHand(this PlayableCard card, CardInfo evolvedInfo, Action onTransformedCallback = null, Action preTransformCallback = null) + { + Singleton.Instance.SwitchToView(View.Default); + (Singleton.Instance as PlayerHand3D)?.MoveCardAboveHand(card); + yield return new WaitForSeconds(0.15f); + yield return card.Anim.FlipInAir(); + yield return new WaitForSeconds(0.1f); preTransformCallback?.Invoke(); card.SetInfo(evolvedInfo); onTransformedCallback?.Invoke(); diff --git a/InscryptionAPI/Card/TribeManager.cs b/InscryptionAPI/Card/TribeManager.cs index 71dedb01..a98b3e6d 100644 --- a/InscryptionAPI/Card/TribeManager.cs +++ b/InscryptionAPI/Card/TribeManager.cs @@ -29,31 +29,28 @@ private static void UpdateTribeIcon(CardDisplayer3D __instance, CardInfo info) { if (info != null) { - foreach (TribeInfo tribe in tribes) + foreach (TribeInfo tribeInfo in tribes) { - if (tribe?.icon != null) + if (tribeInfo?.icon == null || info.IsNotOfTribe(tribeInfo.tribe)) + continue; + + bool foundSpriteRenderer = false; + foreach (SpriteRenderer spriteRenderer in __instance.tribeIconRenderers) { - if (info.IsOfTribe(tribe.tribe)) + if (spriteRenderer.sprite == null) { - bool foundSpriteRenderer = false; - foreach (SpriteRenderer spriteRenderer in __instance.tribeIconRenderers) - { - if (spriteRenderer.sprite == null) - { - foundSpriteRenderer = true; - spriteRenderer.sprite = tribe.icon; - break; - } - } - if (!foundSpriteRenderer) - { - SpriteRenderer last = __instance.tribeIconRenderers.Last(); - SpriteRenderer spriteRenderer = UnityObject.Instantiate(last); - spriteRenderer.transform.parent = last.transform.parent; - spriteRenderer.transform.localPosition = last.transform.localPosition + (__instance.tribeIconRenderers[1].transform.localPosition - __instance.tribeIconRenderers[0].transform.localPosition); - } + spriteRenderer.sprite = tribeInfo.icon; + foundSpriteRenderer = true; + break; } } + if (!foundSpriteRenderer) + { + SpriteRenderer last = __instance.tribeIconRenderers.Last(); + SpriteRenderer spriteRenderer = UnityObject.Instantiate(last); + spriteRenderer.transform.parent = last.transform.parent; + spriteRenderer.transform.localPosition = last.transform.localPosition + (__instance.tribeIconRenderers[1].transform.localPosition - __instance.tribeIconRenderers[0].transform.localPosition); + } } } } @@ -190,10 +187,7 @@ public static Tribe Add(string guid, string name, string pathToTribeIcon = null, return Add(guid, name, pathToTribeIcon is not null ? TextureHelper.GetImageAsTexture(pathToTribeIcon) : null, appearInTribeChoices, pathToChoiceCardBackTexture is not null ? TextureHelper.GetImageAsTexture(pathToChoiceCardBackTexture) : null); } - public static bool IsCustomTribe(Tribe tribe) - { - return tribeTypes.Contains(tribe); - } + public static bool IsCustomTribe(Tribe tribe) => tribeTypes.Contains(tribe); public static Texture2D GetTribeIcon(Tribe tribe, bool useMissingIconIfNull = true) { @@ -202,14 +196,13 @@ public static Texture2D GetTribeIcon(Tribe tribe, bool useMissingIconIfNull = tr { foreach (TribeInfo tribeInfo in NewTribes) { - if (tribeInfo.tribe == tribe) - { - if (tribeInfo.icon != null && tribeInfo.icon.texture != null) - { - texture2D = tribeInfo.icon.texture; - } - break; - } + if (tribeInfo.tribe != tribe) + continue; + + if (tribeInfo.icon != null && tribeInfo.icon.texture != null) + texture2D = tribeInfo.icon.texture; + + break; } } else @@ -218,15 +211,12 @@ public static Texture2D GetTribeIcon(Tribe tribe, bool useMissingIconIfNull = tr string str = "Art/Cards/TribeIcons/tribeicon_" + tribe.ToString().ToLowerInvariant(); Sprite sprite = ResourceBank.Get(str); if (sprite != null) - { texture2D = sprite.texture; - } } if (texture2D == null && useMissingIconIfNull) - { texture2D = TribeIconMissing; - } + return texture2D; } diff --git a/InscryptionAPI/InscryptionAPI.csproj b/InscryptionAPI/InscryptionAPI.csproj index 48de1b32..92770ac7 100644 --- a/InscryptionAPI/InscryptionAPI.csproj +++ b/InscryptionAPI/InscryptionAPI.csproj @@ -10,7 +10,7 @@ full false true - 2.18.4 + 2.18.5 diff --git a/InscryptionAPI/InscryptionAPIPlugin.cs b/InscryptionAPI/InscryptionAPIPlugin.cs index 991f0051..ec07c1fa 100644 --- a/InscryptionAPI/InscryptionAPIPlugin.cs +++ b/InscryptionAPI/InscryptionAPIPlugin.cs @@ -27,7 +27,7 @@ public class InscryptionAPIPlugin : BaseUnityPlugin { public const string ModGUID = "cyantist.inscryption.api"; public const string ModName = "InscryptionAPI"; - public const string ModVer = "2.18.4"; + public const string ModVer = "2.18.5"; public static string Directory = ""; diff --git a/InscryptionAPI/Totems/TotemManager.cs b/InscryptionAPI/Totems/TotemManager.cs index da72186e..14a53dc2 100644 --- a/InscryptionAPI/Totems/TotemManager.cs +++ b/InscryptionAPI/Totems/TotemManager.cs @@ -18,15 +18,13 @@ internal enum TotemTopState AllTribes } - [HarmonyPatch(typeof(BuildTotemSequencer), "GenerateTotemChoices", new System.Type[] { typeof(BuildTotemNodeData), typeof(int) })] + [HarmonyPatch(typeof(BuildTotemSequencer), "GenerateTotemChoices", new Type[] { typeof(BuildTotemNodeData), typeof(int) })] private class ItemsUtil_AllConsumables { public static IEnumerable Transpiler(IEnumerable instructions) { if (InscryptionAPIPlugin.configCustomTotemTopTypes.Value == TotemTopState.Vanilla) - { return instructions; - } // === We want to turn this @@ -96,7 +94,7 @@ public static void AddCustomTribesToList(List list) } } - [HarmonyPatch(typeof(ResourceBank), "Awake", new System.Type[] { })] + [HarmonyPatch(typeof(ResourceBank), "Awake", new Type[] { })] private class ResourceBank_Awake { public static void Postfix(ResourceBank __instance) diff --git a/InscryptionAPI/Triggers/TakeDamagePatches.cs b/InscryptionAPI/Triggers/TakeDamagePatches.cs index 74b84a95..31158315 100644 --- a/InscryptionAPI/Triggers/TakeDamagePatches.cs +++ b/InscryptionAPI/Triggers/TakeDamagePatches.cs @@ -24,7 +24,7 @@ private static bool AddModifyDamageTrigger(PlayableCard __instance, ref int dama modifyTakeDamage.Sort((a, b) => b.TriggerPriority(__instance, originalDamage, attacker) - a.TriggerPriority(__instance, originalDamage, attacker)); foreach (var modify in modifyTakeDamage) { - if (modify.RespondsToModifyDamageTaken(__instance, damage, attacker, originalDamage)) + if (modify != null && modify.RespondsToModifyDamageTaken(__instance, damage, attacker, originalDamage)) damage = modify.OnModifyDamageTaken(__instance, damage, attacker, originalDamage); } diff --git a/InscryptionCommunityPatch/Card/Vanilla Ability Patches/Act2CuckooFix.cs b/InscryptionCommunityPatch/Card/Vanilla Ability Patches/Act2CuckooFix.cs index 32dcb853..4654a698 100644 --- a/InscryptionCommunityPatch/Card/Vanilla Ability Patches/Act2CuckooFix.cs +++ b/InscryptionCommunityPatch/Card/Vanilla Ability Patches/Act2CuckooFix.cs @@ -10,13 +10,7 @@ namespace InscryptionCommunityPatch.Card; [HarmonyPatch] internal class Act2CuckooFix { - private static MethodBase TargetMethod() - { - MethodBase baseMethod = AccessTools.Method(typeof(CreateEgg), nameof(CreateEgg.OnResolveOnBoard)); - return AccessTools.EnumeratorMoveNext(baseMethod); - } - - [HarmonyTranspiler] + [HarmonyTranspiler, HarmonyPatch(typeof(CreateEgg), nameof(CreateEgg.OnResolveOnBoard), MethodType.Enumerator)] private static IEnumerable FixDialogueSoftlock(IEnumerable instructions) { List codes = new(instructions); diff --git a/InscryptionCommunityPatch/Card/Vanilla Ability Patches/DrawCopyOnDeathFix.cs b/InscryptionCommunityPatch/Card/Vanilla Ability Patches/DrawCopyOnDeathFix.cs new file mode 100644 index 00000000..b3028f91 --- /dev/null +++ b/InscryptionCommunityPatch/Card/Vanilla Ability Patches/DrawCopyOnDeathFix.cs @@ -0,0 +1,19 @@ +using DiskCardGame; +using HarmonyLib; +using InscryptionAPI.Card; +using System.Collections; +using UnityEngine; + +namespace InscryptionCommunityPatch.Card; + +[HarmonyPatch] +internal class DrawCopyOnDeathFix +{ + [HarmonyPatch(typeof(DrawCopyOnDeath), nameof(DrawCopyOnDeath.CardToDraw), MethodType.Getter)] + [HarmonyPostfix] + private static void UseAlternatePortrait(DrawCopyOnDeath __instance, ref CardInfo __result) + { + if (__instance?.Card?.Info != null) + __result = __instance.Card.Info.Clone() as CardInfo; + } +} \ No newline at end of file diff --git a/InscryptionCommunityPatch/ResourceManagers/ActOneEnergyDrone.cs b/InscryptionCommunityPatch/ResourceManagers/ActOneEnergyDrone.cs index c5aaf1f5..4381f1c8 100644 --- a/InscryptionCommunityPatch/ResourceManagers/ActOneEnergyDrone.cs +++ b/InscryptionCommunityPatch/ResourceManagers/ActOneEnergyDrone.cs @@ -15,7 +15,7 @@ public class EnergyConfigInfo { public bool ConfigEnergy => PoolHasEnergy || PatchPlugin.configEnergy.Value; public bool ConfigDrone => PoolHasEnergy || ConfigDroneMox || PatchPlugin.configDrone.Value; - public bool ConfigDefaultDrone => PatchPlugin.configDefaultDrone.Value || !SaveManager.SaveFile.IsPart1; // only parent drone to scale if it's Act 1 + public bool ConfigDefaultDrone => PatchPlugin.configDefaultDrone.Value; public bool ConfigMox => PoolHasGems || PatchPlugin.configMox.Value; public bool ConfigDroneMox => PoolHasGems || PatchPlugin.configDroneMox.Value; } @@ -68,13 +68,12 @@ private static EnergyConfigInfo EnergyConfig private static bool CardIsVisible(this CardInfo info, CardTemple targetTemple) { - if (info.temple != targetTemple) // Non-nature cards can't be selected in Act 1 + // if the CardInfo can't appear in this part of the game - Act 1 = Nature, Grimora = Undead, Magnificus = Wizard + if (info.temple != targetTemple) return false; - // Now we check metacategories // If the card's metacategories are set such that it can't actually appear, don't count it - return info.metaCategories.Exists((CardMetaCategory x) => - x == CardMetaCategory.ChoiceNode || x == CardMetaCategory.TraderOffer || x == CardMetaCategory.Rare); + return info.HasAnyOfCardMetaCategories(CardMetaCategory.ChoiceNode, CardMetaCategory.TraderOffer, CardMetaCategory.Rare); } internal static void TryEnableEnergy(string sceneName) @@ -188,7 +187,7 @@ private static void Part1ResourcesManager_CleanUp(Part1ResourcesManager __instan baseResourceManager.PlayerMaxEnergy = 0; } - if (EnergyConfig.ConfigDrone) + if (EnergyConfig.ConfigDrone && ResourceDrone.m_Instance != null) { ResourceDrone.Instance.CloseAllCells(false); ResourceDrone.Instance.SetOnBoard(false, false); @@ -205,11 +204,11 @@ private static void ResourcesManager_Setup(ResourcesManager __instance) { if (__instance is Part1ResourcesManager && EnergyConfig.ConfigDrone) { - ResourceDrone.Instance.SetOnBoard(true, false); + ResourceDrone.Instance?.SetOnBoard(true, false); if (EnergyConfig.ConfigDroneMox) { PatchPlugin.Logger.LogDebug("Setting up extra resources for the drone."); - ResourceDrone.Instance.Gems.SetAllGemsOn(false, true); + ResourceDrone.Instance?.Gems.SetAllGemsOn(false, true); } } } @@ -221,7 +220,7 @@ private static IEnumerator ResourcesManager_ShowAddMaxEnergy(IEnumerator result, if (__instance is Part1ResourcesManager && EnergyConfig.ConfigDrone) { int cellsToOpen = __instance.PlayerMaxEnergy - 1; - ResourceDrone.Instance.OpenCell(cellsToOpen); + ResourceDrone.Instance?.OpenCell(cellsToOpen); yield return new WaitForSeconds(0.4f); } @@ -237,7 +236,7 @@ private static IEnumerator ResourcesManager_ShowAddEnergy(IEnumerator result, in int num; for (int i = __instance.PlayerEnergy - amount; i < __instance.PlayerEnergy; i = num + 1) { - ResourceDrone.Instance.SetCellOn(i, true, false); + ResourceDrone.Instance?.SetCellOn(i, true, false); yield return new WaitForSeconds(0.05f); num = i; } @@ -259,7 +258,7 @@ private static IEnumerator ResourcesManager_ShowSpendEnergy(IEnumerator result, __instance.transform.position, 0.4f, 0f, new AudioParams.Pitch(0.9f + (float)(__instance.PlayerEnergy + i) * 0.05f), null, null, null, false); - ResourceDrone.Instance.SetCellOn(i, false, false); + ResourceDrone.Instance?.SetCellOn(i, false, false); yield return new WaitForSeconds(0.05f); num = i; } @@ -299,7 +298,7 @@ private static IEnumerator ResourcesManager_ShowLoseGem(IEnumerator result, GemT private static void ResourcesManager_SetGemOnImmediate(GemType gem, bool on, ResourcesManager __instance) { if (__instance is Part1ResourcesManager) - ResourceDrone.Instance.Gems.SetGemOn(gem, on, false); + ResourceDrone.Instance.Gems?.SetGemOn(gem, on, false); } [HarmonyPatch(typeof(TurnManager), nameof(TurnManager.DoUpkeepPhase))] diff --git a/InscryptionCommunityPatch/Sequencers/PackRatNodeBackgroundFix.cs b/InscryptionCommunityPatch/Sequencers/PackRatNodeBackgroundFix.cs index ea474e06..0efb2d09 100644 --- a/InscryptionCommunityPatch/Sequencers/PackRatNodeBackgroundFix.cs +++ b/InscryptionCommunityPatch/Sequencers/PackRatNodeBackgroundFix.cs @@ -1,97 +1,42 @@ using DiskCardGame; using HarmonyLib; +using InscryptionAPI.Helpers; +using InscryptionCommunityPatch.Card; +using Pixelplacement; +using System.Collections; using System.Reflection; using System.Reflection.Emit; +using UnityEngine; namespace InscryptionCommunityPatch.Sequencers; +// 'fixes' the pack rat card not being rare [HarmonyPatch] internal class PackRatNodeBackgroundFix { - private const string name_RatCard = "DiskCardGame.SelectableCard ratCard"; - private const string name_Reward = "DiskCardGame.CardInfo fullConsumablesReward"; - private const string name_PixelPlacement = "Pixelplacement.TweenSystem.TweenBase Position(UnityEngine.Transform, UnityEngine.Vector3, Single, Single, UnityEngine.AnimationCurve, LoopType, System.Action, System.Action, Boolean)"; - private const string name_GetComponent = "DiskCardGame.SelectableCard GetComponent[SelectableCard]()"; - private static MethodBase TargetMethod() + [HarmonyTranspiler, HarmonyPatch(typeof(GainConsumablesSequencer), nameof(GainConsumablesSequencer.FullConsumablesSequence), MethodType.Enumerator)] + private static IEnumerable FixRareBackground(IEnumerable instructions) { - MethodBase baseMethod = AccessTools.Method(typeof(GainConsumablesSequencer), nameof(GainConsumablesSequencer.FullConsumablesSequence)); - return AccessTools.EnumeratorMoveNext(baseMethod); - } - private static IEnumerable Transpiler(IEnumerable instructions) - { - List codes = new List(instructions); - - object op_RatCard = null; - object op_Reward = null; - - // we want to slowly narrow our search until we find exactly where we want to insert our code + List codes = new(instructions); + + // a part of the code block we want to remove can't be removed without breaking the ienum + // so we cut around it for (int i = 0; i < codes.Count; i++) { - // get the ratCard operand - if (codes[i].opcode == OpCodes.Ldfld && codes[i].operand.ToString() == name_RatCard) - op_RatCard = codes[i].operand; - - if (codes[i].opcode == OpCodes.Ldfld && codes[i].operand.ToString() == name_Reward) - op_Reward = codes[i].operand; - - // look for the original code for `component` - if (codes[i].opcode == OpCodes.Callvirt && codes[i].operand.ToString() == name_GetComponent) + if (codes[i].opcode == OpCodes.Callvirt && codes[i].operand.ToString() == "DiskCardGame.SelectableCard GetComponent[SelectableCard]()") { - int startIndex = -1, endIndex = -1; - for (int j = i; j > 0; j--) + int startIndex = i - 3; + for (int j = i + 1; j < codes.Count; j++) { - // find the startIndex - if (codes[j].opcode == OpCodes.Ldarg_0) + if (codes[j].opcode == OpCodes.Stloc_2) { - startIndex = j; + codes.RemoveRange(startIndex, j - 3 - startIndex); break; } } - - // find the endIndex - for (int k = i; k < codes.Count; k++) - { - if (codes[k].opcode == OpCodes.Stloc_2) - { - for (int l = k; l > 0; l--) - { - if (codes[l].opcode == OpCodes.Callvirt) - { - endIndex = l + 1; - break; - } - } - break; - } - } - - MethodInfo customMethod = AccessTools.Method(typeof(PackRatNodeBackgroundFix), nameof(PackRatNodeBackgroundFix.InstantiateSelectableCard), new Type[] { typeof(SelectableCard), typeof(CardInfo) }); - - // remove all the old code - codes.RemoveRange(startIndex, endIndex - startIndex); - - // gainConsumablesSequence.ratCard - codes.Insert(startIndex, new CodeInstruction(OpCodes.Ldloc_1)); - codes.Insert(startIndex + 1, new CodeInstruction(OpCodes.Ldfld, op_RatCard)); - - // gainConsumablesSequence.fullConsumablesReward - codes.Insert(startIndex + 2, new CodeInstruction(OpCodes.Ldloc_1)); - codes.Insert(startIndex + 3, new CodeInstruction(OpCodes.Ldfld, op_Reward)); - - // InstantiateSelectableCard - codes.Insert(startIndex + 4, new CodeInstruction(OpCodes.Call, customMethod)); break; } } - return codes; } - - public static void InstantiateSelectableCard(SelectableCard card, CardInfo info) - { - SelectableCard component = UnityObject.Instantiate(card); - component.SetInfo(info); - component.SetInteractionEnabled(false); - UnityObject.Destroy(component); - } } \ No newline at end of file diff --git a/InscryptionCommunityPatch/Sequencers/TradeableTalkingCardFix.cs b/InscryptionCommunityPatch/Sequencers/TradeableTalkingCardFix.cs new file mode 100644 index 00000000..8b4d68eb --- /dev/null +++ b/InscryptionCommunityPatch/Sequencers/TradeableTalkingCardFix.cs @@ -0,0 +1,53 @@ +using DiskCardGame; +using HarmonyLib; +using InscryptionAPI.Card; +using Pixelplacement; +using System.Collections; +using System.Reflection; +using System.Reflection.Emit; +using UnityEngine; + +namespace InscryptionCommunityPatch.Sequencers; + +[HarmonyPatch] +internal class TradeableTalkingCardFix +{ + [HarmonyPrefix, HarmonyPatch(typeof(TradeCardsForPelts), nameof(TradeCardsForPelts.OnTradableSelected))] + private static bool OnTalkingCardSelected(TradeCardsForPelts __instance, HighlightedInteractable slot, PlayableCard card) + { + if (card != null && card.GetComponent() == null) + return true; + // the card we selected is a talking card + // talking cards change the view when drawn - this changes it back + // transpiler would probably be better but feh + if (__instance.PeltInHand()) + { + AscensionStatsData.TryIncrementStat(AscensionStat.Type.PeltsTraded); + PlayableCard pelt = Singleton.Instance.CardsInHand.Find((PlayableCard x) => x.Info.HasTrait(Trait.Pelt)); + Singleton.Instance.RemoveCardFromHand(pelt); + pelt.SetEnabled(enabled: false); + pelt.Anim.SetTrigger("fly_off"); + Tween.Position(pelt.transform, pelt.transform.position + new Vector3(0f, 3f, 5f), 0.4f, 0f, Tween.EaseInOut, Tween.LoopType.None, null, delegate + { + UnityObject.Destroy(pelt.gameObject); + }); + card.UnassignFromSlot(); + Tween.Position(card.transform, card.transform.position + new Vector3(0f, 0.25f, -5f), 0.3f, 0f, Tween.EaseInOut, Tween.LoopType.None, null, delegate + { + UnityObject.Destroy(card.gameObject); + }); + __instance.StartCoroutine(TradeForTalkingCard(card)); + slot.ClearDelegates(); + slot.HighlightCursorType = CursorType.Default; + } + + return false; + } + + public static IEnumerator TradeForTalkingCard(PlayableCard card) + { + yield return Singleton.Instance.AddCardToHand(CardSpawner.SpawnPlayableCard(card.Info), new Vector3(0f, 0.5f, -3f), 0f); + ViewManager.Instance.SwitchToView(View.OpponentQueue); + ViewManager.Instance.Controller.SwitchToControlMode(ViewController.ControlMode.TraderCardsForPeltsPhase); + } +} \ No newline at end of file