Commit graph

14 commits

Author SHA1 Message Date
Erik
f6db964fd5 feat(interaction): Slice 4 - equipped-child world picking
A click on a remote character's wielded weapon reported nothing. The picker
was already correct: RetailSelectionScene publishes every drawn part under its
own live-entity server GUID and RetailWorldPicker returns the weapon as the
polygon winner. The failure was downstream eligibility - WorldSelectionQuery
required TryGetInteractionEligibleRecord, whose _visible set admits
LiveEntityProjectionKind.World only, so the winning hit was discarded.

Retail has no such gate. Render::GfxObjUnderSelectionRay @ 0x0054C740
accumulates each hit under the drawn part's own physics-object id
(CPhysicsPart::get_physobj_id @ 0x0050D490), and CPhysicsPart::Draw @
0x0050D7A0 admits any drawn part whose physobj id is nonzero. An equipped item
is a first-class CPhysicsObj with its own id and part array
(CPhysicsObj::add_child @ 0x0050F870 via CSetup::GetHoldingLocation @
0x005213F0). There is no parent redirection and no wielded-specific rule, so a
click on a wielded weapon returns THE WEAPON'S GUID. PositionState.WIELDED is
distinct from IN_CONTAINER (acclient.h:6802), so container suppression never
hid a wielded selection either.

LiveEntityRuntime gains two scoped predicates: TryGetAttachedProjectedRecord
(a current Attached projection that is spatially projected) and
TryGetPickEligibleRecord (that arm plus today's World visible-set arm, with
the same WorldEntity.Id staleness recheck). TryGetInteractionEligibleRecord
and the _visible set are deliberately NOT widened - they feed radar,
auto-target, sticky/MoveTo establishment, and CombatAttackTargetSource, and
retail's radar has no wielded blips. A regression test asserts an attached
child stays out of that set while picking admits it.

Marker anchoring had the twin problem. SmartBox::GetObjectBoundingBox @
0x00452E20 pushes the picked object's OWN m_position - which for a child is
the frame CPhysicsObj::UpdateChild @ 0x00512D50 recomposes each tick as
Frame::combine(parent part frame, holding frame) - and
CPartArray::GetSelectionSphere @ 0x00518B80 scales the authored sphere by that
object's own part-array scale. acdream stores the PARENT's root in the child
projection's Position/Rotation because the child's MeshRefs are
parent-relative, which put the vivid brackets at the wielder's feet. The
composed child root is already published per frame to EntityEffectPoseRegistry
by EquippedChildRenderController.PublishChildPose, so selection now borrows it
through an injected Func<uint, Matrix4x4?> wired in LivePresentationComposition
beside the existing selection-sphere hook. There is no parent fallback: a child
with no published composed root has no live frame this tick and no sphere. Its
part-array scale comes from the spawn record, the same source
EquippedChildRenderController.TryRealize reads, because an Attached WorldEntity
carries the parent-derived pose rather than its own ObjScale.

The sr_Use branch of RecvNotice_SmartBoxObjectFound @ 0x004E5AD0 guards
ItemHolder::UseObject with `found->pwd._wielderID != SmartBox::player_id` at
0x004E5BE9 while still selecting and flashing. Equipped-child picking makes
that click reachable, so the gate ships with it as
IWorldSelectionQuery.IsWieldedByPlayer.

CPhysicsObj::SetLighting @ 0x00511A80 is non-recursive, so the pulse lights the
clicked object's own part array only - clicking a weapon never flashes its
wielder. That follows from routing the pulse identity through the same
predicate.

RetailWorldPicker, RetailSelectionScene, WbDrawDispatcher, and
EquippedChildRenderController are untouched, as are all wire and physics paths.

