Save loadouts from observed entity state

This commit is contained in:
Meta Vens 2026-06-21 20:55:22 +01:00
commit 6dae256980
3 changed files with 86 additions and 6 deletions

View file

@ -10586,8 +10586,9 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root)
"AetheriaRuntimeLoadoutTemplateCommands.cs");
var eveBridgePath = Path.Combine(root, "Aetheria.State", "AetheriaEveCommandBridge.cs");
var runtimeStateMapperPath = Path.Combine(root, "Aetheria.State", "AetheriaRuntimeStateMapper.cs");
var inventoryPanelPath = Path.Combine(root, "Assets", "Scripts", "UI", "Menu", "InventoryPanel.cs");
var requiredFiles = new[] { eveCommandDocumentPath, loadoutCommandsPath, eveBridgePath, runtimeStateMapperPath };
var requiredFiles = new[] { eveCommandDocumentPath, loadoutCommandsPath, eveBridgePath, runtimeStateMapperPath, inventoryPanelPath };
var missingFiles = requiredFiles.Where(path => !File.Exists(path)).ToArray();
if (missingFiles.Length > 0)
{
@ -10600,10 +10601,15 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root)
var loadoutCommands = File.ReadAllText(loadoutCommandsPath);
var eveBridge = File.ReadAllText(eveBridgePath);
var runtimeStateMapper = File.ReadAllText(runtimeStateMapperPath);
var inventoryPanel = File.ReadAllText(inventoryPanelPath);
var requiredActionSymbols = new[]
{
"RequestLoadoutTemplateSave",
"RequestLoadoutTemplateSave(Entity entity)",
"ProjectLoadoutTemplate(Entity entity)",
"ProjectEntityLoadout(Entity entity)",
"ProjectSlots(IEnumerable<EquippedItem> slots)",
"ProjectCargoBays(IEnumerable<EquippedCargoBay> bays)",
"SendRuntimeLoadoutTemplateCommand(loadout",
"private static void SendRuntimeLoadoutTemplateCommand(",
"AetheriaRuntimeEveCommands.TrySendLoadoutTemplateCommand",
@ -10622,7 +10628,8 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root)
{
"AetheriaRuntimeStateCommitLog.QueueLoadoutTemplate",
"TrySendRuntimeLoadoutTemplateCommand(",
"private static bool TrySendRuntimeLoadoutTemplateCommand("
"private static bool TrySendRuntimeLoadoutTemplateCommand(",
"RequestLoadoutTemplateSave(EntityConstructionBlueprint blueprint)"
};
var forbiddenActionHits = forbiddenActionSymbols
.Where(symbol => actionGameManager.Contains(symbol, StringComparison.Ordinal))
@ -10634,6 +10641,13 @@ static void RequireInventoryLoadoutSaveRequestAuthority(string root)
string.Join(", ", forbiddenActionHits));
}
if (!inventoryPanel.Contains("GameManager.RequestLoadoutTemplateSave(_displayedEntity)", StringComparison.Ordinal) ||
inventoryPanel.Contains("EntityConstructionBlueprintProjector.CaptureBlueprint(_displayedEntity)", StringComparison.Ordinal))
{
throw new InvalidOperationException(
"InventoryPanel still captures a Unity EntityConstructionBlueprint before submitting a typed loadout-template save.");
}
var requiredBridgeSymbols = new[]
{
"AetheriaRuntimeEveCommandKind.SaveLoadoutTemplate",

View file

@ -617,6 +617,43 @@ public class ActionGameManager : MonoBehaviour
};
}
private static AetheriaRuntimeLoadoutTemplateCommit ProjectLoadoutTemplate(Entity entity)
{
return new AetheriaRuntimeLoadoutTemplateCommit
{
Name = entity?.Name ?? "",
OwnerPlayerKey = $"global:aetheria.player_settings.v1",
RootEntity = ProjectEntityLoadout(entity)
};
}
private static AetheriaRuntimeEntityLoadoutCommit ProjectEntityLoadout(Entity entity)
{
return new AetheriaRuntimeEntityLoadoutCommit
{
Name = entity?.Name ?? "",
Kind = entity is Ship ? "ship" : entity is OrbitalEntity ? "orbital" : "entity",
FactionKey = entity?.Faction?.FactionKey ?? "",
Hull = ProjectLoadoutItem(entity?.Hull),
Equipment = ProjectSlots(entity?.Equipment),
CargoBays = ProjectSlots(entity?.CargoBays),
DockingBays = ProjectSlots(entity?.DockingBays),
CargoContents = ProjectCargoBays(entity?.CargoBays),
DockingBayContents = ProjectCargoBays(entity?.DockingBays),
DockingBayAssignments = entity?.DockingBays?
.Select(dockingBay => entity.Children.IndexOf(dockingBay.DockedShip))
.ToArray() ?? Array.Empty<int>(),
WeaponGroups = entity?.WeaponGroups?
.Select(group => (IReadOnlyList<int>)group.items
.Select(item => entity.Equipment.IndexOf(item))
.ToArray())
.ToArray() ?? Array.Empty<IReadOnlyList<int>>(),
Children = entity?.Children?
.Select(ProjectEntityLoadout)
.ToArray() ?? Array.Empty<AetheriaRuntimeEntityLoadoutCommit>()
};
}
private static AetheriaRuntimeLoadoutItemSlotCommit[] ProjectSlots((int2 position, EquippableItem item)[] slots)
{
return slots?
@ -629,6 +666,18 @@ public class ActionGameManager : MonoBehaviour
.ToArray() ?? Array.Empty<AetheriaRuntimeLoadoutItemSlotCommit>();
}
private static AetheriaRuntimeLoadoutItemSlotCommit[] ProjectSlots(IEnumerable<EquippedItem> slots)
{
return slots?
.Select(slot => new AetheriaRuntimeLoadoutItemSlotCommit
{
X = slot.Position.x,
Y = slot.Position.y,
Item = ProjectLoadoutItem(slot.EquippableItem)
})
.ToArray() ?? Array.Empty<AetheriaRuntimeLoadoutItemSlotCommit>();
}
private static AetheriaRuntimeCargoBayLoadoutCommit[] ProjectCargoBays((int2 position, ItemInstance item)[][] bays)
{
return bays?
@ -646,6 +695,23 @@ public class ActionGameManager : MonoBehaviour
.ToArray() ?? Array.Empty<AetheriaRuntimeCargoBayLoadoutCommit>();
}
private static AetheriaRuntimeCargoBayLoadoutCommit[] ProjectCargoBays(IEnumerable<EquippedCargoBay> bays)
{
return bays?
.Select(bay => new AetheriaRuntimeCargoBayLoadoutCommit
{
Items = bay.Cargo?
.Select(slot => new AetheriaRuntimeLoadoutItemSlotCommit
{
X = slot.Value.x,
Y = slot.Value.y,
Item = ProjectLoadoutItem(slot.Key)
})
.ToArray() ?? Array.Empty<AetheriaRuntimeLoadoutItemSlotCommit>()
})
.ToArray() ?? Array.Empty<AetheriaRuntimeCargoBayLoadoutCommit>();
}
private static AetheriaRuntimeLoadoutItemCommit ProjectLoadoutItem(ItemInstance item)
{
if (item == null)
@ -960,9 +1026,9 @@ public class ActionGameManager : MonoBehaviour
return ObservedGalaxy?.Factions == null || faction == null ? -1 : Array.IndexOf(ObservedGalaxy.Factions, faction);
}
public void RequestLoadoutTemplateSave(EntityConstructionBlueprint blueprint)
public void RequestLoadoutTemplateSave(Entity entity)
{
var loadout = ProjectLoadoutTemplate(blueprint);
var loadout = ProjectLoadoutTemplate(entity);
SendRuntimeLoadoutTemplateCommand(loadout, "unity-inventory", "loadout template save");
}

View file

@ -249,7 +249,7 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
{
_dropdownCommands[AetheriaRuntimeInventoryDropdownSurfaceBuilder.SaveLoadout] = () =>
{
GameManager.RequestLoadoutTemplateSave(EntityConstructionBlueprintProjector.CaptureBlueprint(_displayedEntity));
GameManager.RequestLoadoutTemplateSave(_displayedEntity);
};
}