【学习笔记/MOD开发日志】森罗物语:厨房模糊配方查找方法

前言

森罗物语最近一次更新(1.4更新)将原本的精准配方查找(每个物品种类和数量与配方必须一一匹配)更新为模糊配方查找(只要种类匹配数量无要求)。本笔记将对该功能的算法和实现进行简要解析。

全程流程图

nLDFRn9F6BxlfvWZ9B_qNcZwQqmq8R4aMkF5U5ZPWMvSbdMPDVPM6maW_n5AHIqrMXOqXHg8yiUMBxCpi_ij77OsT6tKYmSviE_EyyppFlFCkrjf9Eh8I2g2MmWXMkxZmLTS6JcD0MbSuinfM0X544pk837s6E1Iqvfyela-VlMS0VZiY350DAL63KMvBQVHnegx2GBhvEHxaD5iiu
本笔记仅对品质评价前的步骤进行解析(“玩家右键放入”~“applyFlexRecipe”)。

逐步分析

 一、物品逐个放入NonNullList(9格的容器)。
 二、配方查找:先对精准配方遍历匹配(略去不表),失败进入模糊配方查找。
 三、模糊配方查找:

1.数组去重

  用Set(不是ItemStack)逐个单元遍历,将重复的物品直接合并。
  算法分析:
   用新数组merge[9]存储合并后的序列。对原数组遍历将merge中没有的物品复制到merge中index所指的单元。

点击查看代码
// FlexPotRecipe.matches() 中的去重代码
Set<Item> record = Sets.newHashSet();
int index = 0;
for (int i = 0; i < container.getContainerSize(); i++) {
    ItemStack stack = container.getItem(i);
    Item item = stack.getItem();
    if (!stack.isEmpty() && !record.contains(item)) {
        merged.set(index, stack);  // 位置由 index 决定
        record.add(item);
        index++;
        if (index >= merged.size()) break;
    }
}

2.调用原版的配方查找方法

  在Flexible配方(无序配方)列表中查找。失败返回空,找到返回Map<Ingredient, Integer>。
  Map是原版用来给每个用于合成的物品匹配到对应的单元,在后续操作(如完成炒菜后哪些物品要被消耗)可以精准定位到需要操作的物品。如果没有进行Map,那么在后续的操作可能导致操作对象错误。

3.模糊配方

  模组中自定义的配方类型(类似于广义表或者树?)。它让每个配方可以有“子配方”(类似广义表元素可以是广义表)。

点击查看代码
// 可以嵌套其他 Ingredient
AnyIngredient.of(
    Ingredient.of(Items.BEEF),           // 条件1:牛肉
    Ingredient.of(Items.PORKCHOP),       // 条件2:猪肉
    Ingredient.of(Items.MUTTON)          // 条件3:羊肉
)
// 任意一个匹配即可
posted @ 2026-06-19 21:20  Wr务虚  阅读(102)  评论(0)    收藏  举报