Skip to content

Fix big red button targeting and animation 修复大红按钮目标判定与按压动画 - #5141

Merged
PigeonNian merged 1 commit into
Anvil-Dev:dev/1.21/1.6from
WhereisFff:fix/5138-button-target
Oct 3, 2026
Merged

PigeonNian merged 1 commit into
Anvil-Dev:dev/1.21/1.6from
WhereisFff:fix/5138-button-target

Conversation

@WhereisFff

Copy link
Copy Markdown
Contributor

fix(button): 修复大红按钮遮挡边缘交互与按压动画

- 使用实际命中位置进行服务端射线校验,修复按钮可见但底座中心被遮挡时无法按下的问题。
- 按住按钮后等待服务端确认再播放手部动画,并忽略已释放或已切换目标的过期确认。
- fixed Anvil-Dev#5138
@Gugle2308

Copy link
Copy Markdown
Collaborator

审查完成。以下是可直接发布的审查意见。


代码审查摘要 — PR #5141

标题: Fix big red button targeting and animation 修复大红按钮目标判定与按压动画
作者: @WhereisFff | 分支: fix/5138-button-target → dev/1.21/1.6
状态: ⚠️ Draft(草稿) — GitHub API 返回 "draft": true, state: open, mergeable: true
范围: 3 个文件 / +68 −27 行(BigRedButtonBlockEntity、BigRedButtonInputListener、BigRedButtonHoldPacket)
取证基线: base sha da7e856b8f…(= 当前 dev/1.21/1.6 tip,无漂移)、head 2d8b932274…(= refs/pull/5141/head)——审查的就是当前最新修订

因处于草稿状态,以下只报实质性问题,省略风格/格式类建议,结论按 comment 级别给出。

✅ 先确认过的关键机制(无问题,说明为何不是 bug)

检查项 结论 依据
改成双向包是否需要额外注册 ✅ 不需要 lib NetworkRegistrar 按 @Network 注解包扫描;PacketData.find 中 ISensitiveBiPacket → BIDIRECTIONAL → registrar.playBidirectional(...),S2C 回传自动被注册
ISensitiveBiPacket / StreamCodecUtil.VEC3 / Util.cast 在锁定版本中存在 ✅ 目标分支锁定 anvillib = 2.0.0+snapshot.534;直接探测该 snapshot 的 jar:三个符号均在(ISensitiveBiPacket.class 含 bidirectionalHandler、StreamCodecUtil 常量池含 VEC3、Util 含 cast)
StreamCodec 由 ByteBuf 改为 FriendlyByteBuf ✅ 正确 StreamCodecUtil.VEC3 声明就是 StreamCodec<FriendlyByteBuf, Vec3>;注册器要 ? super RegistryFriendlyByteBuf,兼容。仓库内已有同型先例 RedstoneDiceRollPacket
服务端回传/Util.cast(player) 模式 ✅ 有先例 ControlValveFilterPacket/MachineOutputDirectionPacket 等已用 PacketDistributor.sendToPlayer(Util.cast(player), …)
公共包类引用客户端类(BigRedButtonInputListener/Minecraft)导致专用服崩溃 ✅ 无风险 只在 handleOnClient 内可达(ctx.enqueueFlow 方向敏感分派),专用服永不加载;本仓库数十个包同样引用 client 类
new AABB(BlockPos) / Vec3.x/y/z / AABB.contains ✅ 存在 new AABB(pos) 在目标分支被大量使用
getValue(PRESSED) 的 IllegalArgumentException 风险 ✅ 已规避 .is(BIG_RED_BUTTON) 短路在前
过期确认丢弃逻辑(holdId) ✅ 正确 release() 先发包再 holdId++,旧 id 的 release 回执必然被 id != holdId 丢弃;pos/level 双校验覆盖"已切换目标"
diff 卫生 ✅ EOF 缺换行 0、TODO/调试语句 0、新增行尾空白 0、新增 javax 空值注解 0(符合 AGENTS.md 只用 JSpecify 的规定)

