Player Affixes - API 开发指南 (pa)

Player Affixes - API 开发指南

本文档为希望与 PlayerAffixes 天赋系统交互或通过自定义逻辑扩展系统的开发者提供详细指南。

1. 访问 API

API 的主要入口点是 site.backrer.playeraffixes.api.PlayerAffixesApi。使用它来获取 ITalentApi 实例。

1
2
3
4
import site.backrer.playeraffixes.api.PlayerAffixesApi;
import site.backrer.playeraffixes.api.ITalentApi;

ITalentApi api = PlayerAffixesApi.getTalentApi();

2. 核心接口

2.1. ITalentApi

管理天赋和词条的核心接口。

方法 说明
getTalentData(Player player) 返回指定玩家的 IPlayerTalentData,包含其已解锁的天赋和词条状态。
getTalent(String id) 通过完整 ID 获取 TalentNode 对象(例如:playeraffixes:strength_boost)。
getAllTalents() 返回所有已注册天赋节点的不可变集合。
unlockTalent(ServerPlayer player, String talentId) 强制为玩家解锁天赋。这会跳过消耗(经验 / 物品)和前置条件检查。
resetTalents(ServerPlayer player) 重置玩家的所有天赋,清除数据,并移除所有由天赋授予的活跃药水效果。
registerAffixHandler(String affixId, IAffixHandler handler) 为特定的词条 ID 注册自定义逻辑处理器。这允许你实现超越简单属性修改的复杂行为。

2.2. IPlayerTalentData

代表玩家持久化的天赋状态。

方法 说明
isTalentUnlocked(String talentId) 检查玩家是否已解锁特定天赋。
getUnlockedTalents() 返回所有已解锁天赋 ID 的集合。
hasAffix(String affixId) 检查玩家是否通过其任何已解锁的天赋启用了特定词条。
getSelectedStartingTalent() 返回已选起始天赋(根节点)的 ID。

3. 自定义词条 (高级)

自定义词条允许你为拥有特定天赋的玩家挂钩游戏事件(如战斗或 Tick)。

3.1. 实现 IAffixHandler

IAffixHandler 接口提供了多个钩子。所有方法都是可选的(默认不执行任何操作)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface IAffixHandler {
/**
* 当玩家参与战斗时触发(作为攻击者或受害者)。
* @param isAttacker 如果拥有此词条的玩家是造成伤害的一方,则为 true。
*/
default void onLivingHurt(LivingHurtEvent event, ServerPlayer player, TalentNode.AffixData affixData, boolean isAttacker) {}

/** 当玩家死亡时触发。 */
default void onLivingDeath(LivingDeathEvent event, ServerPlayer player, TalentNode.AffixData affixData) {}

/** 每个 Tick 为玩家触发。 */
default void onPlayerTick(TickEvent.PlayerTickEvent event, ServerPlayer player, TalentNode.AffixData affixData) {}

/** 当玩家重生时触发。 */
default void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event, ServerPlayer player, TalentNode.AffixData affixData) {}
}

3.2. 访问参数

在 JSON 中定义的词条可以拥有自定义参数。你可以通过 affixData.getParam(key, defaultValue) 访问它们。

1
2
3
4
5
6
7
@Override
public void onLivingHurt(LivingHurtEvent event, ServerPlayer player, TalentNode.AffixData affixData, boolean isAttacker) {
if (isAttacker) {
double multiplier = affixData.getParam("multiplier", 1.2);
event.setAmount((float) (event.getAmount() * multiplier));
}
}

3.3. 注册

FMLCommonSetupEvent 期间注册你的处理器。你必须将注册代码包装在 event.enqueueWork 中。

1
2
3
4
5
6
@SubscribeEvent
public static void onCommonSetup(FMLCommonSetupEvent event) {
event.enqueueWork(() -> {
PlayerAffixesApi.getTalentApi().registerAffixHandler("mymod:lifesteal", new LifestealHandler());
});
}

4. 事件 (Events)

API 在 MinecraftForge.EVENT_BUS 上发布 Forge 事件。

4.1. TalentUnlockEvent

  • Pre: 在解锁前触发。调用 event.setCanceled(true) 可阻止解锁。
  • Post: 在成功解锁并应用效果后触发。

4.2. TalentResetEvent

  • Pre: 在重置前触发。可取消。
  • Post: 在数据清除且效果移除后触发。

5. 集成示例:吸血词条 (Lifesteal)

  1. Java 处理器:
1
2
3
4
5
6
7
8
9
public class LifestealHandler implements IAffixHandler {
@Override
public void onLivingHurt(LivingHurtEvent event, ServerPlayer player, TalentNode.AffixData affixData, boolean isAttacker) {
if (isAttacker && !event.getSource().is(DamageTypeTags.IS_PROJECTILE)) {
double ratio = affixData.getParam("ratio", 0.1);
player.heal((float) (event.getAmount() * ratio));
}
}
}
  1. JSON 天赋:
1
2
3
4
5
6
7
8
9
{
"id": "mymod:lifesteal_talent",
"affixes": [
{
"id": "mymod:lifesteal",
"params": { "ratio": 0.15 }
}
]
}
Icon喜欢这篇作品的话,奖励一下我吧~
💗感谢你的喜欢与支持!
致谢名单
本作品由 JoBackRer 于 2026-01-21 18:04:10 发布
作品地址:Player Affixes - API 开发指南 (pa)
除特别声明外,本站作品均采用 CC BY-NC-SA 4.0 许可协议,转载请注明来自 JoBackRer の blog
Logo