From 343d12c68d4386b996690b8b0210fdbfa2db5e2b Mon Sep 17 00:00:00 2001 From: WhistleWind Date: Tue, 3 Jun 2025 17:01:41 -0700 Subject: [PATCH 1/7] 2.23.2 --- CHANGELOG.md | 6 +++ InscryptionAPI/Assets/ability_evolve_4.png | Bin 0 -> 647 bytes InscryptionAPI/Assets/ability_evolve_5.png | Bin 0 -> 654 bytes InscryptionAPI/Assets/ability_evolve_6.png | Bin 0 -> 658 bytes .../Assets/ability_transformer_4.png | Bin 0 -> 689 bytes .../Assets/ability_transformer_5.png | Bin 0 -> 694 bytes .../Assets/ability_transformer_6.png | Bin 0 -> 703 bytes InscryptionAPI/Card/AbilityManager.cs | 38 ++++++++++--- .../Card/CardAppearanceBehaviourManager.cs | 5 +- InscryptionAPI/Card/CardExtensionsCosts.cs | 50 ++++++++++++++++++ InscryptionAPI/Card/SpecialStatIconManager.cs | 5 +- .../Card/SpecialTriggeredAbilityManager.cs | 5 +- InscryptionAPI/Card/TribeManager.cs | 2 +- InscryptionAPI/Encounters/AIManager.cs | 3 +- InscryptionAPI/Encounters/OpponentManager.cs | 2 +- .../Encounters/SpecialSequenceManager.cs | 3 +- InscryptionAPI/InscryptionAPI.csproj | 2 +- InscryptionAPI/InscryptionAPIPlugin.cs | 18 ++++--- InscryptionAPI/PixelCard/PixelCardManager.cs | 8 +-- .../Animation/GeneratePortrait.cs | 2 +- InscryptionAPI/Totems/TotemManager.cs | 2 +- .../Triggers/SlotAttackSlotPatches.cs | 22 +------- .../Assets/pixel_evolve_4.png | Bin 0 -> 449 bytes .../Assets/pixel_evolve_5.png | Bin 0 -> 448 bytes .../Assets/pixel_evolve_6.png | Bin 0 -> 448 bytes .../Assets/pixel_transformer_1.png | Bin 226 -> 448 bytes .../Assets/pixel_transformer_2.png | Bin 217 -> 453 bytes .../Assets/pixel_transformer_3.png | Bin 232 -> 451 bytes .../Assets/pixel_transformer_4.png | Bin 0 -> 453 bytes .../Assets/pixel_transformer_5.png | Bin 0 -> 450 bytes .../Assets/pixel_transformer_6.png | Bin 0 -> 449 bytes .../Card/Part2CardCostRender.cs | 2 +- .../Card/StackAbilityIcons.cs | 8 +-- .../Act2ShapeshifterPatches.cs | 9 +++- .../EvolveDescriptionFixes.cs | 5 +- .../RandomConsumablePatch.cs | 2 +- .../PixelTutor/PixelPlayableCardArray.cs | 2 +- 37 files changed, 139 insertions(+), 62 deletions(-) create mode 100644 InscryptionAPI/Assets/ability_evolve_4.png create mode 100644 InscryptionAPI/Assets/ability_evolve_5.png create mode 100644 InscryptionAPI/Assets/ability_evolve_6.png create mode 100644 InscryptionAPI/Assets/ability_transformer_4.png create mode 100644 InscryptionAPI/Assets/ability_transformer_5.png create mode 100644 InscryptionAPI/Assets/ability_transformer_6.png create mode 100644 InscryptionCommunityPatch/Assets/pixel_evolve_4.png create mode 100644 InscryptionCommunityPatch/Assets/pixel_evolve_5.png create mode 100644 InscryptionCommunityPatch/Assets/pixel_evolve_6.png create mode 100644 InscryptionCommunityPatch/Assets/pixel_transformer_4.png create mode 100644 InscryptionCommunityPatch/Assets/pixel_transformer_5.png create mode 100644 InscryptionCommunityPatch/Assets/pixel_transformer_6.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cf1ade6..c99d3e8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 2.23.2 +- Fixed error when trying to create cards that evolve/transform in 4 or more turns +- Fixed Fledgling and Transformer sigil appearing as black boxes when a card evolves/transform in 4 or more turns +- Evolve and Transformer icons now show support cards that evolve in 4 or more turns +- Added extension methods for PlayableCard and CardInfo: ProvidesBlueGem, ProvidesGreenGem, ProvidesOrangeGem + # 2.23.1 - Fixed non-CardModificationInfo shields not breaking - Fixed ShieldGeneratorItem not correclty updating visuals diff --git a/InscryptionAPI/Assets/ability_evolve_4.png b/InscryptionAPI/Assets/ability_evolve_4.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2185668173273aeae7692ba477c331efe1c163 GIT binary patch literal 647 zcmeAS@N?(olHy`uVBq!ia0vp^h9Jzr3?yBgHtGQ>#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;R0X`wFKpF^^rtdrtq?k&A{DS{8Jl$^K1>|uSctjR6Fz_7!VaBX$ot!{H zi4xa{lHmNblJdl&REB`W%)AmkKi3ciQ$0gHqu+a&w*l2`OO5bM^YqkW-~e)18Kf9l z85n^qkeSj@HpsOajLcwhCLr68k%>V7NJjy2W;+X5JPXJMf&FES3@?D5g3)M}G61C} zursg#RT>x>8!#?_m$Nv;eZ8x(p2rK(c(crI%W|;Hu zHszH(_br<}d9ll7HTDcg&*mSOUU(k3biU6$`G`~bTE^ssHj?G3B|r9j*bsE?nAgry zre%{2>+~-9R+{8>EvZ}iC}5YqM{dm=w)v1y*L;nOiTaBSl1-A{cZa=Ncy8zMby<&d4H9Asat-vh zZF^`^5qa3poR9Clo4FZZeu5NVH=FsPOBSExd%yo?7tCNc3-Ywg1cjETtDnm{r-UW| D539pT literal 0 HcmV?d00001 diff --git a/InscryptionAPI/Assets/ability_evolve_5.png b/InscryptionAPI/Assets/ability_evolve_5.png new file mode 100644 index 0000000000000000000000000000000000000000..69e05761469b5cff03502ea79717b6c0d85e872c GIT binary patch literal 654 zcmeAS@N?(olHy`uVBq!ia0vp^h9Jzr3?yBgHtGQ>#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;R0X`wFKpF^^rtdrtq?k&A{DS{8Jl$^K1>|uSctjR6Fz_7!VaBX$ot!{H zi4xa{lHmNblJdl&REB`W%)AmkKi3ciQ$0gHqu+a&w*l2`OO5bM^YqkW-~e)18Kf9l z85n^qkeSj@HpsOajLcwhCLr68k%>V7NJjy2W;+X5JPXJMf&FES3@?D5g3)M}G61C} zursg#RT>x>8!#?_m$Nv;eZ8x(p2rK(c(crI%W|;5Y|^*o)|Y>IW~lc+-~Q)b1;aAw8wLA6R6Na) zxoh%Aw9mfWkk3o%^S+e~(YvKRj&-sekll|P~%g?63X;D%$YxK8strbgF+PrR$#5eDTql?)0v9)nVJ5R3hywXoRJm}wy+mD94e@TtAj`RDw{CE2y4{Es{b1)8U; KpUXO@geCx8hsZks literal 0 HcmV?d00001 diff --git a/InscryptionAPI/Assets/ability_evolve_6.png b/InscryptionAPI/Assets/ability_evolve_6.png new file mode 100644 index 0000000000000000000000000000000000000000..202a9d069e6670b9d14c5942174cd97c3d47f76d GIT binary patch literal 658 zcmeAS@N?(olHy`uVBq!ia0vp^h9Jzr3?yBgHtGQ>#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;R0X`wFKpF^^rtdrtq?k&A{DS{8Jl$^K1>|uSctjR6Fz_7!VaBX$ot!{H zi4xa{lHmNblJdl&REB`W%)AmkKi3ciQ$0gHqu+a&w*l2`OO5bM^YqkW-~e)18Kf9l z85n^qkeSj@HpsOajLcwhCLr68k%>V7NJjy2W;+X5JPXJMf&FES3@?D5g3)M}G61C} zursg#RT>x>8!#?_m$Nv;eZ8x(p2rK(c(crI%W|;ILimTeBYo^bZ+#J+4$8GWUwy9PTA<02|4l9}IvTgMe=4dW5T3~3M zo*Xpe{rf%hcp7$WsD3BXZ53~@ELD%yf0uv0px4|UzgeMA(@soh=yv6`VdatC=H&PC zTH^X865>5tg9pkv3){^8tFGGUI{%Tp%1c0&F)0{e97Q`y;Wne)T5i# zC5GAMjf}^ewjQw9a_NJ}52M4rrhI(&TeEUx_BG~d$Z+KdEiQZ_-}}0XNvWM(%=DRT QG$`OaUHx3vIVCg!0RCadH2?qr literal 0 HcmV?d00001 diff --git a/InscryptionAPI/Assets/ability_transformer_4.png b/InscryptionAPI/Assets/ability_transformer_4.png new file mode 100644 index 0000000000000000000000000000000000000000..bc078d0961d8feaaeaa42306f9743139d59184c5 GIT binary patch literal 689 zcmeAS@N?(olHy`uVBq!ia0vp^h9Jzr3?yBgHtGQ>#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;R0X`wFKpF^^rtdrtq?k&A{DS{8Jl$^K1>|uSctjR6Fz_7!VaBX$ot!{H zi4xa{lHmNblJdl&REB`W%)AmkKi3ciQ$0gHqu+a&w*l2`OO5bM^YqkW-~e)18Kf9l z85n^qkeSj@HpsOajLcwhCLr68k%>V7NJjy2W;+X5JPXJMf&FES3@?D5g3)M}G61C} zursg#RT>x>8!#?_m$Nv;eZ8x(p2rK(c(crI%W|;fF~q}rYHwuIVFe!N*}vnfCg?~@a=d+^obfT+{(OC@lHK+Bmcr)C{CD`Sy!E8n z&wG{OjmKZLcw^oqmhY}toUno?XKCc;gUcD(CO-1bJmD_aG}R{a6u0t&CDSCGdO{VK zRta+^onl*fB<=m9vokeY_e_(VoS?DsMd?!Rixat&UM#=zBj}sgjg&m~3EQ1li!n8B z(m9;2nxJaBuT6?^`Jr`D3Wi!g@62h)@2HGEwXj(!aPEZW{`|P#Gw<G{DX5P)RWd!=D(1d$i6x!rc?Ryw7C*p zop=fS?83{1OQQJ*|z`y literal 0 HcmV?d00001 diff --git a/InscryptionAPI/Assets/ability_transformer_5.png b/InscryptionAPI/Assets/ability_transformer_5.png new file mode 100644 index 0000000000000000000000000000000000000000..125c5a794a0de4af22cbe2000a053d176c3a7edb GIT binary patch literal 694 zcmeAS@N?(olHy`uVBq!ia0vp^h9Jzr3?yBgHtGQ>#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;R0X`wFKpF^^rtdrtq?k&A{DS{8Jl$^K1>|uSctjR6Fz_7&Va6R3v)=** zB}!Z)N`mv#O3D+9QW*jgGxJLH{9Hp6O!W-)jDGK7-Ud{&Ej7Y3&C^qhfdj~4WsqWI zWncudKxRrq*&x?yFfxP1nSg9VMkWRUARPt7ne8lK@hl)41a6iwGQ0qK3Pz(@$^ev_ zz|Oz|RB2#jY{0kxVk*c+)&&rgrU2O>zyvgx39K^6(gMhW>M}Gi0Ld=b*thPt=)pI@ zU~~0!aSZYBp4!VfiOGJ)4v_*eJPw5yh`JB zO+akWTV|%+ilu72>`uL&%vUDq^tTzg%+8uAW**Qo@yE2R#zUX(yr1^PO<5`UwvEU> zqoAzJ2$xV7o|PGV9Cn-3o-9p?ZL#XSywFZqTPU(+)s$J4ofWECj}Eu=zY-}jE4t|L zL0Hf>C6b@zc1MP$sch#V&aG8Jx-5oTKkv+G$nU6(KDDrUhSS^$&Cko@e$Twe=Mw*X z!~4&1HxDj}`BCCjHcid0cS7`5b-j*hvK!rt9=tZs(AvK&N=n`0+8(oqQWM!X=gjHU zy*zEI#3PlJ(x-MPwk3W2ye47B{#6auAOCST=DW#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;R0X`wFKpF^^rtdrtq?k&A{DS{8Jl$^K1>|uSctjR6Fz_7&Va6R3v)=** zB}!Z)N`mv#O3D+9QW*jgGxJLH{9Hp6O!W-)jDGK7-Ud{&Ej7Y3&C^qhfdj~4WsqWI zWncudKxRrq*&x?yFfxP1nSg9VMkWRUARPt7ne8lK@hl)41a6iwGQ0qK3Pz(@$^ev_ zz|Oz|RB2#jY{0kxVk*c+)&&rgrU2O>zyvgx39K^6(gMhW>M}Gi0Ld=b*thPt=)pI@ zVDs~IaSZYBp4!VO)@;Dz^!%^>ULg;!thLhT(>b2Je*P=m`cd(pGxIDA_a4gi5=@;b z-sRo3_rReXkC~oFnHL^e!jv^zr@yVJ)8uMd)E$S7J-wSlctxf?uPeX(EX(E1m0iEh zKhBC?rGD73V@1b{pot;J4)=UGF>6D5$4aX-p@~x>43GVo=#k>H=kS9Xv1L}hKiLCC z+0AXbf^Qg4>}F|-?>M1&+f?C(n~Rs`OAi)5jjJA8RXYSvraxz?aXu3r%qMw7_X?+F z#lFwC&YM^ZRL(to&T##kgg`Tyxf5cSb}bexDu3I_yeQ56%|soGziggwFNb(NW;wm; zz2^?MCkM5(!;?;LdFIEnancmtr@Iu}7JdEPldxm|ss>}j|4t8jPfXtR{F}!a>0Jv? z%;&gklDhQflF4eJ_QF~VbT=Attz=h{)LrM^)U)QbL&L;E+0Nc|uek;Ovz1+%Qhps2 N%AT%%F6*2UngHS#=tKYj literal 0 HcmV?d00001 diff --git a/InscryptionAPI/Card/AbilityManager.cs b/InscryptionAPI/Card/AbilityManager.cs index a4d58c6f..83112097 100644 --- a/InscryptionAPI/Card/AbilityManager.cs +++ b/InscryptionAPI/Card/AbilityManager.cs @@ -245,7 +245,7 @@ private static List GenBaseGameAbilityList() } List baseGame = new(); - var gameAsm = typeof(AbilityInfo).Assembly; + Assembly gameAsm = typeof(AbilityInfo).Assembly; foreach (var ability in Resources.LoadAll("Data/Abilities")) { string name = ability.ability.ToString(); @@ -719,18 +719,44 @@ private static IEnumerable EvolveOnUpkeepPatches(IEnumerable 1) { + __result = TextureHelper.GetImageAsTexture($"ability_transformer_{Mathf.Min(info.evolveParams.turnsToEvolve, 6)}.png", InscryptionAPIPlugin.APIAssembly); + return false; + } + if (ability.ability == Ability.Evolve && info?.evolveParams?.turnsToEvolve > 3) { + __result = TextureHelper.GetImageAsTexture($"ability_evolve_{Mathf.Min(info.evolveParams.turnsToEvolve, 6)}.png", InscryptionAPIPlugin.APIAssembly); + return false; + } + return true; + } + [HarmonyPrefix, HarmonyPatch(typeof(AbilitiesUtil), nameof(AbilitiesUtil.LoadAbilityIcon))] + private static bool OverrideEvolveAndTransformerIcon(ref Texture __result, string abilityName) { + if (abilityName.StartsWith("Evolve") || abilityName.StartsWith("Transformer")) { + return false; + } + return true; + } private static void OverrideEvolveDerivedIcon(Evolve evolve, int turnsLeftToEvolve) { if (evolve.Ability == Ability.Evolve) { - evolve.Card.RenderInfo.OverrideAbilityIcon( - Ability.Evolve, ResourceBank.Get("Art/Cards/AbilityIcons/ability_evolve_" + turnsLeftToEvolve) - ); + if (turnsLeftToEvolve > 3) { + evolve.Card.RenderInfo.OverrideAbilityIcon( + Ability.Evolve, TextureHelper.GetImageAsTexture($"ability_evolve_{Mathf.Min(turnsLeftToEvolve, 6)}.png", InscryptionAPIPlugin.APIAssembly) + ); + } + else { + evolve.Card.RenderInfo.OverrideAbilityIcon( + Ability.Evolve, ResourceBank.Get("Art/Cards/AbilityIcons/ability_evolve_" + turnsLeftToEvolve) + ); + } } else if (evolve.Ability == Ability.Transformer && (evolve.Card.Info.evolveParams?.turnsToEvolve ?? 1) != 1) { evolve.Card.RenderInfo.OverrideAbilityIcon( - Ability.Transformer, TextureHelper.GetImageAsTexture($"ability_transformer_{turnsLeftToEvolve}.png", typeof(AbilityManager).Assembly) + Ability.Transformer, TextureHelper.GetImageAsTexture($"ability_transformer_{Mathf.Min(turnsLeftToEvolve, 6)}.png", InscryptionAPIPlugin.APIAssembly) ); } } @@ -808,7 +834,7 @@ private static void LoadTransformerIcon(ref Texture __result, CardInfo info, Abi if (turnsToEvolve <= 1) return; - __result = TextureHelper.GetImageAsTexture($"ability_transformer_{turnsToEvolve}.png", typeof(AbilityManager).Assembly); + __result = TextureHelper.GetImageAsTexture($"ability_transformer_{turnsToEvolve}.png", InscryptionAPIPlugin.APIAssembly); } #endregion diff --git a/InscryptionAPI/Card/CardAppearanceBehaviourManager.cs b/InscryptionAPI/Card/CardAppearanceBehaviourManager.cs index c26739d4..638b54bb 100644 --- a/InscryptionAPI/Card/CardAppearanceBehaviourManager.cs +++ b/InscryptionAPI/Card/CardAppearanceBehaviourManager.cs @@ -1,6 +1,7 @@ using DiskCardGame; using InscryptionAPI.Guid; using System.Collections.ObjectModel; +using System.Reflection; namespace InscryptionAPI.Card; @@ -36,10 +37,10 @@ static CardAppearanceBehaviourManager() private static List GenBaseGameAppearanceList() { List baseGame = new(); - var gameAsm = typeof(CardAppearanceBehaviour).Assembly; + Assembly gameAsm = typeof(CardAppearanceBehaviour).Assembly; foreach (CardAppearanceBehaviour.Appearance ability in Enum.GetValues(typeof(CardAppearanceBehaviour.Appearance))) { - var name = ability.ToString(); + string name = ability.ToString(); baseGame.Add(new FullCardAppearanceBehaviour(ability, gameAsm.GetType($"DiskCardGame.{name}"))); } return baseGame; diff --git a/InscryptionAPI/Card/CardExtensionsCosts.cs b/InscryptionAPI/Card/CardExtensionsCosts.cs index 99e22935..e0975fd2 100644 --- a/InscryptionAPI/Card/CardExtensionsCosts.cs +++ b/InscryptionAPI/Card/CardExtensionsCosts.cs @@ -109,4 +109,54 @@ public static bool OwnerHasBlueGem(this PlayableCard card) return card.OpponentCard ? OpponentGemsManager.Instance.HasGem(GemType.Blue) : ResourcesManager.Instance.HasGem(GemType.Blue); } public static bool IsUsingBlueGem(this PlayableCard card) => card.IsGemified() && card.OwnerHasBlueGem(); + + /// + /// Determines if this card provides its owner with a blue gem. + /// + /// Card to check + public static bool ProvidesBlueGem(this PlayableCard card) + { + return card.HasAbility(Ability.GainGemTriple) || card.HasAbility(Ability.GainGemBlue); + } + /// + /// Determines if this card provides its owner with a green gem. + /// + /// Card to check + public static bool ProvidesGreenGem(this PlayableCard card) + { + return card.HasAbility(Ability.GainGemTriple) || card.HasAbility(Ability.GainGemGreen); + } + /// + /// Determines if this card provides its owner with a orange gem. + /// + /// Card to check + public static bool ProvidesOrangeGem(this PlayableCard card) + { + return card.HasAbility(Ability.GainGemTriple) || card.HasAbility(Ability.GainGemOrange); + } + + /// + /// Determines if this card provides its owner with a blue gem. + /// + /// CardInfo to check + public static bool ProvidesBlueGem(this CardInfo card) + { + return card.HasAbility(Ability.GainGemTriple) || card.HasAbility(Ability.GainGemBlue); + } + /// + /// Determines if this card provides its owner with a green gem. + /// + /// CardInfo to check + public static bool ProvidesGreenGem(this CardInfo card) + { + return card.HasAbility(Ability.GainGemTriple) || card.HasAbility(Ability.GainGemGreen); + } + /// + /// Determines if this card provides its owner with a orange gem. + /// + /// CardInfo to check + public static bool ProvidesOrangeGem(this CardInfo card) + { + return card.HasAbility(Ability.GainGemTriple) || card.HasAbility(Ability.GainGemOrange); + } } \ No newline at end of file diff --git a/InscryptionAPI/Card/SpecialStatIconManager.cs b/InscryptionAPI/Card/SpecialStatIconManager.cs index 3c23b5e1..7804a124 100644 --- a/InscryptionAPI/Card/SpecialStatIconManager.cs +++ b/InscryptionAPI/Card/SpecialStatIconManager.cs @@ -3,6 +3,7 @@ using InscryptionAPI.Guid; using InscryptionAPI.RuleBook; using System.Collections.ObjectModel; +using System.Reflection; using UnityEngine; namespace InscryptionAPI.Card; @@ -84,10 +85,10 @@ static StatIconManager() private static List GenBaseGameStatIconList() { List baseGame = new(); - var gameAsm = typeof(AbilityInfo).Assembly; + Assembly gameAsm = typeof(AbilityInfo).Assembly; foreach (var staticon in Resources.LoadAll("Data/staticons")) { - var name = staticon.iconType.ToString(); + string name = staticon.iconType.ToString(); SpecialTriggeredAbility ab = BASE_GAME_ABILITIES.ContainsKey(staticon.iconType) ? BASE_GAME_ABILITIES[staticon.iconType] : (SpecialTriggeredAbility)Enum.Parse(typeof(SpecialTriggeredAbility), staticon.iconType.ToString()); baseGame.Add(new FullStatIcon(staticon.iconType, ab, staticon, gameAsm.GetType($"DiskCardGame.{name}"))); } diff --git a/InscryptionAPI/Card/SpecialTriggeredAbilityManager.cs b/InscryptionAPI/Card/SpecialTriggeredAbilityManager.cs index 87da2522..ae43c329 100644 --- a/InscryptionAPI/Card/SpecialTriggeredAbilityManager.cs +++ b/InscryptionAPI/Card/SpecialTriggeredAbilityManager.cs @@ -1,6 +1,7 @@ using DiskCardGame; using InscryptionAPI.Guid; using System.Collections.ObjectModel; +using System.Reflection; namespace InscryptionAPI.Card; @@ -45,10 +46,10 @@ static SpecialTriggeredAbilityManager() private static List GenBaseGameSpecialTriggersList() { List baseGame = new(); - var gameAsm = typeof(AbilityInfo).Assembly; + Assembly gameAsm = typeof(AbilityInfo).Assembly; foreach (SpecialTriggeredAbility ability in Enum.GetValues(typeof(SpecialTriggeredAbility))) { - var name = ability.ToString(); + string name = ability.ToString(); baseGame.Add(new(null, name, ability, gameAsm.GetType($"DiskCardGame.{name}"))); } return baseGame; diff --git a/InscryptionAPI/Card/TribeManager.cs b/InscryptionAPI/Card/TribeManager.cs index e3bb5360..0b96aca4 100644 --- a/InscryptionAPI/Card/TribeManager.cs +++ b/InscryptionAPI/Card/TribeManager.cs @@ -142,7 +142,7 @@ public static Tribe Add(string guid, string name, Texture2D tribeIcon = null, bo } private static Texture2D MakePlaceholderCardback(Texture2D tribeIcon) { - Texture2D emptyCardback = TextureHelper.GetImageAsTexture("empty_rewardCardBack.png", typeof(TribeManager).Assembly); + Texture2D emptyCardback = TextureHelper.GetImageAsTexture("empty_rewardCardBack.png", InscryptionAPIPlugin.APIAssembly); if (tribeIcon == null) // if no tribe icon, return the empty card texture return emptyCardback; diff --git a/InscryptionAPI/Encounters/AIManager.cs b/InscryptionAPI/Encounters/AIManager.cs index c28cd0b7..a8fc4004 100644 --- a/InscryptionAPI/Encounters/AIManager.cs +++ b/InscryptionAPI/Encounters/AIManager.cs @@ -1,6 +1,7 @@ using DiskCardGame; using InscryptionAPI.Guid; using System.Collections.ObjectModel; +using System.Reflection; namespace InscryptionAPI.Encounters; @@ -36,7 +37,7 @@ static AIManager() private static List GenBaseGameAIsList() { List baseGame = new(); - var gameAsm = typeof(AI).Assembly; + Assembly gameAsm = typeof(AI).Assembly; foreach (Type aiType in gameAsm.GetTypes().Where(type => type.IsSubclassOf(typeof(AI)))) { baseGame.Add(new(aiType.Name, aiType)); diff --git a/InscryptionAPI/Encounters/OpponentManager.cs b/InscryptionAPI/Encounters/OpponentManager.cs index 7548873d..4ae483c6 100644 --- a/InscryptionAPI/Encounters/OpponentManager.cs +++ b/InscryptionAPI/Encounters/OpponentManager.cs @@ -53,7 +53,7 @@ private static List GenBaseGameOpponents() } List baseGame = new(); - var gameAsm = typeof(Opponent).Assembly; + Assembly gameAsm = typeof(Opponent).Assembly; foreach (Opponent.Type opponent in Enum.GetValues(typeof(Opponent.Type))) { string specialSequencerId = useReversePatch ? OriginalGetSequencerIdForBoss(opponent) : BossBattleSequencer.GetSequencerIdForBoss(opponent); diff --git a/InscryptionAPI/Encounters/SpecialSequenceManager.cs b/InscryptionAPI/Encounters/SpecialSequenceManager.cs index ad9142c1..e1396663 100644 --- a/InscryptionAPI/Encounters/SpecialSequenceManager.cs +++ b/InscryptionAPI/Encounters/SpecialSequenceManager.cs @@ -1,6 +1,7 @@ using DiskCardGame; using InscryptionAPI.Guid; using System.Collections.ObjectModel; +using System.Reflection; namespace InscryptionAPI.Encounters; @@ -38,7 +39,7 @@ static SpecialSequenceManager() private static List GenBaseGameSpecialSequencersList() { List baseGame = new(); - var gameAsm = typeof(SpecialBattleSequencer).Assembly; + Assembly gameAsm = typeof(SpecialBattleSequencer).Assembly; foreach (Type sequencer in gameAsm.GetTypes().Where(type => type.IsSubclassOf(typeof(SpecialBattleSequencer)))) { baseGame.Add(new(sequencer.Name, sequencer)); diff --git a/InscryptionAPI/InscryptionAPI.csproj b/InscryptionAPI/InscryptionAPI.csproj index 82611802..a3a6cf3c 100644 --- a/InscryptionAPI/InscryptionAPI.csproj +++ b/InscryptionAPI/InscryptionAPI.csproj @@ -10,7 +10,7 @@ full false true - 2.23.1 + 2.23.2 diff --git a/InscryptionAPI/InscryptionAPIPlugin.cs b/InscryptionAPI/InscryptionAPIPlugin.cs index b16f3b60..7fb8fdc8 100644 --- a/InscryptionAPI/InscryptionAPIPlugin.cs +++ b/InscryptionAPI/InscryptionAPIPlugin.cs @@ -16,6 +16,7 @@ using InscryptionAPI.RuleBook; using InscryptionAPI.Slots; using InscryptionAPI.Totems; +using System.Reflection; using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Assembly-CSharp")] @@ -30,10 +31,12 @@ public class InscryptionAPIPlugin : BaseUnityPlugin { public const string ModGUID = "cyantist.inscryption.api"; public const string ModName = "InscryptionAPI"; - public const string ModVer = "2.23.1"; + public const string ModVer = "2.23.2"; public static string Directory = ""; + internal static Assembly APIAssembly { get; private set; } = null; + internal static ConfigEntry configOverrideArrows; internal static ConfigEntry configRandomChoiceOrder; internal static ConfigEntry configHideAct1BossScenery; @@ -46,7 +49,7 @@ static InscryptionAPIPlugin() { if (e.Name.StartsWith("API, Version=1")) { - return typeof(InscryptionAPIPlugin).Assembly; + return APIAssembly ??= typeof(InscryptionAPIPlugin).Assembly; } return null; }; @@ -67,7 +70,7 @@ private void OnEnable() Logger = base.Logger; Directory = Path.GetDirectoryName(Info.Location); - HarmonyInstance.PatchAll(typeof(InscryptionAPIPlugin).Assembly); + HarmonyInstance.PatchAll(InscryptionAPIPlugin.APIAssembly); } private void OnDisable() @@ -90,7 +93,7 @@ internal static void ResyncAll() internal static void CheckForOutdatedPlugins() { string outdatedPlugins = ""; - foreach (var pluginAsm in Chainloader.PluginInfos.Values.Select(p => p.Instance.GetType().Assembly).Distinct()) + foreach (Assembly pluginAsm in Chainloader.PluginInfos.Values.Select(p => p.Instance.GetType().Assembly).Distinct()) { foreach (var refAsm in pluginAsm.GetReferencedAssemblies()) { @@ -108,6 +111,7 @@ internal static void CheckForOutdatedPlugins() private void Awake() { + APIAssembly ??= typeof(InscryptionAPIPlugin).Assembly; configCustomTotemTopTypes = Config.Bind("Totems", "Top Types", TotemManager.TotemTopState.CustomTribes, "If Vanilla, don't change totem tops; if CustomTribes, added custom tribes will use custom totem tops; if AllTribes then all totem tops will use a custom top."); configCustomItemTypes = Config.Bind("Items", "Types", ConsumableItemManager.ConsumableState.Custom, "If Vanilla, only vanilla items will be used; if Custom, added custom items will use custom models; if All then all items will use a custom model."); configOverrideArrows = Config.Bind("Menus", "Override Arrows", false, "When true, forces the challenge screen arrows to appear at the top of the screen instead of the sides."); @@ -125,10 +129,10 @@ private void Start() CardManager.AuditCardList(); PixelCardManager.Initialise(); PeltManager.CreateDialogueEvents(); - if (!DialogueManager.CustomDialogue.Exists(x => x.DialogueEvent.id == "Hint_NotEnoughSameColourGemsHint")) - { + //if (!DialogueManager.CustomDialogue.Exists(x => x.DialogueEvent.id == "Hint_NotEnoughSameColourGemsHint")) + //{ - } + //} Logger.LogDebug($"Inserted {DialogueManager.CustomDialogue.Count} dialogue event(s)!"); } diff --git a/InscryptionAPI/PixelCard/PixelCardManager.cs b/InscryptionAPI/PixelCard/PixelCardManager.cs index 2b89df7a..dc40ce00 100644 --- a/InscryptionAPI/PixelCard/PixelCardManager.cs +++ b/InscryptionAPI/PixelCard/PixelCardManager.cs @@ -36,10 +36,10 @@ public static PixelDecalData AddGBCDecal(string pluginGUID, string textureName, } internal static void Initialise() { - PixelGemifiedDecal = TextureHelper.GetImageAsSprite("PixelGemifiedDecal.png", typeof(PixelCardManager).Assembly, TextureHelper.SpriteType.PixelDecal); - PixelGemifiedOrangeLit = TextureHelper.GetImageAsSprite("PixelGemifiedOrange.png", typeof(PixelCardManager).Assembly, TextureHelper.SpriteType.PixelDecal); - PixelGemifiedGreenLit = TextureHelper.GetImageAsSprite("PixelGemifiedGreen.png", typeof(PixelCardManager).Assembly, TextureHelper.SpriteType.PixelDecal); - PixelGemifiedBlueLit = TextureHelper.GetImageAsSprite("PixelGemifiedBlue.png", typeof(PixelCardManager).Assembly, TextureHelper.SpriteType.PixelDecal); + PixelGemifiedDecal = TextureHelper.GetImageAsSprite("PixelGemifiedDecal.png", InscryptionAPIPlugin.APIAssembly, TextureHelper.SpriteType.PixelDecal); + PixelGemifiedOrangeLit = TextureHelper.GetImageAsSprite("PixelGemifiedOrange.png", InscryptionAPIPlugin.APIAssembly, TextureHelper.SpriteType.PixelDecal); + PixelGemifiedGreenLit = TextureHelper.GetImageAsSprite("PixelGemifiedGreen.png", InscryptionAPIPlugin.APIAssembly, TextureHelper.SpriteType.PixelDecal); + PixelGemifiedBlueLit = TextureHelper.GetImageAsSprite("PixelGemifiedBlue.png", InscryptionAPIPlugin.APIAssembly, TextureHelper.SpriteType.PixelDecal); } [HarmonyPostfix, HarmonyPatch(typeof(CardAppearanceBehaviour), nameof(CardAppearanceBehaviour.Card), MethodType.Getter)] diff --git a/InscryptionAPI/TalkingCards/Animation/GeneratePortrait.cs b/InscryptionAPI/TalkingCards/Animation/GeneratePortrait.cs index 5bcfe9c1..bdf295e1 100644 --- a/InscryptionAPI/TalkingCards/Animation/GeneratePortrait.cs +++ b/InscryptionAPI/TalkingCards/Animation/GeneratePortrait.cs @@ -61,7 +61,7 @@ private static void LoadPrefab() private static byte[] LoadResource(string resourceName) { - Assembly target = typeof(InscryptionAPIPlugin).Assembly; + Assembly target = InscryptionAPIPlugin.APIAssembly; using (Stream resourceStream = target.GetManifestResourceStream(resourceName)) { using (MemoryStream memoryStream = new MemoryStream()) diff --git a/InscryptionAPI/Totems/TotemManager.cs b/InscryptionAPI/Totems/TotemManager.cs index 0bb4dab3..12693a05 100644 --- a/InscryptionAPI/Totems/TotemManager.cs +++ b/InscryptionAPI/Totems/TotemManager.cs @@ -293,7 +293,7 @@ public static void SetDefaultTotemTop(GameObject gameObject) where T : Compos private static void InitializeDefaultTotemTop() { - byte[] resourceBytes = TextureHelper.GetResourceBytes("customtotemtop", typeof(InscryptionAPIPlugin).Assembly); + byte[] resourceBytes = TextureHelper.GetResourceBytes("customtotemtop", InscryptionAPIPlugin.APIAssembly); if (AssetBundleHelper.TryGet(resourceBytes, "CustomTotemTop", out GameObject go)) { defaultTotemTop = NewTopPiece("DefaultTotemTop", diff --git a/InscryptionAPI/Triggers/SlotAttackSlotPatches.cs b/InscryptionAPI/Triggers/SlotAttackSlotPatches.cs index 79111558..d162fe6d 100644 --- a/InscryptionAPI/Triggers/SlotAttackSlotPatches.cs +++ b/InscryptionAPI/Triggers/SlotAttackSlotPatches.cs @@ -101,27 +101,7 @@ private static IEnumerable Transpiler(IEnumerable x.opcode == OpCodes.Ldfld && x.operand.ToString() == name_OpposingSlot).operand; // we want to slowly narrow our search until we find exactly where we want to insert our code - /*for (int a = 0; a < codes.Count; a++) - { - // separated into their own methods so I can save on eye strain and brain fog - if (ModifyDirectDamageCheck(codes, combatPhaseOperand, attackingSlotOperand, opposingSlotOperand, ref a)) - { - for (int b = a; b < codes.Count; b++) - { - if (CallTriggerOnDirectDamage(codes, opposingSlotOperand, ref b)) - { - for (int c = b; c < codes.Count; c++) - { - if (OpposingCardNullCheck(codes, opposingSlotOperand, combatPhaseOperand, attackingSlotOperand, c)) - break; - } - break; - } - } - break; - } - }*/ - + // transpiler separated into different methods for sake of clarity int a = ModifyDirectDamageCheck(codes, displayClassOperand, attackingSlotOperand, opposingSlotOperand); a = CallTriggerOnDirectDamage(codes, a, displayClassOperand, attackingSlotOperand, opposingSlotOperand); OpposingCardNullCheck(codes, a, opposingSlotOperand, displayClassOperand, attackingSlotOperand); diff --git a/InscryptionCommunityPatch/Assets/pixel_evolve_4.png b/InscryptionCommunityPatch/Assets/pixel_evolve_4.png new file mode 100644 index 0000000000000000000000000000000000000000..8467a0f20961eab6ac6ca6b69ce96a13345eb33a GIT binary patch literal 449 zcmeAS@N?(olHy`uVBq!ia0vp^f*{Pn3?z9rZ$AN~7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%x0%;&vn!fWqkYXwc@(cdY@N~O@7m&wU;1OBOz`(a3gc&VZgH?cn z5+$w?CBgY=CFO}lsSE*$nRz98ey$-3rh0~YM!)wkZv(2?mKx!i=IN=$zyaj2GDtD9 zGB5&JATy<*Y>;a;7@5K1OhC3FBNKxFkd6Z4%yt&AcovWi0=;F73@?D5g3)M}G61C} zursg#RT>x>8!#?_m$Nv;eZ8x(p2rK(d|ucb)6l_6P%+ z0iG_7AsWH4z1(~Z3LH*f|4sL^Q|;EB+P?19y2^!89|RRjv(0vFnQiidUsbS(At%L8 zeFb*tmu?FGxcf<}^^bSVc|8ov;^H?bgY5Bi^>bP0l+XkK DipgOk literal 0 HcmV?d00001 diff --git a/InscryptionCommunityPatch/Assets/pixel_evolve_5.png b/InscryptionCommunityPatch/Assets/pixel_evolve_5.png new file mode 100644 index 0000000000000000000000000000000000000000..2c30d1a763ea756d7926de7fd8caa3370bd6c798 GIT binary patch literal 448 zcmeAS@N?(olHy`uVBq!ia0vp^f*{Pn3?z9rZ$AN~7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%x0%;&vn!fWqkYXwc@(cdY@N~O@7m&wU;1OBOz`(a3gc&VZgH?cn z5+$w?CBgY=CFO}lsSE*$nRz98ey$-3rh0~YM!)wkZv(2?mKx!i=IN=$zyaj2GDtD9 zGB5&JATy<*Y>;a;7@5K1OhC3FBNKxFkd6Z4%yt&AcovWi0=;F73@?D5g3)M}G61C} zursg#RT>x>8!#?_m$Nv;eZ8x(p2rK(d|ucb)6l_6P%+ z{+=$5AsWH4y$5+23^@*;`scm9u*uk44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%x0%;&vn!fWqkYXwc@(cdY@N~O@7m&wU;1OBOz`(a3gc&VZgH?cn z5+$w?CBgY=CFO}lsSE*$nRz98ey$-3rh0~YM!)wkZv(2?mKx!i=IN=$zyaj2GDtD9 zGB5&JATy<*Y>;a;7@5K1OhC3FBNKxFkd6Z4%yt&AcovWi0=;F73@?D5g3)M}G61C} zursg#RT>x>8!#?_m$Nv;eZ8x(p2rK(d|ucb)6l_6P%+ z{+=$5AsWHHy^MSeiadwz{I{ zLYWh|I}BAc4ClR+dZ?XV8Tw*x(Vpk44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%x0%;&vn!fWqkYXwc@(cdY@N~O@7m&wU;1OBOz`(a3gc&VZgH?cn z5+$w?CBgY=CFO}lsSE*$nRz98ey$-3rh0~YM!)wkZv(2?mKx!i=IN=$zyaj2GDtD9 zGB5&JATy<*Y>;a;7@5K1OhC3FBNKxFkd6Z4%yt&AcovWi0=;F73@?D5g3)M}G61C} zursg#RT>x>8!#?_m$Nv;eZ8x(p2rK(d|ucb)6l_6P%+ z{+=$5AsWH4z1(~Z1}x4y|1Wj7KQXJPYFCHO!hnN{Y*V%6b=Th#&`@9WK*&PrX}aqB zNAAu1uXZ=3&FaZCm%o_H{ar8dgFushGnf9=2|pQ1b}^jYTx=Bsvc}WZ&t;ucLK6Ud C;bJua delta 148 zcmX@W{D^UaqatU3Plzi66B`2 zoO}$597h`d+gHuyTX3_JeTvj#KZ`jf!rekbUGAKQ8S6c}r>}5&8hYvWX47ML^-QiF yn)Nnk`?-KvuA>6&|KpNADze$PPu^8LYZd=jBgW-yf4iJO_IkSdxvX3CK2NWMU8i(osO1+0FtM&jPYRptp>X z;RQ2zW$#dC%Yhb+LFLiS0ii_bXIvKZ8NC) z+2fLzxWj#kjQH)+RX%q{Ec0~rb6Mw<&;$UYO;R8L delta 106 zcmV-w0G0p61K9zPc4JOSL_t(2Q(cV#4geqs0_Fdo4g{x*HGXYA zC@l%P#Ap&NXnDJdYD#khdUm@z%RQEqPw(OApnYZASLb&t%W3Ms18}SWrx>qXD*ylh M07*qoM6N<$f|GYDLjV8( diff --git a/InscryptionCommunityPatch/Assets/pixel_transformer_3.png b/InscryptionCommunityPatch/Assets/pixel_transformer_3.png index d48ce46ea9a1470a8bce4338a5d56423fb27d888..916104668a9f7bd8cef86b81351c96517db9f815 100644 GIT binary patch literal 451 zcmeAS@N?(olHy`uVBq!ia0vp^f*{Pn3?z9rZ$AN~7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%x0%;&vn!fWqkYXwc@(cdY@N~O@7m&wU;1OBOz`(a3gc&VZgH?cn z5+$w?CBgY=CFO}lsSE*$nRz98ey$-3rh0~YM!)wkZv(2?mKx!i=IN=$zyaj2GDtD9 zGB5&JATy<*Y>;a;7@5K1OhC3FBNKxFkd6Z4%yt&AcovWi0=;F73@?D5g3)M}G61C} zursg#RT>x>8!#?_m$Nv;eZ8x(p2rK(d|ucb)6l_6P%+ zL7py-AsWH4y_|duh8#>^|Ic5?mo$5lPLZi}WP_BTVsN;|{aq)nuHi^?UpnuKbjzZz zw<=RVsUK|Kxt-~C+2bw#%nw~2)aNgHI9cO|nL$;6+GmDhJ%%%H94f;=HhH@GxvX zoO}$59L$>k>$lh*FukoYtxRaOCjZJ+n?Cejn2^3v)cAsx1Yg3`doPWQ+_rWXE=XFT zxKDa<*zqg(UgS-`8PcD!+4IT&dnykmtNbvW_f1*vF8g~u#ziU(W{W|#d%F6$taD0e F0s!b>Jx2fl diff --git a/InscryptionCommunityPatch/Assets/pixel_transformer_4.png b/InscryptionCommunityPatch/Assets/pixel_transformer_4.png new file mode 100644 index 0000000000000000000000000000000000000000..968ff26560f6c145502fe9b98b432bc479bb7adf GIT binary patch literal 453 zcmeAS@N?(olHy`uVBq!ia0vp^f*{Pn3?z9rZ$AN~7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%x0%;&vn!fWqkYXwc@(cdY@N~O@7m&wU;1OBOz`(a3gc&VZgH?cn z5+$w?CBgY=CFO}lsSE*$nRz98ey$-3rh0~YM!)wkZv(2?mKx!i=IN=$zyaj2GDtD9 zGB5&JATy<*Y>;a;7@5K1OhC3FBNKxFkd6Z4%yt&AcovWi0=;F73@?D5g3)M}G61C} zursg#RT>x>8!#?_m$Nv;eZ8x(p2rK(d|ucb)6l_6P%+ zA)YRdAsWH4y^KN(iX2Q||IfEe*g7lOt8nScD6h^{5?2BpucR%_V)oE0+rU20QrNuX zt5neJ9paDI^7EIA&V89OZC9kBcfh}D&V%g?bu+L0nArA?ztETARLGX>7LZ+@u6{1- HoD!Mk44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%x0%;&vn!fWqkYXwc@(cdY@N~O@7m&wU;1OBOz`(a3gc&VZgH?cn z5+$w?CBgY=CFO}lsSE*$nRz98ey$-3rh0~YM!)wkZv(2?mKx!i=IN=$zyaj2GDtD9 zGB5&JATy<*Y>;a;7@5K1OhC3FBNKxFkd6Z4%yt&AcovWi0=;F73@?D5g3)M}G61C} zursg#RT>x>8!#?_m$Nv;eZ8x(p2rK(d|ucb)6l_6P%+ zfu1goAsWH4y^MSe3LH$I|IhccDAb+a#U8zUm(7+~4dycQV-Z3PPtLq?o;=AkEw9MS zGku9*(bqX%!PU8HA*b(qv;_QnugW6N^uuW0wcy&2*nA&`6HnWBJqB6i>FVdQ&MBb@ E05c_H)Bpeg literal 0 HcmV?d00001 diff --git a/InscryptionCommunityPatch/Assets/pixel_transformer_6.png b/InscryptionCommunityPatch/Assets/pixel_transformer_6.png new file mode 100644 index 0000000000000000000000000000000000000000..b395c7e49eb7b1104a4a5670eff4b88b32c82104 GIT binary patch literal 449 zcmeAS@N?(olHy`uVBq!ia0vp^f*{Pn3?z9rZ$AN~7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%x0%;&vn!fWqkYXwc@(cdY@N~O@7m&wU;1OBOz`(a3gc&VZgH?cn z5+$w?CBgY=CFO}lsSE*$nRz98ey$-3rh0~YM!)wkZv(2?mKx!i=IN=$zyaj2GDtD9 zGB5&JATy<*Y>;a;7@5K1OhC3FBNKxFkd6Z4%yt&AcovWi0=;F73@?D5g3)M}G61C} zursg#RT>x>8!#?_m$Nv;eZ8x(p2rK(d|ucb)6l_6P%+ z0iG_7AsWH4y^MSeiX4ag{@4Fnz-prBxFGsNw}^k~6P69>nOj1e6N(IKG*>)6K1Zh~ zLw(zsGrWH_x86=`3$s?At?_Sn=fQ4{c|7{X+S5Da^E4TbtzfTL1=-{2>gTe~DWM4f DHF0Au literal 0 HcmV?d00001 diff --git a/InscryptionCommunityPatch/Card/Part2CardCostRender.cs b/InscryptionCommunityPatch/Card/Part2CardCostRender.cs index b6e3727c..2115fd07 100644 --- a/InscryptionCommunityPatch/Card/Part2CardCostRender.cs +++ b/InscryptionCommunityPatch/Card/Part2CardCostRender.cs @@ -25,7 +25,7 @@ public static Sprite FinalVanillaCostSprite( PlayableCard playableCard, bool leftOriented) { - Debug.Log($"Use vanilla style"); + //PatchPlugin.Logger.LogDebug($"Use vanilla style"); Texture2D baseTexture; List masterTextures; diff --git a/InscryptionCommunityPatch/Card/StackAbilityIcons.cs b/InscryptionCommunityPatch/Card/StackAbilityIcons.cs index addbf1a9..684847d3 100644 --- a/InscryptionCommunityPatch/Card/StackAbilityIcons.cs +++ b/InscryptionCommunityPatch/Card/StackAbilityIcons.cs @@ -469,13 +469,13 @@ private static void AddStackCount(SpriteRenderer abilityRenderer, Ability abilit countTransform = counter.transform; } - if (count <= 1) + if (count < 2) countTransform.gameObject.SetActive(false); else { countTransform.gameObject.SetActive(true); - PatchPlugin.Logger.LogDebug($"countTransform [{count - 1}]"); countTransform.gameObject.GetComponent().sprite = GBC_NUMBER_SPRITES[count - 1]; + PatchPlugin.Logger.LogDebug($"countTransform [{count - 1}]"); } } private static Sprite OverridePixelSprite(AbilityInfo abilityInfo, CardInfo cardInfo, PlayableCard card) @@ -492,9 +492,9 @@ private static Sprite OverridePixelSprite(AbilityInfo abilityInfo, CardInfo card Texture2D texture; if (abilityInfo.ability == Ability.Evolve) - texture = TextureHelper.GetImageAsTexture($"pixel_evolve_{pngIndex}.png", typeof(StackAbilityIcons).Assembly); + texture = TextureHelper.GetImageAsTexture($"pixel_evolve_{Mathf.Min(pngIndex, 6)}.png", typeof(StackAbilityIcons).Assembly); else - texture = TextureHelper.GetImageAsTexture($"pixel_transformer_{pngIndex}.png", typeof(StackAbilityIcons).Assembly); + texture = TextureHelper.GetImageAsTexture($"pixel_transformer_{Mathf.Min(pngIndex, 6)}.png", typeof(StackAbilityIcons).Assembly); return TextureHelper.ConvertTexture(texture, TextureHelper.SpriteType.PixelAbilityIcon); } diff --git a/InscryptionCommunityPatch/Card/Vanilla Ability Patches/Act2ShapeshifterPatches.cs b/InscryptionCommunityPatch/Card/Vanilla Ability Patches/Act2ShapeshifterPatches.cs index d06f1df6..2d5cf5ab 100644 --- a/InscryptionCommunityPatch/Card/Vanilla Ability Patches/Act2ShapeshifterPatches.cs +++ b/InscryptionCommunityPatch/Card/Vanilla Ability Patches/Act2ShapeshifterPatches.cs @@ -54,10 +54,15 @@ public static List GetIjiraqDisguises() { if (SaveManager.SaveFile.IsPart2) { - PatchPlugin.Logger.LogInfo($"GetIjiraqDisguises: Act2:{SaveData.Data.collection.CardInfos.Count}"); + if (PatchPlugin.configFullDebug.Value) + PatchPlugin.Logger.LogDebug($"GetIjiraqDisguises: Act2:{SaveData.Data.collection.CardInfos.Count}"); + return new(SaveData.Data.collection.CardInfos); } - PatchPlugin.Logger.LogInfo($"GetIjiraqDisguises: DeckCount:{RunState.Run.playerDeck.Cards.Count}"); + + if (PatchPlugin.configFullDebug.Value) + PatchPlugin.Logger.LogDebug($"GetIjiraqDisguises: DeckCount:{RunState.Run.playerDeck.Cards.Count}"); + return new(RunState.Run.playerDeck.Cards); } } \ No newline at end of file diff --git a/InscryptionCommunityPatch/Card/Vanilla Ability Patches/EvolveDescriptionFixes.cs b/InscryptionCommunityPatch/Card/Vanilla Ability Patches/EvolveDescriptionFixes.cs index 9b4ca459..c28906cd 100644 --- a/InscryptionCommunityPatch/Card/Vanilla Ability Patches/EvolveDescriptionFixes.cs +++ b/InscryptionCommunityPatch/Card/Vanilla Ability Patches/EvolveDescriptionFixes.cs @@ -8,8 +8,9 @@ namespace InscryptionCommunityPatch.Card; -// Changes the Rulebook to display the correct number of turns for Fledgling - +/// +/// Changes the Rulebook to display the correct number of turns for Fledgling +/// [HarmonyPatch] internal static class EvolveDescriptionFixes { diff --git a/InscryptionCommunityPatch/Card/Vanilla Ability Patches/RandomConsumablePatch.cs b/InscryptionCommunityPatch/Card/Vanilla Ability Patches/RandomConsumablePatch.cs index ce3df22b..34e17c00 100644 --- a/InscryptionCommunityPatch/Card/Vanilla Ability Patches/RandomConsumablePatch.cs +++ b/InscryptionCommunityPatch/Card/Vanilla Ability Patches/RandomConsumablePatch.cs @@ -13,7 +13,7 @@ private static void DisableInAct2(ref bool __result) { if (SaveManager.SaveFile.IsPart2) { - PatchPlugin.Logger.LogInfo("Trinket Bearer is disabled in Act 2."); + PatchPlugin.Logger.LogMessage("Trinket Bearer is disabled in Act 2."); __result = false; } } diff --git a/InscryptionCommunityPatch/PixelTutor/PixelPlayableCardArray.cs b/InscryptionCommunityPatch/PixelTutor/PixelPlayableCardArray.cs index 126f3a71..698876c5 100644 --- a/InscryptionCommunityPatch/PixelTutor/PixelPlayableCardArray.cs +++ b/InscryptionCommunityPatch/PixelTutor/PixelPlayableCardArray.cs @@ -244,7 +244,7 @@ protected IEnumerator SpawnAndPlaceCards(List cards, int numRows, int }); displayedCards.Clear(); - if (numRows <= 0) + if (numRows < 1) { PatchPlugin.Logger.LogDebug($"NumRows for PixelPlayableCardArray is 0, displaying no cards"); yield break; From 010202c64c1fa1678dcc8142b1c3760d6c81ec26 Mon Sep 17 00:00:00 2001 From: WhistleWind Date: Wed, 4 Jun 2025 18:52:17 -0700 Subject: [PATCH 2/7] Removed unneeded patch --- InscryptionAPI/Card/AbilityManager.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/InscryptionAPI/Card/AbilityManager.cs b/InscryptionAPI/Card/AbilityManager.cs index 83112097..7481d598 100644 --- a/InscryptionAPI/Card/AbilityManager.cs +++ b/InscryptionAPI/Card/AbilityManager.cs @@ -731,13 +731,13 @@ private static bool OverrideTransformIcon(ref Texture __result, AbilityIconInter } return true; } - [HarmonyPrefix, HarmonyPatch(typeof(AbilitiesUtil), nameof(AbilitiesUtil.LoadAbilityIcon))] - private static bool OverrideEvolveAndTransformerIcon(ref Texture __result, string abilityName) { - if (abilityName.StartsWith("Evolve") || abilityName.StartsWith("Transformer")) { - return false; - } - return true; - } + //[HarmonyPrefix, HarmonyPatch(typeof(AbilitiesUtil), nameof(AbilitiesUtil.LoadAbilityIcon))] + //private static bool OverrideEvolveAndTransformerIcon(ref Texture __result, string abilityName) { + // if (abilityName.StartsWith("Evolve") || abilityName.StartsWith("Transformer")) { + // return false; + // } + // return true; + //} private static void OverrideEvolveDerivedIcon(Evolve evolve, int turnsLeftToEvolve) { if (evolve.Ability == Ability.Evolve) From 6f75b376d7a46ad70b62c7d01ae39b4f50a62531 Mon Sep 17 00:00:00 2001 From: WhistleWind Date: Wed, 4 Jun 2025 20:34:10 -0700 Subject: [PATCH 3/7] Minor syntax changes --- .../Triggers/CustomTriggerFinder.cs | 3 +-- .../Triggers/CustomTriggerPatches.cs | 23 +++++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/InscryptionAPI/Triggers/CustomTriggerFinder.cs b/InscryptionAPI/Triggers/CustomTriggerFinder.cs index 87c9d094..916b86be 100644 --- a/InscryptionAPI/Triggers/CustomTriggerFinder.cs +++ b/InscryptionAPI/Triggers/CustomTriggerFinder.cs @@ -366,8 +366,7 @@ public static List Call(this CardTriggerHandler self, FuncAll trigger recievers of type T. public static IEnumerable FindGlobalTriggers(bool findFacedown, PlayableCard excluding = null) { - var result = Enumerable.Empty(); - + IEnumerable result = Enumerable.Empty(); if (BoardManager.Instance) { result = result.Concat(FindTriggersOnBoard(findFacedown)); diff --git a/InscryptionAPI/Triggers/CustomTriggerPatches.cs b/InscryptionAPI/Triggers/CustomTriggerPatches.cs index beac3fed..7b682e81 100644 --- a/InscryptionAPI/Triggers/CustomTriggerPatches.cs +++ b/InscryptionAPI/Triggers/CustomTriggerPatches.cs @@ -262,14 +262,14 @@ private static void PassiveHealthBuffs(PlayableCard __instance, ref int __result [HarmonyPrefix] private static bool OpposingSlotsPrefix(PlayableCard __instance, ref List __result, ref int __state) { - var all = CustomTriggerFinder.FindGlobalTriggers(true).ToList(); + List all = CustomTriggerFinder.FindGlobalTriggers(true).ToList(); all.RemoveAll(x => (x as TriggerReceiver) == null); all.Sort((x, x2) => x.GetTriggerPriority(__instance, OpposingSlotTriggerPriority.ReplacesDefaultOpposingSlot, new(), new(), 0, false) - x2.GetTriggerPriority(__instance, OpposingSlotTriggerPriority.ReplacesDefaultOpposingSlot, new(), new(), 0, false)); bool didModify = false; bool discard = false; __state = 1; - foreach (var opposing in all) + foreach (ISetupAttackSequence opposing in all) { if (opposing.RespondsToModifyAttackSlots(__instance, OpposingSlotTriggerPriority.ReplacesDefaultOpposingSlot, new(), __result ?? new(), __state, false)) { @@ -278,13 +278,8 @@ private static bool OpposingSlotsPrefix(PlayableCard __instance, ref List.Instance.PlayerSlotsCopy : Singleton.Instance.OpponentSlotsCopy).FindAll(x => x.Card != null && - !__instance.CanAttackDirectly(x)).Count); - } - if (didModify) - { + + if (didModify) { if (__instance.HasAbility(Ability.SplitStrike)) { ProgressionData.SetAbilityLearned(Ability.SplitStrike); @@ -306,8 +301,12 @@ private static bool OpposingSlotsPrefix(PlayableCard __instance, ref List.Instance.PlayerSlotsCopy : Singleton.Instance.OpponentSlotsCopy).FindAll(x => x.Card != null && + !__instance.CanAttackDirectly(x)).Count); + } + + if (__instance.HasAbility(Ability.SplitStrike)) { __state += 1; } if (__instance.HasTriStrike()) @@ -352,7 +351,7 @@ private static void OpposingSlots(PlayableCard __instance, ref List __ if (isAttackingDefaultSlot && removeDefaultAttackSlot) __result.Remove(defaultslot); bool didRemoveOriginalSlot = __instance.HasAbility(Ability.SplitStrike) && (!__instance.HasTriStrike() || removeDefaultAttackSlot); - var all = CustomTriggerFinder.FindGlobalTriggers(true).ToList(); + List all = CustomTriggerFinder.FindGlobalTriggers(true).ToList(); all.RemoveAll(x => (x as TriggerReceiver) == null); var dummyresult = __result; // used for sorting by trigger priority all.Sort((x, x2) => x.GetTriggerPriority(__instance, OpposingSlotTriggerPriority.Normal, original, dummyresult, __state, didRemoveOriginalSlot) - From 4de9c9fa045a1bfba030be3fb18bb63fc01a2874 Mon Sep 17 00:00:00 2001 From: WhistleWind Date: Tue, 10 Jun 2025 11:27:32 -0700 Subject: [PATCH 4/7] Added 'UpdatePlayableCardCosts' event to community patch's Part1CardCostRender and Part2CardCostRender classes --- CHANGELOG.md | 2 ++ InscryptionCommunityPatch/Card/Part1CardCostRender.cs | 3 ++- InscryptionCommunityPatch/Card/Part2CardCostRender.cs | 11 +++++++++++ InscryptionCommunityPatch/Card/Part3CardCostRender.cs | 3 +-- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c99d3e8c..b2d1edad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ # 2.23.2 - Fixed error when trying to create cards that evolve/transform in 4 or more turns - Fixed Fledgling and Transformer sigil appearing as black boxes when a card evolves/transform in 4 or more turns +- Fixed Part2VanillaCardCost event not being invoked - Evolve and Transformer icons now show support cards that evolve in 4 or more turns +- Added 'UpdatePlayableCardCosts' event to community patch's Part1CardCostRender and Part2CardCostRender classes - Added extension methods for PlayableCard and CardInfo: ProvidesBlueGem, ProvidesGreenGem, ProvidesOrangeGem # 2.23.1 diff --git a/InscryptionCommunityPatch/Card/Part1CardCostRender.cs b/InscryptionCommunityPatch/Card/Part1CardCostRender.cs index dccb04f3..5f3b5d69 100644 --- a/InscryptionCommunityPatch/Card/Part1CardCostRender.cs +++ b/InscryptionCommunityPatch/Card/Part1CardCostRender.cs @@ -7,13 +7,13 @@ namespace InscryptionCommunityPatch.Card; -//[HarmonyPatch] /// /// Modifies how card costs are rendered in Act to add support for mixed card costs, custom costs, and energy and Mox costs. /// public static class Part1CardCostRender { public static event Action> UpdateCardCost; + public static event Action> UpdatePlayableCardCost; public static List CostTextures(CardInfo cardInfo, PlayableCard playableCard, int bloodCost, int bonesCost, int energyCost, List gemsCost) { @@ -66,6 +66,7 @@ public static List CostTextures(CardInfo cardInfo, PlayableCard playa // Call the event and allow others to modify the list of textures UpdateCardCost?.Invoke(cardInfo, costTextures); + UpdatePlayableCardCost?.Invoke(playableCard, costTextures); return costTextures; } diff --git a/InscryptionCommunityPatch/Card/Part2CardCostRender.cs b/InscryptionCommunityPatch/Card/Part2CardCostRender.cs index 2115fd07..a51266fe 100644 --- a/InscryptionCommunityPatch/Card/Part2CardCostRender.cs +++ b/InscryptionCommunityPatch/Card/Part2CardCostRender.cs @@ -15,8 +15,18 @@ namespace InscryptionCommunityPatch.Card; public static class Part2CardCostRender { public static event Action> UpdateCardCost; + /// + /// For textures that are 24 x 13 in size. + /// public static event Action> UpdateVanillaCardCost; // 24 x 13 + public static event Action> UpdatePlayableCardCost; + /// + /// For textures that are 24 x 13 in size. + /// + + public static event Action> UpdateVanillaPlayableCardCost; + public static bool RightAct2Cost => PatchPlugin.rightAct2Cost.Value; public static Sprite FinalVanillaCostSprite( @@ -149,6 +159,7 @@ public static List VanillaCostTextures(PixelCardDisplayer display, Ca // Call the event and allow others to modify the list of textures UpdateCardCost?.Invoke(cardInfo, costTextures); + UpdateVanillaCardCost?.Invoke(cardInfo, costTextures); return costTextures; } diff --git a/InscryptionCommunityPatch/Card/Part3CardCostRender.cs b/InscryptionCommunityPatch/Card/Part3CardCostRender.cs index b9946063..841c258b 100644 --- a/InscryptionCommunityPatch/Card/Part3CardCostRender.cs +++ b/InscryptionCommunityPatch/Card/Part3CardCostRender.cs @@ -45,8 +45,7 @@ public class CustomCostRenderInfo internal void UpdateDisplayedTextures() { - if (CostContainer != null) - CostContainer.DisplayCostOnContainer(MainCostTexture, EmissionTexture); + CostContainer?.DisplayCostOnContainer(MainCostTexture, EmissionTexture); } /// From 8b926c819942b71d5aff3b7a273d42ef617b2a24 Mon Sep 17 00:00:00 2001 From: WhistleWind Date: Wed, 11 Jun 2025 16:37:07 -0700 Subject: [PATCH 5/7] Minor cleanup, fixed incorrect documentation for PostCardGettingAttacked --- InscryptionAPI/Card/ShieldManager.cs | 63 +++++------ .../Triggers/CustomTriggerPatches.cs | 100 +++++++++--------- InscryptionAPI/Triggers/Interfaces.cs | 20 +--- 3 files changed, 78 insertions(+), 105 deletions(-) diff --git a/InscryptionAPI/Card/ShieldManager.cs b/InscryptionAPI/Card/ShieldManager.cs index 6964c8ae..bcb29f23 100644 --- a/InscryptionAPI/Card/ShieldManager.cs +++ b/InscryptionAPI/Card/ShieldManager.cs @@ -189,42 +189,33 @@ 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 - // 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; - // } - //} +/* 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/Triggers/CustomTriggerPatches.cs b/InscryptionAPI/Triggers/CustomTriggerPatches.cs index 7b682e81..c2b447ca 100644 --- a/InscryptionAPI/Triggers/CustomTriggerPatches.cs +++ b/InscryptionAPI/Triggers/CustomTriggerPatches.cs @@ -11,8 +11,7 @@ namespace InscryptionAPI.Triggers; [HarmonyPatch] internal static class CustomTriggerPatches { - [HarmonyPatch(typeof(PlayerHand), nameof(PlayerHand.AddCardToHand))] - [HarmonyPostfix] + [HarmonyPostfix, HarmonyPatch(typeof(PlayerHand), nameof(PlayerHand.AddCardToHand))] private static IEnumerator TriggerOnAddedToHand(IEnumerator result, PlayableCard card) { yield return result; @@ -21,8 +20,8 @@ private static IEnumerator TriggerOnAddedToHand(IEnumerator result, PlayableCard yield break; } - [HarmonyPatch(typeof(CombatPhaseManager), nameof(CombatPhaseManager.DoCombatPhase))] - [HarmonyPostfix] + #region Combat Triggers + [HarmonyPostfix, HarmonyPatch(typeof(CombatPhaseManager), nameof(CombatPhaseManager.DoCombatPhase))] private static IEnumerator TriggerOnBellRung(IEnumerator result, bool playerIsAttacker) { yield return CustomTriggerFinder.TriggerAll(false, x => x.RespondsToBellRung(playerIsAttacker), x => x.OnBellRung(playerIsAttacker)); @@ -30,8 +29,7 @@ private static IEnumerator TriggerOnBellRung(IEnumerator result, bool playerIsAt yield break; } - [HarmonyPatch(typeof(CombatPhaseManager), nameof(CombatPhaseManager.SlotAttackSequence))] - [HarmonyPostfix] + [HarmonyPostfix, HarmonyPatch(typeof(CombatPhaseManager), nameof(CombatPhaseManager.SlotAttackSequence))] private static IEnumerator TriggerOnSlotAttackSequence(IEnumerator result, CardSlot slot) { yield return CustomTriggerFinder.TriggerAll(false, x => x.RespondsToPreSlotAttackSequence(slot), x => x.OnPreSlotAttackSequence(slot)); @@ -40,22 +38,22 @@ private static IEnumerator TriggerOnSlotAttackSequence(IEnumerator result, CardS yield break; } - [HarmonyPatch(typeof(CombatPhaseManager), nameof(CombatPhaseManager.SlotAttackSlot))] - [HarmonyPostfix] + [HarmonyPostfix, HarmonyPatch(typeof(CombatPhaseManager), nameof(CombatPhaseManager.SlotAttackSlot))] private static IEnumerator TriggerOnPostSingularSlotAttackSlot(IEnumerator result, CardSlot attackingSlot, CardSlot opposingSlot) { yield return result; yield return CustomTriggerFinder.TriggerAll(false, x => x.RespondsToPostSingularSlotAttackSlot(attackingSlot, opposingSlot), x => x.OnPostSingularSlotAttackSlot(attackingSlot, opposingSlot)); yield break; } + #endregion + #region Scale Patch private static Type scaleChangedCoroutine; private static FieldInfo scaleChangedDamage; private static FieldInfo scaleChangedToPlayer; private static FieldInfo scaleChangedNumWeights; - [HarmonyPatch(typeof(LifeManager), nameof(LifeManager.ShowDamageSequence))] - [HarmonyPostfix] + [HarmonyPostfix, HarmonyPatch(typeof(LifeManager), nameof(LifeManager.ShowDamageSequence))] private static IEnumerator TriggerOnScalesChanged(IEnumerator result, int damage, int numWeights, bool toPlayer) { int initialDamage = damage; @@ -82,18 +80,10 @@ private static IEnumerator TriggerOnScalesChanged(IEnumerator result, int damage x.OnPostScalesChanged(damage, toPlayer, initialDamage, initialToPlayer)); yield break; } + #endregion - [HarmonyPatch(typeof(TurnManager), nameof(TurnManager.DoUpkeepPhase))] - [HarmonyPostfix] - private static IEnumerator TriggerOnUpkeepInHand(IEnumerator result, bool playerUpkeep) - { - yield return result; - yield return CustomTriggerFinder.TriggerInHand(x => x.RespondsToUpkeepInHand(playerUpkeep), x => x.OnUpkeepInHand(playerUpkeep)); - yield break; - } - - [HarmonyPatch(typeof(BoardManager), nameof(BoardManager.ResolveCardOnBoard))] - [HarmonyPostfix] + #region Resolve and Slot Assignment + [HarmonyPostfix, HarmonyPatch(typeof(BoardManager), nameof(BoardManager.ResolveCardOnBoard))] private static IEnumerator TriggerOnOtherCardResolveInHand(IEnumerator result, PlayableCard card, bool resolveTriggers = true) { yield return result; @@ -104,30 +94,7 @@ private static IEnumerator TriggerOnOtherCardResolveInHand(IEnumerator result, P yield break; } - [HarmonyPatch(typeof(TurnManager), nameof(TurnManager.PlayerTurn))] - [HarmonyPostfix] - private static IEnumerator TriggerOnTurnEndInHandPlayer(IEnumerator result) - { - yield return result; - yield return CustomTriggerFinder.TriggerInHand(x => x.RespondsToTurnEndInHand(true), x => x.OnTurnEndInHand(true)); - yield break; - } - - [HarmonyPatch(typeof(TurnManager), nameof(TurnManager.OpponentTurn))] - [HarmonyPostfix] - private static IEnumerator TriggerOnTurnEndInHandOpponent(IEnumerator result, TurnManager __instance) - { - bool turnSkipped = __instance.Opponent.SkipNextTurn; - yield return result; - if (!turnSkipped) - { - yield return CustomTriggerFinder.TriggerInHand(x => x.RespondsToTurnEndInHand(false), x => x.OnTurnEndInHand(false)); - } - yield break; - } - - [HarmonyPatch(typeof(BoardManager), nameof(BoardManager.AssignCardToSlot))] - [HarmonyPostfix] + [HarmonyPostfix, HarmonyPatch(typeof(BoardManager), nameof(BoardManager.AssignCardToSlot))] private static IEnumerator TriggerOnOtherCardAssignedToSlotInHand(IEnumerator result, PlayableCard card, bool resolveTriggers) { CardSlot slot2 = card.Slot; @@ -147,11 +114,12 @@ private static IEnumerator TriggerOnOtherCardAssignedToSlotInHand(IEnumerator re } yield break; } + #endregion + #region OnDie private static FieldInfo triggerField; - [HarmonyPatch(typeof(PlayableCard), nameof(PlayableCard.Die))] - [HarmonyPostfix] + [HarmonyPostfix, HarmonyPatch(typeof(PlayableCard), nameof(PlayableCard.Die))] private static IEnumerator TriggerDeathTriggers(IEnumerator result, PlayableCard __instance, bool wasSacrifice, PlayableCard killer = null) { CardSlot slotBeforeDeath = __instance.Slot; @@ -180,6 +148,7 @@ private static IEnumerator TriggerDeathTriggers(IEnumerator result, PlayableCard } yield break; } + #endregion [HarmonyPatch(typeof(ConsumableItemSlot), nameof(ConsumableItemSlot.ConsumeItem))] [HarmonyPostfix] @@ -228,6 +197,7 @@ private static IEnumerator TriggerItemUse(IEnumerator result, ConsumableItemSlot yield break; } + #region Passive Stat Buffs [HarmonyPatch(typeof(PlayableCard), nameof(PlayableCard.GetPassiveAttackBuffs))] [HarmonyPostfix] private static void PassiveAttackBuffs(PlayableCard __instance, ref int __result) @@ -257,7 +227,9 @@ private static void PassiveHealthBuffs(PlayableCard __instance, ref int __result } __result = dummyResult; } + #endregion + #region GetOpposingSlots [HarmonyPatch(typeof(PlayableCard), nameof(PlayableCard.GetOpposingSlots))] [HarmonyPrefix] private static bool OpposingSlotsPrefix(PlayableCard __instance, ref List __result, ref int __state) @@ -330,12 +302,11 @@ private static bool OpposingSlotsPrefix(PlayableCard __instance, ref List __result, int __state) { List original = new(__result); - bool isAttackingDefaultSlot = !__instance.HasTriStrike() && !__instance.HasAbility(Ability.SplitStrike); CardSlot defaultslot = __instance.Slot.opposingSlot; + bool isAttackingDefaultSlot = !__instance.HasTriStrike() && !__instance.HasAbility(Ability.SplitStrike); - List alteredOpposings = new(); bool removeDefaultAttackSlot = false; - + List alteredOpposings = new(); foreach (IGetOpposingSlots component in CustomTriggerFinder.FindTriggersOnCard(__instance)) { if ((component as TriggerReceiver) != null && component.RespondsToGetOpposingSlots()) @@ -350,6 +321,7 @@ private static void OpposingSlots(PlayableCard __instance, ref List __ if (isAttackingDefaultSlot && removeDefaultAttackSlot) __result.Remove(defaultslot); + bool didRemoveOriginalSlot = __instance.HasAbility(Ability.SplitStrike) && (!__instance.HasTriStrike() || removeDefaultAttackSlot); List all = CustomTriggerFinder.FindGlobalTriggers(true).ToList(); all.RemoveAll(x => (x as TriggerReceiver) == null); @@ -389,6 +361,33 @@ private static void OpposingSlots(PlayableCard __instance, ref List __ } __result.Sort((CardSlot a, CardSlot b) => a.Index - b.Index); } + #endregion + + #region Upkeep and TurnEnd + [HarmonyPostfix, HarmonyPatch(typeof(TurnManager), nameof(TurnManager.DoUpkeepPhase))] + private static IEnumerator TriggerOnUpkeepInHand(IEnumerator result, bool playerUpkeep) { + yield return result; + yield return CustomTriggerFinder.TriggerInHand(x => x.RespondsToUpkeepInHand(playerUpkeep), x => x.OnUpkeepInHand(playerUpkeep)); + yield break; + } + + [HarmonyPatch(typeof(TurnManager), nameof(TurnManager.PlayerTurn))] + [HarmonyPostfix] + private static IEnumerator TriggerOnTurnEndInHandPlayer(IEnumerator result) { + yield return result; + yield return CustomTriggerFinder.TriggerInHand(x => x.RespondsToTurnEndInHand(true), x => x.OnTurnEndInHand(true)); + yield break; + } + + [HarmonyPostfix, HarmonyPatch(typeof(TurnManager), nameof(TurnManager.OpponentTurn))] + private static IEnumerator TriggerOnTurnEndInHandOpponent(IEnumerator result, TurnManager __instance) { + bool turnSkipped = __instance.Opponent.SkipNextTurn; + yield return result; + if (!turnSkipped) { + yield return CustomTriggerFinder.TriggerInHand(x => x.RespondsToTurnEndInHand(false), x => x.OnTurnEndInHand(false)); + } + yield break; + } [HarmonyTranspiler] [HarmonyPatch(typeof(TurnManager), "PlayerTurn", MethodType.Enumerator)] @@ -423,6 +422,7 @@ private static IEnumerator TriggerOnTurnEndInQueueCoro(IEnumerator originalTrigg yield return trigger.OnTurnEndInQueue(playerTurn); } } + #endregion [HarmonyPatch(typeof(GlobalTriggerHandler), nameof(GlobalTriggerHandler.TriggerNonCardReceivers)), HarmonyPostfix] private static IEnumerator TriggerSlotModificationHandlers(IEnumerator sequence, bool beforeCards, Trigger trigger, params object[] otherArgs) diff --git a/InscryptionAPI/Triggers/Interfaces.cs b/InscryptionAPI/Triggers/Interfaces.cs index 1fdf8dee..1da3d589 100644 --- a/InscryptionAPI/Triggers/Interfaces.cs +++ b/InscryptionAPI/Triggers/Interfaces.cs @@ -820,7 +820,7 @@ public interface IShieldPreventedDamageInHand public int ShieldPreventedDamageInHandPriority(PlayableCard target, int damage, PlayableCard attacker); } /// -/// Expanded version of CardGettingAttacked trigger, executed before it, that includes the attacker as an argument +/// Expanded version of CardGettingAttacked trigger, executed after it, that includes the attacker as an argument /// public interface IPostCardGettingAttacked { @@ -828,21 +828,3 @@ public interface IPostCardGettingAttacked public IEnumerator OnPostCardGettingAttacked(PlayableCard target, PlayableCard attacker); public int PostCardGettingAttackedPriority(PlayableCard target, PlayableCard attacker); } - -/*public interface IOnPreTakeDamageFromHammer -{ - public bool RespondsToPreTakeDamageFromHammer(HammerItem hammer, CardSlot targetSlot, GameObject firstPersonItem); - - public IEnumerator OnPreTakeDamageFromHammer(HammerItem hammer, CardSlot targetSlot, GameObject firstPersonItem); - - public int TriggerPriority(HammerItem hammer, CardSlot targetSlot, GameObject firstPersonItem); -} - -public interface IOnPostTakeDamageFromHammer -{ - public bool RespondsToPostTakeDamageFromHammer(HammerItem hammer, CardSlot targetSlot, GameObject firstPersonItem, bool struckTarget); - - public IEnumerator OnPostTakeDamageFromHammer(HammerItem hammer, CardSlot targetSlot, GameObject firstPersonItem, bool struckTarget); - - public int TriggerPriority(HammerItem hammer, CardSlot targetSlot, GameObject firstPersonItem, bool struckTarget); -}*/ \ No newline at end of file From 7ca8fcbd56be18f6ad41e2c31c7b1dc6bc704c72 Mon Sep 17 00:00:00 2001 From: WhistleWind Date: Wed, 11 Jun 2025 16:40:39 -0700 Subject: [PATCH 6/7] Added minor documentation for BreakShield and TriggerBreakShield --- InscryptionAPI/Card/ShieldManager.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/InscryptionAPI/Card/ShieldManager.cs b/InscryptionAPI/Card/ShieldManager.cs index bcb29f23..8720d92f 100644 --- a/InscryptionAPI/Card/ShieldManager.cs +++ b/InscryptionAPI/Card/ShieldManager.cs @@ -23,6 +23,12 @@ 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(); + /// + /// IEnumerator method that wraps BreakShield. Also contains code for triggering IShieldPreventedDamage and IShieldPreventedDamageInHand. + /// + /// Card getting attacked. + /// Damage being dealt. + /// Card attacking the target. public static IEnumerator TriggerBreakShield(PlayableCard target, int damage, PlayableCard attacker) { //InscryptionAPIPlugin.Logger.LogDebug("[TriggerBreakShield] Begin"); @@ -51,6 +57,9 @@ public static IEnumerator TriggerBreakShield(PlayableCard target, int damage, Pl /// The method used for when a shielded card is damaged. Includes extra parameters for modders looking to modify this further. /// This method is only called when damage > 0 and the target has a shield. /// + /// Card getting attacked. + /// Damage being dealt. + /// Card attacking the target. public static void BreakShield(PlayableCard target, int damage, PlayableCard attacker) { DamageShieldBehaviour shield = Array.Find(target.GetComponents(), x => x.HasShields()); From e1bca8bf12488d4f83da4389835c1582e96e696a Mon Sep 17 00:00:00 2001 From: WhistleWind Date: Wed, 11 Jun 2025 16:43:18 -0700 Subject: [PATCH 7/7] Added two new articles to wiki --- CHANGELOG.md | 5 +- docs/wiki/other_features.md | 12 ++++ docs/wiki/toc.yml | 16 +++-- docs/wiki/triggers.md | 21 +++--- docs/wiki/triggers_priority.md | 128 +++++++++++++++++++++++++++++++++ 5 files changed, 167 insertions(+), 15 deletions(-) create mode 100644 docs/wiki/other_features.md create mode 100644 docs/wiki/triggers_priority.md diff --git a/CHANGELOG.md b/CHANGELOG.md index b2d1edad..69156fae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,12 @@ - Fixed error when trying to create cards that evolve/transform in 4 or more turns - Fixed Fledgling and Transformer sigil appearing as black boxes when a card evolves/transform in 4 or more turns - Fixed Part2VanillaCardCost event not being invoked -- Evolve and Transformer icons now show support cards that evolve in 4 or more turns - Added 'UpdatePlayableCardCosts' event to community patch's Part1CardCostRender and Part2CardCostRender classes - Added extension methods for PlayableCard and CardInfo: ProvidesBlueGem, ProvidesGreenGem, ProvidesOrangeGem +- Evolve and Transformer icons now support cards that evolve in 4 or more turns +- Wiki: added articles 'Other Features' and 'Triggers and the Order of Operations' +- Wiki: modified starting section of 'Custom Triggers' article +- Documentation: fixed description for IPostCardGettingAttacked stating it triggers before CardGettingAttacked # 2.23.1 - Fixed non-CardModificationInfo shields not breaking diff --git a/docs/wiki/other_features.md b/docs/wiki/other_features.md new file mode 100644 index 00000000..17d0ac5f --- /dev/null +++ b/docs/wiki/other_features.md @@ -0,0 +1,12 @@ +## Other Features +Listed here are various miscellaneous features that the API adds that aren't covered in other articles, or aren't covered in much detail. + +## Negative and Self-Damage +With the API, it is now possible to make cards deal damage to their owner. +This is done by reducing the value of CombatPhaseManager.DamageDealtThisPhase so it becomes negative. + +## Vanilla Shield Stacking +With the introduction of the ShieldManager, the Nano Armour (Armoured) sigil can now stack, providing multiple shields. + +To minimise inteference with the vanilla game, some interactions have been altered as well; +certain vanilla items and sigils that reset shields will now add an additional shield instead, provided a given card doesn't already have a shield. \ No newline at end of file diff --git a/docs/wiki/toc.yml b/docs/wiki/toc.yml index a86dcaf2..523a45e3 100644 --- a/docs/wiki/toc.yml +++ b/docs/wiki/toc.yml @@ -15,14 +15,16 @@ items: - name: Abilities href: ability_management.md items: - - name: Triggers and Interfaces + - name: Custom Triggers href: triggers.md - - name: Slot Modification - href: slots.md - - name: DamageShieldBehaviour - href: shield.md - name: Custom Sniper Logic href: sniper.md + - name: DamageShieldBehaviour + href: shield.md + - name: Slot Modifications + href: slots.md + - name: Trigger Order + href: triggers_priority.md - name: Custom Properties href: custom_properties.md - name: Ascension (Kaycee's Mod) @@ -47,4 +49,6 @@ items: - name: Sound href: sound.md - name: Localisation - href: localisation.md \ No newline at end of file + href: localisation.md +- name: Other Features + href: other_features.md \ No newline at end of file diff --git a/docs/wiki/triggers.md b/docs/wiki/triggers.md index 63a4c503..03f302b2 100644 --- a/docs/wiki/triggers.md +++ b/docs/wiki/triggers.md @@ -1,14 +1,19 @@ -## Triggers and Interfaces +## Custom Triggers --- -The API adds a number of interfaces you can use to add additional functionality to your ability. -It also adds a new class: `ExtendedAbilityBehaviour`, which has all the interfaces already implemented for immediate use, saving you time. +To give modders finer control over when abilities activate, the API adds a large number of custom triggers that you can add to your abilities or other trigger receivers via interfaces. -### Passive Attack and Health Buffs -To do this, you need to override GetPassiveAttackBuff(PlayableCard target) or GetPassiveAttackBuff(PlayableCard target) to calculate the appropriate buffs. -These return an int representing the buff to give to 'target'. +It also adds a new class: `ExtendedAbilityBehaviour`, which has several of these interfaces already implemented. -In battle, the game will iterate across all cards on the board and check whether they should receive the buffs; this is what 'target' refers to; the current card being checked. -You will need to write the logic for determining what cards should get the buff, as well as what buff they should receive. +For comprehensive information on all custom triggers added by the API, refer to the documentation. If you want to understand the order all these triggers are called, look at the article + +### Passive Stat Buffs +Stat icons are a unique type of ability that modify a card's attack or health. Ants are the quintessential example of stat icons in use, and with the API you can add your very own. + +To do this, implement the IPassiveAttackBuff or IPassiveHealthBuff and implement the required methods. `GetPassiveAttackBuff(PlayableCard target)` or `GetPassiveAttackBuff(PlayableCard target)` are the methods you will use to calculate attack and health buffs respectively. + +In battle, the game will iterate across all cards on the board and check whether they should receive the buffs; this is what `target` refers to: the current card being checked, and NOT just the card with the custom sigil. + +You will need to write the logic for determining what cards should get the buff, as well as what buff they should receive. For example, if you want the buff to only be given to the card with the custom sigil, you will need to check that `target` equals the base card. Note: you need to be very careful about how complicated the logic is in GetPassiveAttackBuffs and GetPassiveHealthBuffs. These methods will be called *every frame* for *every instance of the ability!!* diff --git a/docs/wiki/triggers_priority.md b/docs/wiki/triggers_priority.md new file mode 100644 index 00000000..5ab2152c --- /dev/null +++ b/docs/wiki/triggers_priority.md @@ -0,0 +1,128 @@ +## Triggers and Order of Operations +This article is for modders looking for specific information on the order triggers are called in various contexts. +The information presented here is fairly technical and dry, and assumes you have an understanding of how Inscryption's code works. + +Triggers are listed in the order they are called, with the first entry being the first trigger called and the last entry being the last trigger called. + +Custom triggers start with the letter 'I' and are implemented via interfaces, and the rest are vanilla triggers. + +## Card Damage +Handled by `PlayableCard.TakeDamage`, `ShieldManager.TriggerBreakShield`, and `ShieldManager.BreakShield`. + +Cards with shields only call the first four triggers listed. + +|Trigger|Additional information| +|:-|:-| +|IModifyDamageTaken|Sets the damage amount to the returned value| +|IPreTakeDamage|Called before shields are checked| +|IShieldPreventedDamage|Only called when a card has a shield| +|IShieldPreventedDamageInHand|Only called when a card has a shield

