feat(net): Phase 6.6 — parse UpdateMotion (0xF74C) into MotionUpdated event
Server sends UpdateMotion whenever an entity's motion state changes: NPCs starting a walk cycle, creatures switching to a combat stance, doors opening, a player waving, etc. Phase 6.1-6.4 already handles rendering different (stance, forward-command) pairs for the INITIAL CreateObject, but without this message NPCs freeze in whatever pose they spawned with and never transition to walking/fighting. Added UpdateMotion.TryParse with the same ServerMotionState the CreateObject path uses, reached via a slightly different outer layout (guid + instance seq + header'd MovementData; the MovementData starts with the 8-byte sequence/autonomous header this time rather than being preceded by a length field). Only the (stance, forward- command) pair is extracted — same subset CreateObject grabs. WorldSession dispatches MotionUpdated(guid, state) when a 0xF74C body parses successfully. The App-side wiring (guid→entity lookup and AnimatedEntity cycle swap) is intentionally deferred to a separate commit because it touches GameWindow which is currently being edited by the Phase 9.1 translucent-pass work. 89 Core.Net tests (was 83, +6 for UpdateMotion coverage). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4752b8a528
commit
a71db90310
12 changed files with 675 additions and 45 deletions
75
src/AcDream.Core/Meshing/TranslucencyKind.cs
Normal file
75
src/AcDream.Core/Meshing/TranslucencyKind.cs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
using DatReaderWriter.Enums;
|
||||
|
||||
namespace AcDream.Core.Meshing;
|
||||
|
||||
/// <summary>
|
||||
/// Categorizes how a sub-mesh should be composited into the frame. Determined
|
||||
/// from the Surface.Type flags on the AC dat surface that owns the sub-mesh.
|
||||
/// </summary>
|
||||
public enum TranslucencyKind
|
||||
{
|
||||
/// <summary>Standard opaque. Depth write + test, no blend.</summary>
|
||||
Opaque = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Alpha-keyed (clip-map). Treated as opaque for sorting; the fragment
|
||||
/// shader discards low-alpha fragments. Matches the current rendering of
|
||||
/// doors, windows, and vegetation.
|
||||
/// </summary>
|
||||
ClipMap = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Standard alpha blend: src*a + dst*(1-a).
|
||||
/// Depth-write off, depth-test on. Used for semi-transparent glass,
|
||||
/// water decals, and flame alpha surfaces.
|
||||
/// </summary>
|
||||
AlphaBlend = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Additive blend: src*a + dst. Depth-write off, depth-test on.
|
||||
/// Used for portal swirls, magical glows, and particle effects.
|
||||
/// </summary>
|
||||
Additive = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Inverted alpha blend: src*(1-a) + dst*a. Rare but present in
|
||||
/// the AC dat files.
|
||||
/// </summary>
|
||||
InvAlpha = 4,
|
||||
}
|
||||
|
||||
public static class TranslucencyKindExtensions
|
||||
{
|
||||
// Priority order (highest wins):
|
||||
// 1. Additive — SurfaceType.Additive (0x10000)
|
||||
// 2. InvAlpha — SurfaceType.InvAlpha (0x200)
|
||||
// 3. AlphaBlend — SurfaceType.Alpha (0x100) OR SurfaceType.Translucent (0x10)
|
||||
// 4. ClipMap — SurfaceType.Base1ClipMap (0x04)
|
||||
// 5. Opaque — everything else
|
||||
//
|
||||
// Note: ACViewer groups Base1ClipMap with the alpha-draw bucket (AlphaSurfaceTypes),
|
||||
// but acdream keeps its existing alpha-discard approach for clip-map surfaces
|
||||
// (they render opaque with per-fragment discard) and introduces a separate
|
||||
// translucent pass only for the genuinely blended surface types.
|
||||
|
||||
/// <summary>
|
||||
/// Maps a <see cref="SurfaceType"/> flags value to the correct
|
||||
/// <see cref="TranslucencyKind"/> for the two-pass render split.
|
||||
/// </summary>
|
||||
public static TranslucencyKind FromSurfaceType(SurfaceType type)
|
||||
{
|
||||
if ((type & SurfaceType.Additive) != 0)
|
||||
return TranslucencyKind.Additive;
|
||||
|
||||
if ((type & SurfaceType.InvAlpha) != 0)
|
||||
return TranslucencyKind.InvAlpha;
|
||||
|
||||
if ((type & (SurfaceType.Alpha | SurfaceType.Translucent)) != 0)
|
||||
return TranslucencyKind.AlphaBlend;
|
||||
|
||||
if ((type & SurfaceType.Base1ClipMap) != 0)
|
||||
return TranslucencyKind.ClipMap;
|
||||
|
||||
return TranslucencyKind.Opaque;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue