Skip to content

Fix #4358 #4307 - #4378

Draft
Vo1dExr wants to merge 12 commits into
Anvil-Dev:dev/1.21/1.6from
Vo1dExr:fix/1.21/1.6
Draft

Fix #4358 #4307#4378
Vo1dExr wants to merge 12 commits into
Anvil-Dev:dev/1.21/1.6from
Vo1dExr:fix/1.21/1.6

Conversation

@Vo1dExr

@Vo1dExr Vo1dExr commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Fix #4358
Fix #4307
Fix TransmissionPoleBlock and RemoteTransmissionPoleBlock don't immediately respond to redstone signals
修复输电杆和远程输电杆放置时不立即响应红石信号

Fix TransmissionPoleBlock and RemoteTransmissionPoleBlock don't immediately respond to redstone signals
修复输电杆和远程输电杆放置时不立即响应红石信号
Fix Anvil-Dev#4307
Fix TransmissionPoleBlock and RemoteTransmissionPoleBlock don't immediately respond to redstone signals
修复输电杆和远程输电杆放置时不立即响应红石信号
@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

curl -sL "https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4358" | python3 -c "import json,sys; d=json.load(sys.stdin); print('TITLE:', d['title']); print('BODY:', d['body'])" 2>/dev/null; ech...

