Skip to content

Commit aae3aea

Browse files
committed
feat(CardAssets): Add ancient banner support to card asset profiles
- Introduced new properties for ancient banner texture and material paths in `CardAssetProfile`. - Updated `ModCardTemplate` and related interfaces to include ancient banner material overrides. - Enhanced visual override logic to support ancient banner textures and materials in card nodes. - Improved documentation to reflect the addition of ancient banner fields and their usage in asset profiles.
1 parent c7037c4 commit aae3aea

7 files changed

Lines changed: 232 additions & 15 deletions

Scaffolding/Characters/CharacterAssetProfiles.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,10 @@ internal static CardAssetProfile MergeCardAssetProfiles(CardAssetProfile fallbac
373373
profile.AncientBorderMaterialPath ?? fallback.AncientBorderMaterialPath,
374374
profile.AncientBorderMaterial ?? fallback.AncientBorderMaterial,
375375
profile.AncientTextBgMaterialPath ?? fallback.AncientTextBgMaterialPath,
376-
profile.AncientTextBgMaterial ?? fallback.AncientTextBgMaterial);
376+
profile.AncientTextBgMaterial ?? fallback.AncientTextBgMaterial,
377+
profile.AncientBannerPath ?? fallback.AncientBannerPath,
378+
profile.AncientBannerMaterialPath ?? fallback.AncientBannerMaterialPath,
379+
profile.AncientBannerMaterial ?? fallback.AncientBannerMaterial);
377380
}
378381

