130 - API文档汉化 - 能力

Updated 6 days ago

能力

能力(Ability)就是印记(Sigil)在源码中的称呼。

能力管理

能力系统的管理相较卡牌略显复杂。 首先,每个能力需关联一个必须实现的“AbilityBehaviour”类型。 其次,能力图标纹理并非直接存储在AbilityInfo对象中,而是由独立系统管理(值得注意的是,像素化能力图标确实存储在AbilityInfo对象内,此处不作深入探讨)。

尽管如此,API通过AbilityManager类提供了完整的管理方案。只需创建AbilityInfo对象,并调用AbilityManager.Add方法,传入该信息对象、图标纹理及实现能力的类型即可。

能力类需继承自DiskCardGame.AbilityBehaviour

AbilityInfo myinfo = ...;
Texture2D myTexture = ...;
AbilityManager.Add(MyPlugin.guid, myInfo, typeof(MyAbilityType), myTexture);

亦可使用AbilityManager.New方法简化流程:

AbilityInfo myInfo = AbilityManager.New(MyPlugin.guid, "Ability Name", "Ability Description", typeof(MyAbilityType), "/art/my_icon.png");

扩展方法同样可用:

AbilityManager.New(MyPlugin.guid, "Ability Name", "Ability Description", typeof(MyAbilityType), "/art/my_icon.png")
    .SetDefaultPart1Ability()
    .SetPixelIcon("/art/my_pixel_icon.png");

能力扩展方法

  • SetCustomFlippedTexture: 为对手持有的能力设置自定义翻转纹理
  • SetPixelIcon: 设置GBC(第二章)卡牌渲染时使用的像素图标
  • AddMetaCategories: 添加任意数量的元类别。禁止重复添加。
  • SetDefaultPart1Ability: 使能力出现在第一章图鉴,并随机出现在毛皮商中级卡牌与图腾中
  • SetDefaultPart3Ability: 使能力出现在第三章图鉴,并可用于制卡(需确保能力强度设置准确)
  • SetActivated: 设置是否为主动能力(可点击触发效果)
  • SetPassive: 设置是否为被动能力(无触发效果)
  • SetOpponentUsable: 设置对手是否可使用该能力(如图腾战场景)
  • SetConduit: 设置能力能否用于完成回路连接
  • SetConduitCell: 设置是否为回路电池能力(具体作用尚不明确)
  • SetCanStack: 设置能力是否可叠加(每份卡牌的副本独立触发),可选控制卡牌进化时的叠加行为
  • SetTriggersOncePerStack: 设置可叠加能力是否每叠层仅触发一次。注意:存在卡牌进化后叠加能力会触发两次的...“特性”

能力编程实现

能力系统需要包含能力信息的AbilityInfo实例,同时要求开发者编写继承自AbilityBehaviour的自定义类来实现具体功能。

AbilityBehaviour包含大量虚方法。针对战斗中的每个事件,都需要重写“RespondsToXXX”和“OnXXX”方法对。“RespondsToXXX”用于声明能力是否响应该事件(返回True时触发),实际功能逻辑则在“OnXXX”中实现。

基础游戏示例参考:

public class Sharp : AbilityBehaviour
{
    public override Ability Ability => Ability.Sharp;

    public override bool RespondsToTakeDamage(PlayableCard source) => source != null && source.Health > 0;

    public override IEnumerator OnTakeDamage(PlayableCard source)
    {
        yield return base.PreSuccessfulTriggerSequence();
        base.Card.Anim.StrongNegationEffect();
        yield return new WaitForSeconds(0.55f);
        yield return source.TakeDamage(1, base.Card);
        yield return base.LearnAbility(0.4f);
        yield break;
    }
}

状态图标能力

状态图标是专门影响卡牌生命值和/或攻击力的特殊能力类型。

需创建包含能力信息的StatIconInfo实例,并编写继承自VariableStatBehaviour的自定义类。实现时必须重写GetStateValues抽象方法,该方法返回整型数组:索引0为动态攻击力值,索引1为动态生命值。

基础游戏示例:

public class BellProximity : VariableStatBehaviour
{
    protected override SpecialStatIcon IconType => SpecialStatIcon.Bell;

    protected override int[] GetStatValues()
    {
        int num = BoardManager.Instance.PlayerSlotsCopy.Count - base.PlayableCard.Slot.Index;
        int[] array = new int[2];
        array[0] = num;
        return array;
    }
}

注意:GetStatValues内的逻辑复杂度需严格控制。该方法每帧都会调用,不当实现可能导致游戏性能显著下降。

特殊触发能力

特殊触发能力与常规能力类似,但对玩家不可见(无图标和图鉴条目)。
其API设计极为简洁,只需提供插件GUID、能力名称及实现类型,即可获得包含新能力ID的包装器。

特殊触发能力继承自DiskCardGame.SpecialCardBehaviour。

public readonly static SpecialTriggeredAbility MyAbilityID = SpecialTriggeredAbilityManager.Add(MyPlugin.guid, "Special Ability", typeof(MySpecialTriggeredAbility)).Id;

此后MyAbilityID即可添加至CardInfo对象。

特殊能力的编程方式与常规能力相同,区别在于:

  1. 无元数据对象(因不对玩家可见)
  2. 继承自SpecialCardBehaviour而非AbilityBehaviour

基础游戏示例:

public class TrapSpawner : SpecialCardBehaviour
{
    public override bool RespondsToDie(bool wasSacrifice, PlayableCard killer) => base.PlayableCard.OnBoard;

    public override IEnumerator OnDie(bool wasSacrifice, PlayableCard killer)
    {
        yield return new WaitForSeconds(0.35f);
        yield return BoardManager.Instance.CreateCardInSlot(CardLoader.GetCardByName("Trap"), base.PlayableCard.Slot, 0.1f, true);
        yield return new WaitForSeconds(0.35f);
        yield break;
    }
}

注意代码中使用“base.PlayableCard”而非“base.Card”,开发特殊能力时需牢记此差异。