Skip to content

1.21 Fix final burning heater batch 修复燃烧加热器最后一次加工数量 - #6085

Merged
PigeonNian merged 1 commit into
Anvil-Dev:dev/1.21/1.6from
WhereisFff:dev/1.21/fix-6052-heater-batch
Nov 13, 2026
Merged

PigeonNian merged 1 commit into
Anvil-Dev:dev/1.21/1.6from
WhereisFff:dev/1.21/fix-6052-heater-batch

Conversation

@WhereisFff

Copy link
Copy Markdown
Contributor

fix(recipe): 修复燃烧加热器最后一次加工数量

- 按配方与配置限制计算鱼缸批量加工数量
- 保持一次铁砧触发只消耗一次燃料,并遵守原料及输出容量限制
Copilot AI balanced review requested due to automatic review settings November 12, 2026 19:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@Gugle2308 Gugle2308 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查结论:APPROVE(无阻塞问题,3 条待确认项)

删除的是一个判断逻辑有误的限制条件,修复方向正确。删除之后,「燃料只剩一次加工量」与「燃料充足」走完全相同的路径,符合 issue #6052 的预期;并且“一次铁砧触发只扣一次燃料”这一点仍然由既有机制保证,不依赖被删掉的那段代码。

范围说明:webhook 只提供 patch diff;本 PR 为 1 文件 / +1 −25,与 API 元数据(changed_files=1 / additions=1 / deletions=25)一致,diff 覆盖完整。结论基于 head 82d5bd95(codeload 拉取完整源码树)与 base 0ea57be7 对照,已逐行核对被删方法体与 base 一致、无夹带改动。未覆盖:运行时实机行为、多人同时触发。CI:build ✅ / checkstyle ✅(commits/82d5bd95/check-runs)。目标分支 dev/1.21/1.6。


✅ 根因定位正确(数值可逐一复算)

原 batchLimit 的算术链:

  • BurningHeaterBlockEntity.LIT_THRESHOLD = 240 * 20 = 4800(block/entity/BurningHeaterBlockEntity.java:45);
  • SuperHeatingRecipe.ConsumeFuel.FUEL_COST_TICKS 也是 240 * 20 = 4800(recipe/anvil/wrap/SuperHeatingRecipe.java:311);
  • CauldronProcessing.SUPER_HEATING 对燃烧加热器只接受 LEVEL == 2(api/recipe/CauldronProcessing.java:35-36),而 updateBurningState 的档位线就是 burnTime >= 4800 → 2(同文件 :229-238);
  • 旧代码模拟的是扣完一次燃料之后的等级:remaining = burnTime - 4800,要求 remaining >= 4800,即 burnTime >= 9600。

⇒ 当 burnTime ∈ [4800, 9600) 时,当前确实满足高温熔炼,但旧代码预判“扣一次就掉出该类别”,于是 return Math.min(limit, 1)——正是 issue 描述的“只执行一次物品加工”。燃料充足(≥9600)时该分支不触发,所以这个 bug 只在燃料将尽时出现。逻辑完全自洽。

对称情形也成立:炉温从 LEVEL 2 掉到 1 会脱离 SUPER_HEATING,从 1 掉到 0 会脱离 FAST_COOKING;但因为只有 SuperHeatingRecipe 挂了 ConsumeFuel,被删分支实际只在这条路径上生效。

✅ 删除不会导致“多批次却不扣燃料”

  1. 燃料按“触发”计费,而不按“批次”计费:FishTankRecipes 的 afterCommit 写的是
    effect.acceptWithChance(effect instanceof SuperHeatingRecipe.ConsumeFuel ? impact : context)——传入的是共享的 impact 上下文(文件内注释也写明“自动点燃会消耗物品,只在最终库存提交后统一处理”)。而 ConsumeFuel.accept 的第一句就是
    if (context.get(FUEL_CONSUMED)) return; context.put(FUEL_CONSUMED, true);。
    第一批置位后,后续批次直接跳过 ⇒ 无论 limit 是多少,一次铁砧触发只扣 4800。成本与批次数解耦,用剩余燃料去限制批次数量在语义上本来就是错的。
  2. 匹配时对燃料状态的限制没有丢:HasCauldronProcessor(…, SUPER_HEATING) 仍由 Property 注入(AbstractProcessRecipe.java:882-884),并且 SuperHeatingRecipe 的 inputBlocks 显式带 .with(BurningHeaterBlock.LEVEL, 2)。所以不会出现“加热器已熄灭却仍开新配方”——消失的只是“熄灭前这一次也不许满批”这个错误前置条件。
  3. 输入/输出容量限制未被触碰:ItemBatchPlan.shared/separate + SlotCapacity = tank.getOutputHandler()::getSlotLimit 这行 diff 里没动,无新增溢出路径。
  4. 残留清零:batchLimit / Math.min(limit, 1) 全树 0 命中;getCauldronProcessor() 全树 0 调用者(由 Property 上的 Lombok @Getter 提供,无人用也不影响编译);被删的 3 个 import(CauldronProcessing / BurningHeaterBlock / BurningHeaterBlockEntity)在 head 文件中零引用,AbstractProcessRecipe(:50)/ IRecipeOutcome(:115)仍在使用 ⇒ 无未使用 import。新增行长度约 110 < style.xml 的 LineLength max=140。

⚠️ ConsumeFuel 的注释与实际计费方式不符(本 PR 让这处矛盾变得玩家可见)

SuperHeatingRecipe.ConsumeFuel 的常量注释写的是