379382
internal static CardAssetProfile? MergeCardAssetProfilesPreferSecond(CardAssetProfile? fallback,

Scaffolding/Content/ContentAssetProfiles.cs

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,18 @@ namespace STS2RitsuLib.Scaffolding.Content
102102
/// Direct ancient card text background material override.
103103
/// 直接覆盖 Ancient 卡牌文本背景材质。
104104
/// </param>
105+
/// <param name="AncientBannerPath">
106+
/// Ancient card title banner texture path.
107+
/// Ancient 卡牌卡名横幅贴图路径。
108+
/// </param>
109+
/// <param name="AncientBannerMaterialPath">
110+
/// Material path for ancient card title banner rendering.
111+
/// Ancient 卡牌卡名横幅渲染使用的材质路径。
112+
/// </param>
113+
/// <param name="AncientBannerMaterial">
114+
/// Direct ancient card title banner material override.
115+
/// 直接覆盖 Ancient 卡牌卡名横幅材质。
116+
/// </param>
105117
public sealed record CardAssetProfile(
106118
string? PortraitPath = null,
107119
string? BetaPortraitPath = null,
@@ -125,7 +137,10 @@ public sealed record CardAssetProfile(
125137
string? AncientBorderMaterialPath = null,
126138
Material? AncientBorderMaterial = null,
127139
string? AncientTextBgMaterialPath = null,
128-
Material? AncientTextBgMaterial = null)
140+
Material? AncientTextBgMaterial = null,
141+
string? AncientBannerPath = null,
142+
string? AncientBannerMaterialPath = null,
143+
Material? AncientBannerMaterial = null)
129144
{
130145
/// <summary>
131146
/// Backward-compatible constructor preserving the original parameter list.
@@ -223,6 +238,62 @@ public CardAssetProfile(
223238
{
224239
}
225240

241+
/// <summary>
242+
/// Backward-compatible constructor preserving the ancient texture/material parameter list.
243+
/// 保留 ancient 贴图/材质参数列表的向后兼容构造函数。
244+
/// </summary>
245+
public CardAssetProfile(
246+
string? PortraitPath,
247+
string? BetaPortraitPath,
248+
string? FramePath,
249+
string? PortraitBorderPath,
250+
string? EnergyIconPath,
251+
string? FrameMaterialPath,
252+
string? OverlayScenePath,
253+
string? BannerTexturePath,
254+
string? BannerMaterialPath,
255+
Material? FrameMaterial,
256+
Material? BannerMaterial,
257+
string? PortraitMaterialPath,
258+
Material? PortraitMaterial,
259+
string? AncientBorderPath,
260+
string? AncientTextBgPath,
261+
string? PortraitBorderMaterialPath,
262+
Material? PortraitBorderMaterial,
263+
string? EnergyIconMaterialPath,
264+
Material? EnergyIconMaterial,
265+
string? AncientBorderMaterialPath,
266+
Material? AncientBorderMaterial,
267+
string? AncientTextBgMaterialPath,
268+
Material? AncientTextBgMaterial)
269+
: this(
270+
PortraitPath,
271+
BetaPortraitPath,
272+
FramePath,
273+
PortraitBorderPath,
274+
EnergyIconPath,
275+
FrameMaterialPath,
276+
OverlayScenePath,
277+
BannerTexturePath,
278+
BannerMaterialPath,
279+
FrameMaterial,
280+
BannerMaterial,
281+
PortraitMaterialPath,
282+
PortraitMaterial,
283+
AncientBorderPath,
284+
AncientTextBgPath,
285+
PortraitBorderMaterialPath,
286+
PortraitBorderMaterial,
287+
EnergyIconMaterialPath,
288+
EnergyIconMaterial,
289+
AncientBorderMaterialPath,
290+
AncientBorderMaterial,
291+
AncientTextBgMaterialPath,
292+
AncientTextBgMaterial,
293+
null)
294+
{
295+
}
296+
226297
/// <summary>
227298
/// Default empty profile (no custom paths or materials).
228299
/// 默认空 profile(无自定义路径或材质)。
@@ -656,8 +727,9 @@ public static CardAssetProfile Card(string poolEntry, string cardEntry)
656727
}
657728

658729
/// <summary>
659-
/// Builds default portrait, overlay, ancient border, and ancient text background paths for an ancient card.
660-
/// 为 ancient 卡牌构建默认肖像、覆盖层、ancient 边框和 ancient 文本背景路径。
730+
/// Builds default portrait, overlay, ancient border, ancient title banner, and ancient text background paths
731+
/// for an ancient card.
732+
/// 为 ancient 卡牌构建默认肖像、覆盖层、ancient 边框、ancient 卡名横幅和 ancient 文本背景路径。
661733
/// </summary>
662734
public static CardAssetProfile AncientCard(string poolEntry, string cardEntry, CardType cardType)
663735
{
@@ -674,7 +746,8 @@ public static CardAssetProfile AncientCard(string poolEntry, string cardEntry, C
674746
AncientBorderPath: ImageHelper.GetImagePath(
675747
"atlases/compressed_atlas.sprites/ancient_card_border.png.tres"),
676748
AncientTextBgPath: ImageHelper.GetImagePath(
677-
$"atlases/compressed_atlas.sprites/ancient_text_bg_{normalizedType}.png.tres"));
749+
$"atlases/compressed_atlas.sprites/ancient_text_bg_{normalizedType}.png.tres"),
750+
AncientBannerPath: ImageHelper.GetImagePath("atlases/ui_atlas.sprites/card/ancient_banner.tres"));
678751
}
679752

680753
/// <summary>

