diff --git a/CHANGELOG.md b/CHANGELOG.md
index 89d00a9e..1cf1ade6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+# 2.23.1
+- Fixed non-CardModificationInfo shields not breaking
+- Fixed ShieldGeneratorItem not correclty updating visuals
+- Fixed DamageShieldBehaviours not initialising before being called
+- Added CardInfo.GetAbilityStacks()
+- Changed how DamageShieldBehaviour.ResetShield works to be more inline with how vanilla shields work
+- Removed some shield-reset-related patches
+
# 2.23.0
- Added 'GBC Vanilla Render' config to community patches (false by default) - makes GBC cards render with vanilla cost sprites
- Added 'Vanilla Stacking' config to community patches (false by default) - renders cards with only two (stacking) sigils as they appear in vanilla, eg Spore Mice and Sporedigger
diff --git a/InscryptionAPI/Card/CardExtensionsHelpers.cs b/InscryptionAPI/Card/CardExtensionsHelpers.cs
index 5dc89db1..d953c771 100644
--- a/InscryptionAPI/Card/CardExtensionsHelpers.cs
+++ b/InscryptionAPI/Card/CardExtensionsHelpers.cs
@@ -304,6 +304,22 @@ public static int GetAbilityStacks(this PlayableCard card, Ability ability)
return AbilitiesUtil.GetInfo(ability).canStack ? count : 1;
}
+ ///
+ /// Gets the number of Ability stacks a card has.
+ ///
+ /// The PlayableCard to access.
+ /// The Ability to check for.
+ /// The number of Ability stacks the card has.
+ public static int GetAbilityStacks(this CardInfo info, Ability ability)
+ {
+ int count = info.Abilities.Count(a => a == ability);
+ if (count == 0)
+ return 0;
+
+ // If it's not stackable, you get at most one
+ return AbilitiesUtil.GetInfo(ability).canStack ? count : 1;
+ }
+
///
/// Check if the other PlayableCard is on the same side of the board as this PlayableCard.
///
@@ -776,7 +792,10 @@ public static int GetTotalShields(this PlayableCard card)
// covers for a situation I discovered where you use a SpecialBattleSequencer's triggers to advance a boss fight
// somehow you can end up with a null playablecard which breaks this bit here
if (card == null)
+ {
+ InscryptionAPIPlugin.Logger.LogDebug("[GetTotalShields] Card is null, returning 0.");
return 0;
+ }
int totalShields = 0;
List distinct = new(); // keep track of non-stacking shield abilities so we don't add them again
@@ -792,6 +811,7 @@ public static int GetTotalShields(this PlayableCard card)
}
}
+ //InscryptionAPIPlugin.Logger.LogDebug("[GetTotalShields] Total is " + totalShields);
return totalShields;
}
diff --git a/InscryptionAPI/Card/DamageShieldBehaviour.cs b/InscryptionAPI/Card/DamageShieldBehaviour.cs
index 3bc475f5..e6f44468 100644
--- a/InscryptionAPI/Card/DamageShieldBehaviour.cs
+++ b/InscryptionAPI/Card/DamageShieldBehaviour.cs
@@ -18,13 +18,18 @@ public abstract class DamageShieldBehaviour : AbilityBehaviour
public bool HasShields() => NumShields > 0;
public bool initialised = false;
- public virtual void Start()
+
+ public virtual void Awake()
{
if (base.Card != null)
numShields = StartingNumShields;
initialised = true;
}
+ public virtual void Start()
+ {
+
+ }
public virtual void AddShields(int amount, bool updateDisplay = true)
{
@@ -40,13 +45,15 @@ public virtual void AddShields(int amount, bool updateDisplay = true)
public virtual void RemoveShields(int amount, bool updateDisplay = true)
{
numShields -= amount;
- if (base.Card.GetTotalShields() <= 0)
- base.Card.Status.lostShield = true;
-
- if (!Ability.GetHideSingleStacks() && !HasShields() && !base.Card.Status.hiddenAbilities.Contains(this.Ability))
+ if (!this.HasShields())
{
- base.Card.Status.hiddenAbilities.Add(this.Ability);
- //Debug.Log("Add hidden single");
+ if (Ability.GetHideSingleStacks()) // visually reduce the number of shield stacks
+ {
+ for (int i = 0; i < amount; i++)
+ base.Card.Status.hiddenAbilities.Add(this.Ability);
+ }
+ else if (!base.Card.Status.hiddenAbilities.Contains(this.Ability)) // hide the whole sigil
+ base.Card.Status.hiddenAbilities.Add(this.Ability);
}
if (updateDisplay)
@@ -56,11 +63,15 @@ public virtual void RemoveShields(int amount, bool updateDisplay = true)
}
public virtual void ResetShields(bool updateDisplay)
{
- bool depleted = !HasShields();
+ int currentShields = NumShields;
numShields = StartingNumShields;
base.Card.Status.lostShield = false;
- base.Card.Status.hiddenAbilities.RemoveAll(x => x == this.Ability);
+ for (int i = 0; i < numShields - currentShields; i++)
+ {
+ base.Card.Status.hiddenAbilities.Remove(this.Ability);
+ }
+
if (updateDisplay)
{
base.Card.OnStatsChanged();
diff --git a/InscryptionAPI/Card/ShieldManager.cs b/InscryptionAPI/Card/ShieldManager.cs
index 3b86062a..6964c8ae 100644
--- a/InscryptionAPI/Card/ShieldManager.cs
+++ b/InscryptionAPI/Card/ShieldManager.cs
@@ -23,9 +23,9 @@ public static class ShieldManager
public static List AllShieldAbilities { get; internal set; } = new(AllAbilities);
public static List AllShieldInfos { get; internal set; } = AllShieldAbilities.Select(x => x.Info).ToList();
-
public static IEnumerator TriggerBreakShield(PlayableCard target, int damage, PlayableCard attacker)
{
+ //InscryptionAPIPlugin.Logger.LogDebug("[TriggerBreakShield] Begin");
BreakShield(target, damage, attacker);
List shieldTriggers = CustomTriggerFinder.FindTriggersOnBoard(false).ToList();
@@ -56,9 +56,11 @@ public static void BreakShield(PlayableCard target, int damage, PlayableCard att
DamageShieldBehaviour shield = Array.Find(target.GetComponents(), x => x.HasShields());
if (shield != null)
{
+ //InscryptionAPIPlugin.Logger.LogDebug("[BreakShield] Found DamageShieldBehaviour");
CardModificationInfo info = target.TemporaryMods.Find(x => x.abilities != null && x.abilities.Contains(shield.Ability));
if (info != null)
{
+ //InscryptionAPIPlugin.Logger.LogDebug("[BreakShield] CardModInfo found for behaviour");
target.RemoveTemporaryMod(info, false); // RemoveShields is called here in a patch
info.abilities.Remove(shield.Ability);
target.AddTemporaryMod(info);
@@ -71,6 +73,7 @@ public static void BreakShield(PlayableCard target, int damage, PlayableCard att
target.Anim.StrongNegationEffect();
if (target.GetTotalShields() == 0) // if we removed the last shield
{
+ //InscryptionAPIPlugin.Logger.LogDebug("[BreakShield] TotalShields == 0");
target.Status.lostShield = true;
if (target.Info.HasBrokenShieldPortrait())
target.SwitchToPortrait(target.Info.BrokenShieldPortrait());
@@ -85,20 +88,27 @@ private static void PreventShieldReset(Latch __instance, ref bool __result, Play
if (__instance is LatchDeathShield && card.HasShield())
__result = true;
}
+
[HarmonyPrefix, HarmonyPatch(typeof(LatchDeathShield), nameof(LatchDeathShield.OnSuccessfullyLatched))]
private static bool PreventShieldReset(PlayableCard target)
{
- target.UpdateFaceUpOnBoardEffects();
- return false; // latch death shield doesn't reset shields
+ target.UpdateFaceUpOnBoardEffects(); // latch death shield doesn't reset shields
+ return false;
}
///
- /// The new version of PlayableCard.HasShield implementing the new shield logic.
+ /// Modified version of PlayableCard.HasShield that replaces the original method's result.
///
- public static bool NewHasShield(PlayableCard instance) => instance.GetTotalShields() > 0 && !instance.Status.lostShield;
+ public static bool NewHasShield(PlayableCard instance)
+ {
+ return instance.GetTotalShields() > 0 && !instance.Status.lostShield;
+ }
[HarmonyPostfix, HarmonyPatch(typeof(PlayableCard), nameof(PlayableCard.HasShield))]
- private static void ReplaceHasShieldBool(PlayableCard __instance, ref bool __result) => __result = NewHasShield(__instance);
+ private static void ReplaceHasShieldBool(PlayableCard __instance, ref bool __result)
+ {
+ __result = NewHasShield(__instance);
+ }
[HarmonyPrefix, HarmonyPatch(typeof(PlayableCard), nameof(PlayableCard.ResetShield), new Type[] { })]
private static void ResetModShields(PlayableCard __instance) // runs before the base ResetShield logic
@@ -106,52 +116,9 @@ private static void ResetModShields(PlayableCard __instance) // runs before the
foreach (DamageShieldBehaviour com in __instance.GetComponents())
com.ResetShields(false);
- // if we're using the broken shield portrait, reset to the default portrait - if we're MudTurtle
+ // if we're using the broken shield portrait, reset to the default portrait
if (__instance.Info.name == "MudTurtle" || (__instance.Info.BrokenShieldPortrait() != null && __instance.RenderInfo.portraitOverride == __instance.Info.BrokenShieldPortrait()))
__instance.SwitchToDefaultPortrait();
-
- __instance.Status.lostShield = false;
- }
-
- [HarmonyTranspiler, HarmonyPatch(typeof(ShieldGeneratorItem), nameof(ShieldGeneratorItem.ActivateSequence), MethodType.Enumerator)]
- private static IEnumerable DontResetOnActivate(IEnumerable instructions)
- {
- List codes = new(instructions);
- int index = codes.FindIndex(x => x.operand?.ToString() == "DiskCardGame.BoardManager get_Instance()");
- if (index > 0)
- {
- MethodBase method = AccessTools.Method(typeof(ShieldManager), nameof(ShieldManager.EmptyList));
- codes.RemoveRange(index, 2);
- codes.Insert(index, new(OpCodes.Callvirt, method));
- }
- return codes;
- }
- [HarmonyTranspiler, HarmonyPatch(typeof(ShieldGems), nameof(ShieldGems.OnResolveOnBoard), MethodType.Enumerator)]
- private static IEnumerable DontResetOnResolve(IEnumerable instructions)
- {
- List codes = new(instructions);
- int index = codes.FindLastIndex(x => x.operand?.ToString() == "0.25") - 4;
- if (index > 0)
- {
- MethodBase method = AccessTools.Method(typeof(ShieldManager), nameof(ShieldManager.EmptyList));
- codes.RemoveRange(index, 2);
- codes.Insert(index, new(OpCodes.Callvirt, method));
- }
- return codes;
- }
-
- [HarmonyTranspiler, HarmonyPatch(typeof(RandomCardGainsShieldEffect), nameof(RandomCardGainsShieldEffect.Execute), MethodType.Enumerator)]
- private static IEnumerable DontResetOnExecute(IEnumerable instructions)
- {
- List codes = new(instructions);
- int index = codes.FindLastIndex(x => x.opcode == OpCodes.Newobj);
- if (index > 0)
- {
- MethodBase method = AccessTools.Method(typeof(ShieldManager), nameof(ShieldManager.EmptyList));
- codes.RemoveRange(index, 4);
- codes.Insert(index, new(OpCodes.Callvirt, method));
- }
- return codes;
}
[HarmonyTranspiler, HarmonyPatch(typeof(PlayableCard), nameof(PlayableCard.UpdateFaceUpOnBoardEffects))]
@@ -209,7 +176,7 @@ private static IEnumerable RemoveSingleHiddenStacks(IEnumerable
return codes;
}
- private static List EmptyList() => new(); // for transpiler logic (why can't i just pass an empty list?)
+ private static List EmptyList() => new(); // for transpiler logic
private static List HiddensOnlyRemoveStacks(List abilities, List hiddenAbilities)
{
@@ -222,49 +189,42 @@ private static List HiddensOnlyRemoveStacks(List abilities, Li
}
private static void CorrectHiddenAbilityRender(PlayableCard card)
{
- foreach (DamageShieldBehaviour com in card.GetComponents().Where(x => x.initialised))
- {
- if (com.HasShields())
- {
- if (com.Ability.GetHideSingleStacks())
- {
- // if there are more hidden shields than there should be
- if (card.Status.hiddenAbilities.Count(x => x == com.Ability) >= com.NumShields)
- {
- for (int i = 0; i < com.NumShields; i++)
- {
- card.Status.hiddenAbilities.Remove(com.Ability);
- }
- }
- }
- else
- {
- card.Status.hiddenAbilities.Remove(com.Ability);
- }
- break;
- }
- else
- {
- if (com.Ability.GetHideSingleStacks())
- {
- card.AddShieldCount(1, Ability.DeathShield);
- int shieldsLost = com.StartingNumShields - com.NumShields;
- if (card.Status.hiddenAbilities.Count(x => x == com.Ability) < shieldsLost)
- {
- for (int i = 0; i < shieldsLost; i++)
- {
- //Debug.Log($"{com.StartingNumShields} {com.NumShields} {shieldsLost} Add hidden");
- card.Status.hiddenAbilities.Add(com.Ability);
- }
- }
- }
- else if (!card.Status.hiddenAbilities.Contains(com.Ability))
- {
- card.Status.hiddenAbilities.Add(com.Ability);
- }
- break;
- }
- }
+ //foreach (DamageShieldBehaviour com in card.GetComponents().Where(x => x.initialised))
+ //{
+ // if (com.HasShields())
+ // {
+ // if (com.Ability.GetHideSingleStacks())
+ // {
+ // // if there are more hidden shields than there should be
+ // while (card.Status.hiddenAbilities.Count(x => x == com.Ability) > com.NumShields)
+ // {
+ // card.Status.hiddenAbilities.Remove(com.Ability);
+ // }
+ // }
+ // else
+ // {
+ // card.Status.hiddenAbilities.RemoveAll(x => x == com.Ability);
+ // }
+ // break;
+ // }
+ // else
+ // {
+ // if (com.Ability.GetHideSingleStacks())
+ // {
+ // int shieldsLost = com.StartingNumShields - com.NumShields;
+ // while (card.Status.hiddenAbilities.Count(x => x == com.Ability) < shieldsLost)
+ // {
+ // //Debug.Log($"{com.StartingNumShields} {com.NumShields} {shieldsLost} Add hidden");
+ // card.Status.hiddenAbilities.Add(com.Ability);
+ // }
+ // }
+ // else if (!card.Status.hiddenAbilities.Contains(com.Ability))
+ // {
+ // card.Status.hiddenAbilities.Add(com.Ability);
+ // }
+ // break;
+ // }
+ //}
if (card.Info.HasBrokenShieldPortrait() && card.RenderInfo.portraitOverride == card.Info.BrokenShieldPortrait() && card.HasShield())
{
diff --git a/InscryptionAPI/InscryptionAPI.csproj b/InscryptionAPI/InscryptionAPI.csproj
index 44ac6e8e..82611802 100644
--- a/InscryptionAPI/InscryptionAPI.csproj
+++ b/InscryptionAPI/InscryptionAPI.csproj
@@ -10,7 +10,7 @@
full
false
true
- 2.23.0
+ 2.23.1
diff --git a/InscryptionAPI/InscryptionAPIPlugin.cs b/InscryptionAPI/InscryptionAPIPlugin.cs
index ffeadde4..b16f3b60 100644
--- a/InscryptionAPI/InscryptionAPIPlugin.cs
+++ b/InscryptionAPI/InscryptionAPIPlugin.cs
@@ -30,7 +30,7 @@ public class InscryptionAPIPlugin : BaseUnityPlugin
{
public const string ModGUID = "cyantist.inscryption.api";
public const string ModName = "InscryptionAPI";
- public const string ModVer = "2.23.0";
+ public const string ModVer = "2.23.1";
public static string Directory = "";
diff --git a/InscryptionCommunityPatch/Card/StackAbilityIcons.cs b/InscryptionCommunityPatch/Card/StackAbilityIcons.cs
index 2f8277a4..addbf1a9 100644
--- a/InscryptionCommunityPatch/Card/StackAbilityIcons.cs
+++ b/InscryptionCommunityPatch/Card/StackAbilityIcons.cs
@@ -319,19 +319,20 @@ private static void AddIconNumber(Ability ability, CardInfo info, PlayableCard c
AbilityInfo ai = AbilityManager.AllAbilityInfos.AbilityByID(ability);
if (card != null)
{
- baseAbilities.AddRange(AbilitiesUtil.GetAbilitiesFromMods(card.TemporaryMods/*.Where(x => !x.fromTotem && (!x.fromCardMerge || PatchPlugin.configMergeOnBottom.Value)).ToList()*/));
+ if (ai.IsShieldAbility())
+ count = card.GetShieldBehaviour(ability)?.NumShields;
+
+ baseAbilities.AddRange(AbilitiesUtil.GetAbilitiesFromMods(card.TemporaryMods));
if (ai.GetHideSingleStacks())
{
- for (int i = 0; i < card.Status.hiddenAbilities.Count(x => x == ability); i++)
+ for (int i = 0; i < card.Status.hiddenAbilities.Count; i++)
{
- baseAbilities.Remove(ability);
+ if (card.Status.hiddenAbilities[i] == ability)
+ baseAbilities.Remove(ability);
}
}
else if (card.Status.hiddenAbilities.Contains(ability))
baseAbilities.RemoveAll(x => x == ability);
-
- if (ai.IsShieldAbility())
- count = card.GetShieldBehaviour(ability)?.NumShields;
}
count ??= baseAbilities.Count(ab => ab == ability);
@@ -340,7 +341,7 @@ private static void AddIconNumber(Ability ability, CardInfo info, PlayableCard c
if (count > 1) // we have a stack and need to add an override
{
if (PatchPlugin.doubleStackSplit.Value && count == 2 && count == baseAbilities.Count)
- __instance.SetIcon(__instance.LoadIcon(info, ai, card != null && card.OpponentCard));//RenderSameSigilTwice(__instance, ai, info, card);
+ __instance.SetIcon(__instance.LoadIcon(info, ai, card != null && card.OpponentCard));
else
__instance.SetIcon(PatchTexture(ability, (int)count));
}