Skip to content

Commit f0fbe44

Browse files
authored
Merge branch 'main' into main
2 parents 6fa96b8 + ac5c452 commit f0fbe44

8 files changed

Lines changed: 188 additions & 96 deletions

File tree

InscryptionAPI/Card/AbilityExtensions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -534,8 +534,7 @@ public static AbilityInfo SetHideSingleStacks(this AbilityInfo abilityInfo, bool
534534
/// <returns>Whether single stacks of this ability will be hidden when added to hiddenAbilities.</returns>
535535
public static bool GetHideSingleStacks(this Ability ability)
536536
{
537-
AbilityInfo abilityInfo = AllAbilityInfos.AbilityByID(ability);
538-
return abilityInfo.GetHideSingleStacks();
537+
return AllAbilityInfos.AbilityByID(ability).GetHideSingleStacks();
539538
}
540539
/// <summary>
541540
/// Gets the value of HideSingleStacks. Returns false if HideSingleStacks has not been set.

InscryptionAPI/Card/AbilityManager.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ public static void SyncAbilityList()
200200
AllAbilities = BaseGameAbilities.Concat(NewAbilities).Select(a => a.Clone()).ToList();
201201
AllAbilities = ModifyAbilityList?.Invoke(AllAbilities) ?? AllAbilities;
202202
AllAbilityInfos = AllAbilities.Select(x => x.Info).ToList();
203+
204+
ShieldManager.AllShieldAbilities = AllAbilities.Where(x => x.AbilityBehavior != null && x.AbilityBehavior.IsSubclassOf(typeof(DamageShieldBehaviour))).ToList();
205+
ShieldManager.AllShieldInfos = ShieldManager.AllShieldAbilities.Select(x => x.Info).ToList();
203206
}
204207

