Skip to content

Fix mirror and rotation for fish tank and overflow chute 修复鱼缸和溢流溜槽翻转旋转 - #4947

Merged
WhereisFff merged 1 commit into
Anvil-Dev:dev/1.21/1.6from
Hailcrop:fix/orientation
Sep 19, 2026
Merged

WhereisFff merged 1 commit into
Anvil-Dev:dev/1.21/1.6from
Hailcrop:fix/orientation

Conversation

@Hailcrop

Copy link
Copy Markdown
Contributor

修复鱼缸和溢流溜槽无法被litematica/建筑杖/智能方块放置器正确旋转/翻转,且蓝图预览方向不正常的问题

修复鱼缸和溢流溜槽无法被litematica/建筑杖/智能方块放置器正确旋转/翻转,且蓝图预览方向不正常的问题
@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

curl -sL "https://api.github.com/repos/Anvil-Dev/AnvilCraft/pulls/4947" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('title')); print('state',d.get('state'),'merged',d.get('merge...

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/pulls/4947 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/pulls/4947 (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

已完成审查(diff 65 行 / 2 个文件,全部用 terminal + curl 获取与分析,未发表任何额外评论)。以下为审查意见:


代码审查摘要 — PR #4947

操作: opened(未合并)
范围: 2 个文件(2 Java,0 新增,0 删除)/ 65 行 diff(+30 / −2,3 个 hunk)
目标分支: dev/1.21/1.6(MC 1.21.1,NeoForge 21.0.x)

📋 声称验证表

PR 声称 状态 证据
鱼缸无法正确旋转/翻转 ✅ 已修 base 分支 FishTankBlock.java 完全没有 rotate/mirror 覆写(git show rvbase4947_1216:...FishTankBlock.java | grep rotate|mirror → 0 匹配),原版默认实现是 no-op,FACING 从不变化;本 PR 补上二者
溢流溜槽无法正确旋转/翻转 ✅ 已修 base 的 rotate 只改 FACING,6 个 overflow_* 属性完全不随动 → 旋转后溢流口留在世界方向(视觉/功能双错);新的 rotate/mirror 对端口做了双射置换
蓝图预览方向不正常 building/BlueprintPlacement.java:97state.mirror(this.mirror).rotate(this.rotation),客户端预览(BuildingRodClient)共用同一 BlueprintPlacement record,走的就是这两个新钩子

🔬 关键正确性核对

  1. 端口置换逻辑正确:循环从旧 state 读值、写向新 result,无自覆盖风险;rotation.rotate(d) / mirror.mirror(d) 在 6 个方向上是双射,写入顺序无关(每个属性恰好写一次)。
  2. 不变量保持sanitizeOverflowPorts 假定「出入口轴(FACING 及其 opposite)上永远没有溢流口」。Rotation 绕 Y 轴保轴,mirror.mirror 也只翻转 X 或 Z 轴方向,因此 {FACING, FACING.getOpposite()} 恒被映射到自身集合 —— 变换后该不变量仍成立,不会被 BE 的清理逻辑反噬。
  3. FACING 部分是等价改写(无行为回归):反汇编 mapped client 的 net.minecraft.world.level.block.Mirror.class 核对语义 —— mirror(Direction)FRONT_BACK+axis==X → opposite,LEFT_RIGHT+axis==Z → opposite;getRotation(Direction)LEFT_RIGHT+axis==Z → CLOCKWISE_180FRONT_BACK+axis==X → CLOCKWISE_180,否则 NONE。逐方向代入可知 rotate(getRotation(f)) == mirror.mirror(f) 对 6 个方向恒成立 ⇒ 旧的 FACING 处理与新的等价,本 PR 真正的行为变化只有「端口随方块一起转」。这也让修复范围收得很干净。
  4. 渲染会跟着变对blockstates/fish_tank.json(4 个水平 facing + outlet)与 blockstates/overflow_chute.json(6 个 facing × 6 个 overflow_*)都是 multipart 且条件互不耦合,置换后的每个状态都有对应模型,不会出现「状态对了但模型没变」。
  5. 方块与实体的复合顺序一致:方块 mirror → rotateBlueprintPlacement:97),实体 rotation.rotate(mirror.mirror(facing))BuildingEntityTransform:26)——同一复合顺序,蓝图里方块与实体不会互相打架。
  6. 通用项:EOF 缺换行 0、无 TODO/FIXME/调试残留、无硬编码凭据。

💡 建议(均非阻塞)

  1. 同族遗漏:block/fluid/PumpBlock.javarotate 却没有 mirror。它的 ORIENTATIONOrientationblock/state/Orientation.java:144 已提供 mirror(Mirror)),同族 BlockPlacerBlock:370/375 两个都实现了 → 蓝图镜像放置时泵的朝向不会镜像(与本 PR 修的鱼缸是同一类缺陷)。可顺手补:
    @Override
    public BlockState mirror(BlockState state, Mirror mirror) {
        return state.setValue(ORIENTATION, state.getValue(ORIENTATION).mirror(mirror));
    }
    其余 rotate 无 mirror 的方块(FeCollectorBlock / LensBlock / MonolithBlock / HeavyIronBeamBlock / SlidingRailBlock / ControlValveBlock / GiantMonolithCoreBlock)用的都是 AXIS 类属性,镜像下不变,无需补 —— 已逐个确认,不用管。
  2. 铁砧锤路径与本 PR 语义分叉(既有行为,非本 PR 引入):新增的 rotate/mirror 会带着溢流口一起转,但铁砧锤两条路径绕过 BlockState#rotate —— 长按轮盘走 HammerChangeBlockPacket + StateUtil.findPossibleStatesForProperty(initial, FACING)(只循环 FACING,其他属性保持原样),右键走 AnvilHammerItem.useBlock → HammerManager.getChange(...).change(...)HammerRotateBehavior 直接 setValue(FACING)。若轮盘把出口转到某个已开溢流口所在面,会短暂产生「出入口轴上有溢流口」的状态,靠 OverflowChuteBlockEntity.tick()sanitizeOverflowPorts() 在下一 tick 清掉(该 tick 内 hasOverflowPort(state, FACING) 为真)。这与 use() 的注释(单击管端口、轮盘管朝向)是自洽的,建议确认「锤子只转朝向、端口不跟着转」是有意设计即可;若希望锤子也整块转,把 change()/轮盘改成调用 state.rotate(...) 即可自动一致。
  3. 小疵:同一个 PR 里 FishTankBlockprotected 覆写、OverflowChuteBlockpublic(原作即 public),无功能差异,统一一下更整洁。

