phase(N.4) Adjustment 6: add PartOverrides + HiddenPartsMask to WorldEntity

Resolves Adjustment 4 (Option A): WorldEntity now carries the server-
sent AnimPartChange data as PartOverrides and a HiddenPartsMask bitmask.
EntitySpawnAdapter.OnCreate populates AnimatedEntityState from these
fields at spawn time. GameWindow's CreateObject handler converts the
network-layer AnimPartChange records into lightweight PartOverride
structs.

This unblocks Task 22: the WbDrawDispatcher can now resolve per-part
GfxObj overrides and hidden-part suppression from entity state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-08 15:10:22 +02:00
parent 16a36dda8f
commit 5b4fd4b61d
4 changed files with 70 additions and 14 deletions

View file

@ -55,4 +55,27 @@ public sealed class WorldEntity
/// visible trunk, producing "partial passthrough" bugs.
/// </summary>
public float Scale { get; init; } = 1.0f;
/// <summary>
/// Server-sent part-swap overrides from <c>AnimPartChange</c>. Each entry
/// replaces a Setup part's GfxObj with an alternate model (clothing, weapons,
/// helmets). Carried on the entity so <c>EntitySpawnAdapter</c> can populate
/// <c>AnimatedEntityState</c>'s override map at spawn time. Empty for atlas-
/// tier entities.
/// </summary>
public IReadOnlyList<PartOverride> PartOverrides { get; init; } = Array.Empty<PartOverride>();
/// <summary>
/// Bitmask of hidden Setup parts. Bit <c>i</c> set hides part <c>i</c> at
/// draw time. Sourced from the server's <c>CreateObject</c> record when
/// present. Zero (no parts hidden) is the default.
/// </summary>
public ulong HiddenPartsMask { get; init; }
}
/// <summary>
/// Lightweight value type for a server-sent <c>AnimPartChange</c> (part index
/// → replacement GfxObj id). Decouples <c>WorldEntity</c> (Core) from the
/// network-layer <c>CreateObject.AnimPartChange</c> type.
/// </summary>
public readonly record struct PartOverride(byte PartIndex, uint GfxObjId);