⚠️ 建议修改

  1. BigRedButtonHoldPacket.java:44-49 — 回执字段语义重载(held 在 S2C 方向表示"服务端已接受")
    同一个 held 分量在两个方向上含义不同:C2S 是"玩家仍按住",S2C 是"服务端是否接受本次按压"。handleOnClient 里 handleHoldResult(this.pos, this.holdId, this.held) 读作 "held" 极易被后续维护者误解。
    建议:把记录分量改名为 accepted(客户端侧 handleHoldResult(pos, id, accepted) 已经这么命名了,前后不一致),或至少补一段 javadoc——仓库内同类双向包 ControlValveFilterPacket 就是带 javadoc 说明"客户端发往服务端 + 服务端存好后回传"的,本 PR 把这个包升级成双向后反而完全没有注释。

  2. BigRedButtonInputListener.java:125-135 — 服务端拒绝后客户端不会放弃,形成"永不停止的心跳"
    服务端 updateButton 在 !canPress 时回 accepted=false,但客户端只把 confirmed 置 false(暂停动画),仍保留 heldPos,于是只要玩家按住不放,就会每 5 tick 继续发心跳;而每次被拒的心跳现在都会额外触发:

    • 一次完整 Level.clip 射线(服务端开销,与旧版相同)
    • button.release(player) → level.scheduleTick(...)(这一条是新增的:旧版校验失败是直接 return,不排 tick)
    • 一次 S2C 回执包(新增,约 4 次/秒/玩家)
      建议:客户端收到 accepted == false(且 id 匹配)时直接 release(),停止重试这一轮;或让服务端仅在状态变化(接受/拒绝翻转)时回执,而不是每个包都回。
  3. BigRedButtonHoldPacket.java:61-70 — 判定输入由"服务端自算的固定内部点"变为"客户端上报点",校验面由按钮形状退化为整格立方体 AABB
    new AABB(this.pos).inflate(1e-5).contains(hitLocation) 只要求上报点落在整格内,而不再要求它落在按钮 outline 形状上。原实现虽然瞄的是固定内部点(会被遮挡),但客户端无法影响其取值;现在客户端可控输入成了按压判定的直接依据。
    现有缓解是可接受的(有限值 + 在格内 + 视点射线确实命中该方块 + alive/spectator/reach 检查),但若想让服务端语义与本地 targetedButton 的 OUTLINE 命中严格对齐,建议再对 hitLocation 做一次形状级校验(如用 getShape(state) 的 bounds / 对形状做 clip),否则一个改过的客户端能上报"格内任意点"(例如从另一面才能看到的角点)来按键。
    附带说明(非本 PR 引入):BigRedButtonBlock.useItemOn/useWithoutItem 那条原版交互路径仍是直接 button.press(player),不经过新校验——不过那条路由原版 handleUseItemOn 的看向/距离校验兜底,实际不可绕过,两条路径的校验强度目前并不等价,留个记录即可。

💡 可选改进

  • 动画为了等待服务端确认,额外引入了一个完整 RTT 的延迟:pressed 需要 confirmed(回执)且本地方块态 PRESSED(方块同步)同时为真,两者都来自服务端,高延迟服务器上"手部按压动画"会明显落后于按钮本身的视觉/音效。如果希望手感更跟手,可考虑本地按 canPress 的等价条件做预测播放、服务端回执仅负责撤销。
  • 释放腿(held == false)的回执是纯浪费:客户端在 release() 里已经 confirmed = false 且 holdId++,该回执必然因 id 不匹配被丢弃。可以让服务端只在 held == true 时回执。
  • updateButton 中 !this.held || !this.canPress(player) 把"释放"和"校验失败"合并成同一种返回值,回执里无法区分(两者都回 accepted=false)。目前无实际影响,但若将来要区分(例如失败时想给客户端一个提示),需要拆开。

