事件 API
EmakiCooking 对外公开 Bukkit 事件,外部插件可以监听这些事件来拦截或记录烹饪与营养流程。事件类位于 emaki.jiuwu.craft.cooking.api.event 包,使用标准 HandlerList 样板。
| 事件 | 触发时机 | 可取消 | 可改写 |
|---|---|---|---|
CookingStationInteractEvent | 玩家交互工位、分发到工位逻辑之前 | 否 | 只读 |
CookingRecipeCompleteEvent | 工位即将交付产物之前 | 是 | setDropResult |
PlayerNutritionConsumeEvent | 营养施加之前 | 是 | 仅取消 |
NutritionThresholdChangeEvent | 营养阈值达成或恢复时 | 否 | 只读 |
营养系统的玩法与配置见 营养系统。
CookingStationInteractEvent
玩家与任一烹饪工位方块或家具交互时触发,覆盖原版、CraftEngine、ItemsAdder、Nexo、Oraxen 及其家具等所有方块来源。事件在 EmakiCooking 把交互分发给各工位逻辑之前触发,因此可用于在条件配方求值前感知玩家当前操作的工位。
事件特性
- 不可取消,仅用于通知;交互本身是否取消由 EmakiCooking 各工位逻辑决定。
- 触发后,EmakiCooking 会据此记录玩家“最近交互工位”,供工位占位符(如
%emakicooking_station_location%)定位。 - 在主线程触发。
方法列表
| 方法 | 返回值 | 说明 |
|---|---|---|
getPlayer() | Player | 交互的玩家,可能为 null。 |
getLocation() | Location | 工位方块位置。 |
getStationType() | String | 工位类型文件夹名(chopping_board、wok、grinder、steamer、oven、juicer、fermentation_barrel)。 |
getInteractionType() | String | 交互类型标记(left_click、right_click、shift_left_click、shift_right_click),未知时为空串。 |
监听示例
java
@EventHandler
public void onStationInteract(CookingStationInteractEvent event) {
if (event.getPlayer() == null) {
return;
}
// 记录玩家在哪个工位交互
event.getPlayer().sendMessage("交互工位: " + event.getStationType()
+ " @ " + event.getLocation().getBlockX()
+ "," + event.getLocation().getBlockY()
+ "," + event.getLocation().getBlockZ());
}搭配 %emakicooking_station_*% 占位符,可实现“同种工位、指定个体产出特定食材”等条件配方玩法,详见 占位符参考。
CookingRecipeCompleteEvent
在工位即将交付配方产物之前触发。可用于拦截产出、改写产物是否掉落,或记录配方完成。
事件特性
- 可取消(
Cancellable):取消后不交付产物、不执行完成动作。 - 可改写是否掉落(
setDropResult)。 - 在主线程触发;异步路径会跳过事件。
方法列表
| 方法 | 返回值 | 说明 |
|---|---|---|
getPlayer() | Player | 触发完成的玩家,自动工位完成时可能为 null。 |
getLocation() | Location | 工位位置。 |
getRecipeId() | String | 配方 id。 |
getRecipeName() | String | 配方显示名。 |
getStationType() | String | 工位类型文件夹名(如 wok、oven)。 |
getPhase() | String | 完成阶段标记。 |
getOutputCount() | int | 即将交付的产出条目数。 |
isDropResult() | boolean | 结果是否掉落(而非进背包)。 |
setDropResult(boolean) | void | 改写是否掉落。 |
isCancelled() | boolean | 是否已取消。 |
setCancelled(boolean) | void | 取消或恢复事件。 |
监听示例
java
@EventHandler
public void onRecipeComplete(CookingRecipeCompleteEvent event) {
// 强制所有产物掉落到地面
event.setDropResult(true);
// 拦截某个配方
if (event.getRecipeId().equals("forbidden_dish")) {
event.setCancelled(true);
}
}PlayerNutritionConsumeEvent
在营养被施加到玩家之前触发。该事件聚合原版、MMOItems、NeigeItems 等多个食用来源。
事件特性
- 可取消(
Cancellable):取消后不施加营养,也不执行食材来源动作。 - 在主线程触发;异步路径会跳过事件。
方法列表
| 方法 | 返回值 | 说明 |
|---|---|---|
getPlayer() | Player | 食用物品的玩家。 |
getItem() | ItemStack | 被消费的物品。 |
getItemSource() | String | 解析出的物品来源简写(如 minecraft-apple)。 |
isCancelled() | boolean | 是否已取消。 |
setCancelled(boolean) | void | 取消或恢复事件。 |
监听示例
java
@EventHandler
public void onNutritionConsume(PlayerNutritionConsumeEvent event) {
// 禁止某来源食物提供营养
if (event.getItemSource().startsWith("itemsadder-")) {
event.setCancelled(true);
}
}NutritionThresholdChangeEvent
营养阈值达成或恢复时触发的信息型事件。采用边沿触发:阈值达成时触发一次,恢复时再触发一次。
事件特性
- 不可取消,仅用于通知。
- 区分单类型阈值(
SINGLE)与组合阈值(COMBO)。 - 在主线程触发。
方法列表
| 方法 | 返回值 | 说明 |
|---|---|---|
getPlayer() | Player | 营养变化的玩家。 |
getKind() | Kind | 阈值类型,SINGLE 或 COMBO。 |
getRuleId() | String | 阈值规则 id。 |
getTypeId() | String | 单类型阈值的营养类型 id;COMBO 时为 null。 |
isMet() | boolean | true 表示达成,false 表示恢复。 |
getValue() | double | 单类型时为当前营养值,否则为 0。 |
getThreshold() | double | 配置的阈值。 |
getMatchedCount() | int | 组合阈值匹配的类型数,否则为 0。 |
getRequiredCount() | int | 组合阈值所需类型数,否则为 0。 |
Kind 枚举取值:
| 取值 | 说明 |
|---|---|
SINGLE | 单类型阈值。 |
COMBO | 组合阈值。 |
监听示例
java
@EventHandler
public void onThresholdChange(NutritionThresholdChangeEvent event) {
if (event.getKind() == NutritionThresholdChangeEvent.Kind.COMBO && event.isMet()) {
event.getPlayer().sendMessage("膳食均衡达成:" + event.getRuleId());
}
}注意事项
- 阈值动作本身由服主在
config.yml的nutrition.thresholds中用 CoreLib 动作配置,本事件只用于外部插件感知状态变化。 - 边沿触发意味着同一状态不会重复派发,跨越阈值时才会触发。