Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ShieldManager fixes and improvements #307

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 11 additions & 78 deletions InscryptionAPI/Card/CardExtensionsHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -719,43 +719,14 @@ public static void AddShieldCount(this PlayableCard card, int amount, Ability ab
{
Type behav = AbilityManager.AllAbilities.Find(x => x.Id == ability).AbilityBehavior;
DamageShieldBehaviour component = card.GetComponent(behav) as DamageShieldBehaviour;
if (component == null)
return;

component.AddShields(amount, false);
card.Status.lostShield = !card.HasShield();
if (!updateDisplay)
return;

card.UpdateFaceUpOnBoardEffects();
card.RenderCard();
component?.AddShields(amount, updateDisplay);
}
/// <summary>
/// Increases the amount of shields a specific ability's AbilityBehaviour is currently giving.
/// </summary>
public static void AddShieldCount<T>(this PlayableCard card, int amount, bool updateDisplay = true) where T : DamageShieldBehaviour
{
T component = card.GetComponent<T>();
if (component == null)
return;

component.numShields += amount;
if (component.Ability.GetHideSingleStacks()) // remove hidden abilities
card.Status.hiddenAbilities.RemoveAll(x => x == component.Ability);
else
{
for (int i = 0; i < amount; i++)
{
card.Status.hiddenAbilities.Remove(component.Ability);
}
}

card.Status.lostShield = !card.HasShield();
if (!updateDisplay)
return;

card.UpdateFaceUpOnBoardEffects();
card.RenderCard();
card.GetComponent<T>()?.AddShields(amount, updateDisplay);
}

/// <summary>
Expand All @@ -780,56 +751,11 @@ public static void RemoveShieldCount(this PlayableCard card, int amount, Ability
{
Type behav = AbilityManager.AllAbilities.Find(x => x.Id == ability).AbilityBehavior;
DamageShieldBehaviour component = card.GetComponent(behav) as DamageShieldBehaviour;
if (component == null)
return;

component.numShields -= amount;
if (!component.HasShields()) // add hidden abilities
{
if (component.Ability.GetHideSingleStacks() && !card.Status.hiddenAbilities.Contains(component.Ability))
card.Status.hiddenAbilities.Add(component.Ability);
else
{
for (int i = 0; i < amount; i++)
{
card.Status.hiddenAbilities.Add(component.Ability);
}
}
}

card.Status.lostShield = !card.HasShield();
if (!updateDisplay)
return;

card.UpdateFaceUpOnBoardEffects();
card.RenderCard();
component?.RemoveShields(amount, updateDisplay);
}
public static void RemoveShieldCount<T>(this PlayableCard card, int amount, bool updateDisplay = true) where T : DamageShieldBehaviour
{
T component = card.GetComponent<T>();
if (component == null)
return;

component.numShields -= amount;
if (!component.HasShields()) // add hidden abilities
{
if (component.Ability.GetHideSingleStacks() && !card.Status.hiddenAbilities.Contains(component.Ability))
card.Status.hiddenAbilities.Add(component.Ability);
else
{
for (int i = 0; i < amount; i++)
{
card.Status.hiddenAbilities.Add(component.Ability);
}
}
}

card.Status.lostShield = !card.HasShield();
if (!updateDisplay)
return;

card.UpdateFaceUpOnBoardEffects();
card.RenderCard();
card.GetComponent<T>()?.RemoveShields(amount, updateDisplay);
}

/// <summary>
Expand Down Expand Up @@ -860,7 +786,14 @@ public static int GetTotalShields(this PlayableCard card)

return totalShields;
}
public static int GetShieldCount<T>(this PlayableCard card) where T : DamageShieldBehaviour
{
T comp = card.GetComponent<T>();
if (comp != null)
return comp.NumShields;

return 0;
}
/// <summary>
/// A variant of ResetShield that only resets shields belonging is a certain ability.
/// </summary>
Expand Down
26 changes: 4 additions & 22 deletions InscryptionAPI/Card/DamageShieldBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,6 @@ public virtual void AddShields(int amount, bool updateDisplay = true)
if (HasShields())
base.Card.Status.lostShield = false;

if (Ability.GetHideSingleStacks())
{
for (int i = 0; i < amount; i++)
{
base.Card.Status.hiddenAbilities.Remove(this.Ability);
}
}
else if (HasShields() && base.Card.Status.hiddenAbilities.Contains(this.Ability))
{
base.Card.Status.hiddenAbilities.RemoveAll(x => x == this.Ability);
}

if (updateDisplay)
{
base.Card.OnStatsChanged();
Expand All @@ -52,21 +40,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)
if (base.Card.GetTotalShields() <= 0)
base.Card.Status.lostShield = true;

if (Ability.GetHideSingleStacks())
{
for (int i = 0; i < amount; i++)
{
base.Card.Status.hiddenAbilities.Add(this.Ability);
}
}
else if (!HasShields() && !base.Card.Status.hiddenAbilities.Contains(this.Ability))
if (!Ability.GetHideSingleStacks() && !HasShields() && !base.Card.Status.hiddenAbilities.Contains(this.Ability))
{
base.Card.Status.hiddenAbilities.Add(this.Ability);
//Debug.Log("Add hidden single");
}

if (updateDisplay)
{
base.Card.OnStatsChanged();
Expand Down
59 changes: 28 additions & 31 deletions InscryptionAPI/Card/ShieldManager.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
using BepInEx.Logging;
using DiskCardGame;
using DiskCardGame.CompositeRules;
using HarmonyLib;
using InscryptionAPI.Helpers;
using InscryptionAPI.Helpers.Extensions;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
using UnityEngine;

namespace InscryptionAPI.Card;

[HarmonyPatch]
Expand All @@ -23,50 +20,50 @@ public static void BreakShield(PlayableCard target, int damage, PlayableCard att
DamageShieldBehaviour shield = Array.Find(target.GetComponents<DamageShieldBehaviour>(), x => x.HasShields());
if (shield != null)
{
if (target.TemporaryMods.Exists(x => x.abilities != null && x.abilities.Contains(shield.Ability))) // if the sigil is from a temp mod
CardModificationInfo info = target.TemporaryMods.Find(x => x.abilities != null && x.abilities.Contains(shield.Ability));
if (info != null)
{
Ability ability = shield.Ability;
CardModificationInfo info = target.TemporaryMods.Find(x => x.abilities != null && x.abilities.Contains(shield.Ability));
target.RemoveTemporaryMod(info, false); // RemoveShields is called here in a patch

int shieldsToAdd = shield.NumShields - info.abilities.Count(x => x == shield.Ability);
if (shieldsToAdd > 0)
{
CardModificationInfo updatedinfo = new() { fromCardMerge = info.fromCardMerge, fromLatch = info.fromLatch, fromTotem = info.fromTotem };
for (int i = 0; i < shieldsToAdd; i++)
updatedinfo.abilities.Add(ability);

target.AddTemporaryMod(updatedinfo);
}
info.abilities.Remove(shield.Ability);
target.AddTemporaryMod(info);
}
else
{
shield.RemoveShields(1, false);
}
}
target.Anim.StrongNegationEffect();
if (target.GetTotalShields() == 0) // if we removed the last shield
{
target.Status.lostShield = true;
if (target.Info.HasBrokenShieldPortrait())
target.SwitchToPortrait(target.Info.BrokenShieldPortrait());
}

target.OnStatsChanged();
}

[HarmonyPostfix, HarmonyPatch(typeof(Latch), nameof(Latch.CardHasLatchMod))]
private static void PreventShieldReset(Latch __instance, ref bool __result, PlayableCard card)
{
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
}

[HarmonyPostfix, HarmonyPatch(typeof(PlayableCard), nameof(PlayableCard.HasShield))]
private static void ReplaceHasShieldBool(PlayableCard __instance, ref bool __result) => __result = NewHasShield(__instance);
/// <summary>
/// The new version of PlayableCard.HasShield implementing the new shield logic.
/// </summary>
public static bool NewHasShield(PlayableCard instance) => 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);

[HarmonyPrefix, HarmonyPatch(typeof(PlayableCard), nameof(PlayableCard.ResetShield), new Type[] { })]
private static void ResetModShields(PlayableCard __instance) // runs before the base ResetShield logic
{
Expand Down Expand Up @@ -188,25 +185,21 @@ private static void CorrectHiddenAbilityRender(PlayableCard card)
{
foreach (var com in card.GetComponents<DamageShieldBehaviour>())
{
//Debug.Log($"Hidden start: {card.Status.hiddenAbilities.Count(x => x == com.Ability)}");
if (com.HasShields())
{
if (com.Ability.GetHideSingleStacks())
{
// if there are more hidden shields than there should be
if (com.NumShields <= card.Status.hiddenAbilities.Count(x => x == com.Ability))
int removeStacks = card.Status.hiddenAbilities.Count(x => x == com.Ability) - com.NumShields;
for (int i = 0; i < removeStacks; i++)
{
for (int i = 0; i < com.NumShields; i++)
{
card.Status.hiddenAbilities.Remove(com.Ability);
}
card.Status.hiddenAbilities.Remove(com.Ability);
}
}
}
else
{
card.Status.hiddenAbilities.Remove(com.Ability);
}
//Debug.Log($"Hidden Removed: {card.Status.hiddenAbilities.Count(x => x == com.Ability)}");
break;
}
else
Expand All @@ -216,7 +209,6 @@ private static void CorrectHiddenAbilityRender(PlayableCard card)
int shieldsLost = com.StartingNumShields - com.NumShields;
if (card.Status.hiddenAbilities.Count(x => x == com.Ability) < shieldsLost)
{
// if there are less hidden shields than there should be
for (int i = 0; i < shieldsLost; i++)
{
card.Status.hiddenAbilities.Add(com.Ability);
Expand All @@ -227,10 +219,16 @@ private static void CorrectHiddenAbilityRender(PlayableCard card)
{
card.Status.hiddenAbilities.Add(com.Ability);
}
//Debug.Log($"Hidden Added: {card.Status.hiddenAbilities.Count(x => x == com.Ability)}");
break;
}
}

if (card.Info.HasBrokenShieldPortrait() && card.RenderInfo.portraitOverride == card.Info.BrokenShieldPortrait() && card.HasShield())
{
card.Anim.StrongNegationEffect();
card.SwitchToDefaultPortrait();
}

card.RenderCard();
}

Expand Down Expand Up @@ -287,18 +285,17 @@ private static void ClearTemporaryLatchSigils(PlayableCard __instance, CardModif
__instance.StartCoroutine(__instance.Anim.ClearLatchAbility());
}

// disable the module object so it doesn't replay the animation on death
[HarmonyPostfix, HarmonyPatch(typeof(DiskCardAnimationController), nameof(DiskCardAnimationController.ClearLatchAbility))]
private static IEnumerator DisableLatchModule(IEnumerator result, DiskCardAnimationController __instance)
{
yield return result;
if (__instance.latchModule != null)
{
// disable the module object so it doesn't replay the animation on death
__instance.latchModule.gameObject.SetActive(false);
GameObject baseObj = __instance.latchModule.gameObject.FindChild("Base");
if (baseObj != null)
if (baseObj != null) // fixes the latch module animation when re-applying latch sigil to a card
{
// fixes the latch module animation when re-applying latch sigil to a card
baseObj.SetActive(true);
baseObj.transform.localRotation = Quaternion.Euler(0f, 0f, 90f);
}
Expand Down
2 changes: 1 addition & 1 deletion InscryptionAPI/Triggers/TakeDamagePatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ private static IEnumerable<CodeInstruction> TakeDamageTranspiler(IEnumerable<Cod
codes.Insert(shieldStart++, new(OpCodes.Ldfld, damage));
codes.Insert(shieldStart++, new(OpCodes.Ldarg_0));
codes.Insert(shieldStart++, new(OpCodes.Ldfld, attacker));
codes.Insert(shieldStart++, new(OpCodes.Callvirt, breakShield));
codes.Insert(shieldStart++, new(OpCodes.Call, breakShield));
}
break;
}
Expand Down
24 changes: 20 additions & 4 deletions InscryptionCommunityPatch/Card/StackAbilityIcons.cs
Original file line number Diff line number Diff line change
Expand Up @@ -312,14 +312,30 @@ private static void AddIconNumber(Ability ability, CardInfo info, PlayableCard c
// Find all abilities on the card
// Replace all of the textures where it stacks with a texture showing that it stacks
// Okay, go through each ability on the card and see how many instances it has.
List<Ability> baseAbilities = info.Abilities;
List<Ability> baseAbilities = new(info.Abilities);
int count = -1;
if (card != null)
{
baseAbilities.AddRange(AbilitiesUtil.GetAbilitiesFromMods(card.TemporaryMods));
foreach (Ability ab in card.Status.hiddenAbilities)
baseAbilities.Remove(ab);
if (ability.GetHideSingleStacks())
{
for (int i = 0; i < card.Status.hiddenAbilities.Count(x => x == ability); i++)
{
baseAbilities.Remove(ability);
}
}
else if (card.Status.hiddenAbilities.Contains(ability))
baseAbilities.RemoveAll(x => x == ability);

DamageShieldBehaviour behav = card.TriggerHandler.triggeredAbilities.Find(x => x.Item1 == ability)?.Item2 as DamageShieldBehaviour;
if (behav != null)
count = behav.NumShields;
}
int count = baseAbilities.Count(ab => ab == ability);

if (count != -1)
count = baseAbilities.Count(ab => ab == ability);
//Debug.Log($"[{AbilitiesUtil.GetInfo(ability).rulebookName}] {count}");

if (count > 1) // We need to add an override
__instance.SetIcon(PatchTexture(ability, count));
}
Expand Down
Loading