205208
static AbilityManager()
@@ -238,13 +241,14 @@ private static List<FullAbility> GenBaseGameAbilityList()
238241
if (name == "DeathShield") // add the API ability behaviour to DeathShield
239242
{
240243
ability.SetPassive(false).SetCanStack(true).SetHideSingleStacks(true);
241-
baseGame.Add(new FullAbility (
244+
FullAbility ab = new(
242245
null,
243246
ability.ability,
244247
ability,
245248
typeof(APIDeathShield),
246249
useReversePatch ? OriginalLoadAbilityIcon(name) : AbilitiesUtil.LoadAbilityIcon(name)
247-
));
250+
);
251+
baseGame.Add(ab);
248252
continue;
249253
}
250254
baseGame.Add(new FullAbility (

InscryptionAPI/Card/CardExtensionsHelpers.cs

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -717,9 +717,13 @@ public static void AddShieldCount(this PlayableCard card, int amount, bool updat
717717
/// <param name="updateDisplay">Whether to update the card's display, meaning sigil stack numbers and any shield effects.</param>
718718
public static void AddShieldCount(this PlayableCard card, int amount, Ability ability, bool updateDisplay = true)
719719
{
720-
Type behav = AbilityManager.AllAbilities.Find(x => x.Id == ability).AbilityBehavior;
721-
DamageShieldBehaviour component = card.GetComponent(behav) as DamageShieldBehaviour;
722-
component?.AddShields(amount, updateDisplay);
720+
DamageShieldBehaviour component = card.GetShieldBehaviour(ability);
721+
if (component == null)
722+
{
723+
InscryptionAPIPlugin.Logger.LogError($"[AddShieldCount] DamageShieldBehaviour of Ability [{ability}] not found!");
724+
return;
725+
}
726+
component.AddShields(amount, updateDisplay);
723727
}
724728
/// <summary>
725729
/// Increases the amount of shields a specific ability's AbilityBehaviour is currently giving.
@@ -749,9 +753,13 @@ public static void RemoveShieldCount(this PlayableCard card, int amount, bool up
749753
/// <param name="updateDisplay">Whether to update the card's display, meaning sigil stack numbers and any shield effects.</param>
750754
public static void RemoveShieldCount(this PlayableCard card, int amount, Ability ability, bool updateDisplay = true)
751755
{
752-
Type behav = AbilityManager.AllAbilities.Find(x => x.Id == ability).AbilityBehavior;
753-
DamageShieldBehaviour component = card.GetComponent(behav) as DamageShieldBehaviour;
754-
component?.RemoveShields(amount, updateDisplay);
756+
DamageShieldBehaviour component = card.GetShieldBehaviour(ability);
757+
if (component == null)
758+
{
759+
InscryptionAPIPlugin.Logger.LogError($"[RemoveShieldCount] DamageShieldBehaviour of Ability [{ability}] not found!");
760+
return;
761+
}
762+
component.RemoveShields(amount, updateDisplay);
755763
}
756764
public static void RemoveShieldCount<T>(this PlayableCard card, int amount, bool updateDisplay = true) where T : DamageShieldBehaviour
757765
{
@@ -786,13 +794,32 @@ public static int GetTotalShields(this PlayableCard card)
786794

787795
return totalShields;
788796
}
797+
798+
/// <summary>
799+
/// Retrieves the current value of a DamageShieldBehaviour's NumShield.
800+
/// </summary>
801+
/// <typeparam name="T"></typeparam>
802+
/// <param name="card"></param>
803+
/// <returns>The current value of the DamageShieldBehaviour's NumShield.</returns>
789804
public static int GetShieldCount<T>(this PlayableCard card) where T : DamageShieldBehaviour
790805
{
791806
T comp = card.GetComponent<T>();
792-
if (comp != null)
793-
return comp.NumShields;
807+
return comp?.NumShields ?? 0;
808+
}
794809

795-
return 0;
810+
/// <summary>
811+
/// Retrieves the DamageShieldBehaviour component corresponding to the given Ability, or null if it does not exist.
812+
/// </summary>
813+
/// <param name="card"></param>
814+
/// <param name="ability"></param>
815+
/// <returns>The DamageShieldBehaviour component of the given Ability, or null if it does not exist.</returns>
816+
public static DamageShieldBehaviour GetShieldBehaviour(this PlayableCard card, Ability ability)
817+
{
818+
Type type = ShieldManager.AllShieldAbilities.AbilityByID(ability)?.AbilityBehavior;
819+
if (type == null)
820+
return null;
821+
822+
return card.GetComponent(type) as DamageShieldBehaviour;
796823
}
797824
/// <summary>
798825
/// A variant of ResetShield that only resets shields belonging is a certain ability.
@@ -806,8 +833,32 @@ public static void ResetShield(this PlayableCard card, Ability ability)
806833
if (com.Ability == ability)
807834
com.ResetShields(false);
808835
}
836+
card.Status.lostShield = false;
837+
}
809838

810-
card.ResetShield();
839+
public static bool IsShieldAbility(this Ability ability)
840+
{
841+
return ShieldManager.AllShieldInfos.AbilityByID(ability) != null;
842+
}
843+
public static bool IsShieldAbility(this AbilityInfo abilityInfo)
844+
{
845+
return ShieldManager.AllShieldInfos.Contains(abilityInfo);
846+
}
847+
/// <summary>
848+
/// Returns whether or not the PlayableCard has an Ability that overrides DamageShieldBehaviour.
849+
/// </summary>
850+
/// <param name="card">The PlayableCard object to check.</param>
851+
public static bool HasShieldAbility(this PlayableCard card)
852+
{
853+
return card.AllAbilities().Exists(x => x.IsShieldAbility());
854+
}
855+
/// <summary>
856+
/// Returns whether or not the CardInfo has an Ability that overrides DamageShieldBehaviour.
857+
/// </summary>
858+
/// <param name="cardInfo">The CardInfo object to check.</param>
859+
public static bool HasShieldAbility(this CardInfo cardInfo)
860+
{
861+
return cardInfo.Abilities.Exists(x => x.IsShieldAbility());
811862
}
812863

813864
#endregion

InscryptionAPI/Card/ShieldManager.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,27 @@
33
using HarmonyLib;
44
using InscryptionAPI.Helpers.Extensions;
55
using System.Collections;
6+
using System.Collections.ObjectModel;
67
using System.Reflection;
78
using System.Reflection.Emit;
89
using UnityEngine;
10+
using static InscryptionAPI.Card.AbilityManager;
11+
912
namespace InscryptionAPI.Card;
1013

14+
/// <summary>
15+
/// This manager class handles the logic for shields.
16+
/// </summary>
1117
[HarmonyPatch]
1218
public static class ShieldManager
1319
{
20+
/// <summary>
21+
/// A list of FullAbilities whose AbilityBehaviour overrides DamageShieldBehaviour.
22+
/// </summary>
23+
public static List<FullAbility> AllShieldAbilities { get; internal set; } = new(AllAbilities);
24+
public static List<AbilityInfo> AllShieldInfos { get; internal set; } = AllShieldAbilities.Select(x => x.Info).ToList();
25+
26+
1427
/// <summary>
1528
/// The method used for when a shielded card is damaged. Includes extra parameters for modders looking to modify this further.
1629
/// This method is only called when damage > 0 and the target has a shield.
@@ -71,8 +84,10 @@ private static void ResetModShields(PlayableCard __instance) // runs before the
7184
com.ResetShields(false);
7285

7386
// if we're using the broken shield portrait, reset to the default portrait - if we're MudTurtle
74-
if ((__instance.Info.BrokenShieldPortrait() != null && __instance.RenderInfo.portraitOverride == __instance.Info.BrokenShieldPortrait()) || __instance.Info.name == "MudTurtle")
87+
if (__instance.Info.name == "MudTurtle" || (__instance.Info.BrokenShieldPortrait() != null && __instance.RenderInfo.portraitOverride == __instance.Info.BrokenShieldPortrait()))
7588
__instance.SwitchToDefaultPortrait();
89+
90+
__instance.Status.lostShield = false;
7691
}
7792

7893
[HarmonyTranspiler, HarmonyPatch(typeof(ShieldGeneratorItem), nameof(ShieldGeneratorItem.ActivateSequence), MethodType.Enumerator)]

InscryptionAPI/Card/TribeManager.cs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,31 @@ public static class TribeManager
2727
[HarmonyPostfix]
2828
private static void UpdateTribeIcon(CardDisplayer3D __instance, CardInfo info)
2929
{
30-
if (info != null)
30+
if (info == null || __instance.tribeIconRenderers.Count == 0)
31+
return;
32+
33+
foreach (TribeInfo tribeInfo in tribes)
3134
{
32-
foreach (TribeInfo tribeInfo in tribes)
33-
{
34-
if (tribeInfo?.icon == null || info.IsNotOfTribe(tribeInfo.tribe))
35-
continue;
35+
if (tribeInfo?.icon == null || info.IsNotOfTribe(tribeInfo.tribe))
36+
continue;
3637

37-
bool foundSpriteRenderer = false;
38-
foreach (SpriteRenderer spriteRenderer in __instance.tribeIconRenderers)
39-
{
40-
if (spriteRenderer.sprite == null)
41-
{
42-
spriteRenderer.sprite = tribeInfo.icon;
43-
foundSpriteRenderer = true;
44-
break;
45-
}
46-
}
47-
if (!foundSpriteRenderer)
38+
bool foundSpriteRenderer = false;
39+
foreach (SpriteRenderer spriteRenderer in __instance.tribeIconRenderers)
40+
{
41+
if (spriteRenderer.sprite == null)
4842
{
49-
SpriteRenderer last = __instance.tribeIconRenderers.Last();
50-
SpriteRenderer spriteRenderer = UnityObject.Instantiate(last);
51-
spriteRenderer.transform.parent = last.transform.parent;
52-
spriteRenderer.transform.localPosition = last.transform.localPosition + (__instance.tribeIconRenderers[1].transform.localPosition - __instance.tribeIconRenderers[0].transform.localPosition);
43+
spriteRenderer.sprite = tribeInfo.icon;
44+
foundSpriteRenderer = true;
45+
break;
5346
}
5447
}
48+
if (!foundSpriteRenderer)
49+
{
50+
SpriteRenderer last = __instance.tribeIconRenderers.Last();
51+
SpriteRenderer spriteRenderer = UnityObject.Instantiate(last);
52+
spriteRenderer.transform.parent = last.transform.parent;
53+
spriteRenderer.transform.localPosition = last.transform.localPosition + (__instance.tribeIconRenderers[1].transform.localPosition - __instance.tribeIconRenderers[0].transform.localPosition);
54+
}
5555
}
5656
}
5757

InscryptionAPI/Helpers/ResourcesManagerHelpers.cs

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,59 @@ namespace InscryptionAPI.Helpers;
99

1010
public static class ResourcesManagerHelpers
1111
{
12+
/// <summary>
13+
/// Removes a given amount of energy cells, which determines how much energy a player has available at the start of a turn.
14+
/// Affected by 'ResourcesManager.preventNextEnergyLoss'.
15+
/// </summary>
16+
/// <param name="instance">The ResourcesManager Instance.</param>
17+
/// <param name="amount">How many energy cells to close. Gets capped to the current number of open energy cells.</param>
1218
public static IEnumerator RemoveMaxEnergy(this ResourcesManager instance, int amount)
1319
{
14-
int num = Mathf.Max(instance.PlayerMaxEnergy - amount, 0);
15-
int numToClose = instance.PlayerMaxEnergy - num;
20+
yield return instance.RemoveMaxEnergy(amount, true);
21+
}
22+
23+
/// <summary>
24+
/// A variant of RemoveMaxEnergy that can bypass ResourcesManager.PreventNextEnergyLoss.
25+
/// Affected by 'ResourcesManager.preventNextEnergyLoss'.
26+
/// </summary>
27+
/// <param name="instance">The ResourcesManager Instance.</param>
28+
/// <param name="amount">How many energy cells to close. Gets capped to the current number of open energy cells.</param>
29+
public static IEnumerator RemoveMaxEnergy(this ResourcesManager instance, int amount, bool preventable)
30+
{
31+
if (preventable && instance.preventNextEnergyLoss)
32+
{
33+
instance.preventNextEnergyLoss = false;
34+
yield break;
35+
}
36+
int numToClose = Mathf.Min(instance.PlayerMaxEnergy, amount);
1637

17-
instance.PlayerMaxEnergy = num;
38+
instance.PlayerMaxEnergy -= numToClose;
1839
if (instance.PlayerEnergy > instance.PlayerMaxEnergy)
19-
instance.PlayerEnergy = instance.PlayerMaxEnergy;
40+
{
41+
instance.PlayerEnergy -= numToClose;
42+
yield return instance.ShowSpendEnergy(numToClose);
43+
}
2044

2145
yield return instance.ShowRemoveMaxEnergy(numToClose);
2246
}
2347
public static IEnumerator ShowRemoveMaxEnergy(this ResourcesManager instance, int amount)
2448
{
25-
if (instance is PixelResourcesManager)
49+
PixelResourcesManager pixelManager = instance as PixelResourcesManager;
50+
for (int i = instance.PlayerMaxEnergy + amount - 1; i >= instance.PlayerMaxEnergy; i--)
2651
{
27-
for (int i = instance.PlayerMaxEnergy + amount - 1; i >= instance.PlayerMaxEnergy; i--)
52+
if (pixelManager != null)
2853
{
2954
AudioController.Instance.PlaySound2D("crushBlip3", MixerGroup.None, 0.4f, 0f, new AudioParams.Pitch(0.9f + (instance.PlayerMaxEnergy + i) * 0.05f));
30-
(instance as PixelResourcesManager).energyRenderers[i].sprite = GetEmptyBatterySprite.emptyBatterySprite;
31-
(instance as PixelResourcesManager).BounceRenderer((instance as PixelResourcesManager).energyRenderers[i].transform);
32-
yield return new WaitForSeconds(0.05f);
55+
pixelManager.energyRenderers[i].sprite = GetEmptyBatterySprite.emptyBatterySprite;
56+
pixelManager.BounceRenderer((instance as PixelResourcesManager).energyRenderers[i].transform);
3357
}
34-
}
35-
else if (ResourceDrone.m_Instance != null)
36-
{
37-
for (int i = instance.PlayerMaxEnergy + amount - 1; i >= instance.PlayerMaxEnergy; i--)
58+
else if (ResourceDrone.m_Instance != null)
3859
{
3960
AudioController.Instance.PlaySound3D("crushBlip3", MixerGroup.TableObjectsSFX, instance.transform.position, 0.4f, 0f, new AudioParams.Pitch(0.9f + (instance.PlayerMaxEnergy + i) * 0.05f));
4061
ResourceDrone.Instance.cellRenderers[i].material.DisableKeyword("_EMISSION");
4162
ResourceDrone.Instance.CloseCell(i, false);
42-
yield return new WaitForSeconds(0.05f);
4363
}
64+
yield return new WaitForSeconds(0.05f);
4465
}
4566
}
4667
public static int GemsOfType(this ResourcesManager instance, GemType gem)

0 commit comments

Comments
 (0)