256 lines
10 KiB
C#
256 lines
10 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
#nullable enable
|
|
|
|
namespace GameCult.Aetheria.State.Verse
|
|
{
|
|
public static class AetheriaRuntimeAssets
|
|
{
|
|
public static AetheriaRuntimeAssetManifestDocument ProjectManifest(
|
|
AetheriaRuntimeCatalogSnapshot? catalog,
|
|
string runId = "",
|
|
string baseUri = "cultmesh://aetheria.local/assets")
|
|
{
|
|
var entries = new Dictionary<string, AetheriaRuntimeAssetManifestEntry>(StringComparer.Ordinal);
|
|
Add(entries, MapIcon("entity.player", "Player", "Sprites/Icons/Stroked/Ship"));
|
|
Add(entries, MapIcon("entity.ship", "Ship", "Sprites/Icons/Stroked/Ship"));
|
|
Add(entries, MapIcon("entity.orbital", "Orbital", "Sprites/Icons/Stroked/orbital"));
|
|
Add(entries, MapIcon("entity.station", "Station", "Sprites/Icons/station1"));
|
|
Add(entries, MapIcon("entity.projectile", "Projectile", "Sprites/Icons/Lightning Bolt"));
|
|
Add(entries, MapIcon("body.planet", "Planet", "Sprites/Icons/Stroked/Planet"));
|
|
Add(entries, MapIcon("body.sun", "Sun", "Sprites/Icons/Stroked/Sun"));
|
|
Add(entries, MapIcon("body.asteroid", "Asteroid", "Sprites/Icons/Stroked/Planet"));
|
|
Add(entries, MapPrefab("prefab.entity.player", "Player Ship", "Prefabs/Ships/Djinni"));
|
|
Add(entries, MapPrefab("prefab.entity.ship", "Ship", "Prefabs/Ships/Djinni"));
|
|
Add(entries, MapPrefab("prefab.entity.station", "Station", "Prefabs/Stations/AsteroidOutpost"));
|
|
Add(entries, MapPrefab("prefab.entity.orbital", "Orbital", "Prefabs/Stations/Zenith"));
|
|
Add(entries, MapPrefab("prefab.entity.projectile", "Projectile", "Prefabs/Lightning"));
|
|
foreach (var inventoryAsset in InventoryUiAssets())
|
|
Add(entries, inventoryAsset);
|
|
|
|
foreach (var item in catalog?.Items ?? Array.Empty<AetheriaRuntimeCatalogItem>())
|
|
{
|
|
if (item == null || string.IsNullOrWhiteSpace(item.ItemKey))
|
|
continue;
|
|
|
|
var icon = AssetRefFromCatalogIcon(item.ActionBarIcon, $"item.{item.ItemKey}.icon");
|
|
if (!string.IsNullOrWhiteSpace(icon.AssetKey))
|
|
{
|
|
Add(entries, new AetheriaRuntimeAssetManifestEntry
|
|
{
|
|
Ref = icon,
|
|
Tags = new[] { "item", item.ItemKey, item.Category ?? "" }
|
|
.Where(tag => !string.IsNullOrWhiteSpace(tag))
|
|
.ToArray()
|
|
});
|
|
}
|
|
}
|
|
|
|
return new AetheriaRuntimeAssetManifestDocument
|
|
{
|
|
PublishedAtUtc = DateTime.UtcNow.ToString("O"),
|
|
RunId = runId ?? "",
|
|
BaseUri = string.IsNullOrWhiteSpace(baseUri) ? "cultmesh://aetheria.local/assets" : baseUri,
|
|
Assets = entries.Values
|
|
.OrderBy(entry => entry.Ref.AssetKey, StringComparer.Ordinal)
|
|
.ToArray()
|
|
};
|
|
}
|
|
|
|
public static AetheriaRuntimeAssetRef ResolveEntityIcon(AetheriaRuntimeViewportObject? obj)
|
|
{
|
|
if (obj?.Controlled == true)
|
|
return Sprite("map.entity.player", "Sprites/Icons/Stroked/Ship");
|
|
|
|
var kind = (obj?.Kind ?? "").Trim().ToLowerInvariant();
|
|
if (kind.IndexOf("station", StringComparison.Ordinal) >= 0)
|
|
return Sprite("map.entity.station", "Sprites/Icons/station1");
|
|
if (kind.IndexOf("orbital", StringComparison.Ordinal) >= 0)
|
|
return Sprite("map.entity.orbital", "Sprites/Icons/Stroked/orbital");
|
|
if (kind.IndexOf("projectile", StringComparison.Ordinal) >= 0)
|
|
return Sprite("map.entity.projectile", "Sprites/Icons/Lightning Bolt");
|
|
|
|
return Sprite("map.entity.ship", "Sprites/Icons/Stroked/Ship");
|
|
}
|
|
|
|
public static AetheriaRuntimeAssetRef ResolveBodyIcon(AetheriaRuntimeBodyView? body)
|
|
{
|
|
var kind = (body?.Kind ?? "").Trim().ToLowerInvariant();
|
|
if (kind.IndexOf("sun", StringComparison.Ordinal) >= 0 ||
|
|
kind.IndexOf("star", StringComparison.Ordinal) >= 0)
|
|
return Sprite("map.body.sun", "Sprites/Icons/Stroked/Sun");
|
|
if (kind.IndexOf("asteroid", StringComparison.Ordinal) >= 0)
|
|
return Sprite("map.body.asteroid", "Sprites/Icons/Stroked/Planet");
|
|
|
|
return Sprite("map.body.planet", "Sprites/Icons/Stroked/Planet");
|
|
}
|
|
|
|
public static AetheriaRuntimeAssetRef AssetRefFromCatalogIcon(
|
|
string? catalogPath,
|
|
string fallbackAssetKey)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(catalogPath))
|
|
return AetheriaRuntimeAssetRef.Empty(AetheriaRuntimeAssetKinds.Texture);
|
|
|
|
var resourcePath = NormalizeResourcePath(catalogPath ?? "");
|
|
var assetKey = string.IsNullOrWhiteSpace(fallbackAssetKey)
|
|
? $"catalog.{resourcePath}".Replace('/', '.').Replace('\\', '.')
|
|
: fallbackAssetKey;
|
|
return CultMeshAssetRef(
|
|
assetKey,
|
|
AetheriaRuntimeAssetKinds.Texture,
|
|
resourcePath,
|
|
"image/*");
|
|
}
|
|
|
|
public static AetheriaRuntimeAssetRef InventoryCellBackgroundAtlas()
|
|
{
|
|
return Texture(
|
|
"inventory.cell.background_atlas",
|
|
"Sprites/Flat UI/Nodes/Nodes8BG");
|
|
}
|
|
|
|
public static AetheriaRuntimeAssetRef InventoryCellForegroundAtlas()
|
|
{
|
|
return Texture(
|
|
"inventory.cell.foreground_atlas",
|
|
"Sprites/Flat UI/Nodes/Nodes8");
|
|
}
|
|
|
|
public static AetheriaRuntimeAssetRef InventoryThermalLayerAtlas()
|
|
{
|
|
return Texture(
|
|
"inventory.cell.thermal_layer_atlas",
|
|
"Sprites/Flat UI/pipes");
|
|
}
|
|
|
|
public static IReadOnlyList<AetheriaRuntimeAssetManifestEntry> InventoryUiAssets()
|
|
{
|
|
return new[]
|
|
{
|
|
new AetheriaRuntimeAssetManifestEntry
|
|
{
|
|
Ref = InventoryCellBackgroundAtlas(),
|
|
Tags = new[] { "inventory", "cell", "background", "atlas" }
|
|
},
|
|
new AetheriaRuntimeAssetManifestEntry
|
|
{
|
|
Ref = InventoryCellForegroundAtlas(),
|
|
Tags = new[] { "inventory", "cell", "foreground", "atlas" }
|
|
},
|
|
new AetheriaRuntimeAssetManifestEntry
|
|
{
|
|
Ref = InventoryThermalLayerAtlas(),
|
|
Tags = new[] { "inventory", "thermal", "layer", "atlas" }
|
|
}
|
|
};
|
|
}
|
|
|
|
private static AetheriaRuntimeAssetManifestEntry MapIcon(
|
|
string key,
|
|
string label,
|
|
string resourcePath)
|
|
{
|
|
return new AetheriaRuntimeAssetManifestEntry
|
|
{
|
|
Ref = Sprite($"map.{key}", resourcePath),
|
|
Tags = new[] { "map", "icon", label }
|
|
};
|
|
}
|
|
|
|
private static AetheriaRuntimeAssetManifestEntry MapPrefab(
|
|
string key,
|
|
string label,
|
|
string resourcePath)
|
|
{
|
|
return new AetheriaRuntimeAssetManifestEntry
|
|
{
|
|
Ref = Prefab(key, resourcePath),
|
|
Tags = new[] { "world", "prefab", label }
|
|
};
|
|
}
|
|
|
|
private static AetheriaRuntimeAssetRef Sprite(string key, string resourcePath)
|
|
{
|
|
return CultMeshAssetRef(
|
|
key,
|
|
AetheriaRuntimeAssetKinds.Sprite,
|
|
resourcePath,
|
|
"image/*");
|
|
}
|
|
|
|
private static AetheriaRuntimeAssetRef Texture(string key, string resourcePath)
|
|
{
|
|
return CultMeshAssetRef(
|
|
key,
|
|
AetheriaRuntimeAssetKinds.Texture,
|
|
resourcePath,
|
|
"image/*");
|
|
}
|
|
|
|
private static AetheriaRuntimeAssetRef Prefab(string key, string resourcePath)
|
|
{
|
|
return CultMeshAssetRef(
|
|
key,
|
|
AetheriaRuntimeAssetKinds.Prefab,
|
|
resourcePath,
|
|
"application/vnd.unity.prefab");
|
|
}
|
|
|
|
private static AetheriaRuntimeAssetRef CultMeshAssetRef(
|
|
string key,
|
|
string kind,
|
|
string resourcePath,
|
|
string mimeType)
|
|
{
|
|
var normalizedResourcePath = NormalizeResourcePath(resourcePath);
|
|
return new AetheriaRuntimeAssetRef
|
|
{
|
|
AssetKey = key ?? "",
|
|
Kind = kind ?? "",
|
|
Uri = CultMeshAssetUri(key),
|
|
Transport = AetheriaRuntimeAssetTransports.CultMesh,
|
|
MimeType = mimeType ?? "",
|
|
Metadata = string.IsNullOrWhiteSpace(normalizedResourcePath)
|
|
? new Dictionary<string, string>()
|
|
: new Dictionary<string, string>(StringComparer.Ordinal)
|
|
{
|
|
["resourcesPath"] = normalizedResourcePath
|
|
}
|
|
};
|
|
}
|
|
|
|
private static string CultMeshAssetUri(string key)
|
|
{
|
|
var path = (key ?? "").Trim().Replace('.', '/').Replace('\\', '/').Trim('/');
|
|
return $"cultmesh://aetheria/assets/{path}";
|
|
}
|
|
|
|
private static string NormalizeResourcePath(string path)
|
|
{
|
|
path ??= "";
|
|
const string resourcesPrefix = "Assets/Resources/";
|
|
if (path.StartsWith(resourcesPrefix, StringComparison.OrdinalIgnoreCase))
|
|
path = path.Substring(resourcesPrefix.Length);
|
|
|
|
var extensionIndex = path.LastIndexOf('.');
|
|
if (extensionIndex > 0)
|
|
path = path.Substring(0, extensionIndex);
|
|
|
|
return path.Replace('\\', '/').Trim('/');
|
|
}
|
|
|
|
private static void Add(
|
|
Dictionary<string, AetheriaRuntimeAssetManifestEntry> entries,
|
|
AetheriaRuntimeAssetManifestEntry entry)
|
|
{
|
|
var key = entry.Ref?.AssetKey ?? "";
|
|
if (key.Length == 0)
|
|
return;
|
|
|
|
entries[key] = entry;
|
|
}
|
|
}
|
|
}
|