Move interaction priority into daemon operations
This commit is contained in:
parent
712c34bf52
commit
7e80803a88
7 changed files with 188 additions and 27 deletions
|
|
@ -7533,12 +7533,15 @@ static void RequireUnityObserverDoesNotTickLocalSimulation(string root)
|
|||
{
|
||||
"public void RequestDock()",
|
||||
"public void RequestUndock()",
|
||||
"private void RequestInteract()",
|
||||
"public void RequestTowToStation()",
|
||||
"TryRequestDaemonDock()",
|
||||
"TryRequestDaemonUndock()",
|
||||
"TryRequestDaemonInteract()",
|
||||
"TryRequestDaemonTowToStation()",
|
||||
"observer.Operations.DockNearest(Settings.GameplaySettings.DockingDistance)",
|
||||
"observer.Operations.Undock()",
|
||||
"observer.Operations.Interact(",
|
||||
"observer.Operations.TowToStation(",
|
||||
"TowingStation.CultPositionXZ.x",
|
||||
"TowingStation.CultPositionXZ.y"
|
||||
|
|
@ -7563,7 +7566,9 @@ static void RequireUnityObserverDoesNotTickLocalSimulation(string root)
|
|||
"Missing cockpit component",
|
||||
"Missing thruster component",
|
||||
"Missing reactor component",
|
||||
"Must empty docking bay"
|
||||
"Must empty docking bay",
|
||||
"ZoneRenderer.WormholeInstances.Keys",
|
||||
"RequestEnterWormhole(wormhole);"
|
||||
};
|
||||
var unityDockingAuthorityHits = forbiddenUnityDockingAuthoritySymbols
|
||||
.Where(symbol => actionGameManager.Contains(symbol, StringComparison.Ordinal))
|
||||
|
|
@ -7617,9 +7622,13 @@ static void RequireUnityObserverDoesNotTickLocalSimulation(string root)
|
|||
var requiredDaemonDockNearestSymbols = new[]
|
||||
{
|
||||
"AetheriaRuntimeDaemonCommandKinds.DockNearest",
|
||||
"AetheriaRuntimeDaemonCommandKinds.Interact",
|
||||
"public AetheriaRuntimeDaemonCommandEnvelope DockNearest(",
|
||||
"public AetheriaRuntimeDaemonCommandEnvelope Interact(",
|
||||
"ApplyDockNearestIntent(run, command, context.Intents)",
|
||||
"TryFindNearestDockTarget(run, actorKey, command.ScalarValue, out var targetKey)"
|
||||
"ApplyInteractIntent(run, command, context.Intents)",
|
||||
"TryFindNearestDockTarget(run, actorKey, command.ScalarValue, out var targetKey)",
|
||||
"TryFindNearestWormholeTarget("
|
||||
};
|
||||
var daemonDockNearestSources = daemonDocuments + "\n" + daemonOperationClient + "\n" + daemonOperationsSource;
|
||||
var missingDaemonDockNearestSymbols = requiredDaemonDockNearestSymbols
|
||||
|
|
|
|||
|
|
@ -2000,17 +2000,7 @@ public class ActionGameManager : MonoBehaviour
|
|||
Dialog.Show();
|
||||
Dialog.MoveToCursor();
|
||||
}
|
||||
else if (CurrentEntity.Parent == null)
|
||||
{
|
||||
foreach (var wormhole in ZoneRenderer.WormholeInstances.Keys)
|
||||
{
|
||||
if (!(CultMath.math.length(wormhole.Position - CurrentEntity.CultPositionXZ) < Settings.GameplaySettings.WormholeExitRadius)) continue;
|
||||
RequestEnterWormhole(wormhole);
|
||||
return;
|
||||
}
|
||||
RequestDock();
|
||||
}
|
||||
else RequestUndock();
|
||||
else RequestInteract();
|
||||
};
|
||||
|
||||
Input.Global.MainMenu.performed += context =>
|
||||
|
|
@ -2165,35 +2155,29 @@ public class ActionGameManager : MonoBehaviour
|
|||
foreach (var a in _actionBarActions) a.Disable();
|
||||
}
|
||||
|
||||
private void RequestEnterWormhole(Wormhole wormhole)
|
||||
private void RequestInteract()
|
||||
{
|
||||
TryRequestDaemonEnterWormhole(wormhole);
|
||||
TryRequestDaemonInteract();
|
||||
}
|
||||
|
||||
private bool TryRequestDaemonEnterWormhole(Wormhole wormhole)
|
||||
private bool TryRequestDaemonInteract()
|
||||
{
|
||||
var observer = ResolveDaemonObserver();
|
||||
if (observer == null ||
|
||||
!observer.HasAuthoritativeState ||
|
||||
wormhole == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var targetZoneIndex = ZoneIndex(wormhole.Target);
|
||||
if (targetZoneIndex < 0)
|
||||
if (observer == null || !observer.HasAuthoritativeState)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
observer.Operations.EnterWormhole(targetZoneIndex, wormhole.Position.x, wormhole.Position.y);
|
||||
observer.Operations.Interact(
|
||||
Settings.GameplaySettings.DockingDistance,
|
||||
Settings.GameplaySettings.WormholeExitRadius);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"Failed to send Aetheria daemon wormhole operation; operation not submitted: {ex.Message}");
|
||||
Debug.LogWarning($"Failed to send Aetheria daemon interact operation; operation not submitted: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,6 +210,11 @@ public sealed class AetheriaDaemonOperations
|
|||
return Send((client, observed) => client.Undock(observed));
|
||||
}
|
||||
|
||||
public AetheriaRuntimeDaemonCommandEnvelope Interact(double dockDistance, double wormholeDistance)
|
||||
{
|
||||
return Send((client, observed) => client.Interact(observed, dockDistance, wormholeDistance));
|
||||
}
|
||||
|
||||
public AetheriaRuntimeDaemonCommandEnvelope SetDockedCurrentShip(string targetEntityKey)
|
||||
{
|
||||
return Send((client, observed) => client.SetDockedCurrentShip(observed, targetEntityKey));
|
||||
|
|
|
|||
|
|
@ -2003,6 +2003,79 @@ public class DaemonRuntimeDocumentTests
|
|||
CollectionAssert.Contains(run.Zones[0].Entities[1].DockingBayAssignments, 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DaemonOperationsInteractPrioritizesUndockWormholeThenDock()
|
||||
{
|
||||
var undockRun = RunWithTwoEntities();
|
||||
undockRun.Zones[0].Entities[1].ChildEntityIndices = new[] { 0 };
|
||||
undockRun.Zones[0].Entities[1].DockingBayAssignments = new[] { 0, -1 };
|
||||
var undock = AetheriaRuntimeDaemonCommandDocument.Create(
|
||||
AetheriaRuntimeDaemonCommandKinds.Interact,
|
||||
"codex",
|
||||
"session-interact",
|
||||
46,
|
||||
"zone.0.entity.0");
|
||||
undock.ScalarValue = 10;
|
||||
undock.PositionX = 10;
|
||||
|
||||
var undockResult = AetheriaRuntimeDaemonOperations.Execute(undockRun, new[] { undock });
|
||||
Assert.AreEqual(1, undockResult.AppliedCommandIds.Count);
|
||||
Assert.AreEqual(1, undockResult.Intents.Docking.Count);
|
||||
Assert.IsTrue(undockResult.Intents.Docking[0].Undock);
|
||||
CollectionAssert.DoesNotContain(undockRun.Zones[0].Entities[1].DockingBayAssignments, 0);
|
||||
|
||||
var wormholeRun = RunWithTwoEntities();
|
||||
wormholeRun.Zones[0].AdjacentZoneIndices = new[] { 2 };
|
||||
wormholeRun.Zones[0].Entities[0].PositionX = 0;
|
||||
wormholeRun.Zones[0].Entities[0].PositionZ = 0;
|
||||
wormholeRun.Zones = wormholeRun.Zones
|
||||
.Concat(new[]
|
||||
{
|
||||
new AetheriaRuntimeZoneSnapshotCommit
|
||||
{
|
||||
ZoneIndex = 2,
|
||||
PositionX = 3,
|
||||
PositionY = 4
|
||||
}
|
||||
})
|
||||
.ToArray();
|
||||
var wormhole = AetheriaRuntimeDaemonCommandDocument.Create(
|
||||
AetheriaRuntimeDaemonCommandKinds.Interact,
|
||||
"codex",
|
||||
"session-interact",
|
||||
47,
|
||||
"zone.0.entity.0");
|
||||
wormhole.ScalarValue = 10;
|
||||
wormhole.PositionX = 10;
|
||||
|
||||
var wormholeResult = AetheriaRuntimeDaemonOperations.Execute(wormholeRun, new[] { wormhole });
|
||||
Assert.AreEqual(1, wormholeResult.AppliedCommandIds.Count);
|
||||
Assert.AreEqual(1, wormholeResult.Intents.Wormholes.Count);
|
||||
Assert.AreEqual(2, wormholeRun.CurrentZoneIndex);
|
||||
Assert.AreEqual(3, FindZone(wormholeRun, 2).Entities[0].PositionX, 0.0001);
|
||||
Assert.AreEqual(4, FindZone(wormholeRun, 2).Entities[0].PositionZ, 0.0001);
|
||||
|
||||
var dockRun = RunWithTwoEntities();
|
||||
dockRun.Zones[0].Entities[0].PositionX = 0;
|
||||
dockRun.Zones[0].Entities[0].PositionY = 0;
|
||||
dockRun.Zones[0].Entities[1].PositionX = 3;
|
||||
dockRun.Zones[0].Entities[1].PositionY = 4;
|
||||
var dock = AetheriaRuntimeDaemonCommandDocument.Create(
|
||||
AetheriaRuntimeDaemonCommandKinds.Interact,
|
||||
"codex",
|
||||
"session-interact",
|
||||
48,
|
||||
"zone.0.entity.0");
|
||||
dock.ScalarValue = 10;
|
||||
dock.PositionX = 1;
|
||||
|
||||
var dockResult = AetheriaRuntimeDaemonOperations.Execute(dockRun, new[] { dock });
|
||||
Assert.AreEqual(1, dockResult.AppliedCommandIds.Count);
|
||||
Assert.AreEqual(1, dockResult.Intents.Docking.Count);
|
||||
Assert.IsTrue(dockResult.Intents.Docking[0].Dock);
|
||||
CollectionAssert.Contains(dockRun.Zones[0].Entities[1].ChildEntityIndices, 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DaemonOperationsTowsEntityToStationInDaemonState()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
Dock,
|
||||
DockNearest,
|
||||
Undock,
|
||||
Interact,
|
||||
SetDockedCurrentShip,
|
||||
TowToStation,
|
||||
EnterWormhole,
|
||||
|
|
|
|||
|
|
@ -407,6 +407,18 @@ namespace GameCult.Aetheria.State.Verse
|
|||
return Send(AetheriaRuntimeDaemonCommandKinds.Undock, observed);
|
||||
}
|
||||
|
||||
public AetheriaRuntimeDaemonCommandEnvelope Interact(
|
||||
AetheriaRuntimeObservedDaemonState? observed,
|
||||
double dockDistance,
|
||||
double wormholeDistance)
|
||||
{
|
||||
return Send(AetheriaRuntimeDaemonCommandKinds.Interact, observed, command =>
|
||||
{
|
||||
command.ScalarValue = dockDistance;
|
||||
command.PositionX = wormholeDistance;
|
||||
});
|
||||
}
|
||||
|
||||
public AetheriaRuntimeDaemonCommandEnvelope SetDockedCurrentShip(
|
||||
AetheriaRuntimeObservedDaemonState? observed,
|
||||
string targetEntityKey)
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ namespace GameCult.Aetheria.State.Verse
|
|||
return ApplyDockNearestIntent(run, command, context.Intents);
|
||||
case AetheriaRuntimeDaemonCommandKinds.Undock:
|
||||
return ApplyUndockIntent(run, command, context.Intents);
|
||||
case AetheriaRuntimeDaemonCommandKinds.Interact:
|
||||
return ApplyInteractIntent(run, command, context.Intents);
|
||||
case AetheriaRuntimeDaemonCommandKinds.EnterWormhole:
|
||||
return ApplyEnterWormholeIntent(run, command, context.Intents);
|
||||
case AetheriaRuntimeDaemonCommandKinds.TowToStation:
|
||||
|
|
@ -1095,6 +1097,38 @@ namespace GameCult.Aetheria.State.Verse
|
|||
return true;
|
||||
}
|
||||
|
||||
private static bool ApplyInteractIntent(
|
||||
AetheriaRuntimeRunCheckpointCommit run,
|
||||
AetheriaRuntimeDaemonCommandDocument command,
|
||||
AetheriaRuntimeDaemonIntentState intents)
|
||||
{
|
||||
var actorKey = ResolveActorEntityKey(run, command);
|
||||
if (string.IsNullOrWhiteSpace(actorKey) ||
|
||||
!TryResolveEntity(run, actorKey, out var zoneIndex, out var actorIndex, out _))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsChildReferencedInZone(run, zoneIndex, actorIndex))
|
||||
return ApplyUndockIntent(run, command, intents);
|
||||
|
||||
if (TryFindNearestWormholeTarget(
|
||||
run,
|
||||
actorKey,
|
||||
command.PositionX,
|
||||
out var targetZoneIndex,
|
||||
out var entryX,
|
||||
out var entryY))
|
||||
{
|
||||
command.TargetZoneIndex = targetZoneIndex;
|
||||
command.PositionX = entryX;
|
||||
command.PositionY = entryY;
|
||||
return ApplyEnterWormholeIntent(run, command, intents);
|
||||
}
|
||||
|
||||
return ApplyDockNearestIntent(run, command, intents);
|
||||
}
|
||||
|
||||
private static bool TryFindNearestDockTarget(
|
||||
AetheriaRuntimeRunCheckpointCommit run,
|
||||
string actorEntityKey,
|
||||
|
|
@ -1137,6 +1171,49 @@ namespace GameCult.Aetheria.State.Verse
|
|||
return true;
|
||||
}
|
||||
|
||||
private static bool TryFindNearestWormholeTarget(
|
||||
AetheriaRuntimeRunCheckpointCommit run,
|
||||
string actorEntityKey,
|
||||
double maxDistance,
|
||||
out int targetZoneIndex,
|
||||
out double entryX,
|
||||
out double entryY)
|
||||
{
|
||||
targetZoneIndex = -1;
|
||||
entryX = 0.0;
|
||||
entryY = 0.0;
|
||||
if (!TryResolveEntity(run, actorEntityKey, out var zoneIndex, out _, out var actor))
|
||||
return false;
|
||||
|
||||
var zone = (run.Zones ?? Array.Empty<AetheriaRuntimeZoneSnapshotCommit>())
|
||||
.FirstOrDefault(candidate => candidate != null && candidate.ZoneIndex == zoneIndex);
|
||||
if (zone == null)
|
||||
return false;
|
||||
|
||||
var maxDistanceSq = maxDistance > 0.0 ? maxDistance * maxDistance : double.PositiveInfinity;
|
||||
var closestDistanceSq = double.PositiveInfinity;
|
||||
foreach (var adjacentZoneIndex in zone.AdjacentZoneIndices ?? Array.Empty<int>())
|
||||
{
|
||||
var candidate = (run.Zones ?? Array.Empty<AetheriaRuntimeZoneSnapshotCommit>())
|
||||
.FirstOrDefault(candidateZone => candidateZone != null && candidateZone.ZoneIndex == adjacentZoneIndex);
|
||||
if (candidate == null)
|
||||
continue;
|
||||
|
||||
var deltaX = candidate.PositionX - actor.PositionX;
|
||||
var deltaY = candidate.PositionY - actor.PositionZ;
|
||||
var distanceSq = (deltaX * deltaX) + (deltaY * deltaY);
|
||||
if (distanceSq >= maxDistanceSq || distanceSq >= closestDistanceSq)
|
||||
continue;
|
||||
|
||||
closestDistanceSq = distanceSq;
|
||||
targetZoneIndex = adjacentZoneIndex;
|
||||
entryX = candidate.PositionX;
|
||||
entryY = candidate.PositionY;
|
||||
}
|
||||
|
||||
return targetZoneIndex >= 0;
|
||||
}
|
||||
|
||||
private static bool ApplyDockState(
|
||||
AetheriaRuntimeRunCheckpointCommit run,
|
||||
string actorEntityKey,
|
||||
|
|
|
|||
Loading…
Reference in a new issue