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>
81 lines
4 KiB
C#
81 lines
4 KiB
C#
using AcDream.Core.Meshing;
|
|
using DatReaderWriter.Enums;
|
|
|
|
namespace AcDream.Core.Tests.Meshing;
|
|
|
|
/// <summary>
|
|
/// Verifies that <see cref="TranslucencyKindExtensions.FromSurfaceType"/> maps
|
|
/// SurfaceType flag combinations to the correct <see cref="TranslucencyKind"/>
|
|
/// according to the documented priority order:
|
|
/// Additive > InvAlpha > AlphaBlend (Alpha|Translucent) > ClipMap > Opaque
|
|
/// </summary>
|
|
public class TranslucencyKindTests
|
|
{
|
|
// ── Opaque cases ────────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void Opaque_FromZeroFlags_ReturnsOpaque()
|
|
=> Assert.Equal(TranslucencyKind.Opaque, TranslucencyKindExtensions.FromSurfaceType((SurfaceType)0));
|
|
|
|
[Fact]
|
|
public void Opaque_FromBase1SolidFlag_ReturnsOpaque()
|
|
=> Assert.Equal(TranslucencyKind.Opaque, TranslucencyKindExtensions.FromSurfaceType(SurfaceType.Base1Solid));
|
|
|
|
[Fact]
|
|
public void Opaque_FromBase1ImageFlag_ReturnsOpaque()
|
|
=> Assert.Equal(TranslucencyKind.Opaque, TranslucencyKindExtensions.FromSurfaceType(SurfaceType.Base1Image));
|
|
|
|
// ── ClipMap cases ───────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void ClipMap_FromBase1ClipMapFlag_ReturnsClipMap()
|
|
=> Assert.Equal(TranslucencyKind.ClipMap, TranslucencyKindExtensions.FromSurfaceType(SurfaceType.Base1ClipMap));
|
|
|
|
[Fact]
|
|
public void ClipMap_WithOtherOpaqueFlags_ReturnsClipMap()
|
|
=> Assert.Equal(TranslucencyKind.ClipMap,
|
|
TranslucencyKindExtensions.FromSurfaceType(SurfaceType.Base1ClipMap | SurfaceType.Gouraud));
|
|
|
|
// ── AlphaBlend cases ────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void AlphaBlend_FromAlphaFlag_ReturnsAlphaBlend()
|
|
=> Assert.Equal(TranslucencyKind.AlphaBlend, TranslucencyKindExtensions.FromSurfaceType(SurfaceType.Alpha));
|
|
|
|
[Fact]
|
|
public void AlphaBlend_FromTranslucentFlag_ReturnsAlphaBlend()
|
|
=> Assert.Equal(TranslucencyKind.AlphaBlend, TranslucencyKindExtensions.FromSurfaceType(SurfaceType.Translucent));
|
|
|
|
[Fact]
|
|
public void AlphaBlend_FromAlphaAndTranslucentFlags_ReturnsAlphaBlend()
|
|
=> Assert.Equal(TranslucencyKind.AlphaBlend,
|
|
TranslucencyKindExtensions.FromSurfaceType(SurfaceType.Alpha | SurfaceType.Translucent));
|
|
|
|
[Fact]
|
|
public void AlphaBlend_AlphaWithClipMap_AlphaWins()
|
|
=> Assert.Equal(TranslucencyKind.AlphaBlend,
|
|
TranslucencyKindExtensions.FromSurfaceType(SurfaceType.Alpha | SurfaceType.Base1ClipMap));
|
|
|
|
// ── InvAlpha cases ──────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void InvAlpha_FromInvAlphaFlag_ReturnsInvAlpha()
|
|
=> Assert.Equal(TranslucencyKind.InvAlpha, TranslucencyKindExtensions.FromSurfaceType(SurfaceType.InvAlpha));
|
|
|
|
[Fact]
|
|
public void InvAlpha_InvAlphaBeatsAlpha()
|
|
=> Assert.Equal(TranslucencyKind.InvAlpha,
|
|
TranslucencyKindExtensions.FromSurfaceType(SurfaceType.InvAlpha | SurfaceType.Alpha));
|
|
|
|
// ── Additive cases ──────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void Additive_FromAdditiveFlag_ReturnsAdditive()
|
|
=> Assert.Equal(TranslucencyKind.Additive, TranslucencyKindExtensions.FromSurfaceType(SurfaceType.Additive));
|
|
|
|
[Fact]
|
|
public void Additive_AdditiveBeatsAllOther()
|
|
=> Assert.Equal(TranslucencyKind.Additive,
|
|
TranslucencyKindExtensions.FromSurfaceType(
|
|
SurfaceType.Additive | SurfaceType.InvAlpha | SurfaceType.Alpha | SurfaceType.Base1ClipMap));
|
|
}
|