using Xunit; using XWorld.Framework.ActorBehavior; namespace XWorld.Framework.Tests.ActorBehavior { public class BehaviorTargetingTests { [Theory] [InlineData("sector_test", 2)] [InlineData("sphere_test", 2)] [InlineData("ring_test", 3)] [InlineData("line_test", 2)] public void LogicEffectShapes_SelectExpectedTargets(string behaviorId, int expectedTarget) { BehaviorWorld world = TestTargetWorld.Create(); world.TryStartBehavior(1, behaviorId, BehaviorInput.FromDirection(1, 0)); world.Tick(0.01f); Assert.Contains(world.DrainEvents(), e => e.Kind == BehaviorEventKind.AttributeEffectRequested && e.TargetActorId == expectedTarget); } [Fact] public void LockedEffect_UsesTargetActorInput() { BehaviorWorld world = TestTargetWorld.Create(); world.TryStartBehavior(1, "locked_test", BehaviorInput.FromTargetActor(3)); world.Tick(0.01f); Assert.Contains(world.DrainEvents(), e => e.Kind == BehaviorEventKind.AttributeEffectRequested && e.TargetActorId == 3); } } internal static class TestTargetWorld { public static BehaviorWorld Create() { BehaviorConfigCatalog catalog = BehaviorConfigCatalog.LoadFromJson( "fighter", Skill, EmptyFlyObject, EmptyBuff); var world = new BehaviorWorld(new BehaviorWorldOptions { Mode = BehaviorRunMode.ServerLogic }); world.RegisterCatalog(catalog); world.AddActor(new BehaviorActorState { ActorId = 1, CatalogType = "fighter", TeamId = 1, Position = new BehaviorVector3(0, 0, 0), Forward = new BehaviorVector3(1, 0, 0), Radius = 0.3f, Alive = true }); world.AddActor(new BehaviorActorState { ActorId = 2, CatalogType = "fighter", TeamId = 2, Position = new BehaviorVector3(1, 0, 0), Forward = new BehaviorVector3(-1, 0, 0), Radius = 0.3f, Alive = true }); world.AddActor(new BehaviorActorState { ActorId = 3, CatalogType = "fighter", TeamId = 2, Position = new BehaviorVector3(3, 0, 0), Forward = new BehaviorVector3(-1, 0, 0), Radius = 0.3f, Alive = true }); world.AddActor(new BehaviorActorState { ActorId = 4, CatalogType = "fighter", TeamId = 2, Position = new BehaviorVector3(0, 0, 2), Forward = new BehaviorVector3(0, 0, -1), Radius = 0.3f, Alive = true }); return world; } private const string EmptyFlyObject = @"{ ""type"": ""fighter"", ""version"": 1, ""flyObjects"": [] }"; private const string EmptyBuff = @"{ ""type"": ""fighter"", ""version"": 1, ""buffs"": [] }"; private const string Skill = @"{ ""type"": ""fighter"", ""version"": 1, ""behaviors"": [ { ""id"": ""sector_test"", ""duration"": 0.1, ""canBeInterrupted"": true, ""timeline"": [{ ""time"": 0, ""kind"": ""LogicEffect"", ""effectId"": ""sector_hit"" }], ""logicEffects"": [{ ""id"": ""sector_hit"", ""shape"": ""Sector"", ""radius"": 2, ""angle"": 90, ""target"": ""Enemy"", ""effects"": [{ ""type"": ""Attribute"", ""attribute"": ""hp"", ""value"": -1 }] }] }, { ""id"": ""sphere_test"", ""duration"": 0.1, ""canBeInterrupted"": true, ""timeline"": [{ ""time"": 0, ""kind"": ""LogicEffect"", ""effectId"": ""sphere_hit"" }], ""logicEffects"": [{ ""id"": ""sphere_hit"", ""shape"": ""Sphere"", ""radius"": 1.5, ""target"": ""Enemy"", ""effects"": [{ ""type"": ""Attribute"", ""attribute"": ""hp"", ""value"": -1 }] }] }, { ""id"": ""ring_test"", ""duration"": 0.1, ""canBeInterrupted"": true, ""timeline"": [{ ""time"": 0, ""kind"": ""LogicEffect"", ""effectId"": ""ring_hit"" }], ""logicEffects"": [{ ""id"": ""ring_hit"", ""shape"": ""Ring"", ""minRadius"": 2, ""radius"": 3.5, ""target"": ""Enemy"", ""effects"": [{ ""type"": ""Attribute"", ""attribute"": ""hp"", ""value"": -1 }] }] }, { ""id"": ""line_test"", ""duration"": 0.1, ""canBeInterrupted"": true, ""timeline"": [{ ""time"": 0, ""kind"": ""LogicEffect"", ""effectId"": ""line_hit"" }], ""logicEffects"": [{ ""id"": ""line_hit"", ""shape"": ""Line"", ""radius"": 2, ""width"": 0.5, ""target"": ""Enemy"", ""effects"": [{ ""type"": ""Attribute"", ""attribute"": ""hp"", ""value"": -1 }] }] }, { ""id"": ""locked_test"", ""duration"": 0.1, ""canBeInterrupted"": true, ""timeline"": [{ ""time"": 0, ""kind"": ""LogicEffect"", ""effectId"": ""locked_hit"" }], ""logicEffects"": [{ ""id"": ""locked_hit"", ""shape"": ""Locked"", ""target"": ""HitActor"", ""effects"": [{ ""type"": ""Attribute"", ""attribute"": ""hp"", ""value"": -1 }] }] } ] }"; } }