feat: add actor behavior projectiles

This commit is contained in:
ud18010
2026-07-30 13:15:55 +08:00
parent 9e946c7772
commit 52741e68a8
2 changed files with 204 additions and 1 deletions
@@ -55,6 +55,45 @@ namespace XWorld.Framework.Tests.ActorBehavior
Assert.DoesNotContain(events, e => e.Kind == BehaviorEventKind.TimelineEffect);
Assert.Contains(events, e => e.Kind == BehaviorEventKind.AttributeEffectRequested && e.TargetActorId == 2 && e.Attribute == "hp");
}
[Fact]
public void Projectile_SpawnsMovesHitsAndExpiresAtHitLimit()
{
BehaviorWorld world = TestWorld.CreateServerWorld();
world.TryStartBehavior(1, "slash", BehaviorInput.FromDirection(1, 0));
world.Tick(0.33f);
Assert.True(world.ActiveProjectileCount > 0);
world.Tick(0.1f);
var events = world.DrainEvents();
Assert.Contains(events, e => e.Kind == BehaviorEventKind.ProjectileSpawned);
Assert.Contains(events, e => e.Kind == BehaviorEventKind.ProjectileMoved);
Assert.Contains(events, e => e.Kind == BehaviorEventKind.ProjectileHit && e.TargetActorId == 2);
Assert.Equal(0, world.ActiveProjectileCount);
}
[Theory]
[InlineData("Line")]
[InlineData("Parabola")]
[InlineData("Homing")]
public void ProjectileMovementModes_UpdatePosition(string movementKind)
{
string fly = TestBehaviorJson.FlyObject.Replace(@"""kind"": ""Line""", @"""kind"": """ + movementKind + @"""");
BehaviorConfigCatalog catalog = BehaviorConfigCatalog.LoadFromJson("fighter", TestBehaviorJson.Skill, fly, TestBehaviorJson.Buff);
var world = new BehaviorWorld(new BehaviorWorldOptions { Mode = BehaviorRunMode.ClientPresentation });
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(4, 0, 0), Forward = new BehaviorVector3(-1, 0, 0), Radius = 0.3f, Alive = true });
world.TryStartBehavior(1, "slash", BehaviorInput.FromTargetActor(2));
world.Tick(0.33f);
world.DrainEvents();
world.Tick(0.1f);
Assert.Contains(world.DrainEvents(), e => e.Kind == BehaviorEventKind.ProjectileMoved && e.Position.X > 0);
}
}
internal static class TestWorld