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>
74 lines
2.6 KiB
Markdown
74 lines
2.6 KiB
Markdown
# 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
|
|
|
|
```text
|
|
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
|
|
|
|
```text
|
|
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
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
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.
|