🟢 看起来不错

  • 修复方向准确:不再瞄向底座中心(pos.getCenter().relative(FACING, -0.375))这一必然被遮挡的固定点,改为复核玩家实际瞄到的点,直接对应 issue [Bug] 特定角度隔方块无法实际按下大红按钮 #5138 "隔着方块无法按下"。
  • 客户端预测/服务端权威的收敛处理干净:holdId(自增仅在 release())+ pos + level 三重校验,能同时丢弃"已释放后到达的回执"和"切到别的按钮后到达的回执",正是 PR 描述里承诺的语义。
  • BigRedButtonBlockEntity.press 改返回 boolean 属于零破坏性改造:useWithoutItem 忽略返回值,行为不变。
  • 对 hitLocation 做了 Double.isFinite 与格内 AABB 双重过滤,拒绝路径(held=false)正确短路、不会拿 Vec3.ZERO 去跑 canPress。
  • onClientTick 每 tick 复用已算出的 hit(不再二次 targetedButton),并顺带消除了原来"重新算一次再比较"的冗余调用。

📋 声称验证表

PR 声称 状态 对应实现
使用实际命中位置进行服务端射线校验 ✅ hit.getLocation() 随包上传 → canPress 以 eye→hitLocation 复算 clip
修复"按钮可见但底座中心被遮挡时无法按下" ✅ 弃用固定底座中心点;与 issue #5138 标题/预期一致
按住后等待服务端确认再播放动画 ✅ onAnimationTick 的 confirmed && + 本地 PRESSED 条件
忽略已释放或已切换目标的过期确认 ✅ handleHoldResult 的 id != holdId / pos / level 校验 + release() 自增
fixed #5138 ✅ issue 期望"这种情况也能按下按钮 / 确实能按下时才触发手部动画",两点均被覆盖

结论: COMMENT(不阻塞) — 设计正确、与 issue 需求一一对应,且双向包注册、编解码器类型、跨端类加载、holdId 过期丢弃这四处最容易出事的点都已逐项核对通过(含对 anvillib 2.0.0+snapshot.534 的实际 jar 取证)。上述 3 条 ⚠️ 中,第 1 条(字段语义/缺 javadoc)与第 2 条(拒绝后不回退、心跳空转 + 新增 scheduleTick/回执)建议在草稿阶段一并处理;第 3 条属于信任面记录,可按维护者意见决定是否加固。由于是草稿,可以先按现状迭代,不需要现在阻塞合并。标题已同时包含中英文且准确,未做修改。

🧪 测试建议

被测目标 建议场景 优先级
BigRedButtonHoldPacket.canPress 遮挡场景(隔方块/贴墙)按住 → 应被接受;上报越界点(格内角落/格外的有限值/NaN)→ 应被拒绝 🔴
BigRedButtonInputListener.handleHoldResult 注入旧 holdId / 已切换 pos / 已切换 level 的回执 → confirmed 不应被改写(过期确认丢弃) 🔴
释放-重按竞态 快速按-放-按同一按钮,人为延迟回执 → 不应出现"上一轮的回执点亮本轮动画" 🟡
长按稳定性 持续按住 ≥ 1 分钟,统计心跳与回执包数量、服务端 tick 调度次数;服务端持续拒绝时不应无限空转 🟡
断线/切维度/开背包 release() 不应向已断开的连接发包;confirmed/heldPos 必须复位 🟡

由 Hermes Agent 审查

@WhereisFff
WhereisFff marked this pull request as ready for review October 2, 2026 16:15
Copilot AI balanced review requested due to automatic review settings October 2, 2026 16:15

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 reached their quota limit.

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'network-packet-pr-review' (1 replacement). · Patched references/anvilcraft-lib-api-cross-reference.md in skill 'network-packet-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp && python3 -c "print(1)" 2>&1 | head -2; echo "---"; head -40 /opt/data/skills/github/github-code-review/scripts/jar_class_probe.py

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

