Allow every actor to share daemon control levers
This commit is contained in:
parent
95afb2af5e
commit
c3e401725c
5 changed files with 67 additions and 12 deletions
|
|
@ -13,6 +13,57 @@ internal sealed class AetheriaDaemonYmirSmokeChecks
|
|||
DaemonSimulationAppliesYmirHit();
|
||||
MissingPhysicsOwnerCannotAdvanceProjectiles();
|
||||
ThermalCellsUseFossilConductionAndRadiation();
|
||||
MultipleActorsUseTheSameMovementLever();
|
||||
}
|
||||
|
||||
private static void MultipleActorsUseTheSameMovementLever()
|
||||
{
|
||||
var player = Entity(0, 0, "player");
|
||||
var agent = Entity(1, 0, "worker");
|
||||
var run = new AetheriaRuntimeRunCheckpointCommit
|
||||
{
|
||||
RunId = "shared-lever-smoke",
|
||||
CurrentZoneIndex = 0,
|
||||
CurrentEntityKey = "zone.0.entity.0",
|
||||
Zones = [new AetheriaRuntimeZoneSnapshotCommit { ZoneIndex = 0, Entities = [player, agent] }]
|
||||
};
|
||||
var commands = new[]
|
||||
{
|
||||
MovementCommand("player-move", "zone.0.entity.0", 1, 0),
|
||||
MovementCommand("agent-move", "zone.0.entity.1", 0, 1)
|
||||
};
|
||||
var operation = AetheriaRuntimeDaemonOperations.Execute(run, commands);
|
||||
|
||||
RequireEqual(2, operation.Intents.Movements.Count, "movement intent must retain one lever position per actor");
|
||||
AetheriaRuntimeDaemonSimulation.Step(
|
||||
run,
|
||||
operation.Intents,
|
||||
0.1,
|
||||
AetheriaRuntimeDaemonSimulationSettings.AetheriaDefault,
|
||||
AetheriaRuntimeProjectilePhysicsUnavailable.Instance);
|
||||
Require(player.VelocityX > 0 && Math.Abs(player.VelocityY) < 0.001,
|
||||
"player command must drive its actor through the shared movement lever");
|
||||
Require(agent.VelocityY > 0 && Math.Abs(agent.VelocityX) < 0.001,
|
||||
"agent command must drive its actor through the shared movement lever");
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeDaemonCommandDocument MovementCommand(
|
||||
string commandId,
|
||||
string actor,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
var command = AetheriaRuntimeDaemonCommandDocument.Create(
|
||||
AetheriaRuntimeDaemonCommandKinds.SetMoveVector,
|
||||
"shared-control-smoke",
|
||||
"shared-control-session",
|
||||
0,
|
||||
actor);
|
||||
command.CommandId = commandId;
|
||||
command.DirectionX = x;
|
||||
command.DirectionY = y;
|
||||
command.ScalarValue = 1;
|
||||
return command;
|
||||
}
|
||||
|
||||
private static void ThermalCellsUseFossilConductionAndRadiation()
|
||||
|
|
|
|||
|
|
@ -529,8 +529,8 @@ public class DaemonRuntimeDocumentTests
|
|||
Assert.AreEqual(2, result.OperationResult.AppliedCommandIds.Count);
|
||||
Assert.AreEqual(0, result.OperationResult.RejectedCommandIds.Count);
|
||||
Assert.AreEqual(1, run.Zones[0].Entities[0].TargetEntityIndex);
|
||||
Assert.AreEqual("zone.0.entity.0", result.Intents.Movement.ActorEntityKey);
|
||||
Assert.AreEqual(1.0, result.Intents.Movement.DirectionX, 0.0001);
|
||||
Assert.AreEqual("zone.0.entity.0", result.Intents.Movements.Single().ActorEntityKey);
|
||||
Assert.AreEqual(1.0, result.Intents.Movements.Single().DirectionX, 0.0001);
|
||||
Assert.AreEqual(12.5, result.Run.Zones[0].SimulationTimeSeconds, 0.0001);
|
||||
var frame = result.Frame;
|
||||
Assert.AreEqual("test-daemon", frame.DaemonId);
|
||||
|
|
@ -4646,10 +4646,10 @@ public class DaemonRuntimeDocumentTests
|
|||
|
||||
Assert.AreEqual(5, result.AppliedCommandIds.Count);
|
||||
Assert.IsTrue(result.Intents.HasAny);
|
||||
Assert.AreEqual("zone.0.entity.0", result.Intents.Movement.ActorEntityKey);
|
||||
Assert.AreEqual(0.25, result.Intents.Movement.DirectionX, 0.0001);
|
||||
Assert.AreEqual(-0.5, result.Intents.Movement.DirectionY, 0.0001);
|
||||
Assert.AreEqual(0.75, result.Intents.Movement.Magnitude, 0.0001);
|
||||
Assert.AreEqual("zone.0.entity.0", result.Intents.Movements.Single().ActorEntityKey);
|
||||
Assert.AreEqual(0.25, result.Intents.Movements.Single().DirectionX, 0.0001);
|
||||
Assert.AreEqual(-0.5, result.Intents.Movements.Single().DirectionY, 0.0001);
|
||||
Assert.AreEqual(0.75, result.Intents.Movements.Single().Magnitude, 0.0001);
|
||||
Assert.AreEqual(1, result.Intents.WeaponGroups.Count);
|
||||
Assert.IsTrue(result.Intents.WeaponGroups[0].Fire);
|
||||
Assert.AreEqual(1, result.Intents.WeaponGroups[0].WeaponGroup);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ namespace GameCult.Aetheria.State.Verse
|
|||
{
|
||||
public sealed class AetheriaRuntimeDaemonIntentState
|
||||
{
|
||||
public AetheriaRuntimeDaemonMovementIntent? Movement { get; set; }
|
||||
public List<AetheriaRuntimeDaemonMovementIntent> Movements { get; } =
|
||||
new List<AetheriaRuntimeDaemonMovementIntent>();
|
||||
public List<AetheriaRuntimeDaemonWeaponGroupIntent> WeaponGroups { get; } =
|
||||
new List<AetheriaRuntimeDaemonWeaponGroupIntent>();
|
||||
public List<AetheriaRuntimeDaemonBehaviorIntent> Behaviors { get; } =
|
||||
|
|
@ -23,7 +24,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
public bool SensorPingRequested { get; set; }
|
||||
|
||||
public bool HasAny =>
|
||||
Movement != null ||
|
||||
Movements.Count > 0 ||
|
||||
SensorPingRequested ||
|
||||
WeaponGroups.Count > 0 ||
|
||||
Behaviors.Count > 0 ||
|
||||
|
|
|
|||
|
|
@ -927,13 +927,15 @@ namespace GameCult.Aetheria.State.Verse
|
|||
return false;
|
||||
}
|
||||
|
||||
intents.Movement = new AetheriaRuntimeDaemonMovementIntent
|
||||
intents.Movements.RemoveAll(intent =>
|
||||
string.Equals(intent.ActorEntityKey, actor, StringComparison.Ordinal));
|
||||
intents.Movements.Add(new AetheriaRuntimeDaemonMovementIntent
|
||||
{
|
||||
ActorEntityKey = actor,
|
||||
DirectionX = command.DirectionX,
|
||||
DirectionY = command.DirectionY,
|
||||
Magnitude = command.ScalarValue
|
||||
};
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ namespace GameCult.Aetheria.State.Verse
|
|||
EnsureStats(entities, settings);
|
||||
foreach (var entity in entities)
|
||||
AetheriaRuntimeThermalSimulation.EnsureState(entity);
|
||||
ApplyMovementIntent(run, entities, intents?.Movement, settings);
|
||||
foreach (var movement in intents?.Movements ?? Enumerable.Empty<AetheriaRuntimeDaemonMovementIntent>())
|
||||
ApplyMovementIntent(run, entities, movement, settings);
|
||||
StepRaiderAi(entities);
|
||||
StepTargetPursuit(entities, settings);
|
||||
StepMovement(entities, deltaSeconds);
|
||||
|
|
@ -86,7 +87,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
return;
|
||||
|
||||
var entity = entities.FirstOrDefault(candidate => candidate.EntityIndex == entityIndex);
|
||||
if (entity == null || !IsPlayerOwned(entity) || !IsAlive(entity))
|
||||
if (entity == null || !IsAlive(entity))
|
||||
return;
|
||||
|
||||
var magnitude = Clamp01(movement.Magnitude);
|
||||
|
|
|
|||
Loading…
Reference in a new issue