fix(movement): drop idle FUNC_WAIT resend with no 40250 counterpart

40250 only calls OnWaiting inside CInstanceBase::Transform() while
IsWalking() (InstanceBase.cpp:1922-1930); it never resends position
while standing. Remove _tick_on_waiting and its throttle state.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-22 17:12:16 +09:00
co-authored by Claude Opus 5
parent ad6ea9ad7e
commit 6a175ee293
5 changed files with 17 additions and 26 deletions
+4 -25
View File
@@ -90,15 +90,14 @@ const EntityRules = preload("res://entity_rules.gd")
# §5.4 / §8.8 —— RecvTargetPacket 的目标框收包分派(判定树 + CanViewTargetHP1:1。
const TargetBoard = preload("res://target_board.gd")
# §3.2 上行节流表(对齐 `PythonPlayerEventHandler.cpp` 的 6 个回调):
# OnMove —— 首次开走 / 改向:立即发 FUNC_MOVE,并重置 moving/waiting 两个窗口
# OnMove —— 首次开走 / 改向:立即发 FUNC_MOVE,并重置 moving 窗口
# OnMoving —— 移动中周期上行:300 ms 节流,发 FUNC_MOVE
# OnWaiting—— 站立中周期上行:100 ms 节流且相对上次上行位移 ≥ 1 cm 才发 FUNC_WAIT
# OnWaiting—— 仅在走/跑动作中本帧无位移时触发(InstanceBase.cpp:1930);未移植,
# 见 audit/port-map/UserInterface/PythonPlayerEventHandler.json
# OnStop —— 停下收尾:不节流,发 FUNC_WAIT
# OnAttack —— 不节流,发 FUNC_COMBO + motion index(见 _do_attack_swing
# OnUseSkill—— 不节流,发 FUNC_SKILL|motion + arg(§3.8 施法路径)
const SEND_MOVING_INTERVAL := 0.3 # OnMoving 最小间隔(秒)
const SEND_WAITING_INTERVAL := 0.1 # OnWaiting 最小间隔(秒)
const SEND_WAITING_MIN_DISP_CM := 1.0 # OnWaiting 触发的最小位移(服务器 cm)
# 可点击 / 攻击距离(厘米),照 `InstanceBaseBattle.cpp:294`
# `NEW_IsClickableDistanceDestInstance`:默认 150NPC 500,采集物 100,弓箭走 __GetBowRange。
const CLICK_DIST_DEFAULT_CM := 150.0
@@ -237,7 +236,6 @@ var _view_other_empire_target := true
var _lcontrol_down := false
var _last_sent_pos := Vector3.ZERO # 上一次上行时的玩家世界坐标
var _last_moving_sent_t := 0.0 # 上一次 OnMoving 上行时刻(秒)
var _last_waiting_sent_t := 0.0 # 上一次 OnWaiting 上行时刻(秒)
var _was_moving := false
var _attack_cd := 0.0
var _last_click_actor_t := -10.0
@@ -408,7 +406,6 @@ func clear_for_map_change() -> void:
_main_dead = false
_last_sent_pos = Vector3.ZERO
_last_moving_sent_t = 0.0
_last_waiting_sent_t = 0.0
_was_moving = false
_attack_cd = 0.0
_last_click_actor_t = -10.0
@@ -838,12 +835,10 @@ func _on_local_moved(pos: Vector3) -> void:
return
var now := _now()
if not _was_moving:
# OnMove:立即上行,并把 moving/waiting 两个节流窗口推到「刚发过」
# 让随后的 OnMoving / OnWaiting 各自等一个完整间隔(PythonPlayerEventHandler.cpp:76)。
# OnMove:立即上行,并把 moving 节流窗口推到「刚发过」PythonPlayerEventHandler.cpp:76)。
_send_state(FUNC_MOVE, 0, pos)
_was_moving = true
_last_moving_sent_t = now
_last_waiting_sent_t = now
return
# OnMoving300 ms 节流(:62)。
if now - _last_moving_sent_t < SEND_MOVING_INTERVAL:
@@ -870,21 +865,6 @@ func _send_state(func_id: int, arg: int, world_pos: Vector3) -> void:
client.move(func_id, arg, _heading_deg(_player_yaw()), int(xy.x), int(xy.y))
_last_sent_pos = world_pos
# OnWaiting —— 站立时周期性把当前位置补发上行,防止本地被击退 / 碰撞推挤后与
# 服务器不一致(PythonPlayerEventHandler.cpp:38):100 ms 节流且相对上次上行位移
# ≥ SEND_WAITING_MIN_DISP_CM 才发。
func _tick_on_waiting() -> void:
if _was_moving or _observer_mode or client == null or not client.is_in_game() or pc == null or pc.player == null:
return
var now := _now()
if now - _last_waiting_sent_t < SEND_WAITING_INTERVAL:
return
var disp_cm := _server_xy(pc.player.position).distance_to(_server_xy(_last_sent_pos))
if disp_cm < SEND_WAITING_MIN_DISP_CM:
return
_send_state(FUNC_WAIT, 0, pc.player.position)
_last_waiting_sent_t = now
# OnUseSkill —— 施法瞬间的状态上行:FUNC_SKILL|uMotSkill + uArg(不节流,
# PythonPlayerEventHandler.cpp:120)。调用点(技能合法性 / CD / charge)属 §3.8 的
# `player_skill.gd`,这里只留 1:1 的上行出口,做法同 §3.4 的预留桩。
@@ -1604,7 +1584,6 @@ func _process(dt: float) -> void:
_splash_attack_process(dt) # SPECIAL_ATTACKINGSplashArea -> OnHit
_update_auto_attack()
_refresh_reserved()
_tick_on_waiting()
_flush_victim_list() # 帧末:被击退者 CG_SYNC_POSITION
# CPythonPlayer::__Update_AutoAttack()PythonPlayer.cpp:207
+4
View File
@@ -623,6 +623,10 @@ func _run() -> void:
_ck(fc.calls.move.size() == 2 and fc.calls.move[1][0] == np.FUNC_MOVE, "OnMoving after 300ms -> FUNC_MOVE")
pc.anim_state.emit("wait") # OnStop
_ck(fc.calls.move.size() == 3 and fc.calls.move[2][0] == np.FUNC_WAIT, "OnStop -> FUNC_WAIT")
# 站立期间被推开也不补发:40250 的 OnWaiting 只在走/跑动作中触发(InstanceBase.cpp:1930)。
pc.player.position = Vector3(4, 0, -1)
np._process(0.2)
_ck(fc.calls.move.size() == 3, "idle displacement sends no FUNC_WAIT")
fc.calls.move.clear()
np.on_use_skill(5, 2) # OnUseSkill
_ck(fc.calls.move.size() == 1 and fc.calls.move[0][0] == (np.FUNC_SKILL | 5) and fc.calls.move[0][1] == 2,