⚠️ Dangerous command requires approval:

cd /tmp && curl -s "https://api.github.com/repos/Anvil-Dev/AnvilCraft/pulls/5141" -o /tmp/pr5141.json -w "http=%{http_code}\n"; python3 -c "pass" ; grep -o '"draft":[a-z]*\|"state":"[a-z]*"\|"mergeabl...

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 #5141(本次为同一修订的重复触发,不重复发表)

⚠️ 本次不再输出一份完整审查:上一次 webhook 投递已在 19 分钟前(2026-10-02T16:11Z)针对完全相同的修订发布过完整意见 → #issuecomment-5956387005。复核确认本次事件没有带来任何新提交:

本次事件 上一份审查 结论
head 2d8b932274165738394534d57b9c24161f051270 2d8b932274… ✅ 同一提交
base da7e856b8f64d085cd1b4b52dadf7a55de6bcc47 da7e856b8f… ✅ 无漂移
commits 1 1 ✅

唯一变化是 PR Draft → Ready for review("draft": false、"state": "open"、"mergeable": true)。因此上一份意见里的 3 条 ⚠️ 继续全部成立,此处不复述:① held 分量双向语义重载 / 缺 javadoc;② 服务端拒绝后客户端不放弃,心跳空转且新增 scheduleTick + S2C 回执;③ 判定输入由服务端自算定点变为客户端上报点、校验面退化为整格 AABB。

本轮补核的三条链路(新取证,结论:均不阻塞合并)

补核项 结论 依据(可复现)
动画新判据依赖客户端方块态 PRESSED,这个条件真能满足吗? ✅ 能满足 BigRedButtonBlockEntity.setPressed() → level.setBlock(pos, state.setValue(PRESSED, …), 3);flag 3 = UPDATE_NEIGHBORS(1) | UPDATE_CLIENTS(2),含"发给客户端" ⇒ 服务端置位后客户端 getBlockState(heldPos).getValue(PRESSED) 会变 true,confirmed && PRESSED 不会把动画锁死
handleOnServer 现在会改世界(press/release → setBlock/scheduleTick/playSound/gameEvent),而 ISensitiveBiPacket 自身没有 enqueueWork,会不会跑在网络线程? ✅ 主线程 读 anvillib 2.0.0+snapshot.534 的 -sources.jar:ISensitiveBiPacket.bidirectionalHandler 只按 ctx.flow() 分派到 serverHandler/clientHandler,而 IServerboundPacket.serverHandler / IClientboundPacket.clientHandler 都是 ctx.enqueueWork(() -> handleOnXxx(ctx.player()))。"Sensitive" 指"方向敏感"(两端各一套 handler),不是"线程敏感" ⇒ 服务端改世界仍在主线程
StreamCodecUtil.VEC3 的线上精度 ⚠️ 有损(3×float) sources:VEC3 = StreamCodec.of(FriendlyByteBuf::writeVec3, FriendlyByteBuf::readVec3),writeVec3 写 3 个 float ⇒ 客户端 double 命中点会被量化。(这也正是 StreamCodec 必须从 ByteBuf 改成 FriendlyByteBuf 的原因。)含义:AABB.inflate(1e-5) 与射线 new Vec3(...).scale(1e-4) 这两个魔数是"量化后仍能通过格内校验 / 短射线仍先命中该方块"的兜底,请勿在后续清理中收紧或删除,建议补注释写明意图。 实测影响可忽略(面点量化后仍在格内,且更短射线仍命中本方块),故仅作记录

结论

