Skip to content
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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
20 changes: 20 additions & 0 deletions InscryptionAPI/Card/CardExtensionsHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,22 @@ public static int GetAbilityStacks(this PlayableCard card, Ability ability)
return AbilitiesUtil.GetInfo(ability).canStack ? count : 1;
}

/// <summary>
/// Gets the number of Ability stacks a card has.
/// </summary>
/// <param name="card">The PlayableCard to access.</param>
/// <param name="ability">The Ability to check for.</param>
/// <returns>The number of Ability stacks the card has.</returns>
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;
}

/// <summary>
/// Check if the other PlayableCard is on the same side of the board as this PlayableCard.
/// </summary>
Expand Down Expand Up @@ -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<Ability> distinct = new(); // keep track of non-stacking shield abilities so we don't add them again
Expand All @@ -792,6 +811,7 @@ public static int GetTotalShields(this PlayableCard card)
}
}

//InscryptionAPIPlugin.Logger.LogDebug("[GetTotalShields] Total is " + totalShields);
return totalShields;
}

Expand Down
29 changes: 20 additions & 9 deletions InscryptionAPI/Card/DamageShieldBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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)
Expand All @@ -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();
Expand Down
148 changes: 54 additions & 94 deletions InscryptionAPI/Card/ShieldManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ public static class ShieldManager
public static List<FullAbility> AllShieldAbilities { get; internal set; } = new(AllAbilities);
public static List<AbilityInfo> 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<IShieldPreventedDamage> shieldTriggers = CustomTriggerFinder.FindTriggersOnBoard<IShieldPreventedDamage>(false).ToList();
Expand Down Expand Up @@ -56,9 +56,11 @@ public static void BreakShield(PlayableCard target, int damage, PlayableCard att
DamageShieldBehaviour shield = Array.Find(target.GetComponents<DamageShieldBehaviour>(), 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);
Expand All @@ -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());
Expand All @@ -85,73 +88,37 @@ 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;
}

/// <summary>
/// The new version of PlayableCard.HasShield implementing the new shield logic.
/// Modified version of PlayableCard.HasShield that replaces the original method's result.
/// </summary>
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
{
foreach (DamageShieldBehaviour com in __instance.GetComponents<DamageShieldBehaviour>())
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<CodeInstruction> DontResetOnActivate(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> 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<CodeInstruction> DontResetOnResolve(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> 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<CodeInstruction> DontResetOnExecute(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> 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))]
Expand Down Expand Up @@ -209,7 +176,7 @@ private static IEnumerable<CodeInstruction> RemoveSingleHiddenStacks(IEnumerable
return codes;
}

private static List<CardSlot> EmptyList() => new(); // for transpiler logic (why can't i just pass an empty list?)
private static List<CardSlot> EmptyList() => new(); // for transpiler logic

private static List<Ability> HiddensOnlyRemoveStacks(List<Ability> abilities, List<Ability> hiddenAbilities)
{
Expand All @@ -222,49 +189,42 @@ private static List<Ability> HiddensOnlyRemoveStacks(List<Ability> abilities, Li
}
private static void CorrectHiddenAbilityRender(PlayableCard card)
{
foreach (DamageShieldBehaviour com in card.GetComponents<DamageShieldBehaviour>().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<DamageShieldBehaviour>().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())
{
Expand Down
2 changes: 1 addition & 1 deletion InscryptionAPI/InscryptionAPI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<DebugType>full</DebugType>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<Version>2.23.0</Version>
<Version>2.23.1</Version>
</PropertyGroup>

<PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion InscryptionAPI/InscryptionAPIPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "";

Expand Down
15 changes: 8 additions & 7 deletions InscryptionCommunityPatch/Card/StackAbilityIcons.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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));
}
Expand Down
Loading