Called on cards in the player's hand| +|OnTakeDamage|Called for cards without shields| +|OtherCardDealtDamage|Called after `PlayableCard.Die`| +|IOnOtherCardDealtDamageInHand|Called on card's in the player's hand| + +## Card Death +Handled by `PlayableCard.Die`. + +|Trigger|Additional information| +|:-|:-| +|OnPreDeathAnimation|| +|OnOtherCardPreDeath|| +|IOnOtherCardPreDeathInHand|Called on cards in the player's hand| +|OnOtherCardDie|| +|IOnOtherCardDieInHand|Called on cards in the player's hand| + +## Card Drawing +Handled by `PlayerHand.AddCardToHand`. + +|Trigger|Additional information| +|:-|:-| +|OnDrawn|Called before a card is added to `cardsInHand`| +|OnOtherCardDrawn|Called before a card is added to `cardsInHand`| +|IOnAddedToHand|Called after a card is added to `cardsInHand`| +|IOtherCardAddedToHand|Called after a card is added to `cardsInHand`| + +## Card Playing +Handled by `BoardManager.TransitionAndResolveCreatedCard`, `BoardManager.ResolveCardOnBoard`, and `BoardManager.AssignCardToSlot`. + +|Trigger|Additional information| +|:-|:-| +|OnOtherCardAssignedToSlot|| +|IOnCardAssignedToSlotContext|Provides information on new and old slot| +|IOnOtherCardAssignedToSlotInHand|Called on cards in the player's hand| +|IOnCardAssignedToSlotNoResolve|Only called if assigned card was already resolved| +|OnResolveOnBoard|Called when a card is played from the hand or queue| +|OnOtherCardResolve|Called when a card is played from the hand or queue| +|IOnOtherCardResolveInHand|Called on cards in the player's hand