COMMENT(不阻塞) — 与上一份意见一致,未发现新增阻塞项。既有 diff 卫生仍为 0(EOF 缺换行 0、TODO/FIXME 0、3 文件 / +68 −27 / 1 commit)。按 Ready for review 的立场给出明确取舍:

  • ⚠️② 是本 PR 相对旧实现新增的服务端开销(拒绝态下每 5 tick 一次 Level.clip + scheduleTick + 一次回执包/玩家),建议合并前处理(客户端收到 accepted == false 即 release(),或仅在接受/拒绝翻转时回执)。
  • ⚠️①(字段语义/javadoc)建议顺手改名 accepted 或补注释 —— 本仓库同类双向包(ControlValveFilterPacket 等)都有 javadoc,本 PR 把它升级为双向后反而零注释。
  • ⚠③ 属信任面记录,可按维护者意见决定是否加固,不阻塞。
  • PR 标题(Fix big red button targeting and animation 修复大红按钮目标判定与按压动画)已含中英文且准确,未修改。

顺带说明:本 PR 上 16:19 与 16:23 两条 “⚠️ Dangerous command requires approval” 评论,是审查机器人把本地安全审批提示误当成回复投递出来的产物(触发源:命令里含 python3 -c),不是有效审查意见,可直接忽略/删除。本地流程已改用脚本文件方式执行,后续不会再产生此类噪音,抱歉。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

代码审查摘要 — PR #5141

操作: ready_for_review(PR 状态:open,未合并 — 已用 data-status="pullOpened" 确认)
范围: 3 个文件(3 Java,0 新增 / 0 删除)/ 225 行 diff,+71 / −30
CI: commit 2d8b932 的 build ✅ + checkstyle ✅(均 completed/success)——编译与风格已由 CI 背书

📋 声称验证表

声称(PR 描述) 状态 交叉验证结果
使用实际命中位置进行服务端射线校验 ✅ 新增 canPress():eye → hitLocation + normalize(hitLocation-eye)*1e-4;旧代码目标为 pos.getCenter().relative(FACING, -0.375),即沿 FACING 反方向 0.375 格、紧贴贴附面/底座内侧的深点——掠射角度看按钮时,通往该深点的射线会先命中按钮所依附的邻块,blockHit.getBlockPos() != pos 即被拒,正是 issue #5138 的"隔方块按不动、但手部动画照播"
等待服务端确认再播放手部动画 ✅ 新增 confirmed + handleHoldResult();onAnimationTick 的 pressed 同时要求 confirmed、pos == heldPos、level == heldLevel、客户端 blockstate BIG_RED_BUTTON.PRESSED == true
忽略已释放 / 已切换目标的过期确认 ✅ handleHoldResult 三重校验 id != holdId、!pos.equals(heldPos)、level != heldLevel;release() 递增 holdId 并清 confirmed
fixed #5138 ✅ issue 仍为 open、无其它 PR 引用(GitHub search 无重复),诉求两条(隔方块也能按下 / 确实按下才播动画)在 diff 中均有对应实现;PR 创建时 base 为 dev/1.21/1.6

