Ship S2 fixes: structural anchors are not mounts, mod presets refused, one bad mod never bricks the boot
- Validate: a hardpoint's anchor role is fixed by its type (thruster-emitter, radiator-mesh, else articulation); ShipModPlan's duplicate role check is deleted. - Loadouts.Commit refuses a preset naming a mod design (mod-hull:/mod-ship:), so the shipped catalog never references a mod. - Compose quarantines each package: a bad package is excluded and named, a collision excludes every package involved; the game boots on the rest (or the shipped catalog) and the main menu lists the exclusions. - RequireDesigns refuses a save with a null item or lot instead of throwing NullReferenceException. - Tests: per structural role, muzzle id ties, every slot/zone/lot in RequireDesigns, listing order, exclusion cases. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
7eebd21d29
commit
54917bb39d
13 changed files with 408 additions and 92 deletions
|
|
@ -96,13 +96,22 @@ public static class RunSave
|
|||
// 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();
|
||||
string[] named;
|
||||
try
|
||||
{
|
||||
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();
|
||||
}
|
||||
catch (NullReferenceException error)
|
||||
{
|
||||
// A save with a null entity, item or lot where one is required is malformed, and refused like a missing design.
|
||||
throw new InvalidOperationException("This run's save is malformed: an entity, item or lot is missing where one is required. Start a new game.", error);
|
||||
}
|
||||
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();
|
||||
|
|
|
|||
Loading…
Reference in a new issue