2026-06-25 18:09:33 +01:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using GameCult.Aetheria.State.Verse;
|
|
|
|
|
|
2026-06-28 10:07:05 +01:00
|
|
|
public sealed class AetheriaUnityObservedDockingIndex : IDisposable
|
2026-06-25 18:09:33 +01:00
|
|
|
{
|
|
|
|
|
private readonly Func<AetheriaClient> _resolveClient;
|
2026-06-28 03:34:08 +01:00
|
|
|
private readonly AetheriaUnityObservedEntityIndex _observedEntityIndex;
|
2026-06-25 18:09:33 +01:00
|
|
|
|
|
|
|
|
public AetheriaUnityObservedDockingIndex(
|
|
|
|
|
Func<AetheriaClient> resolveClient,
|
2026-06-28 03:34:08 +01:00
|
|
|
AetheriaUnityObservedEntityIndex observedEntityIndex)
|
2026-06-25 18:09:33 +01:00
|
|
|
{
|
|
|
|
|
_resolveClient = resolveClient ?? throw new ArgumentNullException(nameof(resolveClient));
|
2026-06-28 03:34:08 +01:00
|
|
|
_observedEntityIndex = observedEntityIndex ?? throw new ArgumentNullException(nameof(observedEntityIndex));
|
2026-06-25 18:09:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int ResolveEntityZoneIndex(Entity entity)
|
|
|
|
|
{
|
|
|
|
|
return TryResolveCurrentDocking(entity, out var docking)
|
|
|
|
|
? docking.ZoneIndex
|
|
|
|
|
: -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsEntityUndocked(Entity entity)
|
|
|
|
|
{
|
|
|
|
|
return TryResolveCurrentDocking(entity, out var docking) &&
|
|
|
|
|
!docking.IsDocked;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-27 16:07:46 +01:00
|
|
|
public bool TryResolveCurrentEntity(out Entity entity)
|
|
|
|
|
{
|
|
|
|
|
entity = null;
|
2026-06-28 12:39:17 +01:00
|
|
|
return TryResolveCurrentEntityKey(out var currentEntityKey) &&
|
|
|
|
|
_observedEntityIndex.TryResolveEntityByRecordKey(currentEntityKey, out entity);
|
2026-06-27 16:07:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool TryResolveCurrentEntityKey(out string currentEntityKey)
|
|
|
|
|
{
|
2026-06-28 12:39:17 +01:00
|
|
|
currentEntityKey = "";
|
2026-06-28 13:26:22 +01:00
|
|
|
if (TryResolveCurrentDocking(out var docking))
|
|
|
|
|
currentEntityKey = docking.CurrentEntityKey;
|
2026-06-27 16:07:46 +01:00
|
|
|
return !string.IsNullOrWhiteSpace(currentEntityKey);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool TryResolveCurrentEntityDocument(out AetheriaRuntimeCurrentEntityDocument currentEntity)
|
|
|
|
|
{
|
2026-06-28 12:39:17 +01:00
|
|
|
currentEntity = null;
|
2026-06-28 13:26:22 +01:00
|
|
|
if (!TryResolveCurrentDocking(out var docking))
|
2026-06-28 12:39:17 +01:00
|
|
|
return false;
|
|
|
|
|
|
2026-06-28 13:26:22 +01:00
|
|
|
currentEntity = docking.Entity;
|
2026-06-27 16:07:46 +01:00
|
|
|
return currentEntity != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public AetheriaRuntimeStationRefitDocument ResolveStationRefit()
|
|
|
|
|
{
|
2026-06-28 13:26:22 +01:00
|
|
|
return TryResolveCurrentDocking(out var docking)
|
|
|
|
|
? docking.Refit
|
|
|
|
|
: null;
|
2026-06-27 16:07:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool TryResolveCurrentDockingBayRow(out AetheriaRuntimeStationDockingBayRow dockingBay)
|
|
|
|
|
{
|
2026-06-28 12:39:17 +01:00
|
|
|
dockingBay = null;
|
2026-06-28 13:26:22 +01:00
|
|
|
if (!TryResolveCurrentDocking(out var docking) ||
|
|
|
|
|
!docking.TryResolveCurrentDockingBayRow(out var row))
|
2026-06-28 12:39:17 +01:00
|
|
|
return false;
|
|
|
|
|
|
2026-06-28 13:26:22 +01:00
|
|
|
dockingBay = row;
|
2026-06-27 16:07:46 +01:00
|
|
|
return dockingBay != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool TryResolveCurrentDockingBay(out EquippedDockingBay dockingBay)
|
|
|
|
|
{
|
|
|
|
|
dockingBay = null;
|
2026-06-28 12:39:17 +01:00
|
|
|
var refit = ResolveStationRefit();
|
|
|
|
|
if (!TryResolveCurrentDockingBayRow(out _) ||
|
|
|
|
|
string.IsNullOrWhiteSpace(refit?.DockParentEntityKey) ||
|
|
|
|
|
refit.DockingBayIndex < 0 ||
|
2026-06-28 03:34:08 +01:00
|
|
|
!_observedEntityIndex.TryResolveDockingBayByRecordKey(
|
2026-06-28 12:39:17 +01:00
|
|
|
refit.DockParentEntityKey,
|
|
|
|
|
refit.DockingBayIndex,
|
2026-06-27 16:07:46 +01:00
|
|
|
out dockingBay))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dockingBay != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool TryResolveCurrentDocking(out AetheriaRuntimeCurrentDockingDocument docking)
|
|
|
|
|
{
|
2026-06-28 12:39:17 +01:00
|
|
|
docking = null;
|
2026-06-28 13:26:22 +01:00
|
|
|
if (!TryResolveCurrentDocking(out var currentDocking))
|
2026-06-28 12:39:17 +01:00
|
|
|
return false;
|
|
|
|
|
|
2026-06-28 13:26:22 +01:00
|
|
|
docking = currentDocking.Docking;
|
2026-06-27 16:07:46 +01:00
|
|
|
return docking != null;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-25 18:09:33 +01:00
|
|
|
public bool TryResolveDockingBay(
|
|
|
|
|
Entity child,
|
|
|
|
|
out Entity dockParent,
|
|
|
|
|
out EquippedDockingBay dockingBay)
|
|
|
|
|
{
|
|
|
|
|
return TryResolveDockingBay(child, out dockParent, out dockingBay, out _);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool TryResolveDockingBay(
|
|
|
|
|
Entity child,
|
|
|
|
|
out Entity dockParent,
|
|
|
|
|
out EquippedDockingBay dockingBay,
|
|
|
|
|
out AetheriaRuntimeCurrentDockingDocument docking)
|
|
|
|
|
{
|
|
|
|
|
dockParent = null;
|
|
|
|
|
dockingBay = null;
|
|
|
|
|
docking = null;
|
|
|
|
|
if (!TryResolveCurrentDocking(child, out docking) || !docking.IsDocked)
|
|
|
|
|
return false;
|
|
|
|
|
|
2026-06-28 03:34:08 +01:00
|
|
|
if (!_observedEntityIndex.TryResolveEntityByRecordKey(docking.DockParentEntityKey, out var parent) ||
|
2026-06-25 18:09:33 +01:00
|
|
|
!(parent is OrbitalEntity))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parent.DockingBays == null ||
|
|
|
|
|
docking.DockingBayIndex < 0 ||
|
|
|
|
|
docking.DockingBayIndex >= parent.DockingBays.Count)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dockParent = parent;
|
|
|
|
|
dockingBay = parent.DockingBays[docking.DockingBayIndex];
|
|
|
|
|
return dockingBay != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool TryResolveCurrentDocking(
|
|
|
|
|
Entity entity,
|
|
|
|
|
out AetheriaRuntimeCurrentDockingDocument docking)
|
|
|
|
|
{
|
2026-06-28 12:39:17 +01:00
|
|
|
TryResolveCurrentDocking(out docking);
|
2026-06-25 18:09:33 +01:00
|
|
|
if (entity == null ||
|
|
|
|
|
docking == null ||
|
|
|
|
|
docking.CurrentEntityIndex != entity.DaemonEntityIndex)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-28 03:34:08 +01:00
|
|
|
if (_observedEntityIndex.TryResolveEntityRecordKey(entity, out var entityKey) &&
|
2026-06-25 18:09:33 +01:00
|
|
|
!string.IsNullOrWhiteSpace(docking.CurrentEntityKey) &&
|
|
|
|
|
!string.Equals(docking.CurrentEntityKey, entityKey, StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-28 13:26:22 +01:00
|
|
|
private bool TryResolveCurrentDocking(out AetheriaRuntimeObservedDockingState docking)
|
2026-06-27 16:07:46 +01:00
|
|
|
{
|
2026-06-28 13:26:22 +01:00
|
|
|
docking = null;
|
2026-06-27 16:07:46 +01:00
|
|
|
try
|
|
|
|
|
{
|
2026-06-28 13:26:22 +01:00
|
|
|
docking = _resolveClient()?.State?.CurrentDocking();
|
|
|
|
|
return docking != null;
|
2026-06-27 16:07:46 +01:00
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
2026-06-27 18:12:33 +01:00
|
|
|
return false;
|
2026-06-25 18:09:33 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-28 10:07:05 +01:00
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
}
|
2026-06-25 18:09:33 +01:00
|
|
|
}
|