The slice REMOVES an undocumented deviation (Attached projections excluded
from pick eligibility versus retail's part-id pick) and introduces none, so no
retail-divergence-register row is owed in either direction.

Gates: dotnet build green; AcDream.App.Tests 3,951 passed / 3 skipped;
complete Release solution 9,783 passed / 5 skipped;
tools\run-connected-world-lifecycle-gate.ps1 RESULT=PASS.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 18:30:25 +02:00
Erik
921712f412 fix(interaction): restore retail loot placement and world-drop projection 2026-07-27 00:03:15 +02:00
Erik
f5f7b4177f refactor(runtime): own interaction transactions
Move use throttling, appraisal identity, queued interactions, and exact post-arrival pickup state beneath RuntimeActionState. Keep App as the picker, movement, transport, and retained-presentation adapter while preserving retail send and UseDone ordering. Add reset, disposal, GUID-reuse, callback-reentrancy, and transport-failure coverage.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 11:13:09 +02:00
Erik
b298f99f91 refactor(runtime): own canonical action state
Move selection, combat, and interaction target mode under one Runtime owner; make plugins, retained UI, session routing, and typed runtime views borrow its exact children; and add failure-safe reset, instance isolation, source ownership, and normalized checkpoint coverage without changing retail ordering.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 10:44:09 +02:00
Erik
89e6b207f8 refactor(runtime): close canonical gameplay ownership
Unify the toolbar shortcut manager with Runtime inventory state, route retail-ordered shortcut and spellbook command effects through the canonical owners, and make retained controllers borrow those exact instances. Remove the item-interaction transaction fallback and add graphical/no-window parity plus failure-safe terminal ownership-ledger coverage.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 09:48:51 +02:00
Erik
420e5eea70 refactor(app): key live projections by runtime identity
Move materialized live-object sidecars and presentation worksets to exact RuntimeEntityKey ownership. Runtime remains the only GUID/incarnation/local-ID authority while hydration, animation, effects, lights, equipped children, renderer resources, visibility, liveness, and teardown resolve exact projection identities. Preserve synchronous callbacks, local-ID allocation order, and current rendering behavior.
2026-07-25 21:50:58 +02:00
Erik
1a14812c44 fix(world): restore portal and distant use lifecycles 2026-07-25 09:59:25 +02:00
Erik
5ad32d5753 feat(input): assess world objects on right click
Port SmartBox's release-completed sr_Examine gesture through the configurable SelectRight binding. Cancel camera drags at the shared retail three-pixel threshold, then reuse the canonical picker, selection pulse, and appraisal request path without inventing another wire or UI owner.

Co-authored-by: Codex <codex@openai.com>
2026-07-24 05:42:28 +02:00
Erik
19e8863f4e fix(items): dispatch carried use without world approach 2026-07-23 09:50:28 +02:00
Erik
f9736ece6c fix(runtime): restore interaction completion ownership
Preserve prepublication local motion completion, require the PartArray enter-world lifecycle port, and balance deferred Use busy ownership across dispatch and cancellation. Reconcile the completed GameWindow connected gates and add regression coverage.

Co-authored-by: Codex <codex@openai.com>
2026-07-23 05:51:51 +02:00
Erik
947c61d2d7 refactor(camera): extract the update frame
Move fly/chase publication, combat target tracking, and local player projection behind typed runtime owners. Preserve the inbound-created projection/reconcile barrier while removing GameWindow callbacks and duplicate shadow helpers.
2026-07-22 03:08:58 +02:00
Erik
eeb0f6b45c refactor(runtime): extract local teleport and player mode
Move local teleport, player-mode, animation, shadow, and sealed-dungeon lifetimes out of GameWindow. Make player-mode entry transactional and isolate approach completions by controller lifetime and approach generation so stale callbacks cannot affect replacements.

Co-authored-by: Codex <noreply@openai.com>
2026-07-22 02:50:15 +02:00
Erik
5acc3f01cf fix(interaction): close selection lifecycle review gaps
Bind queued actions and pending inventory requests to exact live incarnations, separate optimistic placement from authoritative responses, and serialize retail-style inventory ownership across UI surfaces.

Co-authored-by: OpenAI Codex <codex@openai.com>
2026-07-21 09:01:02 +02:00
Erik
fa8d5232cc refactor(interaction): add selection interaction owner
Introduce a tested controller for selection mutations, target-mode interception, outbound ordering, Use/PickUp lifetime, and live-incarnation cleanup, plus narrow movement and WorldSession transport adapters.
2026-07-21 07:24:26 +02:00