Called when a card is played from the hand or queue| + +## Combat Phase +Handled by `CombatPhaseManager.DoCombatPhase`, `CombatPhaseManager.SlotAttackSequence`, and `CombatPhaseManager.SlotAttackSlot`. + +`SlotAttackSequence` is called for every attacking card, then `SlotAttackSlot` is called for every time a card attacks. + +|Trigger|Additional information| +|:-|:-| +|IOnBellRun|Called before `DoCombatPhase`| +|IOnPreSlotAttackSequence|Called before `SlotAttackSequence`| +|IGetAttackingSlots|Adds return value to current list of attacking slots, can modify current list within the method| +|ISetupAttackSequence|Replaces current list of targeted slots with return value

Called with priority `ReplacesDefaultOpposingSlot`| +|IGetOpposingSlots|Adds return value to current list of targeted slots, can modify current list within the method| +|ISetupAttackSequence|Replaces current list of targeted slots with return value

Called with priority `Normal`| +|ISetupAttackSequence|Replaces current list of targeted slots with return value

Called with priority `BringsBackOpposingSlot`| +|ISetupAttackSequence|Replaces current list of targeted slots with return value

Called with priority `PostAdditionModification`| +|OnSlotTargetedForAttack|| +|IModifyDirectDamage|Called only if direct damage is being dealt

