跳到主要内容

能力的创建与生命周期

能力工厂是全局类型定义,能力实例属于某一张地图或某一支队伍。注册一个工厂不会让所有宿主共享同一个实例。

选择宿主

地图目标点、区域效果和整图播报继承 MapCapability;套件、经济和队伍资源继承 TeamCapability。先按数据属于谁选择宿主,再决定能力需要哪些接口。

TeamCapability 的宿主类型是 BaseTeam。如果组件只支持服务端,可以像内置套件一样限制实例创建;如果还要建立客户端副本,构造器就不能假设宿主一定是 ServerTeam

注册与安装

注册工厂应早于宿主创建。可在公共初始化事件的 enqueueWork 中调用 FPSMCapabilityManager.register()。同一类型重复注册会抛出异常,不适合放到每次服务器启动都会执行的地图注册回调中。

安装使用宿主容器:

map.getCapabilityMap().add(RoundAnnouncements.class);
map.getCapabilityMap().get(RoundAnnouncements.class)
.ifPresent(RoundAnnouncements::announceNextRound);

示例类型来自第一种能力教程add() 管理实例创建、init() 和事件总线注册。get() 查询已有实例;想在缺少时创建,使用 getOrCreate(),并先确定创建操作符合当前比赛状态。

回调的职责

回调适合处理
构造器保存宿主引用、建立局部字段
init()安装后初始化,建立与宿主关联的资源
tick()宿主容器驱动的持续逻辑
reset()保留组件,清理一场比赛的临时状态
destroy()移除组件时释放资源

能力 tick 并不会因为地图 isStart == false 自动停止。只应在比赛中运行的能力,需要在自身逻辑中判断地图状态。

实例事件监听

能力实例会注册到 Forge 总线,因此可以使用非静态 @SubscribeEvent 方法。总线会把其他地图事件也发给这个实例,处理前必须检查宿主:

@SubscribeEvent
public void onVictory(FPSMapEvent.VictoryEvent event) {
if (event.getMap() != getHolder()) return;
reset();
}

这段方法适合放入地图能力。不要依赖全局“当前地图”来决定归属,否则多个竞技场同时运行时会相互影响。

移除与彻底关闭

remove(Type.class) 经过容器生命周期,可能受到能力不可移除标记或事件取消的影响。unregisterAllFromBus() 只解除事件监听,不等同于执行每个组件的 destroy()

普通回合重置保留配置组件;地图彻底删除或服务器关闭才进入宿主的关闭路径。自定义后台资源应明确由谁关闭,不能只把引用从字段设为 null