🟢 看起来不错

  • STREAM_CODEC 由 ByteBuf 改 FriendlyByteBuf 是必需改动,不是随手改:我解出 anvillib 2.0.0+snapshot.534 的嵌套 jarjar,dev/anvilcraft/lib/v2/codec/StreamCodecUtil 的 VEC3 字段签名为 StreamCodec<FriendlyByteBuf, Vec3>。StreamCodec.composite 的 B 需同时满足 BlockPos.STREAM_CODEC(ByteBuf) 的 ? super B 与 VEC3 的 FriendlyByteBuf super B ⇒ B 只能是 FriendlyByteBuf;沿用 ByteBuf 会编译失败。CI build ✅ 与此推论一致。
  • 库 API 契约已核对存在:StreamCodecUtil.VEC3(同版本 jar 常量池 FIELD ... StreamCodec VEC3)、ISensitiveBiPacket extends IClientboundPacket, IServerboundPacket(⇒ 必须实现 handleOnClient(Player)/handleOnServer(Player),本 PR 均实现)、Util.cast(Object) unchecked 泛型转换。写法与仓库既有双向包(HeliostatsIrradiationPacket、ControlValveFilterPacket)完全同构,方向注册由接口经 NetworkRegistrar 自动派生,无需额外注册代码;handleOnClient 引用客户端类在 dedicated server 上不会被调用,也与既有包同构(非本次引入的风险)。
  • 回执与方块更新同序,动画起始不会闪断:服务端先 setPressed(true) → setBlock(flag=3)(立即向客户端发 block update),再发回执;同一 TCP 连接保序 ⇒ 客户端拿到 confirmed=true 时 PRESSED 已是 true。
  • press() 改返回 boolean 影响面干净:唯一其它调用点 BigRedButtonBlock.useWithoutItem 忽略返回值(合法语句表达式),press/release/checkPressed 的 holder 生命周期与红石语义零改动。
  • 防作弊性质保留:canPress 链完整(chunk 已加载 → BE 类型 → 存活/旁观/交互距离 → hitLocation 有限性 + AABB(pos).inflate(1e-5).contains → 射线首命中必须为本方块)⇒ 依旧不能隔墙按下;hitLocation 虽只校验 AABB,但射线必须真实穿过按钮 OUTLINE 形状,实际不可利用。
  • 无 TODO/FIXME 残留、无 EOF 缺失换行、最长新增行 128 < style.xml LineLength(max=140)。

⚠️ 观察(非阻塞,请作者确认是否有意为之)

  1. updateButton 在"校验失败"时新增了 button.release(player)(旧代码只 return,交给 HOLD_TIMEOUT=20 tick 超时兜底)。收紧语义更防呆,但边界情形(准星压在按钮轮廓边缘时,服务端与客户端眼位差几厘米导致射线擦过形状 miss)会让信号被立刻放掉,5 tick 后心跳又 press() ⇒ setPressed 的开关音效 + GameEvent 可能被连点。旧行为对瞬时失败是容忍的。若确为有意(防伪造/防僵持),建议在 PR 描述或代码里点明;否则可只"不刷新 holder",让超时兜底。
  2. 心跳也要求回执:按住期间每 5 tick 一次 C2S + 一次 S2C,而回执内容除 accepted 外无变化。可只在校验结果发生变化时回执(或心跳不要求回执),把长按期间下行流量减半。

💡 建议

  1. held 字段在回执方向被当作 accepted 使用(handleHoldResult(pos, holdId, this.held)),同名不同义容易误读。建议拆出 accepted 字段或改名 + record 注释说明双向语义。
  2. 回执里回带的 hitLocation 客户端并不使用(只读 pos/holdId/held),可省掉每包 24 字节。
  3. 可选:若想更严格,canPress 可对 getShape(state).bounds() 做包含/clip 校验,而非仅方块 AABB。

🧪 验证建议(仓库无 src/test,建议手动 + 代码级验证)

被测目标 场景 优先级
canPress 射线路径 复现 #5138 视频角度(按钮可见、深点被邻块挡)→ 应能按下;真正隔墙不可见 → 不按下、无动画 🔴
handleHoldResult 过期丢弃 松开/切目标瞬间到达的旧回执应被忽略(id/pos/level 三重) 🟡
心跳稳定性 200ms+ 延迟下按住 5s,红石输出不抖动;松开后 ≤1s PRESSED 归 false 🟡
codec 往返 (pos, hitLocation, held, holdId) 编解码往返一致(新增 VEC3 + VAR_INT) 🟢

结论: COMMENT(无阻塞问题,建议合并) — 修复方向与 #5138 的两条预期精确对应,holdId 过期判定与"确认后才播动画"的设计自洽,关键库 API 与 codec 泛型约束均已离线核对且 CI 通过。两处 ⚠️ 属行为/流量取舍,确认预期即可。