Scaffolding/Content/ModCardTemplate.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ public abstract class ModCardTemplate(
3131
: CardModel(baseCost, type, rarity, target, showInCardLibrary), IModCardAssetOverrides,
3232
IModCardPortraitMaterialOverride, IModCardFrameMaterialOverride, IModCardBannerMaterialOverride,
3333
IModCardPortraitBorderMaterialOverride, IModCardEnergyIconMaterialOverride,
34-
IModCardAncientBorderMaterialOverride, IModCardAncientTextBgMaterialOverride
34+
IModCardAncientBorderMaterialOverride, IModCardAncientTextBgMaterialOverride,
35+
IModCardAncientBannerMaterialOverride
3536
{
3637
/// <summary>
3738
/// Legacy constructor overload; <paramref name="autoAdd" /> is ignored.
@@ -84,6 +85,9 @@ protected ModCardTemplate(
8485
/// <inheritdoc />
8586
protected sealed override IEnumerable<IHoverTip> ExtraHoverTips => AdditionalHoverTips.ToArray();
8687

88+
/// <inheritdoc />
89+
public virtual Material? CustomAncientBannerMaterial => AssetProfile.AncientBannerMaterial;
90+
8791
/// <inheritdoc />
8892
public virtual Material? CustomAncientBorderMaterial => AssetProfile.AncientBorderMaterial;
8993

@@ -117,6 +121,9 @@ protected ModCardTemplate(
117121
/// <inheritdoc />
118122
public virtual string? CustomAncientTextBgPath => AssetProfile.AncientTextBgPath;
119123

124+
/// <inheritdoc />
125+
public virtual string? CustomAncientBannerPath => AssetProfile.AncientBannerPath;
126+
120127
/// <inheritdoc />
121128
public virtual string? CustomFrameMaterialPath => AssetProfile.FrameMaterialPath;
122129

@@ -132,6 +139,9 @@ protected ModCardTemplate(
132139
/// <inheritdoc />
133140
public virtual string? CustomAncientTextBgMaterialPath => AssetProfile.AncientTextBgMaterialPath;
134141

142+
/// <inheritdoc />
143+
public virtual string? CustomAncientBannerMaterialPath => AssetProfile.AncientBannerMaterialPath;
144+
135145
/// <inheritdoc />
136146
public virtual string? CustomOverlayScenePath => AssetProfile.OverlayScenePath;
137147

Scaffolding/Content/Patches/ContentAssetModelVisualOverridePatches.cs

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -528,15 +528,15 @@ private static bool TryGetPortraitMaterial(CardModel card, out Material material
528528
}
529529

530530
/// <summary>
531-
/// Applies custom <see cref="Material" /> overrides for card subnodes that do not expose model material getters.
532-
/// 为没有 model 材质 getter 的卡牌子节点应用自定义 <see cref="Material" /> 覆盖
531+
/// Applies custom visual overrides for card subnodes that do not expose model getters.
532+
/// 为没有 model getter 的卡牌子节点应用自定义视觉覆盖
533533
/// </summary>
534534
internal class CardNodeMaterialPatch : IPatchMethod
535535
{
536536
public static string PatchId => "content_asset_override_card_node_material";
537537

538538
public static string Description =>
539-
"Allow mod cards to override portrait border, energy icon, and ancient node materials";
539+
"Allow mod cards to override portrait border, energy icon, and ancient node visuals";
540540

541541
public static bool IsCritical => false;
542542

@@ -551,6 +551,22 @@ public static void Postfix(NCard __instance)
551551
if (model == null || __instance.Visibility != ModelVisibility.Visible)
552552
return;
553553

554+
ApplyTexture(
555+
__instance,
556+
model,
557+
"%AncientBorder",
558+
static o => o.CustomAncientBorderPath,
559+
nameof(IModCardAssetOverrides.CustomAncientBorderPath),
560+
ModCharacterOwnedVisualOverrideHelper.TryCardAncientBorderTexture);
561+
562+
ApplyTexture(
563+
__instance,
564+
model,
565+
"%AncientBanner",
566+
static o => o.CustomAncientBannerPath,
567+
nameof(IModCardAssetOverrides.CustomAncientBannerPath),
568+
ModCharacterOwnedVisualOverrideHelper.TryCardAncientBannerTexture);
569+
554570
ApplyMaterial<IModCardPortraitBorderMaterialOverride>(
555571
__instance,
556572
model,
@@ -586,6 +602,33 @@ public static void Postfix(NCard __instance)
586602
static o => o.CustomAncientTextBgMaterialPath,
587603
nameof(IModCardAssetOverrides.CustomAncientTextBgMaterialPath),
588604
ModCharacterOwnedVisualOverrideHelper.TryCardAncientTextBgMaterial);
605+
606+
ApplyMaterial<IModCardAncientBannerMaterialOverride>(
607+
__instance,
608+
model,
609+
"%AncientBanner",
610+
static o => o.CustomAncientBannerMaterial,
611+
static o => o.CustomAncientBannerMaterialPath,
612+
nameof(IModCardAssetOverrides.CustomAncientBannerMaterialPath),
613+
ModCharacterOwnedVisualOverrideHelper.TryCardAncientBannerMaterial);
614+
}
615+
616+
private static void ApplyTexture(
617+
NCard card,
618+
CardModel model,
619+
NodePath nodePath,
620+
Func<IModCardAssetOverrides, string?> pathSelector,
621+
string memberName,
622+
TryCharacterOwnedTextureOverride tryCharacterOwned)
623+
{
624+
if (!TryGetTexture(model, pathSelector, memberName, tryCharacterOwned, out var texture))
625+
return;
626+
627+
var node = card.GetNodeOrNull<TextureRect>(nodePath);
628+
if (node == null)
629+
return;
630+
631+
node.Texture = texture;
589632
}
590633

591634
private static void ApplyMaterial<TDirectOverride>(
@@ -632,7 +675,27 @@ private static bool TryGetMaterial<TDirectOverride>(
632675
memberName);
633676
}
634677

678+
private static bool TryGetTexture(
679+
CardModel model,
680+
Func<IModCardAssetOverrides, string?> pathSelector,
681+
string memberName,
682+
TryCharacterOwnedTextureOverride tryCharacterOwned,
683+
out Texture2D texture)
684+
{
685+
texture = null!;
686+
if (!tryCharacterOwned(model, ref texture))
687+
return true;
688+
689+
return !ContentAssetOverridePatchHelper.TryUseTextureOverride(
690+
model,
691+
ref texture,
692+
pathSelector,
693+
memberName);
694+
}
695+
635696
private delegate bool TryCharacterOwnedMaterialOverride(CardModel model, ref Material material);
697+
698+
private delegate bool TryCharacterOwnedTextureOverride(CardModel model, ref Texture2D texture);
636699
}
637700

638701
/// <summary>

Scaffolding/Content/Patches/ContentAssetOverridePatches.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,12 @@ public interface IModCardAssetOverrides
429429
/// </summary>
430430
string? CustomAncientTextBgPath => AssetProfile.AncientTextBgPath;
431431

432+
/// <summary>
433+
/// Override for ancient card title banner texture path.
434+
/// Ancient 卡牌卡名横幅纹理路径覆盖。
435+
/// </summary>
436+
string? CustomAncientBannerPath => AssetProfile.AncientBannerPath;
437+
432438
/// <summary>
433439
/// Override for frame <see cref="Material" /> resource path.
434440
/// 边框 <see cref="Material" /> 资源路径覆盖。
@@ -459,6 +465,12 @@ public interface IModCardAssetOverrides
459465
/// </summary>
460466
string? CustomAncientTextBgMaterialPath => AssetProfile.AncientTextBgMaterialPath;
461467

468+
/// <summary>
469+
/// Override for ancient card title banner <see cref="Material" /> resource path.
470+
/// Ancient 卡牌卡名横幅 <see cref="Material" /> 资源路径覆盖。
471+
/// </summary>
472+
string? CustomAncientBannerMaterialPath => AssetProfile.AncientBannerMaterialPath;
473+
462474
/// <summary>
463475
/// Override for built-in overlay packed scene path.
464476
/// 内置覆盖层 packed scene路径覆盖。
@@ -574,6 +586,21 @@ public interface IModCardAncientTextBgMaterialOverride
574586
Material? CustomAncientTextBgMaterial => null;
575587
}
576588

589+
/// <summary>
590+
/// Optional direct ancient card title banner <see cref="Material" /> override for cards.
591+
/// 用于 ancient 卡牌的可选直接卡名横幅 <see cref="Material" /> 覆盖。
592+
/// </summary>
593+
public interface IModCardAncientBannerMaterialOverride
594+
{
595+
/// <summary>
596+
/// Direct ancient card title banner material override.
597+
/// Return <c>null</c> to continue with other override layers.
598+
/// 直接的 ancient 卡牌卡名横幅材质覆盖。
599+
/// 返回 <c>null</c> 以继续使用其它覆盖层。
600+
/// </summary>
601+
Material? CustomAncientBannerMaterial => null;
602+
}
603+
577604
/// <summary>
578605
/// Optional direct banner <see cref="Material" /> override for cards.
579606
/// This bypasses resource-path loading and is checked before

Scaffolding/Content/Patches/ModCharacterOwnedRelicVisualOverrideHelper.cs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,14 +206,16 @@ internal static void InvalidateCachesForCharacterEntry(string normalizedCharacte
206206
string.IsNullOrWhiteSpace(a.EnergyIconPath) && string.IsNullOrWhiteSpace(a.FrameMaterialPath) &&
207207
string.IsNullOrWhiteSpace(a.AncientBorderPath) &&
208208
string.IsNullOrWhiteSpace(a.AncientTextBgPath) &&
209+
string.IsNullOrWhiteSpace(a.AncientBannerPath) &&
209210
string.IsNullOrWhiteSpace(a.OverlayScenePath) && string.IsNullOrWhiteSpace(a.BannerTexturePath) &&
210211
string.IsNullOrWhiteSpace(a.BannerMaterialPath) && a.FrameMaterial == null &&
211212
a.BannerMaterial == null && string.IsNullOrWhiteSpace(a.PortraitMaterialPath) &&
212213
a.PortraitMaterial == null &&
213214
string.IsNullOrWhiteSpace(a.PortraitBorderMaterialPath) && a.PortraitBorderMaterial == null &&
214215
string.IsNullOrWhiteSpace(a.EnergyIconMaterialPath) && a.EnergyIconMaterial == null &&
215216
string.IsNullOrWhiteSpace(a.AncientBorderMaterialPath) && a.AncientBorderMaterial == null &&
216-
string.IsNullOrWhiteSpace(a.AncientTextBgMaterialPath) && a.AncientTextBgMaterial == null)
217+
string.IsNullOrWhiteSpace(a.AncientTextBgMaterialPath) && a.AncientTextBgMaterial == null &&
218+
string.IsNullOrWhiteSpace(a.AncientBannerMaterialPath) && a.AncientBannerMaterial == null)
217219
return null;
218220

219221
return a;
@@ -615,6 +617,44 @@ internal static bool TryCardAncientTextBgMaterial(CardModel instance, ref Materi
615617
return false;
616618
}
617619

620+
internal static bool TryCardAncientBannerMaterial(CardModel instance, ref Material result)
621+
{
622+
var overrides = TryGetOwningCharacterOverrides(instance);
623+
var profile = overrides?.TryGetVanillaCardVisualOverrideForContext(instance);
624+
if (profile == null)
625+
return true;
626+
627+
if (profile.AncientBannerMaterial != null)
628+
{
629+
result = profile.AncientBannerMaterial;
630+
return false;
631+
}
632+
633+
var path = profile.AncientBannerMaterialPath;
634+
if (string.IsNullOrWhiteSpace(path) ||
635+
!AssetPathDiagnostics.Exists(path, instance, nameof(CardAssetProfile.AncientBannerMaterialPath)))
636+
return true;
637+
638+
result = ResourceLoader.Load<Material>(path);
639+
return false;
640+
}
641+
642+
internal static bool TryCardAncientBannerTexture(CardModel instance, ref Texture2D result)
643+
{
644+
var overrides = TryGetOwningCharacterOverrides(instance);
645+
var profile = overrides?.TryGetVanillaCardVisualOverrideForContext(instance);
646+
if (profile == null)
647+
return true;
648+
649+
var path = profile.AncientBannerPath;
650+
if (string.IsNullOrWhiteSpace(path) ||
651+
!AssetPathDiagnostics.Exists(path, instance, nameof(CardAssetProfile.AncientBannerPath)))
652+
return true;
653+
654+
result = ResourceLoader.Load<Texture2D>(path);
655+
return false;
656+
}
657+
618658
internal static bool TryCardOverlayPath(CardModel instance, ref string result)
619659
{
620660
var overrides = TryGetOwningCharacterOverrides(instance);

0 commit comments

Comments
 (0)