Keep AttackDone control statuses out of chat, preserve dead motion across zero-velocity position updates, render the authored power meter from right to left, and retain the rotatable viewer offset during target tracking. Co-Authored-By: Codex <codex@openai.com>
2.6 KiB
Combat live-gate corrections pseudocode
Sources: Sept 2013 EoR named retail client and ACE server source.
ClientCombatSystem::HandleAttackDoneEvent(0x0056C500)gmCombatUI::RecvNotice_SetPowerbarLevel(0x004CC0E0)CPhysicsObj::MoveOrTeleport(0x00516330)CameraSet::Rotate(0x00458310)- ACE
Player.OnAttackDone,Player_Melee.cs - ACE
WeenieError.YouChargedTooFar,Player_Move.cs
Attack completion versus visible errors
HandleAttackDoneEvent(sequence, error):
consume error as combat-controller state
decide whether repeat may continue or the attack aborts
do not write an error line to chat
ACE OnAttackDone(final sequence):
send AttackDone(ActionCancelled) to reset the client power meter
if the player must see a failure:
send a separate WeenieError event
Therefore AttackDone(ActionCancelled) is silent. A separate
YouChargedTooFar (0x003D) remains visible and is formatted by the ordinary
WeenieError path. ACE emits it when the charge exceeds 15 metres; target
selection itself is not range-limited by retail.
Power meter direction
RecvNotice_SetPowerbarLevel(level):
find nested meter 0x10000050
set meter scalar attribute 0x69 to level
authored meter direction = 1
visible fill = rightmost (width * clamp(level)) pixels
The red meter grows from the Power label at the right toward Speed at the left. The green desired-power thumb remains an independent scrollbar child. Clipping the rightmost portion must retain the full tiled image's UV offset.
Persistent death motion
on UpdatePosition(position, velocity):
update physics pose and velocity
do not derive an interpreted motion command from velocity
on UpdateMotion(Dead):
apply the persistent Dead motion cycle through the motion interpreter
A corpse legitimately sends zero velocity. Turning that velocity into Ready overrides the server-authored Dead cycle and makes the creature stand again. Retail keeps position/velocity transport separate from interpreted motion.
Keep in View orbit
See 2026-07-11-combat-target-camera-pseudocode.md. The corrective detail is:
targetHeadingFrame = frame looking from player pivot toward target point
viewerOffset.xy = the independently rotatable camera boom offset
eye = pivot + targetHeadingFrame.transform(viewerOffset)
forward = normalize(pivot - eye) // LOOK_AT_PIVOT
Tracking changes the frame that transforms viewerOffset; it does not reset
or discard the offset. Manual camera orbit therefore remains usable while
Keep in View is active.