using AcDream.Core.Combat; using AcDream.Core.Selection; using AcDream.Runtime.Gameplay; namespace AcDream.Runtime.Tests.Gameplay; public sealed class RuntimeActionStateTests { [Fact] public void ViewProjectsTheExactCanonicalChildrenAndRevisions() { using var actions = new RuntimeActionState(); actions.Selection.Select( 0x50000001u, SelectionChangeSource.World); actions.Combat.SetCombatMode(CombatMode.Missile); actions.Combat.OnUpdateHealth(0x50000001u, 0.625f); actions.Interaction.EnterUseItemOnTarget(0x70000001u); RuntimeActionSnapshot snapshot = actions.View.Snapshot; Assert.Equal(1, snapshot.SelectionRevision); Assert.Equal(0x50000001u, snapshot.SelectedObjectId); Assert.Equal(2, snapshot.CombatRevision); Assert.Equal(CombatMode.Missile, snapshot.CombatMode); Assert.Equal(1, snapshot.TrackedTargetHealthCount); Assert.Equal(1, snapshot.InteractionRevision); Assert.Equal( InteractionModeKind.UseItemOnTarget, snapshot.InteractionMode); Assert.Equal(0x70000001u, snapshot.InteractionSourceObjectId); Assert.True( actions.View.TryGetHealth(0x50000001u, out float health)); Assert.Equal(0.625f, health); } [Fact] public void ResetSessionConvergesEveryChildAfterObserverFailures() { var actions = new RuntimeActionState(); actions.Selection.Select( 0x50000001u, SelectionChangeSource.World); actions.Combat.SetCombatMode(CombatMode.Melee); actions.Combat.OnUpdateHealth(0x50000001u, 0.25f); actions.Interaction.EnterExamine(); actions.Selection.Changed += static _ => throw new InvalidOperationException("selection observer"); actions.Combat.CombatModeChanged += static _ => throw new InvalidOperationException("combat observer"); actions.Interaction.Changed += static _ => throw new InvalidOperationException("interaction observer"); Assert.Throws(actions.ResetSession); RuntimeActionOwnershipSnapshot snapshot = actions.CaptureOwnership(); Assert.Equal(0u, snapshot.SelectedObjectId); Assert.Equal(0u, snapshot.PreviousObjectId); Assert.Equal(0u, snapshot.PreviousValidObjectId); Assert.Equal(CombatMode.NonCombat, snapshot.CombatMode); Assert.Equal(0, snapshot.TrackedTargetHealthCount); Assert.Equal(InteractionMode.None, snapshot.InteractionMode); Assert.Throws(actions.Dispose); } [Fact] public void DisposeIsTerminalAndConvergedAfterObserverFailures() { var actions = new RuntimeActionState(); actions.Selection.Select( 0x50000001u, SelectionChangeSource.World); actions.Combat.SetCombatMode(CombatMode.Magic); actions.Combat.OnUpdateHealth(0x50000001u, 0.5f); actions.Interaction.EnterUse(); actions.Selection.Changed += static _ => throw new InvalidOperationException("selection observer"); actions.Combat.CombatModeChanged += static _ => throw new InvalidOperationException("combat observer"); actions.Interaction.Changed += static _ => throw new InvalidOperationException("interaction observer"); Assert.Throws(actions.Dispose); RuntimeActionOwnershipSnapshot snapshot = actions.CaptureOwnership(); Assert.True(snapshot.IsConverged); actions.Dispose(); } [Fact] public void InstancesAreFullyIsolated() { using var first = new RuntimeActionState(); using var second = new RuntimeActionState(); first.Selection.Select( 0x50000001u, SelectionChangeSource.World); first.Combat.SetCombatMode(CombatMode.Missile); first.Interaction.EnterUse(); Assert.Equal( new RuntimeActionSnapshot( 0, 0u, 0u, 0u, 0, CombatMode.NonCombat, 0, 0, InteractionModeKind.None, 0u), second.View.Snapshot); } }