Sets the damage being dealt to the returned value| +|OnDealDamageDirectly|| +|IOnCardDealtDamageDirectly|Called for every card on the board| +|OnCardGettingAttacked|Called only if a card is being attacked| +|IPostCardGettingAttacked|| +|IOnPostSingularSlotAttackSlot|Called after `SlotAttackSlot`| +|OnAttackEnded|Called after all cards have finished attacking| +|IOnPostSlotAttackSequence|Called after `SlotAttackSequence`| + +## Consumable Items +Handled by `ConsumableItemSlot.ConsumeItem` and each ConsumableItem's `ActivateSequence`. + +|Trigger|Additional information| +|:-|:-| +|IItemCanBeUsed|Can stop items from being used| +|IOnItemPreventedFromUse|Called if `IItemCanBeUsed` stopped an item from being used| +|IOnPreItemUsed|Called before `ConsumeItem` and `ActivateSequence`| +|IOnPostItemUsed|Called after `ConsumeItem` and `ActivateSequence`| + +## Passive Stat Buffs +Handled by `PlayableCard.GetPassiveAttackBuffs` and `PlayableCard.GetPassiveHealthBuffs`. + +These patches are called every frame. + +|Trigger|Additional information| +|:-|:-| +|IOnCardPassiveAttackBuffs|Sets attack buff to returned value| +|IPassiveAttackBuffs|Adds to attack buff with returned value| + +|Trigger|Additional information| +|:-|:-| +|IOnCardPassiveHealthBuffs|Sets health buff to returned value| +|IPassiveHealthBuffs|Adds to health buff with returned value| + +## Scale Damage +Handled by `LifeManager.ShowDamageSequence`. + +|Trigger|Additional information| +|:-|:-| +|IOnPreScalesChangedRef|Modifies the damage being dealt and weights being added to the physical scale| +|IOnPreScalesChanged|Called before `ShowDamageSequence`| +|IOnPostScalesChanged|Called after `ShowDamageSequence`| + +## Turn Sequence +Handled by `TurnManager.GameSequence`, `TurnManager.PlayerTurn`, `TurnManager.OpponentTurn`, `TurnManager.DoUpkeepPhase`. + +Triggers for the opponent's turn are not called if their turn is skipped. + +|Trigger|Additional information| +|:-|:-| +|OnUpkeep|| +|IOnUpkeepInHand|Called on cards in the player's hand| +|OnTurnEnd|Called after `DoCombatPhase`| +|IOnTurnEndInQueue|Called on cards in the opponent's queue| +|IOnTurnEndInHand|Called on cards in the player's hand|