Skip to content

事件 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_boardwokgrindersteamerovenjuicerfermentation_barrel)。
getInteractionType()String交互类型标记(left_clickright_clickshift_left_clickshift_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工位类型文件夹名(如 wokoven)。
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阈值类型,SINGLECOMBO
getRuleId()String阈值规则 id。
getTypeId()String单类型阈值的营养类型 id;COMBO 时为 null。
isMet()booleantrue 表示达成,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.ymlnutrition.thresholds 中用 CoreLib 动作配置,本事件只用于外部插件感知状态变化。
  • 边沿触发意味着同一状态不会重复派发,跨越阈值时才会触发。