Move target cycling into daemon operations

This commit is contained in:
Meta Vens 2026-06-21 11:41:32 +01:00
commit 1f47ea387b
7 changed files with 282 additions and 17 deletions

View file

@ -2067,31 +2067,17 @@ public class ActionGameManager : MonoBehaviour
Input.Player.TargetNearest.performed += context =>
{
if(CurrentEntity.VisibleEnemies.Any())
{
RequestTargetSelection(CurrentEntity.VisibleEnemies.Where(x => x != CurrentEntity)
.MaxBy(x => CultMath.math.length(x.CultPosition - CurrentEntity.CultPosition)));
}
RequestTargetNearest();
};
Input.Player.TargetNext.performed += context =>
{
if (!CurrentEntity.VisibleEnemies.Any()) return;
var targets = CurrentEntity.VisibleEnemies.Where(x => x != CurrentEntity)
.OrderBy(x => CultMath.math.length(x.CultPosition - CurrentEntity.CultPosition))
.ToArray();
var currentTargetIndex = Array.IndexOf(targets, CurrentEntity.Target.Value);
RequestTargetSelection(targets[(currentTargetIndex + 1) % targets.Length]);
RequestTargetNext();
};
Input.Player.TargetPrevious.performed += context =>
{
if (!CurrentEntity.VisibleEnemies.Any()) return;
var targets = CurrentEntity.VisibleEnemies.Where(x => x != CurrentEntity)
.OrderBy(x => CultMath.math.length(x.CultPosition - CurrentEntity.CultPosition))
.ToArray();
var currentTargetIndex = Array.IndexOf(targets, CurrentEntity.Target.Value);
RequestTargetSelection(targets[(currentTargetIndex + targets.Length - 1) % targets.Length]);
RequestTargetPrevious();
};
#endregion
@ -3743,6 +3729,21 @@ public class ActionGameManager : MonoBehaviour
TryRequestDaemonTargetSelection(target);
}
private void RequestTargetNearest()
{
TryRequestDaemonTargetCycle(AetheriaRuntimeDaemonCommandKinds.TargetNearest);
}
private void RequestTargetNext()
{
TryRequestDaemonTargetCycle(AetheriaRuntimeDaemonCommandKinds.TargetNext);
}
private void RequestTargetPrevious()
{
TryRequestDaemonTargetCycle(AetheriaRuntimeDaemonCommandKinds.TargetPrevious);
}
private bool TryRequestDaemonTargetSelection(Entity target)
{
var observer = ResolveDaemonObserver();
@ -3775,6 +3776,38 @@ public class ActionGameManager : MonoBehaviour
}
}
private bool TryRequestDaemonTargetCycle(AetheriaRuntimeDaemonCommandKinds command)
{
var observer = ResolveDaemonObserver();
if (observer == null || !observer.HasAuthoritativeState)
{
return false;
}
try
{
switch (command)
{
case AetheriaRuntimeDaemonCommandKinds.TargetNearest:
observer.Operations.TargetNearest();
return true;
case AetheriaRuntimeDaemonCommandKinds.TargetNext:
observer.Operations.TargetNext();
return true;
case AetheriaRuntimeDaemonCommandKinds.TargetPrevious:
observer.Operations.TargetPrevious();
return true;
default:
return false;
}
}
catch (Exception ex)
{
Debug.LogWarning($"Failed to send Aetheria daemon target cycle operation; operation not submitted: {ex.Message}");
return false;
}
}
private void RequestOverrideShutdown(bool enabled)
{
TryRequestDaemonOverrideShutdown(enabled);

View file

@ -20,6 +20,21 @@ public sealed class AetheriaDaemonOperations
return Send((client, observed) => client.ClearTarget(observed));
}
public AetheriaRuntimeDaemonCommandEnvelope TargetNearest()
{
return Send((client, observed) => client.TargetNearest(observed));
}
public AetheriaRuntimeDaemonCommandEnvelope TargetNext()
{
return Send((client, observed) => client.TargetNext(observed));
}
public AetheriaRuntimeDaemonCommandEnvelope TargetPrevious()
{
return Send((client, observed) => client.TargetPrevious(observed));
}
public AetheriaRuntimeDaemonCommandEnvelope SetMoveVector(
double directionX,
double directionY,

View file

@ -1071,6 +1071,79 @@ public class DaemonRuntimeDocumentTests
Assert.AreEqual(-1, run.Zones[0].Entities[0].TargetEntityIndex);
}
[Test]
public void DaemonOperationsCyclesTargetsFromAuthoritativeContacts()
{
var run = RunWithTwoEntities();
var zone = run.Zones[0];
zone.Entities[0].PositionX = 0;
zone.Entities[0].PositionY = 0;
zone.Entities[1].PositionX = 5;
zone.Entities[1].PositionY = 0;
zone.Entities = zone.Entities
.Concat(new[]
{
new AetheriaRuntimeEntitySnapshotCommit
{
EntityIndex = 2,
Name = "Near Hostile",
PositionX = 2,
PositionY = 0
}
})
.ToArray();
zone.Entities[0].Contacts = new[]
{
new AetheriaRuntimeEntityContactCommit
{
TargetEntityIndex = 1,
Visible = true,
Hostile = true
},
new AetheriaRuntimeEntityContactCommit
{
TargetEntityIndex = 2,
Visible = true,
Hostile = true
}
};
var nearest = AetheriaRuntimeDaemonCommandDocument.Create(
AetheriaRuntimeDaemonCommandKinds.TargetNearest,
"codex",
"session-target",
15,
"zone.0.entity.0");
var next = AetheriaRuntimeDaemonCommandDocument.Create(
AetheriaRuntimeDaemonCommandKinds.TargetNext,
"codex",
"session-target",
16,
"zone.0.entity.0");
var previous = AetheriaRuntimeDaemonCommandDocument.Create(
AetheriaRuntimeDaemonCommandKinds.TargetPrevious,
"codex",
"session-target",
17,
"zone.0.entity.0");
var previousFromNoneResult = AetheriaRuntimeDaemonOperations.Execute(run, new[] { previous });
Assert.AreEqual(1, previousFromNoneResult.AppliedCommandIds.Count);
Assert.AreEqual(2, zone.Entities[0].TargetEntityIndex);
var nearestResult = AetheriaRuntimeDaemonOperations.Execute(run, new[] { nearest });
Assert.AreEqual(1, nearestResult.AppliedCommandIds.Count);
Assert.AreEqual(2, zone.Entities[0].TargetEntityIndex);
var nextResult = AetheriaRuntimeDaemonOperations.Execute(run, new[] { next });
Assert.AreEqual(1, nextResult.AppliedCommandIds.Count);
Assert.AreEqual(1, zone.Entities[0].TargetEntityIndex);
var previousResult = AetheriaRuntimeDaemonOperations.Execute(run, new[] { previous });
Assert.AreEqual(1, previousResult.AppliedCommandIds.Count);
Assert.AreEqual(2, zone.Entities[0].TargetEntityIndex);
}
[Test]
public void DaemonOperationsMutatesHotEntityControlsInDaemonState()
{