跳到主要内容

CannonRTP API

CannonRTP 向其他插件公开了三个 Bukkit 事件以供接入。所有事件位于 com.magmaguy.cannonrtp.api 包中,并在服务器主线程上触发。

要进行监听,只需注册一个普通的 Bukkit @EventHandler —— 无需额外的注册步骤。

CannonRTPLaunchEvent

在玩家即将开始炮台发射序列的瞬间触发,应用任何视觉效果或特效之前。可取消。

属性类型描述
playerPlayer触发炮台的玩家
cannonIdString炮台的配置 id(去掉 .yml 的文件名)
cannonDisplayNameString炮台的 displayName 字段
cannonLocationLocation被触发的具体放置点位置
destinationLocation为本次发射选定的、已通过预验证的安全落点

取消事件会完全中止此次发射:玩家停留在原地,不应用任何效果,不会开始内置的发射冷却,且目的地会被退还到炮台队列的头部。为避免在每个玩家扫描 tick 上反复触发一个持续被取消的事件,只要该玩家仍处于触发范围内,CannonRTP 会把重试间隔从 1 秒逐步退避到 30 秒;离开触发范围或完成一次被接受的发射都会清除该退避。适用于基于区域的黑名单、冷却插件、经济门控或 PvP 区域检查。

@EventHandler
public void onLaunch(CannonRTPLaunchEvent event) {
if (event.getPlayer().getWorld().getName().equals("event_world")) {
event.setCancelled(true);
}
}

CannonRTPLocationValidationEvent

在 CannonRTP 进行预加载搜索时,对每个候选落点进行验证时触发;此外,当发射在提交时刻(即空投传送之前)重新校验已消耗的目的地时,会再次触发。仅在所有内置检查(世界边界、表面、不安全材料、保护插件集成)通过之后才触发。

属性类型描述
cannonIdString正在执行搜索的炮台的配置 id
cannonDisplayNameString炮台的 displayName 字段
candidateLocation正在考量的候选落点

该事件在 Bukkit 意义上不可取消。如需否决某个候选点,请调用:

event.setRejected("inside arena spawn protection");

在预加载期间,CannonRTP 之后会像该候选点未通过内部检查一样将其丢弃并继续搜索。而在提交时刻,否决会改为取消发射并回收玩家,而不是把玩家传送到监听器已不再接受的位置。监听器可以实现超出内置保护适配器之外的自定义区域规则。

注意:两次分派都发生在主线程上,且预加载尝试为全局每 tick 一次、在活跃炮台之间轮询。请保持处理器轻量。

CannonRTPLandingEvent

在玩家被传送到目的地且发射序列完全结束之后触发(LANDING 阶段已运行、缓降已移除、落地爆发已播放)。不可取消 —— 如需在发射前否决,请使用 CannonRTPLaunchEvent

属性类型描述
playerPlayer刚刚着陆的玩家
cannonIdString发射该玩家的炮台的配置 id
cannonDisplayNameString炮台的 displayName 字段
destinationLocation玩家被送往的目的地的副本

适用于在首次到达时发放奖励、触发后续特效、授予区域权限、广播到达消息或用于数据分析。

线程与生命周期

  • 这三个事件均在主线程上分派。
  • CannonRTPLocationValidationEvent 在全局预加载 tick 中分派(每服务器 tick 一次尝试,在活跃炮台之间轮询),因此监听器中的繁重工作会明显拖慢炮台填充其队列的速度。它还会在每次发射的提交时刻(即重新校验已排队的目的地时)再分派一次。
  • CannonRTPLaunchEventLaunchSequence 构造之前立即分派,因此你修改的任何状态(药水效果、物品栏、游戏模式)会在 searching 阶段开始之前生效。
  • CannonRTPLandingEvent 每次发射只分派一次,在 LANDING 阶段的 tick 中、落地爆发之后分派。

使用 cannonId

cannonId 与所有管理员命令(/wc place/wc target 等)所使用的 id 相同,并与去掉 .yml 的炮台配置文件名一致。请注意,一份炮台配置可能驱动多个世界中的放置点;它们都共享相同的 cannonIdcannonDisplayName。如果你需要具体的放置点,请使用 CannonRTPLaunchEvent 中的 cannonLocation