AetherDb: evasion-catalog, the literal per-weapon tracking table and plight's 1x2 Shape
One-shot, dry run unless apply, refuses a second apply. Deleted in its own commit after the catalog lands. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
db19ecfeb7
commit
1d85e1d4da
1 changed files with 110 additions and 1 deletions
|
|
@ -33,13 +33,14 @@ public static class Program
|
|||
case "brownout-migrate": return BrownoutMigrate(args.Contains("apply"));
|
||||
case "roles-migrate": return RolesMigrate(args.Contains("apply"));
|
||||
case "firing-arc-migrate": return FiringArcMigrate(args.Contains("apply"));
|
||||
case "evasion-catalog": return EvasionCatalog(args.Contains("apply"));
|
||||
case "targeting-catalog": return TargetingCatalog(args.Contains("apply"));
|
||||
case "targeting-catalog-6c": return TargetingCatalog6c(args.Contains("apply"));
|
||||
case "targeting-catalog-6d": return TargetingCatalog6d(args.Contains("apply"));
|
||||
case "ship-authoring": return ShipAuthoringCommands.Run(args.Skip(1).ToArray());
|
||||
case "field-kinds": return FieldKindsCatalog(args.Contains("apply"));
|
||||
default:
|
||||
Console.WriteLine("commands: census, factions, station-fit, hardpoint-fit, loadout [seed], save, settings, settings-dump, dangling [clear <Type.Member>]... [apply], shield-migrate [apply], brownout-migrate [apply], roles-migrate [apply], firing-arc-migrate [apply], targeting-catalog [apply], targeting-catalog-6c [apply], targeting-catalog-6d [apply], ship-authoring create|inspect|validate|compose, field-kinds [apply]");
|
||||
Console.WriteLine("commands: census, factions, station-fit, hardpoint-fit, loadout [seed], save, settings, settings-dump, dangling [clear <Type.Member>]... [apply], shield-migrate [apply], brownout-migrate [apply], roles-migrate [apply], firing-arc-migrate [apply], evasion-catalog [apply], targeting-catalog [apply], targeting-catalog-6c [apply], targeting-catalog-6d [apply], ship-authoring create|inspect|validate|compose, field-kinds [apply]");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1085,6 +1086,114 @@ public static class Program
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Evasion r6 (aetheria-release:cut_spec:cut-evasion-term.r6): authors every weapon's mount rate, in degrees per
|
||||
// second, by name, and gives plight the 1x2 Shape of Spectra (ruling plight-shape). The table is the operator's
|
||||
// authored outcome (ruling weapon-tracking-authored): nothing here reads a footprint, a caliber or a hardpoint to
|
||||
// choose a rate. Launchers and guided weapons never mount-track; they are authored +infinity. Dry run unless passed
|
||||
// "apply". Refuses a weapon without a row, a row without a record, a duplicated name, a rate authored to something
|
||||
// else, and an apply with nothing left to land (the second apply). Deleted in its own commit after apply lands: the
|
||||
// catalog is then the table's only copy.
|
||||
private static int EvasionCatalog(bool apply)
|
||||
{
|
||||
var db = AetherDb.Open(catalogWritable: apply);
|
||||
const float infinity = float.PositiveInfinity;
|
||||
var rates = new (string Name, float Rate)[]
|
||||
{
|
||||
("ClearPath", 12f), ("Spectra", 10f), ("FastBlast+-", 9f), ("Earp", 8f), ("6k Shooter", 7f),
|
||||
("ColdFire", 6f), ("Autocannon", 4f), ("ChargeBlast+-", 3.5f), ("DeathCluster", 3f), ("ChargeBlast SG", 3f),
|
||||
("pretty pretty bang bang", 3f), ("plight", 2f), ("CShot RainbowLite Lazer", 1.5f),
|
||||
("GT 3K", infinity), ("pswarm", infinity), ("scorched void policy", infinity), ("LRMM72", infinity),
|
||||
("SRMM72", infinity),
|
||||
};
|
||||
|
||||
var refusals = new List<string>();
|
||||
foreach (var group in rates.GroupBy(r => r.Name, StringComparer.Ordinal).Where(g => g.Count() > 1))
|
||||
refusals.Add($"the table names \"{group.Key}\" twice");
|
||||
|
||||
var weapons = db.Cache.GetAll<WeaponItemData>().ToArray();
|
||||
foreach (var row in rates)
|
||||
if (weapons.Count(w => w.Name == row.Name) != 1)
|
||||
refusals.Add($"table row \"{row.Name}\" matches {weapons.Count(w => w.Name == row.Name)} catalog weapons, not 1");
|
||||
foreach (var weapon in weapons)
|
||||
{
|
||||
if (rates.All(r => r.Name != weapon.Name)) refusals.Add($"catalog weapon \"{weapon.Name}\" has no row");
|
||||
if (!weapon.Behaviors.OfType<WeaponData>().Any()) refusals.Add($"catalog weapon \"{weapon.Name}\" has no weapon behaviour");
|
||||
}
|
||||
|
||||
var spectra = weapons.FirstOrDefault(w => w.Name == "Spectra");
|
||||
var plight = weapons.FirstOrDefault(w => w.Name == "plight");
|
||||
if (spectra != null && (spectra.Shape.Width != 1 || spectra.Shape.Height != 2 || !spectra.Shape.Cells[0, 0] || !spectra.Shape.Cells[0, 1]))
|
||||
refusals.Add("Spectra's Shape is not one wide, two high, both cells occupied");
|
||||
if (refusals.Count > 0)
|
||||
{
|
||||
foreach (var refusal in refusals) Console.WriteLine($"REFUSED: {refusal}");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Console.WriteLine($"{"weapon",-26} {"field",-10} {"was",-14} {"now",-14}");
|
||||
var changed = new List<(object Document, CultRecordKey Key)>();
|
||||
foreach (var (name, rate) in rates)
|
||||
{
|
||||
var weapon = weapons.Single(w => w.Name == name);
|
||||
var touched = false;
|
||||
foreach (var behavior in weapon.Behaviors.OfType<WeaponData>())
|
||||
{
|
||||
var was = behavior.Tracking;
|
||||
var label = was.Min + ".." + was.Max;
|
||||
if (was.Min == rate && was.Max == rate)
|
||||
{
|
||||
Console.WriteLine($"{name,-26} {"Tracking",-10} {label,-14} {label,-14} (already authored, left alone)");
|
||||
continue;
|
||||
}
|
||||
if (!float.IsPositiveInfinity(was.Min) || !float.IsPositiveInfinity(was.Max))
|
||||
{
|
||||
Console.WriteLine($"REFUSED: \"{name}\" Tracking is authored {label}, not the table's {rate}; the catalog was edited since");
|
||||
return 1;
|
||||
}
|
||||
behavior.Tracking = new PerformanceStat { Min = rate, Max = rate };
|
||||
Console.WriteLine($"{name,-26} {"Tracking",-10} {label,-14} {rate + ".." + rate,-14}");
|
||||
touched = true;
|
||||
}
|
||||
if (touched) changed.Add((weapon, db.Cache.RefOf(weapon).Key));
|
||||
}
|
||||
|
||||
var wasShape = $"{plight.Shape.Width}x{plight.Shape.Height}";
|
||||
if (plight.Shape.Width == spectra.Shape.Width && plight.Shape.Height == spectra.Shape.Height
|
||||
&& plight.Shape.Cells.Cast<bool>().SequenceEqual(spectra.Shape.Cells.Cast<bool>()))
|
||||
Console.WriteLine($"{"plight",-26} {"Shape",-10} {wasShape,-14} {wasShape,-14} (already Spectra's, left alone)");
|
||||
else
|
||||
{
|
||||
var copy = new Shape(spectra.Shape.Width, spectra.Shape.Height);
|
||||
for (var x = 0; x < copy.Width; x++)
|
||||
for (var y = 0; y < copy.Height; y++)
|
||||
copy.Cells[x, y] = spectra.Shape.Cells[x, y];
|
||||
plight.Shape = copy;
|
||||
Console.WriteLine($"{"plight",-26} {"Shape",-10} {wasShape,-14} {plight.Shape.Width + "x" + plight.Shape.Height,-14}");
|
||||
if (!changed.Any(c => ReferenceEquals(c.Document, plight))) changed.Add((plight, db.Cache.RefOf(plight).Key));
|
||||
}
|
||||
|
||||
Console.WriteLine($"\n{changed.Count} weapon records changed");
|
||||
if (!apply)
|
||||
{
|
||||
Console.WriteLine(changed.Count == 0 ? "Dry run. Nothing to land." : $"Dry run. Pass \"apply\" to land {changed.Count} changed records.");
|
||||
return 0;
|
||||
}
|
||||
if (changed.Count == 0)
|
||||
{
|
||||
Console.WriteLine("REFUSED: nothing to land; the catalog already carries the table.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
foreach (var (document, _) in changed) CultRecordRefs.Validate(document);
|
||||
db.Cache.Commit(batch =>
|
||||
{
|
||||
foreach (var (document, key) in changed) batch.Upsert(document.GetType(), document, key);
|
||||
});
|
||||
Console.WriteLine($"Landed {changed.Count} changed records in Aetheria.cc");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Fire control Cut 6a (docs/fire-control-cut.md, Cut 2's "Catalog:" bullet). Cut 2 shipped the behaviour and
|
||||
// never shipped the data: no targeting-system design exists, so tools/AetherDb loadout throws
|
||||
// InvalidLoadoutException ("No compatible targeting system found for entity!") for every armed hull. This
|
||||
|
|
|
|||
Loading…
Reference in a new issue