Reason: Security scan — [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4358 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4358 (https://getvet.sh); [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4307 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4307 (https://getvet.sh); script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

curl -sL "https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4358" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('body','')[:600])" 2>/dev/null; echo "=====4307====="; curl ...

Reason: Security scan — [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4358 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4358 (https://getvet.sh); [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4307 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4307 (https://getvet.sh); script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

curl -sL "https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4307" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('body','')[:2500])" 2>/dev/null || curl -sL "https://api.git...

Reason: Security scan — [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4307 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4307 (https://getvet.sh); script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

分析完成。我已完整验证了 PR 的修复机制(多方块放置顺序、neighborChanged 逻辑等价性、电网 flush 语义、序列化路径),现在输出审查意见。

代码审查摘要 — PR #4378

操作: opened
范围: 4 个文件 (4 Java, 0 新增, 0 删除) / 357 行 diff
分支: fix/1.21/1.6dev/1.21/1.6(单提交 5c84c94,基于 c2aef94

📋 声称验证表

声称 状态 对应文件
Fix #4358 放电器退出重进后不放电 DischargerBlockEntity(持久化 powerValue)
Fix #4307 充电器高频红石无中生电 ✅(含边界注意) ChargerBlockEntity(consume>=generate 守卫)
Fix 输电杆/远程输电杆放置不立即响应红石 TransmissionPoleBlock, RemoteTransmissionPoleBlock(新增 onPlace + 改写 neighborChanged)

🟢 修复机制验证(输电杆)

  • 逻辑等价性确认neighborChanged 新旧写法在所有 4 种 (SWITCH, signal) 组合下状态转移完全一致(旧 if (bl == signal) {toggle} ⟺ 新 if ((ON) == !signal) return; 同步到 signal)。但旧代码有一个隐藏缺陷:bl 只取 BOTTOM 的 SWITCH,当 BOTTOM 状态恰好与信号一致(如放置时有红石 → BOTTOM 已由 getPlacementState 置 OFF)而 TOP 仍被 placedState() 强制为 ON 时,旧代码直接 no-op,TOP 永远不会被纠正——这正是"放置时不立即响应红石"的根因。
  • 新代码修复路径成立:枚举 Vertical3PartHalf/Vertical4PartHalf 为 TOP-first 顺序,setPlacedBy 最后放置的是紧邻 BOTTOM 的 MID/MID_LOWER,其 setBlockAndUpdate 会触发 BOTTOM 的 neighborChanged,此时 TOP 已存在 → 新逻辑把 BOTTOM+TOP 一起同步到红石状态。新增的 onPlace 覆盖其他放置路径(如替换已有杆的底部)。修复机制经推演确认有效。
  • 空实现 onPlace(Level, BlockPos, BlockState)(3 参废弃签名)与代码库既有习惯一致(OverseerBlock、TeslaTowerBlock、新版 dev 分支的输电杆均如此),代码库内无 3 参调用方,无副作用。

🟢 #4358 修复验证(放电器)

  • 旧代码 powerValue 不持久化:重进后电网 flush() 读到 getOutputPower()=0。配方放电路径(isFeDischarging=false 的倒计时分支)在重进后永远不会重新设置 powerValue,整个剩余配方期间对外输出 0——这就是"仍有放电时间却不放电"的确切机制。持久化后电网在重进后的第一次 flush 即读到正确值。✅
  • 序列化对称(saveAdditional/loadAdditional 同时更新,int 类型匹配字段);旧存档缺 "PowerValue" 时 getInt 回落 0,但 tick 会在 1 个游戏刻内重新计算,无持久兼容问题。✅

⚠️ 警告

  • ChargerBlockEntity — 新守卫 grid.getConsume() >= grid.getGenerate() 的边界自锁getFeChargingPowerLevel() 把充电器自身抽电按电网发电量取档(512/256/128/64),且 getInputPower() = -powerValue 计入 consume。当电网发电量恰为档位×数量(如单充电器 + 单发电 256/128/64/512,或 N 充电器 N×档位==发电量)时,充电器被卡死:首次 flush 后 consume == generate,守卫持续 return,且停充时 powerValue 仍被赋值(已移到 powered 检查之前)→ 充电器"不充电却持续计入消耗"→ 电网恒等于平衡点 → 永久自锁(旧代码 isGridWorking() 允许相等,此场景可正常充电)。建议确认这是否为 [Bug] 非常好的充电器,这使我电流相生 #4307 的预期取舍;若需保留充电能力,可考虑守卫通过后再上报 powerValue,或在相等时允许短时充电。
  • ChargerBlockEntity — 守卫 return 跳过尾部逻辑timeLeft > 0 内的早退会同时跳过 comparator 信号刷新(signalCache/updateNeighborsAt)和每 10 tick 的 syncPacket。电网过载期间客户端进度显示/比较器输出会停留旧值(恢复后自愈,但建议在 return 前补一次 sync 或把守卫改成不早退的 if 包裹)。
  • DischargerBlockEntity — 与充电器不对称:充电器把 powerValue 赋值放在 powered 检查之前,放电器放在之后。因 getInputPower()/getOutputPower() 都已在 POWERED 时返回 0,电网侧无影响,但持久化值语义不一致(红石暂停时充电器会刷新 powerValue 而放电器不会)。建议统一。

💡 建议

  • onPlace 与 neighborChanged 逻辑重复(两个杆文件各一份 ~15 行):建议抽为私有方法(如 syncSwitchState(...)),并给 onPlace 加上与 neighborChanged 相同的早退守卫((SWITCH==ON)==!hasNeighborSignal),避免结构已正确时仍无条件 setBlockAndUpdate 两个方块产生多余方块更新。
  • 格式改动混入 bugfix PR:ChargerBlockEntity/DischargerBlockEntity 中大量纯格式调整(签名换行、空白、Javadoc、new ItemEntity 换行)与功能改动混在一起,增加 review 噪音;两个杆文件的 neighborChanged 前存在双空行,若仓库有 Checkstyle 可能报警。建议拆分为独立格式化提交。
  • 守卫语义可考虑与转换器(BasePowerConverterBlockEntity 用 OVERLOAD 状态)保持一致,或在注释中说明为何用 >=(严格禁止相等)而非 OVERLOAD(>)。

🧪 测试建议

被测目标 推荐测试场景 优先级
TransmissionPoleBlock.neighborChanged/onPlace 杆放在已通电红石旁放置(BOTTOM 被 getPlacementState 置 OFF、TOP 置 ON 的不一致场景)→ 断言 TOP 立即变 OFF 🔴
RemoteTransmissionPoleBlock 同上(4 段杆, pos.above(3)) 🔴
ChargerBlockEntity.tick 电网 generate==consume(恰为档位边界 64/128/256/512)时充电是否意外停摆;高频红石时钟下物品 FE 是否仍净增长 🔴
DischargerBlockEntity 配方放电中途退出重进 → 输出功率恢复;FE 放电中途退出重进 🟡
ChargerBlockEntity.saveAdditional/loadAdditional 旧存档(无 PowerValue 键)加载兼容 🟢

结论: APPROVE — 三处修复机制均经源码级验证成立:#4358(持久化 powerValue,配方放电路径是关键受益者)、#4307(严格盈余守卫,方向正确)、输电杆(TOP-first 枚举顺序使 BOTTOM 的 neighborChanged 在结构完整时触发,新逻辑同步 BOTTOM+TOP)。无阻塞性问题;主要遗留是 >= 守卫在"发电量恰为档位整数倍"电网下的自锁边界,请作者确认是否符合预期。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

curl -sL "https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4358" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('body','')[:2500])" 2>/dev/null || curl -sL "https://api.git...

Reason: Security scan — [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4358 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4358 (https://getvet.sh); script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp && rm -rf anvillib && git clone --depth 1 --branch dev/1.21.1 https://github.com/Anvil-Dev/AnvilLib.git anvillib 2>&1 | tail -2 && grep -rln "placedState\|AbstractMultiPartBlock\|IHasMultiBloc...

Reason: recursive delete

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp && python3 -c "import zipfile; z=zipfile.ZipFile('anvillib-snapshot500.jar'); names=[n for n in z.namelist() if 'multipart' in n.lower() or 'MultiPart' in n]; print('\n'.join(names[:20]))" 2>&...

Reason: script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

代码审查摘要 — PR #4378

操作: synchronize
范围: 4 个文件(全部为 Java 修改,0 新增 / 0 删除)/ 363 行 diff
涉及: TransmissionPoleBlockRemoteTransmissionPoleBlockChargerBlockEntityDischargerBlockEntity
声明: Fix #4358(放电器重进游戏后不放电)、Fix #4307(高频红石"无中生电")、Fix 输电杆放置时不立即响应红石信号

已对照目标分支 dev/1.21/1.6git fetch + git show FETCH_HEAD)验证 PowerGrid/SimplePowerGrid/IPowerConsumer 聚合逻辑与多方块放置流程。无 TODO/密钥/EOF 问题。


🔴 关键

  • ChargerBlockEntity.tick() — 新守卫 grid.getConsume() >= grid.getGenerate() 会杀死最常见的 1:1 放电器→充电器转换getFeChargingPowerLevel() 的功率上限是 generate / 充电器数量,单放电器 + 单充电器时 demand 恰等于 generate ⇒ 首次充电周期后 consume == generate ⇒ 守卫恒真 ⇒ 充电器永久停摆,物品卡在处理槽(moveItemToTransformingSlot() 在守卫之前执行,物品已被提交却永远无法推进)。改动前 isGridWorking()generate >= consume)允许平衡电网工作,此配置是可用的——这是本 PR 引入的功能回归,且击中该转换器对的核心用法。
  • 守卫触发时 powerValue 仍被挂账(赋值在守卫之前)→ 幻影负载 + 能量黑洞。被守卫拦截时充电器继续向电网报告 getInputPower() = -powerValue 的需求;电网 tick 会从蓄电池 extract() 填补该缺口(consume > generate 分支),但充电器实际不工作 ⇒ 蓄电池能量被抽走凭空蒸发,同时挤压同电网其他用电器。建议在拦截分支将 powerValue 清零(或把赋值移到守卫之后)。

⚠️ 警告

  • 守卫判定基于 GRID_TICK 粒度的陈旧快照consume/generate 仅在电网 flush 时刷新),高频红石下判定存在竞态。若电网中存在真实发电机,[Bug] 非常好的充电器,这使我电流相生 #4307 的"无中生电"可能只是被大幅削弱而非彻底堵死——只有纯空电网(0 >= 0)被完全封死。建议守卫改为 grid.getGenerate() <= 0 || grid.getRemaining() < 0:空电网(generate==0)仍被拦截(保住 [Bug] 非常好的充电器,这使我电流相生 #4307 修复),1:1 平衡电网(remaining==0)恢复可用,过载(remaining<0)照常拦截。
  • 输电杆的 onPlace 在常规放置流程中基本空转:放置时底部方块先落(BlockItemsetBlock 主部件),onPlace 触发时顶部方块尚不存在 ⇒ topState.is(...) 提前 return;随后 setPlacedBy 按枚举序 TOP→MID_UPPER→MID_LOWER 补件,真正初始化开关的是 MID_LOWER 放置触发的底部 neighborChanged(此时 TOP 已就位)——而这条路径新旧代码都能走到。若上报的杆 bug 复现路径不在该路径上(如替换损坏部件、活塞推动、结构工具放置),请实测确认修复确实覆盖。另注意杆只响应 BOTTOM 位置的强充能(hasNeighborSignal(pos)),信号接在顶部/中部仍不响应(既有行为,非本 PR 引入)。
  • onPlace 无条件覆盖 SWITCH(忽略 oldState:替换已损坏的底部部件时,会把通过其他方式设置的开关状态重置为"随红石"。另外 setBlockAndUpdate 在 onPlace 内会二次触发 onPlace(第二次同值 set 后终止),无害但属于可避免的噪音。

💡 建议

  • bugfix PR 混入大量纯格式改动(换行重排、尾随空格清理、注释格式、getShape 签名换行等),约占 diff 一半,干扰 diff 审阅。建议后续将格式整理与逻辑修复分开提交。
  • Discharger 未加守卫属有意不对称(生产者应持续供电),合理;但建议在 PR 描述中说明该设计意图。
  • powerValue 持久化对 [Bug] 放电器在退出重进游戏后就不会放电 #4358必要且对症的:重进后充电器 demand=0 → 电网 consume=0 → 放电器按 consume 分级输出(getFeDischargingPowerLevel)归零 → 双方死锁;持久化在首个 tick 即恢复正确账目。注意:新守卫让这条修复链更加关键,建议在注释中标注依赖关系。

🟢 看起来不错

  • neighborChanged 重写与旧逻辑真值表完全等价(ON+充能→OFF / OFF+无充能→ON / 其余不变,逐一验证 4 种情形),无布尔反转问题。
  • 充电器把 powerValue 赋值移到 powered 判断之前无害(getInputPower() 在 POWERED 时仍返回 0),只改善展示与序列化一致性。
  • Charger/Discharger 的 NBT 键 PowerValue 读写对称、命名与既有键风格一致。

📋 声称验证表

声称 状态 对应实现
Fix #4358 放电器重进游戏后不放电 saveAdditional/loadAdditional 新增 PowerValue 持久化(Charger + Discharger);打破"重进后 demand=0→consume=0→放电器输出=0"死锁链
Fix #4307 高频红石无中生电 ⚠️ 空电网场景(0>=0)被堵死 ✅;但有 1:1 转换回归与陈旧快照竞态(见 🔴)
输电杆/远程输电杆放置响应红石 ⚠️ 新增 onPlace + neighborChanged 等价重写;常规放置路径下实际初始化仍依赖既有 neighborChanged 路径,修复覆盖面需实测确认

🧪 测试建议

被测目标 推荐测试场景 优先级
ChargerBlockEntity.tick() 单放电器+单充电器 1:1 循环应持续转换(当前会停摆) 🔴
ChargerBlockEntity.tick() 空电网 + 高频红石时钟 + 充能物品(#4307 复现)应完全无法充能 🔴
ChargerBlockEntity.tick() 过载电网(产<耗)+ 蓄电池:蓄电池不应凭空漏电 🔴
DischargerBlockEntity 重进游戏后放电恢复(#4358 复现) 🟡
TransmissionPoleBlock.onPlace 已充能区域放置 → 立即断开电网;移除信号 → 立即接入 🟡
电网守卫边界 generate == consume(平衡)与 generate == consume+1 的边界行为 🟡

结论: REQUEST_CHANGESpowerValue 序列化修复与 pole 的 neighborChanged 重写质量良好,但充电器新守卫 consume >= generate 使标准 1:1 放电器→充电器转换永久停摆,且拦截期间挂账的 powerValue 造成蓄电池能量凭空蒸发。建议改为 generate <= 0 || remaining < 0 并在拦截时清零 powerValue,同时补实测确认杆的放置修复覆盖目标场景。


由 Hermes Agent 审查

⚠️ File-mutation verifier: 1 file(s) were NOT modified this turn despite any wording above that may suggest otherwise. Run git status or read_file to confirm.
/tmp/fetch_issues.py — [write_file] Write denied: '/tmp/fetch_issues.py' is a protected system/credential file.

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/anvilcraft-power-grid-review.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched SKILL.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

分析完成,证据链齐全。输出审查意见:

代码审查摘要 — PR #4378

操作: synchronize
范围: 4 个文件(4 Java,0 新增,0 删除)/ 364 行 diff
分支: fix/1.21/1.6 → dev/1.21/1.6(MC 1.21.1)

🔴 关键

1. TransmissionPoleBlock.java / RemoteTransmissionPoleBlock.java — 「放置时立即响应红石」的修复实际不生效

新增的 5 参 onPlace(BlockState, Level, BlockPos, BlockState, boolean) 在放置流程中永远不会在结构完整时执行

  • 放置顺序:SimpleMultiPartBlockItem.placeBlock 先清空各部件位置 → vanilla setBlock 放置 BOTTOM(此时触发 5 参 onPlace,但 MID/TOP 还是 AIR,topState.is(TRANSMISSION_POLE) 为 false → 提前 return)→ 之后 AbstractMultiPartBlock.setPlacedBy 才按 Vertical3PartHalf.values()(TOP→MID→BOTTOM 顺序)放置其余部件,其中 TOP/MID 的 onPlace 又因 HALF != BOTTOM 提前 return。
  • 整个放置流程中唯一能在结构完整时触发的路径是 MID 放置时对 BOTTOM 的 neighborChanged 通知——但重写后的 neighborChanged 与旧代码语义完全相同:旧 if (bl == hasNeighborSignal) 与新守卫 if ((SWITCH==ON) == !hasNeighborSignal) return; 的触发条件和状态翻转一一对应(ON+信号→OFF、OFF+无信号→ON,其余情况不动作),纯属等价重构。
  • 而在「放置在有信号处」场景:getPlacementState 已把 BOTTOM 置为 OFF,placedState 把 TOP 强制置为 ON → MID 放置触发 BOTTOM 的 neighborChanged 时,守卫 (OFF==ON) == !true → true → 提前 return → TOP 保持 ON。而电网组件恰恰在 TOP 部件上(TransmissionPoleBlockEntity.getComponentType() 要求 HALF == TOP,tick 按 TOP 的 SWITCH 连接/断开电网),所以杆子依然照常输电、顶部灯照常亮——bug 原样保留。
  • 根因 placedState() 无条件 .setValue(SWITCH, ON) 未被触碰。

2. ChargerBlockEntity.java#4307「无中生电」修复不充分

新守卫 if (grid.getConsume() >= grid.getGenerate()) return; 与原有 isGridWorking()generate >= consume)相比,唯一的净变化是排除了 consume == generate 的精确平衡边界

  • 充电器自身名义耗电 getFeChargingPowerLevel()generate/count 经 512/256/128/64 阶梯向下取整,单充电器时 consume 几乎总是严格小于 generate → 守卫不触发 → storage.receiveEnergy() 照常凭空给物品注入真实 FE(没有任何实际储能被消耗)。
  • grid.getConsume()/getGenerate()GRID_TICK(20 tick)才在 flush() 刷新一次;高频红石切换时充电器处于 powered 相的 getInputPower() 返回 0,陈旧值下守卫更难触发。
  • 结论:[Bug] 非常好的充电器,这使我电流相生 #4307 复现路径(充电器 + 任意小发电机,或高频红石)大概率仍可无中生电,建议实测确认,或改为要求真实盈余(如排除自身耗电后 grid.getRemaining() > 0)。

⚠️ 警告

  • Charger/Discharger 不对称 — Charger 的 powerValue 更新移到 if (powered) return; 之前(红石禁用时仍刷新),Discharger 的仍在之后(禁用时保持陈旧显示值)。若有意为之可忽略,否则建议统一。
  • Charger 早退副作用 — 守卫 return 会跳过 tick 尾部的 moveItemToTransformedOverSlot() 与比较器信号更新(updateNeighborsAt),暂停期间比较器输出可能滞后,下次正常 tick 才恢复。

💡 建议

  • 输电杆正确修法:在 placedState() 中按 level.hasNeighborSignal(pos) 同步 SWITCH(而非强制 ON),或在 BOTTOM 的 neighborChanged 中增加「TOP 已存在但两部件 SWITCH 不一致时强制对齐」的路径;5 参 onPlace 可整体删除。
  • checkRecipeItemNotValidonDataPacket 等纯格式调整建议与功能改动分开提交,便于回溯。

🟢 看起来不错

  • [Bug] 放电器在退出重进游戏后就不会放电 #4358 修复正确PowerValue 持久化(save/load 对称)命中根因:配方放电路径的 powerValue = recipe.power 只在 moveItemToTransformingSlot() 时写入一次,重进游戏后归零且 isFeDischarging 为 false 不再重算,导致 getOutputPower() 恒为 0;持久化后两个 BE 一并修复,旧存档缺 key 时 getInt 默认 0 行为可接受。
  • 两个 pole 的 neighborChanged 守卫结构(client 检查、HALF、TOP 校验前置)保持服务端安全,可读性更好。

📋 声称验证表

声称 状态 说明
Fix #4358(放电器重进后不放电) PowerValue 持久化,根因修复
Fix #4307(充电器无中生电) ⚠️ 仅排除 consume==generate 边界;独立充电器+发电机自由能量环路仍在
输电杆/远程输电杆放置时立即响应红石 5 参 onPlace 为死代码;neighborChanged 为行为等价重构;placedState 仍强制 SWITCH=ON

🧪 测试建议

被测目标 推荐测试场景 优先级
TransmissionPoleBlock.onPlace/neighborChanged 在有信号方块旁放置杆子 → 验证 TOP 部件 SWITCH 立即为 OFF、灯不亮、电网断开 🔴
ChargerBlockEntity.tick 守卫 充电器 + 64~127 发电电网(精确平衡)→ 应暂停;充电器 + 小发电机 + 高频红石时钟 → 验证物品 FE 是否凭空增加 🔴
DischargerBlockEntity 持久化 配方放电中途退出重进 → 恢复后应继续输出 recipe.power 功率 🟢

结论: REQUEST_CHANGES#4358 修复到位;但输电杆放置修复因 onPlace 触发时机错误而完全失效(建议改修 placedState 或 3 参 IHasMultiBlock 钩子),#4307 守卫仅覆盖精确平衡边界,需实测确认是否真正堵住复现路径。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

后台下载已超时退出(HTTP:000,cjsah maven 不可达),但该下载已无必要——AbstractMultiPartBlock 后来确认就在 mod 仓库自身源码中(src/main/java/dev/dubhe/anvilcraft/block/multipart/),放置流程分析已基于它完成,审查结论不受影响,无需追加操作。

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/multipart-block-placement-order.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched SKILL.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

分析完成,所有关键点已交叉验证。整理审查意见:


代码审查摘要 — PR #4378

操作: synchronize
范围: 4 个文件 (4 Java) / 422 行 diff
声称修复: #4358(放电器重进不放电)、#4307(充电器"电流相生")、输电杆/远程输电杆放置时不立即响应红石信号


🔴 关键

1. TransmissionPoleBlock.java / RemoteTransmissionPoleBlock.java — onPlace 的 SWITCH 赋值与既有语义完全反转,且时机错误导致永远无法自纠

三处交叉验证,逻辑互斥:

  • getPlacementState(既有代码) 已正确设置 BOTTOM:hasNeighborSignal(pos) ? SWITCH.OFF : SWITCH.ON(红石信号 → 断开)
  • update()(本 PR) 同样遵循该语义:hasNeighborSignal → OFF,否则 ON
  • 新增 onPlace 却是 !hasNeighborSignal → OFFhasNeighborSignal → ON —— 恰好相反

同时 onPlace 的触发时机使 update() 永远无法纠正它:多方块放置顺序是 setBlock(BOTTOM)(内部触发 onPlace)→ setPlacedBy → 才放 MID/TOP。BOTTOM 的 onPlace 执行时 TOP 尚不存在,update()topState.is(ModBlocks.TRANSMISSION_POLE) 检查提前 return;MID/TOP 部件的 onPlace 又因 HALF != BOTTOM 直接 return。反转后的 SWITCH 值在放置完成后永远不会被修正。

净效果(对照 TransmissionPoleBlockEntity.tick:SWITCH.ON → 接入电网,OFF → 断开):

放置场景 期望 实际结果
无红石信号 接入电网 三部件全被 onPlace 置 OFF → TOP 的 BE tick 立即 grid.remove(this)杆子不导电(新回归,线路断开)
有红石信号 断开电网 三部件全 ON → 正常接入电网 → "放置不响应红石"的原 bug 依旧存在

即修复的核心意图(放置时立即同步 TOP 与 BOTTOM)完全落空,且无信号场景出现更严重的回归。

建议修法:删除 onPlace 中反转的 if/else(BOTTOM 状态已由 getPlacementState 正确设置),改为在 TOP 部件放置时从 BOTTOM 位置触发同步:

@Override
protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) {
    if (state.getValue(HALF) == Vertical3PartHalf.TOP) {
        update(level.getBlockState(pos.below(2)), level, pos.below(2)); // Remote 用 below(3)
    }
}

2. ChargerBlockEntity.java — 新门控 grid.getConsume() < grid.getGenerate() 自我包含 + 严格不等,电网恰好平衡时充电器永久卡死

  • grid.getConsume()flush() 汇总所有消费者的 getInputPower()包含充电器自身的 powerValuegetInputPower() = -powerValue
  • 被门控阻塞时 powerValue 仍每 tick 写入(新位置在 powered 检查之前),consume 永不下降 → 门控永不恢复 → 永久停摆
  • 卡死点恰是档位阶梯的设计平衡点:getFeChargingPowerLevel() 把消耗量化到 512/256/128/64 档,单充电器 + 发电 64/128/256/512、双充电器 + 发电 1024 等"总档位消耗 == 发电"的常见配置全部命中(如 G=512、count=1 → perDevice=512 → c=512 → 512 < 512 false → 卡死;G=1024、count=2 → 同理)
  • 旧代码 isGridWorking()(即 >=)在这些边界点正常工作,严格 < 把"刚好充满"变成"永久停摆"

建议:改为 grid.getConsume() <= grid.getGenerate()<= 与旧 >= 语义对齐,只收紧过载场景),或门控阻塞时把 powerValue 归零让电网重平衡。

⚠️ 警告

  • ChargerBlockEntity.java / DischargerBlockEntity.java — PowerValue 持久化([Bug] 放电器在退出重进游戏后就不会放电 #4358)可能未触及根因powerValue 是每 tick 无条件重算的派生值(isFeCharging/isFeDischarging 时覆写),持久化仅影响重载后首个 tick 前的窗口。放电器重进后不放电的根因更可能在电网重注册链路(ServerBlockEntityEventListener.ServerLoad → PowerGridManager.addComponent 异步队列)或 grid == null 时的提前 return。建议实测确认;若仍不放电,排查注册路径而非 powerValue。序列化本身向后兼容(getInt 缺省 0),无 schema 破坏。
  • powerValue 赋值位置不对称:Charger 移到 if (powered) return; 之前,Discharger 在之后。虽然 getInputPower()/getOutputPower() 都有 POWERED 守卫、电网读数不受影响,但语义混乱,应统一。顺带:Discharger 中 powerValue = getFeDischargingPowerLevel() 随后总被实际抽取值覆盖(既有死赋值,非本 PR 引入,可顺手清理)。

💡 建议

  • ChargerBlockEntity.javaisGridWorking() 在门控中数学冗余(consume < generate 已蕴含 generate >= consume),可简化为单一条件。
  • Charger/Discharger — 大量纯格式改动(参数换行、尾随空格清理、new ItemEntity 折行)与功能修复混在一起,建议格式化独立提交,便于 review 与回溯。

🟢 看起来不错

  • update() 抽取后 neighborChanged 行为与原实现严格等价(提前返回条件 (isOn == !signal) 与原 if (bl == signal) 数学等价,目标赋值一致)
  • Discharger 未加 surplus 门控(生产者不受限)——与 Charger 的对称设计正确
  • 5 参 protected onPlace 替换已废弃的 3 参空覆写,1.21.1 编译兼容

📋 声称验证表

声称 状态 对应文件
Fix #4307 充电器"电流相生" ⚠️ ChargerBlockEntity(门控方向正确,但引入平衡点永久卡死)
Fix #4358 放电器重进不放电 ⚠️ Discharger/Charger 序列化(powerValue 为派生值,根因存疑,需实测)
输电杆放置时立即响应红石 TransmissionPoleBlock / RemoteTransmissionPoleBlock(onPlace 逻辑反转 + 时机错误,修复失效且引入新回归)

结论: REQUEST_CHANGES — 输电杆 onPlace 的 SWITCH 反转是确定性功能错误(放置后线路状态与红石语义相反,需修正反转并调整 update() 触发时机);充电器门控的严格不等会在常见平衡配置下永久卡死,需改为 <= 或排除自身消耗。

🧪 测试建议

被测目标 推荐测试场景 优先级
TransmissionPoleBlock.onPlace 无信号/有信号两种放置场景,验证 BOTTOM/TOP 的 SWITCH 状态与电网接入 🔴
ChargerBlockEntity.tick 电网恰好平衡(发电 == 充电档位 64/128/256/512)时充电是否卡死;配方充电路径在新门控下是否暂停 🔴
ChargerBlockEntity 序列化 存档→重载→放电/充电状态与 powerValue 一致性(#4358 复现验证) 🟡

由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/multipart-block-placement-order.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched SKILL.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

分析完成。所有关键路径都已验证(放置顺序、电网结算、isFeCharging 生命周期)。以下为审查意见,将直接作为评论发布。


代码审查摘要 — PR #4378

操作: synchronize
范围: 4 个文件(4 Java)/ 446 行 diff
声称修复: #4358(放电器重进游戏后不放电)、#4307(快速切换红石信号无中生电)、输电杆/远程输电杆放置时不立即响应红石信号

🔴 关键

  • ChargerBlockEntity.java:420-427 — FE 充电死锁,充电器给物品充 FE 完全失效

    if (isFeCharging) {
        powerValue = -(getFeChargingPowerLevel());
        this.setStartupCoolDown(20);        // ← 每 tick 重置为 20
    }
    if (startupCoolDown > 0) {
        this.startupCoolDown--;             // 20→19,永远到不了 0
        return;
    }
    if (timeLeft > 0 && ...) { /* FE 充电逻辑 */ }   // ← 不可达

    isFeCharging 为 true 的整个充电期间,setStartupCoolDown(20) 每 tick 执行,startupCoolDown 永远 ≥ 19,第 428 行起的 FE 充电分支永远无法执行。后果:可接收 FE 的物品被移入槽 1 后永不充电(timeLeft 不减少、moveItemToTransformedOverSlot() 永不触发),且 isSlotDisabled(1) = timeLeft > 0 导致物品被锁死;同时 powerValue = -(getFeChargingPowerLevel()) 每 tick 向电网上报消耗,电网白耗电。唯一解脱途径是玩家拆方块或手动抽取。
    修复:把 setStartupCoolDown(20)isFeCharging 分支移除(仅保留 powered 分支那一处),或在进入 FE 充电时(如 moveItemToTransformingSlot() 内)只置一次。

  • ChargerBlockEntity.java:428 — 盈余门槛自包含,电网饱和时充电器连同物品永久卡死
    grid.getConsume() 已包含本充电器自己的申报(PowerGrid.java:187consume += consumer.getInputPower(),充电器 getInputPower() 返回 -powerValue)。配方充电时 powerValue = recipe.power 自物品进槽 1 起就计入消耗;当 consume >= generate 门槛不满足时充电器暂停,但申报不撤销consume 居高不下 → 门槛永不满足 → 物品永久锁在槽 1(玩家无法取回,只能拆方块)。多台充电器/多负载场景下同理。建议门槛计算排除自身申报(如 consume - ownClaim < generate),或等待期间把 powerValue 清零。

⚠️ 警告

  • ChargerBlockEntity.java:413-418 — 通电禁用时仍预装载物品(行为变化)
    moveItemToTransformingSlot() 被移到 powered 判断之前:红石通电(禁用)状态下,输入槽物品仍会被拉入槽 1 并因 timeLeft > 0 锁定,玩家在禁用期间无法取回。若这是有意的「预热」设计请在 PR 描述中说明;否则应把 powered 检查放回 moveItemToTransformingSlot() 之前。

💡 建议

  • ChargerBlockEntitystartupCoolDown 未持久化,迟滞可被重进游戏绕过
    本 PR 修 [Bug] 放电器在退出重进游戏后就不会放电 #4358 正是靠持久化 powerValue,但 startupCoolDown 只存在内存中:断电 → 立即退出重进 → cooldown 归 0 → 充电立刻恢复,[Bug] 非常好的充电器,这使我电流相生 #4307 的「快速切换信号刷能量」利用只需配合重进即可绕开迟滞。建议一并写入 NBT。

  • TransmissionPoleBlock.java:157-166 / RemoteTransmissionPoleBlock.java — onPlace 的 setValue 是死代码,修复依赖隐性的放置顺序
    onPlace 里两条分支只改本地变量,随后 update() 会按 hasNeighborSignal 重新计算并 setBlockAndUpdate 持久化,本地赋值无任何效果(等价于直接 update(state, level, pos))。实际让修复生效的是 setPlacedBy 的部件放置顺序:Vertical3PartHalf.values() 为 TOP→MID→BOTTOM,TOP 先就位,MID 放置时触发 BOTTOM 的 neighborChanged,此时 update() 才能看到顶部部件并写入 SWITCH。若枚举顺序或放置流程变动,修复会静默失效。建议在 onPlace 中当顶部部件存在时直接写底部+顶部 SWITCH,或至少加注释说明该依赖。

  • Charger/Discharger 不对称 — 充电器新增了迟滞 + 盈余门槛 + 预装载,放电器只改了 powerValue 赋值时机和 NBT。若 [Bug] 非常好的充电器,这使我电流相生 #4307 的利用只在充电器侧成立,这样处理合理,但建议在 PR 描述中说明意图,避免后续被当作遗漏「补齐」。

🟢 看起来不错

  • [Bug] 放电器在退出重进游戏后就不会放电 #4358 修复方向正确powerValue 持久化 + 赋值时机提前到 timeLeft == 0 也可上报,重进游戏后放电器能立即向电网报功率(旧代码依赖 tick 内分支重算,存在重载窗口)。
  • 电网盈余门槛(consume < generate)本身方向正确,isGridWorking()consume < generate 下冗余但无害。
  • update() 抽取后与旧 neighborChanged 行为逐分支等价(已验证四种 SWITCH×信号组合),无回归。
  • 格式化清理(方法签名换行、尾随空格)一致,未混入无关改动。

📋 声称验证表

声称 状态 说明
Fix #4358 放电器重进不放电 PowerValue NBT 持久化 + 赋值时机提前(DischargerBlockEntity)
Fix #4307 切换信号无中生电 ⚠️ 充电器 20 tick 迟滞有效,但 FE 分支死锁使充电器 FE 路径完全失效;迟滞可被重进绕过
输电杆/远程输电杆放置时立即响应红石 放置顺序验证通过(TOP→MID→BOTTOM,MID 触发 BOTTOM 的 neighborChanged);实现较脆弱(见 💡)

🧪 测试建议

被测目标 推荐测试场景 优先级
ChargerBlockEntity.tick() FE 物品(可 receiveEnergy)完整充电流程:isFeCharging=true 后 startupCoolDown 应能归 0 并触发 receiveEnergy 🔴
ChargerBlockEntity.tick() 电网 consume == generate 边界:充电器暂停后 powerValue 申报是否导致永久卡死 🟡
ChargerBlockEntity NBT saveAdditional/loadAdditional 往返:PowerValue、startupCoolDown 一致性(含旧存档无新 key 的兼容) 🟢
红石迟滞 通电 5 tick → 断电 → 充电应在 20 tick 后才恢复;断电后立刻重进存档应保持剩余 cooldown 🟡
TransmissionPoleBlock.onPlace 有/无红石信号时放置 3 部件杆,验证底部+顶部 SWITCH 立即为 OFF/ON 🟢

结论: REQUEST_CHANGESChargerBlockEntity 的 FE 充电死锁(🔴)必须修复:if (isFeCharging) 分支内的 setStartupCoolDown(20) 使 FE 充电逻辑不可达,这是本 PR 引入的功能性回归,合并前需解决;盈余门槛自包含卡死问题也建议一并处理。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/multipart-block-placement-order.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched references/anvilcraft-power-grid-review.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched SKILL.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Vo1dExr
Vo1dExr marked this pull request as draft August 11, 2026 16:27
# Conflicts:
#	src/main/java/dev/dubhe/anvilcraft/block/entity/ChargerBlockEntity.java
@Vo1dExr
Vo1dExr marked this pull request as ready for review August 11, 2026 16:42
@Gugle2308

Copy link
Copy Markdown
Collaborator

我已完整分析 diff 与目标分支源码。关键逻辑均已交叉验证(PowerGrid.flush/isWorkingSimpleMultiPartBlock.setPlacedBy 放置顺序、TransmissionPoleBlockEntity.tick 的 SWITCH 消费、ChargerBlockEntity 新旧 tick 对照)。以下为审查意见。


代码审查摘要 — PR #4378

操作: converted_to_draft
范围: 4 个文件(4 Java)/ 446 行 diff
分支: fix/1.21/1.6 → dev/1.21/1.6

🔴 关键

1. ChargerBlockEntity.tick() — FE 充能死锁(必须修复)

新代码:

if (isFeCharging) {
    powerValue = -(getFeChargingPowerLevel());
    this.setStartupCoolDown(20);   // ← 每 tick 重置
}
if (startupCoolDown > 0) {
    this.startupCoolDown--;        // 19
    return;                        // ← 永远 return
}
if (timeLeft > 0 && isGridWorking() && grid.getConsume() < grid.getGenerate()) {
    // FE 实际充能逻辑 —— 永远不可达
}

只要 isFeCharging == true,每个 tick 都会把 startupCoolDown 重置为 20,随后立刻 startupCoolDown--; returnFE 充能分支永远无法到达:电池类物品移入槽 1 后 timeLeft(=remainingFE)永不变化、永不完成、永不进入 moveItemToTransformedOverSlot(),物品永久卡死,只能靠玩家右键 tryExtractItemFromSlot1() 取出。isFeCharging 仅在两处被清(moveItemToTransformedOverSlot/tryExtractItemFromSlot1),前者因 timeLeft 不减而永不到达 → 自锁。

setStartupCoolDown(20) 应只在 powered 分支设置(解除锁定后延迟 20 tick 启动的意图),绝不能在 isFeCharging 分支每 tick 重置

2. 两个输电杆的 onPlace 无法在首次放置时同步 TOP 段 SWITCH(修复不完整)

update() 的目标态是「有信号 → OFF / 无信号 → ON」,但 onPlace 中的赋值方向恰好相反(!hasNeighborSignal → OFFhasNeighborSignal → ON)。虽然这会让 update() 的提前 return 条件为 false 从而强制写入,但关键时序问题在于:

  • 玩家放置时 setBlock(BOTTOM) 先触发 onPlace(BOTTOM),此时 setPlacedBy 尚未放置 TOP/MID → update()!topState.is(TRANSMISSION_POLE) 提前 return,onPlace 设置的值从未落盘
  • setPlacedBy 按枚举顺序先放 TOP(placedState() 强制 SWITCH=ON),再放 MID;
  • MID 放置触发 BOTTOM.neighborChanged → update(),此时 BOTTOM 的 SWITCH 已是 getPlacementState 给的正确值(有信号→OFF),(OFF==ON) == !hasSignal 为 true → 提前 return,TOP 段仍保持 ON

结果:放置在有红石信号处时,TOP 段 SWITCH 依然是 ON(placedState() 强制),TransmissionPoleBlockEntity.tick() 据此判定杆子仍接入电网——bug 现象依旧onPlace 的强制同步只在 TOP 已存在时才生效(活塞推动、替换放置等)。另外该反向赋值极易误导后续维护者。建议:要么在 onPlace 中先 setBlockAndUpdate 再同步,要么调整 placedState() 让 TOP 跟随 getPlacementState 的信号值,并让 update() 在「BOTTOM 已正确但 TOP 不一致」时也能同步 TOP。

⚠️ 警告

3. ChargerBlockEntity.tick()moveItemToTransformingSlot() 移到 powered 检查之前,锁定状态会吞物品

旧代码 if (powered) return; 在最先,红石锁定时槽 0 物品不会被动;新代码 if (timeLeft == 0) moveItemToTransformingSlot(); 先执行,锁定状态也会把物品移入槽 1,且 isSlotDisabled() 返回 timeLeft > 0 → 槽 1 被 GUI 锁定,玩家无法直接取出。若红石锁定的意图是「阻止充能」,此改动会意外吞入物品。请确认是否有意。

4. startupCoolDown 未序列化

本 PR 新增了 PowerValue 的 save/load,但 startupCoolDown 未保存。chunk 卸载/重载后 cooldown 归零,20 tick 上电延迟失效,可能复现 #4307 的电网波动问题。建议一并序列化或明确其为瞬态。

5. grid.getConsume() < grid.getGenerate() 严格盈余条件 + 快照延迟

consume/generatePowerGrid.tick() 每 20 tick flush() 一次,充电器每 tick 读取的是旧快照;且该条件要求严格盈余(旧代码 isGridWorking()generate >= consume 就工作)。电网恰好平衡(generate == consume,含充电器自身需求)时充电器会完全停止;暂停时 powerValue 未清零仍计入 consume,可能形成「不充能但仍占额度」的循环。若这是 #4307 的预期行为(只在盈余时充能),建议在暂停路径显式清零 powerValue 并注释说明。

🟢 看起来不错

  • DischargerpowerValue = getFeDischargingPowerLevel() 提前到 moveItemToTransformingSlot() 之前,放电开始即上报功率,方向正确。
  • 新增 PowerValue 序列化,修复 chunk 重载后功率丢失。
  • update() 重构消除了旧代码 bl == hasNeighborSignal 的双重否定,语义等价性经推演正确(其余分支逻辑无变化)。

📋 声称验证表

声称 状态 说明
Fix #4358(杆子不立即响应红石) ⚠️ onPlace 改动方向正确但首次放置时序下无法同步 TOP 段,修复不完整
Fix #4307 ⚠️ Charger/Discharger 有针对性改动,但 FE 充能死锁(问题 1)阻断主流程

结论: COMMENT — PR 处于 draft 状态,按规则仅报严重问题。问题 1(FE 充能死锁)与问题 2(杆子 TOP 段不同步)建议在转 ready 前修复;问题 3–5 建议确认设计意图。核心修复思路(onPlace 强制同步、启动冷却、功率序列化)方向合理。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

curl -sL "https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4307" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('title')); print('---'); print(d.get('body'))" 2>/dev/null; ...

Reason: Security scan — [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4307 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4307 (https://getvet.sh); [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4358 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4358 (https://getvet.sh); script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/anvilcraft-power-grid-review.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

All verification complete. Here is the review:


代码审查摘要 — PR #4378

操作: synchronize
范围: 4 个文件 (4 Java, 0 新增, 0 删除) / 440 行 diff / 24 hunks
修复目标: #4358(放电器重进后不放电)、#4307(高频红石白嫖充能)、输电杆/远程输电杆放置时不立即响应红石信号

🔴 关键

未发现合并阻断级问题。两个 bug 修复和输电杆修复均经代码交叉验证成立(diff 已用 git applydev/1.21/1.6 当前 base 验证可干净应用)。

⚠️ 警告

  • ChargerBlockEntity.tick — 红石锁定不再阻止物品吸入(行为回归)moveItemToTransformingSlot() 被移到 if (powered) 判断之前。旧代码 if (powered) return; 在最前,红石上电时机器完全惰性,物品留在输入槽(槽 0)。新代码在上电状态下仍会把物品从槽 0 拉入处理槽(槽 1),并置 timeLeft > 0isSlotDisabled() 返回 true → 物品被锁在槽 1,上电期间玩家无法取回。同 PR 中 DischargerBlockEntity 保持了旧顺序powered 判断在前),两者不一致,说明此处重排很可能是无意的。建议把 powered 判断恢复到 moveItemToTransformingSlot() 之前(不影响 [Bug] 非常好的充电器,这使我电流相生 #4307 的修复效果——物品在断电时才吸入,冷却同样从 20 开始计)。
  • ChargerBlockEntity.tick — 门控/冷却期间仍上报虚耗电powerValue = -(getFeChargingPowerLevel())isFeCharging 时每 tick 无条件写入,包括 20 tick 启动冷却期和电网门控失败期间。两个后果:(1) 冷却期电网仍按需求计费,放电器真实抽取 FE,但充电器不充能——能量被转存或流失(每物品 20 tick 的损耗);(2) 门控失败时虚耗电使 consume 居高不下,PowerGrid.tick() 过载分支会抽干电池储能去填补这个虚需求(need = consume - generate → storage 被 extract),而充电器实际什么都没充——电池白白流失。建议把 powerValue 更新移进门控条件内,或门控失败时置 0。
  • ChargerBlockEntity.tick — 门控条件冗余isGridWorking() && grid.getConsume() <= grid.getGenerate()isGridWorking() = grid.isWorking() = generate >= consume,与第二个条件完全等价。另注意 getConsume()/getGenerate() 仅在 ServerTickEvent.Pre 每 GRID_TICK(20) 刷新一次,门控读到的值最多滞后 19 tick(可接受,但需知晓)。

💡 建议

  • DischargerBlockEntity — 卡死状态下 isFeDischarging 不清理(潜在虚发电隐患) — 当输出槽(槽 2)满时,放完电的物品留在槽 1,moveItemToTransformedOverSlot() 只置 powerValue = 0 就 return,isFeDischarging 保持 true(旧代码已如此)。新代码的 powerValue = getFeDischargingPowerLevel() 每 tick 无条件写入使该状态下 powerValue 每 tick 先被置非零、tick 末尾再被清 0。当前电网 flush 在 BE tick 之后读取(读到清 0 后的值),不会产生虚发电;但这个顺序很脆弱,一旦 flush 时机变化就是白嫖发电。建议在物品无法移出时同时清 isFeDischarging
  • 输电杆 — update() 静态性不一致 — RemoteTransmissionPoleBlock 为 private static,TransmissionPoleBlock 为实例方法,统一一下。旧的空 IHasMultiBlock.onPlace/onRemove(Level, BlockPos, BlockState) 保留无碍(接口契约),但真正的 vanilla 5 参 onPlace 才是干活入口,建议加一行注释说明,避免后人误改空壳。

🟢 看起来不错

  • [Bug] 放电器在退出重进游戏后就不会放电 #4358 根因定位准确:旧代码 powerValue 不序列化,且配方类物品(isFeDischarging == false)只在 moveItemToTransformingSlot() 里赋值,重进后永久为 0 → 不放电。序列化 PowerValue + 无条件重算(FE 路径)双管齐下,配方/FE 两条路径都覆盖。旧存档缺 key 时 getInt 默认 0,降级安全,放入新物品后即自愈。
  • 输电杆 onPlace 修复验证通过:base 分支只有空的 3 参接口方法,vanilla 5 参 hook 从未被覆写——这正是"放置不响应"的根因。新增的 update() 逻辑与旧逻辑行为等价(有信号置 OFF、无信号置 ON + 无变化则跳过),且提前 return 守卫有效阻止了 setBlockAndUpdate → onPlace/neighborChanged 的递归循环。
  • 多方块放置顺序验证setPlacedBy 按枚举序 TOP→MID→BOTTOM 放置(Vertical3PartHalf.values()),因此无论玩家以哪一段为主方块放置,底部方块的 update()(自身 onPlace 或最后一段相邻放置触发的 neighborChanged 链)都能看到完整结构并立即响应。
  • [Bug] 非常好的充电器,这使我电流相生 #4307 修复原理成立:高频红石下冷却永远无法走完(每次上电重置为 20),无法触发批量 FE 转移。

📋 声称验证表

声称 状态 对应实现
Fix #4358 放电器重进后不放电 DischargerBlockEntity: PowerValue 序列化 + tick 无条件重算;ChargerBlockEntity 同步修复
Fix #4307 高频红石白嫖充能 ChargerBlockEntity: startupCoolDown(20) + 电网盈余门控
输电杆/远程输电杆放置时立即响应红石 两 Block: 新增 vanilla 5 参 onPlace + 抽取 update() 方法

结论: COMMENT — 三个修复目标均正确实现并通过代码级验证(含放置顺序、递归守卫、存档兼容);上述警告项为行为回归与边界场景,建议修复或确认后再合入。其中"上电仍吸入物品"一项强烈建议恢复 powered 判断顺序。

🧪 测试建议

被测目标 推荐测试场景 优先级
ChargerBlockEntity.tick() 红石 1/2/20 tick 周期切换 → 高频下不充能;稳定断电 20 tick 后才开始充能 🔴
ChargerBlockEntity.tick() 上电状态下向槽 0 放入物品 → 验证物品是否被吸入槽 1 并锁定(回归点) 🔴
DischargerBlockEntity 配方物品放电中途保存/重进 → 功率输出恢复(#4358 回归测试);FE 物品同场景 🔴
TransmissionPoleBlock/RemoteTransmissionPoleBlock 从下往上放置在已通电导线旁 → SWITCH 立即置 OFF;拆顶部再放回 → 恢复响应 🟡
ChargerBlockEntity 输出槽满时完成充能(卡死态)→ 电网数据无虚耗/虚发 🟡

由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

分析完成。所有关键路径已在 PR head 分支(pr4378)上交叉验证。以下是审查意见。


代码审查摘要 — PR #4378

操作: ready_for_review
范围: 4 个文件(全部 Java,0 新增 / 0 删除)/ 440 行 diff
分支: fix/1.21/1.6 → dev/1.21/1.6
声称修复: #4358(放电器重进游戏后不放电)、#4307(充电器"电流相生")、输电杆/远程输电杆放置时不立即响应红石信号

📋 声称验证表

声称 状态 说明
Fix #4358 DischargerBlockEntity 持久化 powerValue。机制确认:配方放电路径(isFeDischarging=false)的 powerValue 只在 moveItemToTransformingSlot 设置,重进后不再重算 → 恒为 0 → 电网 0 发电。持久化 + if (isFeDischarging) 提前重算是正确修复
Fix #4307 Charger 充电新增 grid.getConsume() <= grid.getGenerate() 门控 + 20 tick startupCooldown:电网过载时暂停充电、断电后延迟重启,切断"电流相生"环
输电杆放置即时响应 update() 无条件按信号同步 BOTTOM+TOP 两侧 SWITCH。Vertical3PartHalf/Vertical4PartHalf 枚举按 TOP 优先声明,setPlacedBy 先放 TOP 再放 MID/LOWER,MID/LOWER 放置触发 BOTTOM neighborChanged 时 TOP 已存在 → 放置即刻同步。旧代码只在 bl == hasSignal(状态与目标相反)时翻转,而放置时 BOTTOM 已是目标态(getPlacementState 按信号设置),TOP 恒 ON 永远不会被纠正——这正是原 bug

🔴 关键(需修复后合并)

1. ChargerBlockEntity — 输出槽满时永久卡死(本次重构引入的回归)

新 tick 中 if (startupCoolDown > 0) { startupCoolDown--; return; } 的 early-return 位于底部 if (timeLeft == 0) { moveItemToTransformedOverSlot(); } 之前。而 if (timeLeft == 0) 分支每 tick 都把 cooldown 重置为 20 → cooldown 永不为零 → 底部输出移动只在 timeLeft 由 1→0 的过渡 tick 执行一次(此时 cooldown 恰好为 0)。

触发路径:物品完成瞬间输出槽(slot 2)已满 → moveItemToTransformedOverSlot 提前 return(物品留在 slot 1)→ 此后即使清空输出槽,该物品也永远卡在 slot 1、新物品无法进机,机器永久停摆(只能手动空手右键取出或拆方块)。旧代码无 cooldown,底部输出移动每 tick 重试,输出一旦腾空即自动恢复——这是行为回归。

建议: 仅在 moveItemToTransformingSlot 真正移动了新物品时才置 cooldown(让它返回 boolean),或把输出移动逻辑挪到 cooldown early-return 之前。

⚠️ 警告

  • ChargerBlockEntity — powered 时仍会吞入输入物品(行为变化)if (timeLeft == 0) { moveItemToTransformingSlot(); ... } 被移到 if (powered) return; 之前。旧代码 powered 时完全惰性;新代码红石锁定时输入物品仍会被移入加工槽(玩家视角"吞入"但未加工),解锁后才开始 20 tick 计时。建议将 move 也纳入 powered 保护。
  • ChargerBlockEntity — 暂停时仍向电网报告标称功耗if (isFeCharging) { powerValue = -(getFeChargingPowerLevel()); } 在门控关闭/cooldown 期间仍每 tick 执行 → getInputPower() 持续计入 grid.consume(flush 是每 GRID_TICK 聚合)。后果:(a) 电网界面显示充电器在耗电而实际未充;(b) 门控要求"富余 ≥ 自身标称需求"才放行——例:generate=300、其他耗电 50 时,充电器标称 256 → 306>300 → 永久被挡,尽管实际富余 250。保守方向正确,但建议暂停期间 powerValue 归零。
  • ChargerBlockEntity — 门控条件冗余isGridWorking() && grid.getConsume() <= grid.getGenerate()——PowerGrid.isWorking() 内部就是 generate >= consume,两者完全重复,保留其一即可。

🟢 看起来不错

  • 输电杆 update() 的早退守卫 (bottom == new) && (top == newTop) 避免冗余 setBlockAndUpdate,且新旧逻辑稳态目标一致(有信号→OFF,无信号→ON),无极性反转。
  • powerValue/startupCoolDown NBT 持久化(getInt 默认 0)对旧存档向后兼容。
  • 布尔坍塌、坐标复制粘贴、EOF 换行、TODO/密钥残留等常规扫描全部干净。

🧪 测试建议

被测目标 推荐测试场景 优先级
ChargerBlockEntity.tick() 输出槽满时完成加工 → 清空输出后应自动恢复(当前会卡死) 🔴
ChargerBlockEntity.tick() powered 锁定状态下放入输入物品,解锁后行为验证 🟡
ChargerBlockEntity.tick() 电网过载 → 恢复供电 → 充电暂停/恢复 + cooldown 时序 🟡
ChargerBlockEntity.save/load StartupCoolDown/PowerValue 存档往返 🟢
TransmissionPoleBlock 已激活红石旁放置两种输电杆,验证 BOTTOM+TOP SWITCH 立即同步 🟢

结论: REQUEST_CHANGES — 三个 fix 的核心机制均验证成立,但 Charger 的 startupCooldown 重构引入输出槽满时的永久卡死回归,需修复后合并。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched references/anvilcraft-power-grid-review.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/anvilcraft-power-grid-review.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched SKILL.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

for n in 4358 4307; do echo "===== ISSUE $n ====="; curl -sL "https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/$n" | python3 -c "import json,sys; d=json.load(sys.stdin); print('TITLE:', d.get(...

Reason: Security scan — [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/$n — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/$n (https://getvet.sh); script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

分析完成。我已经完整验证了放置顺序(枚举 TOP 优先 → setPlacedBy 先放 TOP 再放 MID → MID 放置触发底部 neighborChanged → update() 在顶部存在后执行)、电网逻辑(isWorking()consume <= generate,GRID_TICK=20 缓存)、以及两个 issue 的根因。现在输出审查意见。


代码审查摘要 — PR #4378

操作: synchronize
范围: 4 个文件(全为 Java)/ 440 行 diff
声称: Fix #4358(放电器退出重进后不放电)、Fix #4307(高频红石切换无中生电)、Fix 输电杆/远程输电杆放置时不立即响应红石信号

📋 声称验证表

声称 状态 对应实现
Fix #4358 放电器重进后不放电 DischargerBlockEntity 持久化 PowerValue;根因正确:配方放电路径(isFeDischarging=falsepowerValue=recipe.power)重启后 powerValue 归 0 → getOutputPower()=0
Fix #4307 高频红石切换充能 ChargerBlockEntity 新增 startupCoolDown(20 tick):powered 期间每 tick 重置冷却,断电后需 20 tick 才能恢复充电 → 高频切换无法累积充电刻
Fix 输电杆放置不立即响应红石 update() 抽取 + onPlace 调用;放置时序:底部先落(onPlace 早退)→ setPlacedBy 先放 TOP 再放 MID → MID 放置触发底部的 neighborChanged → update() 在 TOP 已存在后执行,两端 SWITCH 被正确校正
充电器同样受益 Charger 也持久化 PowerValue,避免重启后配方充电"免费用电"(getInputPower() 读到 0)

🔴 关键

  • ChargerBlockEntity.tick() — redstone 禁用时仍会吞入输入物品(行为回归)
    if (timeLeft == 0) { moveItemToTransformingSlot(); ... } 被移到了 if (powered) 检查之前。旧代码 if (powered) return; 在最前,禁用期间物品留在输入槽;新代码在禁用期间仍会把 slot 0 的物品移入处理槽并锁定 timeLeft,玩家从漏斗侧看到物品"消失"(只能靠 GUI tryExtractItemFromSlot1 或拆方块取回)。若这是为让 powered 期间持续重置冷却而做的调整,建议改为 powered 时只重置冷却、不移动物品。

⚠️ 警告

  • ChargerBlockEntity — grid.getConsume() <= grid.getGenerate() 是死条件(no-op)
    PowerGrid.isWorking() 就是 generate >= consume,而 isGridWorking() = getGrid().isWorking(),两者完全同义。新增闸门没有改变任何行为——[Bug] 非常好的充电器,这使我电流相生 #4307 的实际修复机制只有冷却。若意图是"仅在有剩余容量时充电",应使用 grid.getRemaining() > 0 之类语义;且两处读的都是每 GRID_TICK(20 tick) 才刷新的缓存值,注意时滞。
  • startupCoolDown 空闲态永不归零
    timeLeft == 0 时每 tick 都 setStartupCoolDown(20) 再自减到 19 → 冷却在空闲时永远无法走完。结果:每个新物品(含第一个)都要吃满 20 tick 启动延迟,语义变成"每物品处理延迟"而非"上电防抖",与 [Bug] 非常好的充电器,这使我电流相生 #4307 意图不完全一致。输出槽满、物品卡在 slot 1 时同理(虽无害)。
  • 冷却期间虚报电网需求
    if (isFeCharging) powerValue = -(getFeChargingPowerLevel()) 在冷却检查之前执行 → 20 tick 内电网 consume 计入充电器需求但 FE 并未注入物品 → 电网账目虚高(可能引发 OVERLOAD 属性翻转);且 getFeChargingPowerLevel()count 把冷却中的充电器也算进去,稀释 per-device 档位,拖慢其他充电器。
  • 旧存档兼容(自愈但需知晓)
    旧存档无 PowerValue/StartupCoolDown 键 → 读 0。进行中的配方充/放电重启后功率归零(充电器免费充电 / 放电器不发电),直到下一个物品周期自愈。

💡 建议

  • TransmissionPoleBlock/RemoteTransmissionPoleBlockonPlace 在放置时必然先于顶部部件触发(early return),真正生效的路径是 MID 放置时触发的底部 neighborChanged。onPlace 冗余但无害;更清晰的写法是覆写 setPlacedBy 在全部部件落位后调用一次 update()
  • DischargerBlockEntitypowerValue = getFeDischargingPowerLevel() 是同 tick 内必然被实际抽取值覆盖的死赋值(仅 slot 1 为空/storage 为 null 的瞬态生效),建议删除或移到真正需要的地方。
  • ChargerSyncPacket — 未包含 startupCoolDown,客户端在冷却期会看到进度条冻结 20 tick(外观问题,可后续处理)。

🟢 看起来不错

  • update() 的化简(toggle-if-match → 按信号赋值 + 无变化早退)与旧逻辑逐状态等价,且避免了无谓的 setBlockAndUpdate;早退守卫正确防住了 setBlock 触发的重复调用(有界,无死循环)。
  • [Bug] 放电器在退出重进游戏后就不会放电 #4358 根因定位准确(配方路径 powerValue 未持久化),修复最小且有效;NBT 键名与现有 camelCase 风格(TimeLeft/TimeTotalCache)一致。
  • 大量纯格式调整(换行、注解参数拆分、@SuppressWarnings 行内化)无行为影响。
  • 远程杆 4 段(pos.above(3))、普通杆 3 段(pos.above(2))偏移与 Vertical4PartHalf/Vertical3PartHalf 枚举一致。

🧪 测试建议

被测目标 推荐测试场景 优先级
输电杆放置响应 已通电红石线旁放置 3/4 段杆 → 顶部件 SWITCH 应立即为 OFF 且从电网断开;无信号时放杆 → ON 🔴
Charger 红石控制 高频时钟(5 tick 周期)对充电器 → 物品不应被充能;断电后应延迟 20 tick 才恢复 🔴
充电器禁用状态 powered 期间向输入槽投物品 → 确认物品是否被吞入处理槽(回归验证) 🟡
序列化 配方充/放电进行中存档→重启→功率应保持(#4358/#4307 回归) 🔴
电网闸门 发电 < 64 电网上的 FE 充电器 → 确认静默停摆行为是否符合预期 🟡

结论: COMMENT — 三个声称的修复方向均正确且核心机制有效(#4358 持久化、#4307 冷却、输电杆放置时序链路),无编译/数据丢失风险。建议合并前处理:充电器 powered 时吞入物品的回归(确认意图或修复),以及删除/修正冗余的 consume <= generate 闸门。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/multipart-block-placement-order.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched references/anvilcraft-power-grid-review.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched SKILL.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Vo1dExr
Vo1dExr marked this pull request as draft August 12, 2026 11:53
@Gugle2308

Copy link
Copy Markdown
Collaborator

分析完成,所有关键链路已通过目标分支源码验证。整理审查结论:


代码审查摘要 — PR #4378(Draft)

操作: converted_to_draft
范围: 4 个文件(4 Java)/ 440 行 diff
修复目标: #4358 放电器重进游戏后不放电、#4307 高频红石切换无中生电、输电杆放置时不响应红石

🔴 关键问题

1. ChargerBlockEntity.tick() — 成品物品永久卡死(硬死锁)
新 tick 顺序下,moveItemToTransformedOverSlot() 实际变成了不可达代码:

if (timeLeft == 0) {
    moveItemToTransformingSlot();
    this.setStartupCoolDown(20);   // ← 每次 timeLeft==0 都重新武装 20
}
...
if (startupCoolDown > 0) {
    this.startupCoolDown--;
    return;                        // ← timeLeft==0 时必然在此 return
}
...
if (timeLeft == 0) {
    moveItemToTransformedOverSlot();   // ← 永远执行不到
}

只要 timeLeft == 0,cooldown 每 tick 都被重置为 20,永远在 cooldown 分支 return。具体死锁场景(非常常见):

  • 物品充满后 remainingFE <= 0 分支把 timeLeft 置 0,但输出槽(slot 2)被占用 → 当 tick 的 moveItemToTransformedOverSlot()if (!slot2.isEmpty()) { powerValue = 0; return; } 提前返回,物品留在 slot 1。
  • 之后玩家清空 slot 2,物品也永远不会移到输出槽——因为 timeLeft == 0 每 tick 重置 cooldown,moveItemToTransformedOverSlot() 永远不再执行。
  • 后果:充电器永久卡死,无法处理下一个物品;且 isFeCharging 保持 true,powerValue = -(getFeChargingPowerLevel()) 每 tick 设置 → 电网永久挂载一份幻影负载(见警告 2)。

旧代码 if (timeLeft == 0) moveItemToTransformedOverSlot(); 在每次 tick 都会执行(slot 2 空了就自动移走),不存在此问题。建议:cooldown 只在 startupCoolDown <= 0 时武装(避免重复重置),或把 moveItemToTransformedOverSlot() 挪到 cooldown return 之前。

⚠️ 警告

2. startupCooldown 期间的幻影电网负载
powerValue = -(getFeChargingPowerLevel()) 被移出 timeLeft > 0 守卫、且设置在 cooldown return 之前 → 每个充电周期有 20 tick 以满档位向电网上报消耗(getInputPower() 只检查 POWERED 不检查 cooldown),但实际没有充电。电网 GRID_TICK = 20flush() 会把这 20 tick 的幻影消耗算进 consume → 其他设备(靠 isWorking() 判断)可能看到假过载;若电网本就接近满载,充电器自身的幻影消耗还会让新的 grid.getConsume() <= grid.getGenerate() 自检失败 → 停止充电 → 幻影值持续存在 → 永久停摆(此"被阻塞时幻影常驻"旧代码也有,但 cooldown 让健康电网也会出现 20 tick 假负载)。另外该自检与 isGridWorking() 是同一个布尔条件写了两遍(isGridWorking() = grid.isWorking() = generate >= consume),可保留其一。

3. powered 状态下物品被拉进充电槽
moveItemToTransformingSlot() 现在在 powered 检查之前执行(旧代码 if (powered) return; 在最前)。红石持续供电时,输入槽物品会被拉进 slot 1 并锁住(isSlotDisabled = timeLeft > 0),只能靠右键 tryExtractItemFromSlot1() 取回。而 Discharger 保留了旧顺序(powered 先 return)——两个机器行为不对称,疑似非预期。如果是有意预装载,建议在描述中说明。

🟢 看起来不错

  • 输电杆修复方向正确且经得起推敲:根因是 placedState() 强制非底部部件 SWITCH = ON,而旧 neighborChanged 只在「底部自身状态与信号不匹配」时才动作——有信号放置时底部 OFF(getPlacementState 正确)但顶部 ON,旧逻辑检测底部(已正确)→ 不动作 → 顶部永远 ON。新 update() 无条件双向对齐两个部件的 SWITCH,配合 setPlacedBy 按枚举序 [TOP, MID, BOTTOM](跳过 BOTTOM)放置——放 MID 时触发底部的 neighborChanged,此刻 TOP 已就位,修复生效 ✅。早退守卫(顶部未就位/值未变化)避免了空指针和冗余写。onPlace 作为防御性补充(/setblock、活塞推入等场景),无递归风险(update 内 setBlockAndUpdate 会再触发 onPlace,但值已匹配早退)。
  • [Bug] 放电器在退出重进游戏后就不会放电 #4358PowerValue 序列化已加(两个 BE 都有)✅;powerValue 移出 timeLeft > 0 让电网 flush() 在重载后立即读到正确的输出值 ✅。
  • [Bug] 非常好的充电器,这使我电流相生 #4307:20 tick 稳定期方案有效——powered 每 tick 重置 cooldown,需要连续 20 个非 powered tick 才会开始充电,高频切换永远凑不满,feCooldown 爆发式充能无法再被触发 ✅。StartupCoolDown 也持久化了,防止通过重进游戏绕过稳定期 ✅。
  • Discharger 侧 powerValue 的瞬态错误值在同一 tick 内被 moveItemToTransformedOverSlot()powerValue = 0 覆盖,最终值正确,无实际影响。

📋 声称验证表

声称 状态 说明
Fix #4358(放电器重载不输出) PowerValue 持久化 + 移出 timeLeft 守卫
Fix #4307(高频红石无中生电) startupCoolDown 20 tick 稳定期,持久化防重载绕过
输电杆/远程输电杆放置立即响应红石 update() 无条件双向对齐 + onPlace(放置顺序已验证 TOP→MID→BOTTOM)

结论: COMMENT(Draft 阶段) — 三个修复目标方向全部正确,但 #1 的死锁(输出槽占用后永久卡死)是必须修复的硬伤,建议修复后再转 Ready。draft 阶段先不阻塞,等逻辑修正后可再看一轮。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/anvilcraft-power-grid-review.md in skill 'minecraft-mod-pr-review' (1 replacement).

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] 放电器在退出重进游戏后就不会放电 [Bug] 非常好的充电器,这使我电流相生

2 participants