Ship S2: the game composes and loads mod ships
Boot opens the derived catalog when GameData/Mods holds packages (ShipModCatalog.ResolveCatalog), preloads each hull's GLB into an assembled inactive prototype (ShipModShips), and LoadEntity clones it when the hull names a Visual. ShipModPlan decides which anchor fills which ShipInstance slot; a ShipModTemplate prefab carries the shared effects. Continue refuses a run that names a design the catalog no longer holds (RunSave.RequireDesigns). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
f470c1b775
commit
460bb85ed0
16 changed files with 702 additions and 13 deletions
|
|
@ -91,6 +91,28 @@ public static class RunSave
|
|||
return (game, zones);
|
||||
}
|
||||
|
||||
// Continue's gate: every design a saved run names (each zone's items and each minted lot) must be one this catalog
|
||||
// holds. A run made with a mod that is no longer installed is refused, naming the mod ships, before any scene is
|
||||
// built; the save is never edited to fit.
|
||||
public static void RequireDesigns(CultCache cache, SavedGame game)
|
||||
{
|
||||
var named = (game.Zones ?? Array.Empty<CultRecordRef<SavedZone>>())
|
||||
.SelectMany(zone => cache.Get(zone)?.Contents?.Entities ?? new List<EntityPack>())
|
||||
.SelectMany(EntitySerializer.Items).Select(item => item.Data.Key)
|
||||
.Concat(Lots(cache).Lots.Values.Select(lot => lot.Design.Key))
|
||||
.Where(key => key.IsSet()).Distinct()
|
||||
.Where(key => cache.Get<ItemData>(key) == null)
|
||||
.Select(key => key.Value).OrderBy(key => key, StringComparer.Ordinal).ToArray();
|
||||
if (named.Length == 0) return;
|
||||
const string modHull = "mod-hull:";
|
||||
var mods = named.Where(key => key.StartsWith(modHull, StringComparison.Ordinal)).Select(key => key.Substring(modHull.Length)).ToArray();
|
||||
var others = named.Where(key => !key.StartsWith(modHull, StringComparison.Ordinal)).ToArray();
|
||||
throw new InvalidOperationException("This run names designs the catalog no longer holds" +
|
||||
(mods.Length > 0 ? $"; missing mod ships: {string.Join(", ", mods)}" : "") +
|
||||
(others.Length > 0 ? $"; missing other designs: {string.Join(", ", others)}" : "") +
|
||||
". Reinstall them, or start a new game.");
|
||||
}
|
||||
|
||||
// The stored ledger, or a fresh empty one when the run has minted nothing yet.
|
||||
public static ProvenanceLedger Lots(CultCache cache) => cache.GetGlobal<ProvenanceLedger>() ?? new ProvenanceLedger();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue