fix(combat): persist death and retarget on kill
Keep the velocity-only NPC adaptation inside the locomotion family so authoritative Dead motion remains persistent. Route selection clears through a dedicated combat target controller that reacquires the closest eligible creature when retail Auto Target conditions apply. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
5276a83087
commit
9b97102c67
10 changed files with 281 additions and 19 deletions
60
docs/research/2026-07-12-death-and-auto-target-pseudocode.md
Normal file
60
docs/research/2026-07-12-death-and-auto-target-pseudocode.md
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
# Persistent death and post-death Auto Target pseudocode
|
||||
|
||||
Sources: Sept 2013 EoR named retail client.
|
||||
|
||||
- `ClientCombatSystem::AutoTarget` (`0x0056BC80`)
|
||||
- `ClientCombatSystem::RecvNotice_SelectionChanged` (`0x0056BD80`)
|
||||
- `CPlayerSystem::SelectNext` (`0x0055F9A0`)
|
||||
- `MovementManager::unpack_movement` (`0x00524440`)
|
||||
- `CPhysicsObj::MoveOrTeleport` (`0x00516330`)
|
||||
|
||||
## Animation authority
|
||||
|
||||
```text
|
||||
on UpdateMotion(interpretedState):
|
||||
pass the state through MovementManager and CMotionInterp
|
||||
Dead is a persistent substate selected by the motion table
|
||||
|
||||
on UpdatePosition(position, velocity):
|
||||
update the physics pose and velocity
|
||||
do not select Ready, Walk, Run, or any other animation
|
||||
```
|
||||
|
||||
acdream retains a documented AP-80 adaptation for ACE actors that move only
|
||||
through position snapshots: velocity may choose a visible locomotion cycle.
|
||||
That adaptation is now restricted to replacing only Ready/Walk/Run-family
|
||||
states. An authoritative action or substate such as attack, hit reaction, or
|
||||
Dead always wins. This preserves the adaptation without allowing a late
|
||||
position delta to make a corpse stand again.
|
||||
|
||||
## Auto Target after the selected creature dies
|
||||
|
||||
```text
|
||||
when authoritative Dead motion is applied to the selected object:
|
||||
clear selected object
|
||||
publish SelectionChanged
|
||||
|
||||
RecvNotice_SelectionChanged():
|
||||
update target tracking
|
||||
if selected object is zero
|
||||
and combat mode is Melee or Missile
|
||||
and Auto Target is enabled:
|
||||
AutoTarget()
|
||||
|
||||
AutoTarget():
|
||||
if a recent valid last-attacked object exists:
|
||||
select it
|
||||
else:
|
||||
SelectNext(forward=true, includeCurrent=true, COMPASS_ITEM)
|
||||
|
||||
SelectNext(... COMPASS_ITEM) while in Melee/Missile:
|
||||
reject non-attackable, fellowship, hidden, and out-of-radar candidates
|
||||
rank eligible candidates by the retail weighted spatial distance
|
||||
select the best candidate
|
||||
```
|
||||
|
||||
The current M2 world-state projection has no retail `lastAttacked` instance-id
|
||||
quality, so its existing closest eligible creature scan implements the
|
||||
fallback branch. The important lifecycle behavior is exact: authoritative
|
||||
death clears selection, and the SelectionChanged consumer reacquires only
|
||||
when Auto Target is enabled in Melee/Missile combat.
|
||||
Loading…
Add table
Add a link
Reference in a new issue