🟢 看起来不错

  • 修复范围克制、只用 FACING/端口两个语义面,没有顺手改动无关代码。
  • 端口置换用「按方向遍历 + 双射映射」而非硬编码 6 组 case,后续加属性不易漏。
  • 未用 Direction.values() 的顺序做任何假设(顺序安全)。

🧪 测试建议

被测目标 推荐场景 优先级
OverflowChuteBlock.rotate/mirror 6 方向 × 3 Rotation / 3 Mirror 全组合断言:端口集合等于原集合按 rotate/mirror 映射后的结果;并断言 {FACING, opposite} 上端口恒为 false(不变量) 🔴
FishTankBlock.rotate/mirror 4 水平朝向 × Rotation/Mirror:mirror 下 NORTH 保持 NORTH、EAST↔WEST(FRONT_BACK)/ NORTH↔SOUTH(LEFT_RIGHT),TROPICAL/OUTLET 不变 🟡
蓝图 round-trip 存入 → 旋转 90°×n + 镜像 → 再逆变换,状态与端口应回到原值;方块与实体(BuildingEntityTransform)朝向一致 🟡

结论: APPROVE — 逻辑正确、范围克制、无阻塞问题;上面两条 💡 是同族遗留项,可作为后续 issue 或顺手修。

建议标题: Fix rotate/mirror for fish tank and overflow chute (overflow ports follow) 修复鱼缸与溢流溜槽的旋转/镜像(溢流口随方块转动) —— 现标题把 mirror 译作「翻转」易与「旋转」混淆,且未体现溢流口随动这一实质修复;本次因 gh auth status 显示 token 失效(gh 未认证),未自动修改,仅作建议。

由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/vanilla-bytecode-semantics-forensics.md in skill 'minecraft-modding' (1 replacement). · Patched SKILL.md in skill 'minecraft-modding' (1 replacement).

@WhereisFff
WhereisFff merged commit 0b2f547 into Anvil-Dev:dev/1.21/1.6 Sep 19, 2026
2 checks passed
@Gugle2308

Copy link
Copy Markdown
Collaborator

PR #4947 状态为 closed,按 webhook 规则(closed/labeled → 停止)不进行审查、不发布任何评论。

已跳过:diff 下载、代码分析、gh 标题修改、评论发表。

@Hailcrop
Hailcrop deleted the fix/orientation branch September 20, 2026 02:18
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.

3 participants