/** 每次合成消耗的燃烧时间(tick),240秒 = 4800tick */
public static final int FUEL_COST_TICKS = 240 * 20;

但实际实现是每次铁砧触发扣一次(FUEL_CONSUMED 挂在共享 impact 上),不是“每次合成/每批”扣一次。旧代码那段 burnTime 模拟,本质上是按“每批都要扣一次燃料”的假设写的——这也是它能自圆其说的唯一理由;删掉它之后,同一份燃料换来的产物数量就完全取决于 maxEfficiency 与原料数量,注释里的“每次合成”与代码的“每次触发”正式分岔。

建议二选一(属设计确认,非代码错误):

  • 若认可“一次触发一次燃料” ⇒ 把注释改成“每次铁砧触发消耗的燃烧时间”,使文档与实现对齐;
  • 若本意确实是“每批消耗 4800” ⇒ 那这次删除并非完整修复,需要改成按 plan.batches() 计费(这是另一个更大的改动,不建议在本 PR 内做)。

💡 玩家可见的效率变化,建议写进描述或更新日志

改动后,burnTime ∈ [4800, 9600) 的加热器一次触发即可产出 min(maxEfficiency, CONFIG.inWorldRecipeMaxEfficiency) 批、消耗仍是 4800。也就是说,低燃料不再受惩罚,单位燃料的产出曲线从“越低越亏”变成恒定。这是 issue 的期望(“正确执行正确数量的物品加工”),但属于收益提升,写明原因可以避免以后被当作“燃料白嫖”回滚。若设计上确实想限制单次触发最多烧炼量,正确的落点是 SuperHeatingRecipe 的 maxEfficiency,而不是恢复这里的 clamp。

💡 maxEfficiency 对 super_heating 恒为 Integer.MAX_VALUE

SuperHeatingRecipe 走 super(createProperty(...)) ⇒ AbstractProcessRecipe(Property) 把 maxEfficiency 定为 Integer.MAX_VALUE(AbstractProcessRecipe.java:74-76),生成的 24 个 super_heating 配方 JSON 也没有 max_efficiency 字段。因此 Math.min(process.maxEfficiency(), CONFIG.inWorldRecipeMaxEfficiency) 实际等于仅取配置值。补一行注释可以避免后续维护者误以为“每个配方自带上限”。


📋 声称验证表

PR 声称 状态 证据
按配方与配置限制计算鱼缸批量加工数量 ✅ FishTankRecipes.java:64 = Math.min(process.maxEfficiency(), AnvilLibRecipe.CONFIG.inWorldRecipeMaxEfficiency),与旧方法首行逐字相同;ItemBatchPlan 两分支都用这个 limit
保持一次铁砧触发只消耗一次燃料 ✅ FishTankRecipes.java:151 把 ConsumeFuel 路由到共享 impact;ConsumeFuel.accept 的 FUEL_CONSUMED 幂等守卫(SuperHeatingRecipe.java:326-327)
遵守原料及输出容量限制 ✅ SlotCapacity/ItemBatchPlan 未改动;getSlotLimit 委托到 FishTankBlockEntity:164-178
fixed #6052 ✅(跨线) issue 报在 26.1.2 / snapshot2862,本 PR 目标 dev/1.21/1.6;同一 bug 在 1.21 线同样存在,逻辑等价修复成立。26.1 线的对应 PR 是 #6082(26.1 Fix final burning heater batch,head ee039c28,同为 1 文件 +1 −25),两份 diff 结构完全一致,唯一差别是 outcome 类型名(1.21 为内嵌 SuperHeatingRecipe.ConsumeFuel + 静态 FUEL_COST_TICKS,26.1 已提为独立 record ConsumeBurningHeaterFuel + fuelCostTicks() 字段)⇒ 语义等价。两线需一起合入,否则另一线仍可复现。

另附旁证:同仓另一处批量上限 anvil/MassInjectBehavior.java:34 一直直接使用 inWorldRecipeMaxEfficiency、从未有燃烧时间守卫 ⇒ 本次删除是向既有约定对齐,而非引入新模式。


🧪 建议验证

  1. 原始复现:燃烧加热器燃至 burnTime 略高于 4800(旧代码必现只加工 1 次),鱼缸放足够原料 + 空输出 → 落砧一次,应加工满批且燃料只扣 4800;
  2. 回归:burnTime ≥ 9600 时批次数与改动前一致;
  3. 边界:burnTime 恰为 9600(旧代码最后一个不触发 clamp 的值)与恰为 4800(旧代码第一个触发 clamp 的值,改动后应满批并把加热器烧至 LEVEL 0)各测一次;
  4. 不应加工:burnTime 略低于 4800(LEVEL 1)→ 高温熔炼不匹配,落砧无产出(确认没被顺手放宽到燃烧加热器任意等级);
  5. 燃料归一:连续多次落砧,确认每次触发各扣一次 4800,不会因批次数多扣;
  6. 电加热器路径不受影响:加热器下方放普通电加热器(HEATER,无 ConsumeFuel 实际消耗)跑高温熔炼,批次数应与改动前一致;
  7. 输出溢出:输出槽接近满时落砧,产物只进槽内、不留掉落物。

@PigeonNian PigeonNian left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@PigeonNian
PigeonNian merged commit 781803a into Anvil-Dev:dev/1.21/1.6 Nov 13, 2026
2 checks passed
@WhereisFff
WhereisFff deleted the dev/1.21/fix-6052-heater-batch branch November 13, 2026 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 当燃烧加热器剩余时间仅够一次加工时,加工物品数量错误

4 participants