配方形状转换
把「一维/二维的物品数组」转换成 Forge IRecipe#setMatchingRecipe 能吃的 Object[]:String[] 行 + Character 键 + 物品/矿辞配对。
基本信息
| 属性 | 值 |
|---|---|
| 全限定名 | wanion.lib.recipe.RecipeHelper |
| 类型 | public final class,构造私有,全 static |
| 重载数 | 3(两个吃 Object[],一个吃 Object[][]) |
| 默认边长 | 3(rawShapeToShape(Object[]) 转发到下一重载并传字面量 3) |
| 字符起点 | int f = 1,赋值时 (char) f++ 截断(\0 不作键,故空格位只能是 null/\0) |
成员
| 成员 | 签名 | 说明 |
|---|---|---|
| 一维默认 | @Nonnull public static Object[] rawShapeToShape(@Nonnull Object[] objects) |
转发到下一重载,squareRoot = 3 |
| 一维变长 | @Nonnull public static Object[] rawShapeToShape(@Nonnull Object[] objects, int squareRoot) |
展平成 squareRoot × squareRoot 网格,索引 y * squareRoot + x |
| 二维变长 | @Nonnull public static Object[] rawShapeToShape(@Nonnull Object[][] objects, int squareRoot) |
objects.length 行 × squareRoot 列,逐行处理 |
三个重载的产出数组结构相同:
[ String(行0), String(行1), ..., Character(键0), 物品0, Character(键1), 物品1, ... ]
数组长度 = 行数 + 唯一键数 × 2。
逐项处理
| 步骤 | 行为 |
|---|---|
| 1. 归一化键 | objects[index] instanceof ItemStack ? MetaItem.get((ItemStack) objects[index]) : objects[index] —— ItemStack 换成 Integer meta 键,其余(Item、String 矿辞名、Block、ItemStack[] 等)原样作键 |
| 2. 记住 ItemStack | 键为 Integer 时 keyStackMap.put((Integer) key, (ItemStack) objects[index])(一维重载无条件覆盖,二维重载加了 && !keyStackMap.containsKey(key) 只记首个) |
| 3. 分配字符 | 键已存在 → 复用 thingToCharMap.get(key);否则 thingToCharMap.put(key, almostTheShape[y][x] = (char) f++) |
| 4. 拼行 | new String(almostTheShape[i]),即每行一个 String |
| 5. 拼键值对 | shape[行数 + 2*i] = thingToCharMap.get(object)(Character),shape[行数 + 1 + 2*i] = (object instanceof Integer) ? keyStackMap.get(object) : object |
三个重载的差异
| 属性 | 一维 Object[](默认 3) |
一维 Object[] + squareRoot |
二维 Object[][] + squareRoot |
|---|---|---|---|
| 行数来源 | squareRoot |
squareRoot |
objects.length |
| 列数来源 | squareRoot |
squareRoot |
squareRoot |
| 索引 | y * squareRoot + x |
y * squareRoot + x |
y 遍历行、x 遍历 inputArray.length |
| 提前结束 | 有 boolean done:索引越界或遇 null 即 done = true,外层双循环同时退出 |
同左 | 无 done,continue 跳过 null 继续 |
null 行处理 |
遇 null 即停 | 遇 null 即停 | if (inputArray == null) continue; 整行跳过 |
null 单元格 |
触发 done,almostTheShape 该格留 \0 |
触发 done |
if (key == null) continue; 跳过该格 |
| 扫描顺序 | 行内从左到右(x 外、y 内) |
同左 | 先外层 y,再内层 x(逐行) |
⚠️ 一维重载的截断行为:
rawShapeToShape(new Object[]{A, null, B}, 3)会在x=1, y=0命中objects[1] == null置done = true,B(索引 2)被丢弃且不再分配字符。需要在中间留空位时用二维重载。
空位表示
almostTheShape 是 char[][],初值 \0。行 String 里 \0 即 Forge 形状数组的空格。f 从 1 开始,保证 null(\0)永远不会成为有效键。
相关条目
- MetaItem 物品键编码 - 本文件的核心依赖,
ItemStack→Integer键 - 高级配方注册表 - 另一条配方路线:不生成形状数组,运行时直接匹配
- 工具类 - 库内通用工具