170 - API文档汉化 - 对手
Updated 6 days ago对手
特殊序列器
特殊序列器(Special Sequencers)本质上是“全局能力”——它们监听与卡牌相同的触发器,并能基于这些触发器执行代码(例如当卡牌被打出或死亡时、在每个回合开始时等)。虽然您可以直接继承SpecialBattleSequencer基类,但根据使用场景不同,建议从现有序列器层级结构中选择继承。您可通过dnSpy查看所有可用序列器,但以下三类需特别关注:
- SpecialBattleSequencer:所有特殊序列器的基类,默认情况下使用该基类
- BossBattleSequencer:用于头目战场景
- Part1BossBattleSequencer:专用于第一幕头目战(钓鱼人、矿工、猎人与毛皮商及莱西)
特殊序列器需直接设置在玩家触发战斗的对应地图节点NodeData实例上,通过字符串值关联序列器实现。使用API中的SpecialSequenceManager类进行自定义设置:
public class MyCustomBattleSequencer : Part1BossBattleSequencer
{
public static readonly string ID = SpecialSequenceManager.Add(Plugin.PluginGuid, "MySequencer", typeof(MyCustomBattleSequencer));
}
对手系统
在本API语境中,对手(Opponents)可理解为头目单位。Opponent.Type枚举类型用于标识对手类型。需注意某些IDE中可能将该参数类型简示为Type,请勿与System.Type类型混淆。
与其他系统类似,对手是需要自行编写的类,负责处理战斗中的特殊事件。根据对手类型不同,需选择以下基类之一:
- Opponent:所有对手的基类,通常不应直接继承
- Part1Opponent:用于莱西小屋的常规战斗
- Part1BossOpponent:用于莱西小屋的头目战
- PixelOpponent:用于GBC(即第二章)游戏中的战斗
- PixelBossOpponent:用于GBC游戏中的头目战
- Part3Opponent:用于机托邦的常规战斗
- Part3BossOpponent:用于机托邦的头目战
自定义对手需搭配特殊序列器使用(注:特殊序列器与对手系统为何分离属于设计决策,不作解释)。以下代码演示如何创建关联特殊序列器的对手:
public class MyBossOpponent : Part1BossOpponent
{
public static readonly Opponent.Type ID = OpponentManager.Add(Plugin.PluginGuid, "MyBossOpponent", MyCustomBattleSequencer.ID, typeof(MyBossOpponent)).Id;
}
注意OpponentManager.Add的第三个参数为字符串类型,其值应与前文特殊序列器示例中设置的ID保持一致。
若需为对手类型指定蓝图(blueprint),可参照先前示例设置蓝图,并在Awake
、Start
或IntroSequence
重写方法中进行配置(若未在EncounterData对象中设置):
public override IEnumerator IntroSequence(EncounterData encounter)
{
encounterData.Blueprint = EncounterManager.AllEncountersCopy.Find(enc => enc.name == "TurnPlan_2");
List<List<CardInfo>> plan = EncounterBuilder.BuildOpponentTurnPlan(encounterData.Blueprint, difficulty, removeLockedCards);
base.ReplaceAndAppendTurnPlan(plan);
yield return QueueNewCards();
yield return base.IntroSequence(encounter);
}
AI系统
多数情况下无需自定义AI。默认情况下,游戏会评估电脑准备打出的卡牌,通过暴力测试所有可能的卡槽位置,并模拟每个位置下完整回合的结果,最终选择最优解。仅有极少数例外情况。
例如在矿工头目战中,电脑会始终在0号槽位打出骡子(Pack Mule),1号槽位打出郊狼(Coyote)。为确保固定出牌顺序,该战斗使用自定义AI覆盖默认逻辑。
如需实现自定义AI,需创建继承自DiskCardGame.AI的类,并重写SelectSlotsForCards虚方法。该方法即自定义AI逻辑的实现位置。
通过API中的AIManager类注册新AI,并保留返回的字符串ID引用:
public class MyCustomAI : AI
{
public static readonly string ID = AIManager.Add(Plugin.PluginGuid, "MyAI", typeof(MyCustomAI)).Id;
public override List<CardSlot> SelectSlotsForCards(List<CardInfo> cards, CardSlot[] slots)
{
// 在此实现自定义逻辑
}
}
实际使用自定义AI需在特殊序列器的BuildCustomEncounter方法中设置:
public class MyCustomBattleSequencer : Part1BossBattleSequencer
{
public override EncounterData BuildCustomEncounter(CardBattleNodeData nodeData)
{
EncounterData data = base.BuildCustomEncounter(nodeData);
data.aiId = MyCustomAI.ID;
return data;
}
}
头目面具系统
创建自定义头目对手时,可能需要修改莱西在战斗中佩戴的面具。API提供完整支持方案:
修改现有面具
可替换《邪恶冥刻》中已存在的任何面具(包括原版或其他开发者添加的面具):
MaskManager.Override("guid", "nameOfNewMask", LeshyAnimationController.Mask.Angler, "pathToTexture");
此示例将钓鱼人面具替换为自定义纹理。注意:该方法会同时修改模型以避免UV映射问题。如需保留原模型,需调用.SetModelType(MaskManager.ModelType.Angler)
添加随机选择面具
添加新面具至随机选择池,当莱西佩戴面具时会随机选择:
MaskManager.AddRandom("guid", "nameOfNewMask", LeshyAnimationController.Mask.Prospector, "pathToTexture");
此示例为矿工战斗添加新面具选项,莱西将在默认面具与此新面具间随机选择。可添加数量无限制。
添加自定义面具
基础添加方法:
MaskManager.Add("guid", "nameOfNewMask", "pathToTexture");
添加自定义模型
ResourceLookup resourceLookup = new ResourceLookup();
resourceLookup.FromAssetBundle("pathToAssetBundle", "prefabNameInsideBundle");
MaskManager.ModelType modelType = MaskManager.RegisterPrefab("guid", "nameOfModel", resourceLookup);
var mask = MaskManager.Add("guid", "nameOfMask");
mask.SetModelType(modelType);
佩戴面具指令
强制莱西佩戴指定面具(适用于自定义头目战流程):
LeshyAnimationController.Instance.PutOnMask(LeshyAnimationController.Mask.Woodcarver, false);
添加面具行为
public class Plugin : BaseUnityPlugin
{
private void Awake()
{
MyCustomMask.Setup();
}
}
public class MyCustomMask : MaskBehaviour
{
public static LeshyAnimationController.Mask ID;
public static void Setup()
{
var mask = MaskManager.Add("guid", "nameOfNewMask", "pathToTexture");
mask.SetMaskBehaviour(typeof(MyCustomMask));
ID = mask.ID;
}
}
Pages
- 0 - 邪恶冥刻模组简体中文语言包Wiki
- 100 - API文档汉化 - 首页
- 110 - API文档汉化 - 入门指南
- 120 - API文档汉化 - 卡牌
- 121 - API文档汉化 - 自定义卡牌费用系统
- 122 - API文档汉化 - 会说话的卡牌
- 123 - API文档汉化 - 自定义毛皮
- 130 - API文档汉化 - 能力
- 131 - API文档汉化 - 自定义触发器
- 132 - API文档汉化 - 自定义狙击逻辑
- 133 - API文档汉化 - 伤害护盾行为
- 134 - API文档汉化 - 卡槽修改功能
- 135 - API文档汉化 - 触发器与执行顺序
- 140 - API文档汉化 - 自定义/扩展属性
- 150 - API文档汉化 - 扬升(凯茜模组)
- 160 - API文档汉化 - 地图与遭遇战
- 170 - API文档汉化 - 对手
- 180 - API文档汉化 - 图腾
- 190 - API文档汉化 - 道具
- 1A0 - API文档汉化 - 规则书
- 1A1 - API文档汉化 - 添加自定义页面
- 1A2 - API文档汉化 - 添加文本重定向功能
- 1B0 - API文档汉化 - 本地化
- 1B0 - API文档汉化 - 声音
- 1B0 - API文档汉化 - 资产包
- 1C0 - API文档汉化 - 其他特性
- 200 - JSONLoader文档汉化 - Wiki
- 201 - JSONLoader文档汉化 - 枚举值