160 - API文档汉化 - 地图与遭遇战

Updated 6 days ago

地图与遭遇战

自定义地图与遭遇战

与能力不同,遭遇战通过枚举和字符串的组合编码到游戏数据中。例如,对手由Opponent.Type枚举定义,但特殊序列器和独特AI规则则以字符串形式嵌入每个遭遇战数据中。

要创建自定义遭遇战(例如自定义头目战),您需要组合使用对手类型、特殊序列器和AI规则。

遭遇战回合计划

创建遭遇战时,需同时制定决定对战过程中出牌顺序的回合计划。本API提供多种方法简化此流程。

以下示例将创建一个14回合的回合计划,其卡牌序列如下: 第1回合 - 打出2张寻骨猎犬;其生成槽位由游戏自动选择(制定回合计划时无法控制) 第2-3回合 - 不出牌 第4回合 - 打出1张骨堆 第5回合 - 打出1张骨堆(当难度≥10时替换为寻骨猎犬) 第6回合 - 不出牌 第7回合 - 打出1张骨堆 随后重复第1-7回合一次。

using static InscryptionAPI.Encounters.EncounterManager;

private void AddEncounters()
{
    CardBlueprint bonePile_rp = NewCardBlueprint("Bonepile").SetReplacement("Bonehound", 10);
    
    List<List<CardBlueprint>> turnPlan = new()
    {
        CreateTurn("Bonehound", "Bonehound"),
        CreateTurn(),
        CreateTurn(),
        CreateTurn("Bonepile"),
        CreateTurn(bonePile_rp),
        CreateTurn(),
        CreateTurn("Bonepile")
    };
    
    New("ExampleEncounter").AddTurns(turnPlan).DuplicateTurns(1);
}

提供以下便捷方法:

  • New: 创建新的EncounterBlueprintData实例并添加到API(不会自动添加到任何区域)
  • NewCardBlueprint: 创建新CardBlueprint
  • CreateTurn: 创建表示单个回合的List<CardBlueprint>,可传入卡牌名称、CardBlueprint对象或留空表示空回合

扩展方法分类说明:

  • EncounterBlueprintData
    • SetDifficulty: 设置遭遇战可触发的最低/最高难度
    • AddDominantTribes: 用于图腾战,决定可能使用的图腾顶部
    • SetRegionSpecific: 游戏未使用,仅作保留(除非您有自定义用途)
    • AddRandomReplacementCards: 设置卡牌可能被随机替换的候选卡
    • SetRedundantAbilities: 设置图腾战中莱西不能选择的能力
    • SetUnlockedCardPrerequisites: 设置本遭遇战中可使用的卡牌解锁条件
    • AddTurnMods: 在第三章中,用于在指定回合对指定难度以上的卡牌进行超频
    • AddTurn/AddTurns: 添加单个/多个回合
    • DuplicateTurns: 按指定次数复制现有回合
    • SyncDifficulties: 同步回合计划中所有卡牌的最低/最高难度
  • CardBlueprint
    • SetDifficulty: 设置卡牌可被使用的最低/最高难度
    • SetReplacement: 设置当难度≥指定值时替换的卡牌
  • List<CardBlueprint>
    • SetTurnDifficulty: 设置列表中每张卡牌的难度范围
    • DuplicateTurn: 按指定次数复制当前回合列表(需配合AddTurns()使用)

添加地图节点

添加自定义地图节点时,需准备实现可能复杂的游戏逻辑。每个新节点都需要一个“序列器”类来控制节点触发事件,包括:

  • 游戏对象创建
  • 对象动画
  • 玩家牌组操作
  • 其他自定义功能

序列器类必须实现ICustomNodeSequencer接口,否则API无法正确执行事件。API提供两个模板类简化开发:

  • CustomNodeSequencer:基础抽象类,已实现所有节点相关接口
  • CustomCardChoiceNodeSequencer:专用于自定义卡牌选择节点

强烈建议反编译游戏原生节点序列器类以理解其工作机制

除序列器外,还需创建节点地图动画。这需要提供4张49x49像素的纹理数组,若需模拟游戏节点的“抖动”效果,纹理内容应保持相似。

最终通过API注册节点:

Assembly asm = typeof(MyCustomSequencer).Assembly;

NewNodeManager.New(
    "MyPluginGUID", "MyCustomNode",
    GenerationType.SpecialEvent, typeof(MyCustomSequencer),
    new List<Texture2D> {
        TextureHelper.GetImageAsTexture("animated_node_1.png", asm),
        TextureHelper.GetImageAsTexture("animated_node_2.png", asm),
        TextureHelper.GetImageAsTexture("animated_node_3.png", asm),
        TextureHelper.GetImageAsTexture("animated_node_4.png", asm)
    }
);

GenerationType是标志位枚举,定义节点生成位置(可用按位或运算符|组合):

  • None: 不自动生成,但可手动添加(如手动操作第三章地图时)
  • SpecialCardChoice: 出现在战后随机事件池
  • SpecialEvent: 出现在战前随机事件池
  • RegionStart: 强制出现在每张地图起点(除非条件不满足)
  • PreBoss: 强制出现在头目战前(除非条件不满足)
  • PostBoss: 强制出现在头目战后(除非条件不满足)

条件节点

可通过SelectionCondition类实现节点生成条件逻辑。注册节点时可添加两种条件类型:

  • 前提条件(任一条件为false则阻止生成)
  • 强制生成条件(任一条件为true则强制生成)

游戏内置基础条件:

  • CardsInDeckTraits: 检查牌组卡牌是否含有指定特质(可设黑/白名单)
  • EitherOr: 检查是否满足任意给定条件
  • IsAscension: 检查是否处于凯茜模组模式
  • PastRunsCompleted: 检查已完成运行次数是否≥指定值
  • PreviousNodes/RowContent: 检查历史节点/上一行节点是否包含指定NodeType(可设黑/白名单)
  • StoryEventCompleted: 检查指定剧情事件是否完成
  • WithinGridYRange: 检查当前节点位置是否在Y轴范围内

API扩展条件:

  • ChallengeIsActive: 检查指定挑战是否激活(可设黑/白名单)
  • NumChallengesOfTypeActive: 根据greaterThanNumActive参数比较激活挑战数量

示例代码:

NewNodeManager.New(
    "MyPluginGUID", "MyCustomNode",
    GenerationType.SpecialEvent, typeof(MyCustomSequencer),
    /* 纹理列表 */,
    new List<NodeData.SelectionCondition> {
        new ChallengeIsActive(AscensionChallenge.BaseDifficulty, exclude: true) // 当无BaseDifficulty挑战激活时阻止生成
    },
    new List<NodeData.SelectionCondition> {
        new NumChallengesOfTypeActive(AscensionChallenge.BaseDifficulty, 2, greaterThanNumActive: false) // 当≥2个BaseDifficulty挑战激活时强制生成
    }
);