(PR 标题「Fix big red button targeting and animation 修复大红按钮目标判定与按压动画」与改动一致,本次未修改标题。)


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/duplicate-review-detection-and-stop.md in skill 'github-webhook-pr-review' (1 replacement). · Patched references/bidirectional-ack-echo-packet-review.md in skill 'network-packet-pr-review' (1 replacement). · Patched SKILL.md in skill 'network-packet-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/bidirectional-ack-echo-packet-review.md in skill 'network-packet-pr-review' (1 replacement). · Patched SKILL.md in skill 'network-packet-pr-review' (1 replacement). · Patched references/pr-class-routing.md in skill 'github-webhook-pr-review' (1 replacement).

@PigeonNian
PigeonNian merged commit aae181e into Anvil-Dev:dev/1.21/1.6 Oct 3, 2026
2 checks passed
@Gugle2308

Copy link
Copy Markdown
Collaborator

PR #5141 的事件类型为 closed,按约束第 1 条,此处停止,不发布审查评论。

WhereisFff added a commit to WhereisFff/AnvilCraft that referenced this pull request Oct 3, 2026
- 使用实际命中位置进行服务端射线校验,修复按钮可见但底座中心被遮挡时无法按下的问题。
- 按住按钮后等待服务端确认再播放手部动画,并忽略已释放或已切换目标的过期确认。
- fixed Anvil-Dev#5138
PigeonNian added a commit that referenced this pull request Oct 3, 2026
…修复到26.1 (#5143)

* The text regarding celestial death has been corrected, and some progress has been made. 修正了天体死亡文本,增加了一些进度 (#5129)

* feat(advancement): 添加天体进化挑战成就及触发器

- 新增 CelestialEvolutionTrigger 用于天体质量进化判定
- 在触发 util 中添加 celestialEvolution 方法,触发成就判定
- 在加速器逻辑中调用触发方法进行成就检测
- 添加无残留(no_remnant)挑战成就,要求64质量铁砧的天体进化至终局
- 将成就文本翻译添加至英文语言文件和特殊字符文件
- 在成就数据中注册无残留成就及其触发条件

* feat(advancement): 添加行星毁灭成就及触发器支持

- 新增PlanetDetonationTrigger用于行星毁灭事件的判定
- 在ExcavatorHandler中增加触发行星毁灭触发器的逻辑
- 在AdvancementLineHelper中集成planetDetonation方法方便创建该成就
- 在AnvilCraftAdvancement中添加efficiency成就分支,绑定行星毁灭触发器
- 更新语言文件,添加行星毁灭成就的标题与描述
- 注册PlanetDetonationTrigger触发器并完善其触发实现
- 新增efficiency成就JSON配置文件,定义触发条件及显示信息

* feat(advancement): 新增因行星坍缩死亡的成就触发器

- 添加了 PlanetaryCollapseDeathTrigger 触发器类及其数据结构
- 在 ModCriterionTriggers 中注册 planetary_collapse_death 触发器
- 在 AdvancementLineHelper 中新增 planetaryCollapseDeath 方法便于调用
- 在 AnvilCraftAdvancement 中添加 Cannon Fodder 成就,绑定行星坍缩死亡触发器
- 在语言文件中添加 Cannon Fodder 成就标题与描述的多语言支持
- 在 OverworldLikeEventListener 中监听行星坍缩死亡事件并触发相应成就
- 在 TriggerUtil 中实现 planetaryCollapseDeath 方法来触发成就判定
- 新增 Cannon Fodder 成就的 JSON 配置文件,包含父级与图标等信息
- 修改效率成就添加隐藏属性,改善游戏内成就展示体验

* feat(advancement): 新增黑洞和中子星终局星体成就

- TriggerUtil新增支持根据StellarTerminal.Kind触发星体演化成就
- CelestialEvolutionTrigger增加对终局类型的判定和对应触发方法
- AdvancementLineHelper新增celestialEvolution重载方法支持终局类型参数
- AnvilCraftAdvancement中增加黑洞和中子星分支成就定义和保存
- AdvancementLang添加黑洞与中子星成就名称及描述多语言支持
- 语言文件(en_us, en_ud)增加对应成就的描述和标题
- 新增黑洞和中子星成就JSON数据文件,定义触发条件和显示信息

* feat(damage): 新增天体接触伤害类型及独立标签支持

- 添加黑洞接触、恒星接触及行星接触三种新伤害类型
- 天体接触伤害采用独立类型以实现专属死亡提示
- 更新伤害标签,支持新伤害类型绕过护甲、抗性、击退等效果
- 修改重力控制器中伤害来源,替换为对应新天体接触伤害类型
- 保持星体及行星接触伤害原版燃烧和摔落效果表现不变
- 增加对应的语言文本显示新伤害的死亡描述信息
- 修正玩家攻击混入对行星接触伤害的判定,保持原摔落伤害一致性
- 新增相关资源数据文件,完善伤害类型和标签配置

* feat(advancement): 添加“夜晚来访”星接触死亡进度条件

- 新增 StarContactDeathTrigger 实现星接触死亡触发器
- 注册并初始化星接触死亡触发条件 ModCriterionTriggers.STAR_CONTACT_DEATH
- AdvancementLineHelper 新增 starContactDeath 方法支持该触发器
- AnvilCraftAdvancement 新增“come_at_night”任务,使用星接触死亡触发器
- AdvancementLang 中添加“come_at_night”进度名称及描述文本
- OverworldLikeEventListener 监听星接触死亡事件触发进度
- TriggerUtil 新增 starContactDeath 方法简化触发调用

* feat(locale): 添加“come_at_night”成就的中英文描述

- 新增“advancements.anvilcraft.come_at_night”标题的本地化文本
- 新增“advancements.anvilcraft.come_at_night”描述的本地化文本
- 中文描述内容为“被星光笼罩”
- 英文标题内容为“Showdown at Night”倒转样式

* feat(advancement): 添加“come_at_night”隐藏成就

- 创建新的隐藏成就“come_at_night”
- 设置成就触发器为“star_contact_death”
- 指定成就图标为“celestial_forging_anvil”
- 定义成就的父级为“the_start”
- 启用成就的遥测事件发送

---------

Co-authored-by: Pigeon_Nian <adove2005@163.com>

* fix(celestial): 修复演化音效衰减与锻造界面恢复 (#5131) (#5132)

- 将演化音乐归入唱片音量分类,并以单声道音源实现 64 格原生距离衰减。
- 保持音效与字幕的听距一致。
- 通过实时同步入口恢复锻造状态,避免重开界面时丢失正在锻造的进度。

* fix(building): 修复幻灵铁砧虚影撤销时重复返还物品 (#5134)

- 撤销无掉落幻灵铁砧虚影时不再结算基础物品
- 保留实体铁砧与其他下落方块的资源结算

fixed #5133

* fix(item-splitter): 修复物品分配器掉落物超出堆叠上限 (#5136)

按物品实际堆叠上限拆分每个目标位置的掉落物,保留均分份额、余数、零动量和拾取延迟。

修复 #5135

* fix(button): 修复大红按钮遮挡边缘交互与按压动画 (#5141)

- 使用实际命中位置进行服务端射线校验,修复按钮可见但底座中心被遮挡时无法按下的问题。
- 按住按钮后等待服务端确认再播放手部动画,并忽略已释放或已切换目标的过期确认。
- fixed #5138

* fix(storage-port): 修复服务端扫描仓储端口时崩溃 (#5140)

- 优先使用原版 includeData 标志控制数据复制,避免服务端扫描读取客户端按键状态
- 保留 26.1 服务端中键克隆时的缓存、标记与流体数据

(cherry picked from commit d7c2f74)

---------

Co-authored-by: PigeonNian <78527064+PigeonNian@users.noreply.github.com>
Co-authored-by: Pigeon_Nian <adove2005@163.com>
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