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>
84 lines
2.9 KiB
Markdown
84 lines
2.9 KiB
Markdown
# Retail combat target camera pseudocode
|
|
|
|
Source: Sept 2013 EoR named retail client.
|
|
|
|
- `ClientCombatSystem::UpdateTargetTracking` (`0x0056A950`)
|
|
- `ClientCombatSystem::TrackTarget` (`0x0056AED0`)
|
|
- `CameraSet::TrackTarget` (`0x00458280`)
|
|
- `CameraSet::SetTargetForOffset` (`0x004576E0`)
|
|
- `CameraManager::SetTargetObject` (`0x00456380`)
|
|
- `CameraManager::UpdateCamera` (`0x00456660`)
|
|
|
|
## Option consumer
|
|
|
|
```text
|
|
UpdateTargetTracking():
|
|
if ViewCombatTarget is enabled
|
|
and combat mode is Melee or Missile
|
|
and current attack target is valid:
|
|
camera.TrackTarget(attackTarget)
|
|
else:
|
|
camera.TrackTarget(0)
|
|
```
|
|
|
|
## Camera state
|
|
|
|
```text
|
|
CameraSet.TrackTarget(targetId):
|
|
if targetId != 0:
|
|
targeting = true
|
|
camera.SetTargetObject(targetId, wholeObject)
|
|
camera.targetOffset = (0, 0, 0.5 metres)
|
|
else:
|
|
targeting = false
|
|
|
|
SetTargetForOffset(camera.viewerOffset)
|
|
|
|
SetTargetForOffset(viewerOffset), while targeting:
|
|
camera.targetStatus = LOOK_AT_OBJECT | LOOK_AT_PIVOT
|
|
|
|
CameraSet.Rotate(angle), including while targeting:
|
|
viewerOffset.xy = rotate(viewerOffset.xy, angle)
|
|
SetTargetForOffset(viewerOffset)
|
|
```
|
|
|
|
## Per-frame pose
|
|
|
|
```text
|
|
pivot = player part position + transformed pivotOffset
|
|
direction = zero
|
|
|
|
if targetStatus contains LOOK_AT_OBJECT and target object exists:
|
|
targetPoint = target.position localToGlobal targetOffset
|
|
direction += normalize(targetPoint - pivot)
|
|
|
|
headingFrame = frameWhoseForwardIs(direction)
|
|
desiredEye = pivot + headingFrame.transformVector(viewerOffset)
|
|
|
|
if targetStatus contains LOOK_AT_PIVOT:
|
|
desiredForward = normalize(pivot - desiredEye)
|
|
|
|
damp current viewer toward (desiredEye, desiredForward)
|
|
```
|
|
|
|
The target therefore changes the direction of the boom around the player; it
|
|
does not replace the player as the boom's pivot. `LOOK_AT_PIVOT` keeps the
|
|
player centered while the target-facing boom keeps the combat target in view.
|
|
The viewer offset remains independently rotatable: manual camera orbit rotates
|
|
that offset inside the target-facing frame rather than being discarded or
|
|
snapped back to zero.
|
|
|
|
## Port mapping
|
|
|
|
- `GameWindow.GetCombatCameraTargetPoint` applies the option/mode/valid-target
|
|
gates and transforms the target-local 0.5 metre Z offset.
|
|
- `RetailChaseCamera.ComputeTrackedHeading` ports the pivot-to-target direction.
|
|
- `RetailChaseCamera.ComputeDesiredPose` ports the heading-frame transform and
|
|
preserves the viewer-offset yaw while tracking.
|
|
- The diagnostic legacy `ChaseCamera` remains intentionally non-retail under
|
|
existing divergence row TS-19; the production retail camera owns this behavior.
|
|
|
|
The ACE and ACME reference trees are not present in this worktree (only the
|
|
in-tree WorldBuilder reference is available), so no interpretation-aid cross
|
|
check was possible. The named retail functions above are complete for this
|
|
behavior and remain the ground truth.
|