Sweep: every old design-name literal in C# becomes its generic name; product texts ship without the authoring notes
Scenarios, tests, AetherDb templates and name-keyed maps now resolve designs by the generic names (231 literals in 30 files); TargetingCatalog's product texts lose the authoring note, Steadfast carries its r3 text, DragOnBreath plight's old design text. Not built yet; tests that depend on the generic-designs command and new tests follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
37acc6bbc3
commit
f7cf3257d0
30 changed files with 212 additions and 212 deletions
|
|
@ -20,13 +20,13 @@ public sealed class AiFusedDiscipline : Scenario
|
|||
("Cockpit 2x2", int2(2, 6), None),
|
||||
("Large Drive", int2(1, 0), Reversed),
|
||||
("Large Drive", int2(3, 0), Reversed),
|
||||
("Talaria", int2(2, 14), CounterClockwise),
|
||||
("Talaria", int2(3, 14), Clockwise),
|
||||
("Core Power", int2(2, 4), None),
|
||||
("Rugged Drive", int2(2, 14), CounterClockwise),
|
||||
("Rugged Drive", int2(3, 14), Clockwise),
|
||||
("Compact Reactor", int2(2, 4), None),
|
||||
(weapon, int2(1, 8), None),
|
||||
("Iapyx", int2(2, 2), CounterClockwise),
|
||||
("Iapyx", int2(3, 2), Clockwise),
|
||||
("not if i see you first", int2(3, 10), None),
|
||||
("Radiator", int2(2, 2), CounterClockwise),
|
||||
("Radiator", int2(3, 2), Clockwise),
|
||||
("Compact Sensor", int2(3, 10), None),
|
||||
("Fire Control Array", int2(1, 6), Clockwise));
|
||||
|
||||
stage.Player(stage.Generated("Djinni"), float2(0, 0));
|
||||
|
|
|
|||
|
|
@ -27,27 +27,27 @@ public sealed class Arcs : Scenario
|
|||
("Cockpit 2x2", int2(4, 6), None),
|
||||
("Large Drive", int2(3, 0), Reversed),
|
||||
("Large Drive", int2(5, 0), Reversed),
|
||||
("Talaria", int2(4, 14), CounterClockwise),
|
||||
("Talaria", int2(5, 14), Clockwise),
|
||||
("Core Power", int2(4, 4), None),
|
||||
("GT 3K", int2(2, 5), None),
|
||||
("GT 3K", int2(7, 5), None),
|
||||
("FastBlast+-", int2(3, 8), None),
|
||||
("FastBlast+-", int2(6, 8), None),
|
||||
("Iapyx", int2(4, 2), CounterClockwise),
|
||||
("Iapyx", int2(5, 2), Clockwise),
|
||||
("not if i see you first", int2(5, 10), None),
|
||||
("Rugged Drive", int2(4, 14), CounterClockwise),
|
||||
("Rugged Drive", int2(5, 14), Clockwise),
|
||||
("Compact Reactor", int2(4, 4), None),
|
||||
("Guided Missile Launcher", int2(2, 5), None),
|
||||
("Guided Missile Launcher", int2(7, 5), None),
|
||||
("Cell Blaster", int2(3, 8), None),
|
||||
("Cell Blaster", int2(6, 8), None),
|
||||
("Radiator", int2(4, 2), CounterClockwise),
|
||||
("Radiator", int2(5, 2), Clockwise),
|
||||
("Compact Sensor", int2(5, 10), None),
|
||||
("Fire Control Array", int2(3, 6), Clockwise),
|
||||
("Autocannon", int2(8, 4), Clockwise),
|
||||
("ChargeBlast SG", int2(0, 4), CounterClockwise));
|
||||
("Charged Scatter Blaster", int2(0, 4), CounterClockwise));
|
||||
var turret = stage.Fit("Turret",
|
||||
("ClearPath", int2(1, 2), None),
|
||||
("ClearPath", int2(5, 2), None),
|
||||
("Skiron", int2(0, 2), CounterClockwise),
|
||||
("Skiron", int2(7, 2), Clockwise),
|
||||
("Core Power", int2(3, 3), None),
|
||||
("Light Machine Gun", int2(1, 2), None),
|
||||
("Light Machine Gun", int2(5, 2), None),
|
||||
("Long Radiator", int2(0, 2), CounterClockwise),
|
||||
("Long Radiator", int2(7, 2), Clockwise),
|
||||
("Compact Reactor", int2(3, 3), None),
|
||||
("Turret Control Module", int2(3, 5), None),
|
||||
("not if i see you first", int2(4, 5), None),
|
||||
("Compact Sensor", int2(4, 5), None),
|
||||
("Fire Control Array", int2(3, 6), None));
|
||||
|
||||
stage.Player(fighter, float2(0, 0), facing: float2(0, 1));
|
||||
|
|
|
|||
|
|
@ -23,16 +23,16 @@ public sealed class Belt : Scenario
|
|||
("Cockpit 2x2", int2(2, 6), None),
|
||||
("Large Drive", int2(1, 0), Reversed),
|
||||
("Large Drive", int2(3, 0), Reversed),
|
||||
("Talaria", int2(2, 14), CounterClockwise),
|
||||
("Talaria", int2(3, 14), Clockwise),
|
||||
("Core Power", int2(2, 4), None),
|
||||
("GT 3K", int2(0, 5), None),
|
||||
("GT 3K", int2(5, 5), None),
|
||||
("plight", int2(1, 8), None),
|
||||
("FastBlast+-", int2(4, 8), None),
|
||||
("Iapyx", int2(2, 2), CounterClockwise),
|
||||
("Iapyx", int2(3, 2), Clockwise),
|
||||
("not if i see you first", int2(3, 10), None),
|
||||
("Rugged Drive", int2(2, 14), CounterClockwise),
|
||||
("Rugged Drive", int2(3, 14), Clockwise),
|
||||
("Compact Reactor", int2(2, 4), None),
|
||||
("Guided Missile Launcher", int2(0, 5), None),
|
||||
("Guided Missile Launcher", int2(5, 5), None),
|
||||
("Lightning Projector", int2(1, 8), None),
|
||||
("Cell Blaster", int2(4, 8), None),
|
||||
("Radiator", int2(2, 2), CounterClockwise),
|
||||
("Radiator", int2(3, 2), Clockwise),
|
||||
("Compact Sensor", int2(3, 10), None),
|
||||
("Fire Control Array", int2(1, 6), Clockwise));
|
||||
|
||||
// The belt is a ring about its parent's position at the belt orbit's distance. The player stands 100 m outside
|
||||
|
|
|
|||
|
|
@ -27,16 +27,16 @@ public sealed class Crossing : Scenario
|
|||
("Cockpit 2x2", int2(2, 6), None),
|
||||
("Large Drive", int2(1, 0), Reversed),
|
||||
("Large Drive", int2(3, 0), Reversed),
|
||||
("Talaria", int2(2, 14), CounterClockwise),
|
||||
("Talaria", int2(3, 14), Clockwise),
|
||||
("Core Power", int2(2, 4), None),
|
||||
("GT 3K", int2(0, 5), None),
|
||||
("GT 3K", int2(5, 5), None),
|
||||
("plight", int2(1, 8), None),
|
||||
("FastBlast+-", int2(4, 8), None),
|
||||
("Iapyx", int2(2, 2), CounterClockwise),
|
||||
("Iapyx", int2(3, 2), Clockwise),
|
||||
("not if i see you first", int2(3, 10), None),
|
||||
("Rugged Drive", int2(2, 14), CounterClockwise),
|
||||
("Rugged Drive", int2(3, 14), Clockwise),
|
||||
("Compact Reactor", int2(2, 4), None),
|
||||
("Guided Missile Launcher", int2(0, 5), None),
|
||||
("Guided Missile Launcher", int2(5, 5), None),
|
||||
("Lightning Projector", int2(1, 8), None),
|
||||
("Cell Blaster", int2(4, 8), None),
|
||||
("Radiator", int2(2, 2), CounterClockwise),
|
||||
("Radiator", int2(3, 2), Clockwise),
|
||||
("Compact Sensor", int2(3, 10), None),
|
||||
("Fire Control Array", int2(1, 6), Clockwise));
|
||||
|
||||
stage.Player(fighter, float2(0, 0), facing: float2(0, 1));
|
||||
|
|
|
|||
|
|
@ -17,22 +17,22 @@ public sealed class Duel : Scenario
|
|||
("Cockpit 2x2", int2(2, 6), None),
|
||||
("Large Drive", int2(1, 0), Reversed),
|
||||
("Large Drive", int2(3, 0), Reversed),
|
||||
("Talaria", int2(2, 14), CounterClockwise),
|
||||
("Talaria", int2(3, 14), Clockwise),
|
||||
("Core Power", int2(2, 4), None),
|
||||
("GT 3K", int2(0, 5), None),
|
||||
("GT 3K", int2(5, 5), None),
|
||||
("FastBlast+-", int2(1, 8), None),
|
||||
("FastBlast+-", int2(4, 8), None),
|
||||
("Iapyx", int2(2, 2), CounterClockwise),
|
||||
("Iapyx", int2(3, 2), Clockwise),
|
||||
("not if i see you first", int2(3, 10), None),
|
||||
("PotaT+-", int2(1, 5), None),
|
||||
("Rugged Drive", int2(2, 14), CounterClockwise),
|
||||
("Rugged Drive", int2(3, 14), Clockwise),
|
||||
("Compact Reactor", int2(2, 4), None),
|
||||
("Guided Missile Launcher", int2(0, 5), None),
|
||||
("Guided Missile Launcher", int2(5, 5), None),
|
||||
("Cell Blaster", int2(1, 8), None),
|
||||
("Cell Blaster", int2(4, 8), None),
|
||||
("Radiator", int2(2, 2), CounterClockwise),
|
||||
("Radiator", int2(3, 2), Clockwise),
|
||||
("Compact Sensor", int2(3, 10), None),
|
||||
("Capacitor", int2(1, 5), None),
|
||||
("Fire Control Array", int2(1, 6), Clockwise),
|
||||
("Store-All Plus", int2(2, 8), None));
|
||||
("Cargo Bay", int2(2, 8), None));
|
||||
|
||||
stage.Player(fighter, float2(0, 0));
|
||||
var rival = stage.Place(fighter, float2(0, 900), facing: float2(0, -1), stance: ScenarioStance.Hostile, piloted: true);
|
||||
stage.Cargo(rival, "Spectra");
|
||||
stage.Cargo(rival, "Light Laser");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,15 +30,15 @@ public sealed class FusedRounds : Scenario
|
|||
("Cockpit 2x2", int2(4, 6), None),
|
||||
("Large Drive", int2(3, 0), Reversed),
|
||||
("Large Drive", int2(5, 0), Reversed),
|
||||
("Talaria", int2(4, 14), CounterClockwise),
|
||||
("Talaria", int2(5, 14), Clockwise),
|
||||
("Core Power", int2(4, 4), None),
|
||||
("Rugged Drive", int2(4, 14), CounterClockwise),
|
||||
("Rugged Drive", int2(5, 14), Clockwise),
|
||||
("Compact Reactor", int2(4, 4), None),
|
||||
("Smoke Proximity", int2(3, 8), None),
|
||||
("Smoke Delayed", int2(6, 8), None),
|
||||
("DeathCluster", int2(5, 17), None),
|
||||
("Iapyx", int2(4, 2), CounterClockwise),
|
||||
("Iapyx", int2(5, 2), Clockwise),
|
||||
("not if i see you first", int2(5, 10), None),
|
||||
("Cluster Cannon", int2(5, 17), None),
|
||||
("Radiator", int2(4, 2), CounterClockwise),
|
||||
("Radiator", int2(5, 2), Clockwise),
|
||||
("Compact Sensor", int2(5, 10), None),
|
||||
("Fire Control Array", int2(3, 6), Clockwise));
|
||||
|
||||
stage.Player(shooter, float2(0, 0), facing: float2(0, 1));
|
||||
|
|
|
|||
|
|
@ -17,16 +17,16 @@ public sealed class LauncherAngles : Scenario
|
|||
("Cockpit 2x2", int2(2, 6), None),
|
||||
("Large Drive", int2(1, 0), Reversed),
|
||||
("Large Drive", int2(3, 0), Reversed),
|
||||
("Talaria", int2(2, 14), CounterClockwise),
|
||||
("Talaria", int2(3, 14), Clockwise),
|
||||
("Core Power", int2(2, 4), None),
|
||||
("GT 3K", int2(0, 5), None),
|
||||
("pswarm", int2(5, 5), None),
|
||||
("FastBlast+-", int2(1, 8), None),
|
||||
("FastBlast+-", int2(4, 8), None),
|
||||
("Iapyx", int2(2, 2), CounterClockwise),
|
||||
("Iapyx", int2(3, 2), Clockwise),
|
||||
("not if i see you first", int2(3, 10), None),
|
||||
("Rugged Drive", int2(2, 14), CounterClockwise),
|
||||
("Rugged Drive", int2(3, 14), Clockwise),
|
||||
("Compact Reactor", int2(2, 4), None),
|
||||
("Guided Missile Launcher", int2(0, 5), None),
|
||||
("Swarm Rocket Pod", int2(5, 5), None),
|
||||
("Cell Blaster", int2(1, 8), None),
|
||||
("Cell Blaster", int2(4, 8), None),
|
||||
("Radiator", int2(2, 2), CounterClockwise),
|
||||
("Radiator", int2(3, 2), Clockwise),
|
||||
("Compact Sensor", int2(3, 10), None),
|
||||
("Fire Control Array", int2(1, 6), Clockwise));
|
||||
|
||||
stage.Player(launcher, float2(0, 0));
|
||||
|
|
|
|||
|
|
@ -23,35 +23,35 @@ public sealed class Pursuit : Scenario
|
|||
("Cockpit 2x2", int2(2, 6), None),
|
||||
("Large Drive", int2(1, 0), Reversed),
|
||||
("Large Drive", int2(3, 0), Reversed),
|
||||
("Talaria", int2(2, 14), CounterClockwise),
|
||||
("Talaria", int2(3, 14), Clockwise),
|
||||
("Core Power", int2(2, 4), None),
|
||||
("Rugged Drive", int2(2, 14), CounterClockwise),
|
||||
("Rugged Drive", int2(3, 14), Clockwise),
|
||||
("Compact Reactor", int2(2, 4), None),
|
||||
("Mine Launcher", int2(0, 5), None),
|
||||
("pswarm", int2(5, 5), None),
|
||||
("FastBlast+-", int2(1, 8), None),
|
||||
("FastBlast+-", int2(4, 8), None),
|
||||
("Iapyx", int2(2, 2), CounterClockwise),
|
||||
("Iapyx", int2(3, 2), Clockwise),
|
||||
("not if i see you first", int2(3, 10), None),
|
||||
("Swarm Rocket Pod", int2(5, 5), None),
|
||||
("Cell Blaster", int2(1, 8), None),
|
||||
("Cell Blaster", int2(4, 8), None),
|
||||
("Radiator", int2(2, 2), CounterClockwise),
|
||||
("Radiator", int2(3, 2), Clockwise),
|
||||
("Compact Sensor", int2(3, 10), None),
|
||||
("Fire Control Array", int2(1, 6), Clockwise),
|
||||
("Store-All Plus", int2(2, 8), None));
|
||||
("Cargo Bay", int2(2, 8), None));
|
||||
var pursuer = stage.Fit("Longinus",
|
||||
("Cockpit 2x2", int2(2, 6), None),
|
||||
("Large Drive", int2(1, 0), Reversed),
|
||||
("Large Drive", int2(3, 0), Reversed),
|
||||
("Talaria", int2(2, 14), CounterClockwise),
|
||||
("Talaria", int2(3, 14), Clockwise),
|
||||
("Core Power", int2(2, 4), None),
|
||||
("GT 3K", int2(0, 5), None),
|
||||
("GT 3K", int2(5, 5), None),
|
||||
("FastBlast+-", int2(1, 8), None),
|
||||
("FastBlast+-", int2(4, 8), None),
|
||||
("Iapyx", int2(2, 2), CounterClockwise),
|
||||
("Iapyx", int2(3, 2), Clockwise),
|
||||
("not if i see you first", int2(3, 10), None),
|
||||
("PotaT+-", int2(1, 5), None),
|
||||
("Rugged Drive", int2(2, 14), CounterClockwise),
|
||||
("Rugged Drive", int2(3, 14), Clockwise),
|
||||
("Compact Reactor", int2(2, 4), None),
|
||||
("Guided Missile Launcher", int2(0, 5), None),
|
||||
("Guided Missile Launcher", int2(5, 5), None),
|
||||
("Cell Blaster", int2(1, 8), None),
|
||||
("Cell Blaster", int2(4, 8), None),
|
||||
("Radiator", int2(2, 2), CounterClockwise),
|
||||
("Radiator", int2(3, 2), Clockwise),
|
||||
("Compact Sensor", int2(3, 10), None),
|
||||
("Capacitor", int2(1, 5), None),
|
||||
("Fire Control Array", int2(1, 6), Clockwise),
|
||||
("Store-All Plus", int2(2, 8), None));
|
||||
("Cargo Bay", int2(2, 8), None));
|
||||
|
||||
var player = stage.Player(layer, float2(0, 0), facing: float2(0, 1));
|
||||
stage.Cargo(player, "Coolant Vent", "Coolant Vent", "Coolant Vent", "Thruster Overdrive", "Thruster Overdrive");
|
||||
|
|
|
|||
|
|
@ -22,16 +22,16 @@ public sealed class RefusedRounds : Scenario
|
|||
("Cockpit 2x2", int2(4, 6), None),
|
||||
("Large Drive", int2(3, 0), Reversed),
|
||||
("Large Drive", int2(5, 0), Reversed),
|
||||
("Talaria", int2(4, 14), CounterClockwise),
|
||||
("Talaria", int2(5, 14), Clockwise),
|
||||
("Core Power", int2(4, 4), None),
|
||||
("Rugged Drive", int2(4, 14), CounterClockwise),
|
||||
("Rugged Drive", int2(5, 14), Clockwise),
|
||||
("Compact Reactor", int2(4, 4), None),
|
||||
("Smoke Refused", int2(3, 8), None),
|
||||
("Smoke Refused Beam", int2(6, 8), None),
|
||||
("Smoke Refused Charge", int2(3, 17), None),
|
||||
("Autocannon", int2(5, 17), None),
|
||||
("Iapyx", int2(4, 2), CounterClockwise),
|
||||
("Iapyx", int2(5, 2), Clockwise),
|
||||
("not if i see you first", int2(5, 10), None),
|
||||
("Radiator", int2(4, 2), CounterClockwise),
|
||||
("Radiator", int2(5, 2), Clockwise),
|
||||
("Compact Sensor", int2(5, 10), None),
|
||||
("Fire Control Array", int2(3, 6), Clockwise));
|
||||
|
||||
stage.Player(shooter, float2(0, 0), facing: float2(0, 1));
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@ public sealed class StarvedReactor : Scenario
|
|||
("Cockpit 2x2", int2(2, 6), None),
|
||||
("Large Drive", int2(1, 0), Reversed),
|
||||
("Large Drive", int2(3, 0), Reversed),
|
||||
("Talaria", int2(2, 14), CounterClockwise),
|
||||
("Talaria", int2(3, 14), Clockwise),
|
||||
("MoveOnPro", int2(2, 4), None),
|
||||
("Spectra", int2(1, 8), None),
|
||||
("Spectra", int2(4, 8), None),
|
||||
("Iapyx", int2(2, 2), CounterClockwise),
|
||||
("Iapyx", int2(3, 2), Clockwise),
|
||||
("not if i see you first", int2(3, 10), None),
|
||||
("Rugged Drive", int2(2, 14), CounterClockwise),
|
||||
("Rugged Drive", int2(3, 14), Clockwise),
|
||||
("Muon Fusion Reactor", int2(2, 4), None),
|
||||
("Light Laser", int2(1, 8), None),
|
||||
("Light Laser", int2(4, 8), None),
|
||||
("Radiator", int2(2, 2), CounterClockwise),
|
||||
("Radiator", int2(3, 2), Clockwise),
|
||||
("Compact Sensor", int2(3, 10), None),
|
||||
("Fire Control Array", int2(1, 6), Clockwise));
|
||||
stage.Player(starved, float2(0, 0));
|
||||
stage.Place(stage.Bare("Longinus"), float2(0, 400));
|
||||
|
|
|
|||
|
|
@ -21,15 +21,15 @@ public sealed class WeaponFeel : Scenario
|
|||
("Cockpit 2x2", int2(4, 6), None),
|
||||
("Large Drive", int2(3, 0), Reversed),
|
||||
("Large Drive", int2(5, 0), Reversed),
|
||||
("Talaria", int2(4, 14), CounterClockwise),
|
||||
("Talaria", int2(5, 14), Clockwise),
|
||||
("Core Power", int2(4, 4), None),
|
||||
("ChargeBlast SG", int2(3, 17), None),
|
||||
("Rugged Drive", int2(4, 14), CounterClockwise),
|
||||
("Rugged Drive", int2(5, 14), Clockwise),
|
||||
("Compact Reactor", int2(4, 4), None),
|
||||
("Charged Scatter Blaster", int2(3, 17), None),
|
||||
("Autocannon", int2(5, 17), None),
|
||||
("FastBlast+-", int2(3, 8), None),
|
||||
("Iapyx", int2(4, 2), CounterClockwise),
|
||||
("Iapyx", int2(5, 2), Clockwise),
|
||||
("not if i see you first", int2(5, 10), None),
|
||||
("Cell Blaster", int2(3, 8), None),
|
||||
("Radiator", int2(4, 2), CounterClockwise),
|
||||
("Radiator", int2(5, 2), Clockwise),
|
||||
("Compact Sensor", int2(5, 10), None),
|
||||
("Fire Control Array", int2(3, 6), Clockwise));
|
||||
|
||||
stage.Player(shooter, float2(0, 0), facing: float2(0, 1));
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ using static CultMath.math;
|
|||
// (to decide whether the pump can keep up this tick). Cut 7 asks for the brownout curve to live on exactly
|
||||
// the stats the behaviour actually curves (PumpedHeat), but F6 forbade a PowerSupply term on any
|
||||
// stat a request reads at all, on pain of the exact oscillation Soul measured against the shipped catalog's own
|
||||
// "OK Disperser" radiator (SOUL_RadiatorRequestDependsOnItsOwnGrantAndOscillates, docs/stats-and-power-cut.md).
|
||||
// "Heat Pump" radiator (SOUL_RadiatorRequestDependsOnItsOwnGrantAndOscillates, docs/stats-and-power-cut.md).
|
||||
// The six tests below that authored one were marked Skip rather than deleted or silently reworked to hide the
|
||||
// gap, naming the conflict as real, scoped work for a future pass rather than a fix a registry correction should
|
||||
// smuggle in.
|
||||
|
|
|
|||
|
|
@ -121,13 +121,13 @@ public sealed class CatalogRoleTests
|
|||
AssertRange(autocannon, "Range", false, "barrel");
|
||||
AssertRange(autocannon, "Penetration", false, "barrel");
|
||||
|
||||
var lrm = Design("LRMM72");
|
||||
var lrm = Design("Long-Range Missile Rack");
|
||||
Assert.Equal(new[] { "guidance system", "thruster", "warhead" }, Roles(lrm));
|
||||
AssertRange(lrm, "Damage", false, "warhead");
|
||||
AssertRange(lrm, "Cooldown", true, "guidance system");
|
||||
AssertRange(lrm, "LockAngle", false, "guidance system");
|
||||
|
||||
var srm = Design("SRMM72");
|
||||
var srm = Design("Short-Range Missile Rack");
|
||||
Assert.Equal(new[] { "guidance system", "thruster", "warhead" }, Roles(srm));
|
||||
AssertRange(srm, "Damage", false, "warhead");
|
||||
AssertRange(srm, "Cooldown", true, "guidance system");
|
||||
|
|
@ -152,12 +152,12 @@ public sealed class CatalogRoleTests
|
|||
AssertRange(Design("Small Drive"), "Thrust", false, "nozzle");
|
||||
|
||||
// Designs whose non-flat stats named no role are pointed at the role their kind's map gives them.
|
||||
AssertNamed(Design("DeathCluster"), "Count", "feed mechanism");
|
||||
AssertNamed(Design("Cluster Cannon"), "Count", "feed mechanism");
|
||||
AssertNamed(Design("Flak Gun"), "Count", "feed mechanism");
|
||||
AssertNamed(Design("GT 3K"), "MinRange", "guidance system");
|
||||
AssertNamed(Design("plight"), "DamageSpread", "focusing array");
|
||||
AssertNamed(Design("MoveOnPro"), "Modifier", "core");
|
||||
AssertNamed(Design("MoveOnPro Station Reactor"), "Modifier", "core");
|
||||
AssertNamed(Design("Guided Missile Launcher"), "MinRange", "guidance system");
|
||||
AssertNamed(Design("Lightning Projector"), "DamageSpread", "focusing array");
|
||||
AssertNamed(Design("Muon Fusion Reactor"), "Modifier", "core");
|
||||
AssertNamed(Design("Muon Fusion Station Reactor"), "Modifier", "core");
|
||||
|
||||
// Each seller's means come from its maker's profile; the Pirates are middling and inconsistent.
|
||||
var profiles = new Dictionary<string, (float Mean, float Dev)>
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ public sealed partial class RunStartTests
|
|||
Assert.Equal(4, galaxy.HomeZones.Count);
|
||||
|
||||
var player = staged.Player;
|
||||
var plight = player.Equipment.Single(item => item.Data.Name == "plight");
|
||||
var small = player.Equipment.Single(item => item.Data.Name == "FastBlast+-");
|
||||
var plight = player.Equipment.Single(item => item.Data.Name == "Lightning Projector");
|
||||
var small = player.Equipment.Single(item => item.Data.Name == "Cell Blaster");
|
||||
Assert.Contains(player.Equipment, item => item.Data.Name == "Fire Control Array");
|
||||
var groupOf = new System.Func<EquippedItem, int>(item => System.Array.FindIndex(player.WeaponGroups, group => group.items.Contains(item)));
|
||||
Assert.True(groupOf(plight) >= 0 && groupOf(small) >= 0, "both guns are in a weapon group");
|
||||
|
|
|
|||
|
|
@ -24,14 +24,14 @@ public sealed partial class RunStartTests
|
|||
|
||||
// The Duel's guns on a Longinus: the generated Longinus's thrusters (two Large Drive forward, two Talaria on the
|
||||
// flanks) and power, its Targeting Computer, and the Duel's cockpit, guns, launchers and sensor.
|
||||
private static ScenarioFit EvLonginus(ScenarioStage stage, string gun = "FastBlast+-", string second = null) => stage.Fit("Longinus",
|
||||
("Cockpit 2x2", int2(2, 6), ItemRotation.None), ("Core Power", int2(2, 4), ItemRotation.None),
|
||||
private static ScenarioFit EvLonginus(ScenarioStage stage, string gun = "Cell Blaster", string second = null) => stage.Fit("Longinus",
|
||||
("Cockpit 2x2", int2(2, 6), ItemRotation.None), ("Compact Reactor", int2(2, 4), ItemRotation.None),
|
||||
("Large Drive", int2(1, 0), ItemRotation.Reversed), ("Large Drive", int2(3, 0), ItemRotation.Reversed),
|
||||
("Talaria", int2(2, 14), ItemRotation.CounterClockwise), ("Talaria", int2(3, 14), ItemRotation.Clockwise),
|
||||
("GT 3K", int2(0, 5), ItemRotation.None), ("GT 3K", int2(5, 5), ItemRotation.None), (gun, int2(1, 8), ItemRotation.None),
|
||||
(second ?? gun, int2(4, 8), ItemRotation.None), ("Iapyx", int2(2, 2), ItemRotation.CounterClockwise), ("Iapyx", int2(3, 2), ItemRotation.Clockwise),
|
||||
("not if i see you first", int2(3, 10), ItemRotation.None), ("PotaT+-", int2(1, 6), ItemRotation.None),
|
||||
("Targeting Computer", int2(1, 7), ItemRotation.None), ("Store-All Plus", int2(2, 8), ItemRotation.None));
|
||||
("Rugged Drive", int2(2, 14), ItemRotation.CounterClockwise), ("Rugged Drive", int2(3, 14), ItemRotation.Clockwise),
|
||||
("Guided Missile Launcher", int2(0, 5), ItemRotation.None), ("Guided Missile Launcher", int2(5, 5), ItemRotation.None), (gun, int2(1, 8), ItemRotation.None),
|
||||
(second ?? gun, int2(4, 8), ItemRotation.None), ("Radiator", int2(2, 2), ItemRotation.CounterClockwise), ("Radiator", int2(3, 2), ItemRotation.Clockwise),
|
||||
("Compact Sensor", int2(3, 10), ItemRotation.None), ("Capacitor", int2(1, 6), ItemRotation.None),
|
||||
("Targeting Computer", int2(1, 7), ItemRotation.None), ("Cargo Bay", int2(2, 8), ItemRotation.None));
|
||||
|
||||
// The catalog's two generated ships, far apart in the fixture arena, at the fixture seed.
|
||||
private (Zone arena, Ship longinus, Ship djinni) EvFleet()
|
||||
|
|
@ -349,7 +349,7 @@ public sealed partial class RunStartTests
|
|||
var settings = _items.GameplaySettings;
|
||||
var thrusters = longinus.GetBehaviors<Thruster>().Where(t => t.Item.Active.Value).ToList();
|
||||
var largeDrives = thrusters.Where(t => t.Item.Data.Name == "Large Drive").ToList();
|
||||
var flanks = thrusters.Where(t => t.Item.Data.Name == "Talaria").ToList();
|
||||
var flanks = thrusters.Where(t => t.Item.Data.Name == "Rugged Drive").ToList();
|
||||
Assert.Equal(2, largeDrives.Count);
|
||||
Assert.Equal(2, flanks.Count);
|
||||
|
||||
|
|
@ -584,13 +584,13 @@ public sealed partial class RunStartTests
|
|||
// reactor, cockpit and radiators. What the evasion tests price is this ship's strafing, not whatever the generator
|
||||
// rolls for it from the galaxy.
|
||||
private static ScenarioFit EvDjinni(ScenarioStage stage) => stage.Fit("Djinni",
|
||||
("Cockpit 2x2", int2(6, 3), ItemRotation.None), ("Core Power", int2(6, 11), ItemRotation.None),
|
||||
("Talaria", int2(6, 0), ItemRotation.Reversed), ("Talaria", int2(5, 1), ItemRotation.Reversed), ("Talaria", int2(7, 1), ItemRotation.Reversed),
|
||||
("Talaria", int2(4, 4), ItemRotation.CounterClockwise), ("Talaria", int2(4, 11), ItemRotation.CounterClockwise),
|
||||
("Talaria", int2(9, 4), ItemRotation.Clockwise), ("Talaria", int2(9, 11), ItemRotation.Clockwise),
|
||||
("Talaria", int2(6, 14), ItemRotation.None),
|
||||
("Iapyx", int2(1, 4), ItemRotation.Reversed), ("Iapyx", int2(3, 1), ItemRotation.Reversed),
|
||||
("Iapyx", int2(9, 1), ItemRotation.Reversed), ("Iapyx", int2(11, 4), ItemRotation.Reversed));
|
||||
("Cockpit 2x2", int2(6, 3), ItemRotation.None), ("Compact Reactor", int2(6, 11), ItemRotation.None),
|
||||
("Rugged Drive", int2(6, 0), ItemRotation.Reversed), ("Rugged Drive", int2(5, 1), ItemRotation.Reversed), ("Rugged Drive", int2(7, 1), ItemRotation.Reversed),
|
||||
("Rugged Drive", int2(4, 4), ItemRotation.CounterClockwise), ("Rugged Drive", int2(4, 11), ItemRotation.CounterClockwise),
|
||||
("Rugged Drive", int2(9, 4), ItemRotation.Clockwise), ("Rugged Drive", int2(9, 11), ItemRotation.Clockwise),
|
||||
("Rugged Drive", int2(6, 14), ItemRotation.None),
|
||||
("Radiator", int2(1, 4), ItemRotation.Reversed), ("Radiator", int2(3, 1), ItemRotation.Reversed),
|
||||
("Radiator", int2(9, 1), ItemRotation.Reversed), ("Radiator", int2(11, 4), ItemRotation.Reversed));
|
||||
|
||||
private EvRange EvRangeLaunch()
|
||||
{
|
||||
|
|
@ -598,9 +598,9 @@ public sealed partial class RunStartTests
|
|||
var scenario = new Scripted(false, stage =>
|
||||
{
|
||||
stage.Player(stage.Bare("Djinni"), float2(-50000, -50000));
|
||||
gunner = stage.Place(EvLonginus(stage, "FastBlast+-", "ColdFire"), float2(0, 0), facing: float2(0, 1)) as Ship;
|
||||
gunner = stage.Place(EvLonginus(stage, "Cell Blaster", "Long Laser"), float2(0, 0), facing: float2(0, 1)) as Ship;
|
||||
target = stage.Place(EvDjinni(stage), float2(0, 200), facing: float2(0, 1)) as Ship;
|
||||
lasing = stage.Place(EvLonginus(stage, "ColdFire"), float2(0, 400), facing: float2(0, -1)) as Ship;
|
||||
lasing = stage.Place(EvLonginus(stage, "Long Laser"), float2(0, 400), facing: float2(0, -1)) as Ship;
|
||||
});
|
||||
var (_, arena, _, failures) = Launch(scenario, Inputs(() => GalaxySeed));
|
||||
Assert.True(failures.Count == 0, string.Join("; ", failures));
|
||||
|
|
|
|||
|
|
@ -367,8 +367,8 @@ public sealed partial class RunStartTests
|
|||
{
|
||||
("Point Defense Gun", 40f, 80000, 60f, WeaponModifiers.RapidFire, (1.5f, 4f), (1f, 1f), (300f, 550f), (.06f, .025f), (1f, .3f),
|
||||
(1100f, 1600f), (.4f, .2f), (40f, 15f), (400f, 150f), true, 250, 3f),
|
||||
("Point Defense Laser", 30f, 110000, 30f, PdDesign("Spectra").WeaponModifiers, (5f, 12f), (1f, 1f), (400f, 750f), (.2f, .1f), (.05f, 0f),
|
||||
(0f, 0f), (6f, 10f), (300f, 150f), (300f, 100f), false, PdDesign("Spectra").Behaviors.OfType<InstantWeaponData>().Single().MagazineSize, PdDesign("Spectra").Behaviors.OfType<InstantWeaponData>().Single().ReloadTime),
|
||||
("Point Defense Laser", 30f, 110000, 30f, PdDesign("Light Laser").WeaponModifiers, (5f, 12f), (1f, 1f), (400f, 750f), (.2f, .1f), (.05f, 0f),
|
||||
(0f, 0f), (6f, 10f), (300f, 150f), (300f, 100f), false, PdDesign("Light Laser").Behaviors.OfType<InstantWeaponData>().Single().MagazineSize, PdDesign("Light Laser").Behaviors.OfType<InstantWeaponData>().Single().ReloadTime),
|
||||
("Flak Gun", 120f, 180000, 80f, WeaponModifiers.Cluster, (30f, 70f), (6f, 8f), (350f, 800f), (.6f, .35f), (4f, 2f),
|
||||
(900f, 1300f), (1f, .5f), (300f, 150f), (800f, 300f), true, 40, 4f),
|
||||
};
|
||||
|
|
@ -449,7 +449,7 @@ public sealed partial class RunStartTests
|
|||
return FireControl.TrackingRate(range.Gun, range.Gunner);
|
||||
}
|
||||
var pd = FireControl.PMount(omega, RateOf("Point Defense Gun"));
|
||||
var clearPath = FireControl.PMount(omega, RateOf("ClearPath"));
|
||||
var clearPath = FireControl.PMount(omega, RateOf("Light Machine Gun"));
|
||||
Assert.True(pd >= .75f, $"the PD gun follows a speed demon: {pd}");
|
||||
Assert.True(clearPath <= .25f, $"the machine gun does not: {clearPath}");
|
||||
}
|
||||
|
|
@ -458,7 +458,7 @@ public sealed partial class RunStartTests
|
|||
[Fact]
|
||||
public void PlightHasItsRuledShape()
|
||||
{
|
||||
var plight = _cache.GetAll<WeaponItemData>().Single(w => w.Name == "plight");
|
||||
var plight = _cache.GetAll<WeaponItemData>().Single(w => w.Name == "Lightning Projector");
|
||||
Assert.Equal(1, plight.Shape.Width);
|
||||
Assert.Equal(2, plight.Shape.Height);
|
||||
Assert.True(plight.Shape.Cells[0, 0] && plight.Shape.Cells[0, 1], "both cells are occupied");
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ public sealed class MunitionPartsTests : IDisposable
|
|||
// both ranged stats. The column names are the retired fields'.
|
||||
private static readonly (string Design, float ThrustMin, float ThrustMax, float MissileVelocityMin, float MissileVelocityMax, float DodgeFrequency)[] Golden =
|
||||
{
|
||||
("GT 3K", 135, 325, 150, 300, 0.25f),
|
||||
("LRMM72", 400, 600, 200, 300, 0.25f),
|
||||
("SRMM72", 1600, 2400, 400, 600, 1f),
|
||||
("pswarm", 500, 2000, 400, 600, 1f),
|
||||
("scorched void policy", 500, 2000, 400, 600, 1f),
|
||||
("Guided Missile Launcher", 135, 325, 150, 300, 0.25f),
|
||||
("Long-Range Missile Rack", 400, 600, 200, 300, 0.25f),
|
||||
("Short-Range Missile Rack", 1600, 2400, 400, 600, 1f),
|
||||
("Swarm Rocket Pod", 500, 2000, 400, 600, 1f),
|
||||
("Incendiary Rocket Pod", 500, 2000, 400, 600, 1f),
|
||||
};
|
||||
|
||||
private static PerformanceStat Flat(float value) => new PerformanceStat { Min = value, Max = value };
|
||||
|
|
@ -208,13 +208,13 @@ public sealed class MunitionPartsTests : IDisposable
|
|||
[Fact]
|
||||
public void CatalogLoadRefusesAnIncompleteOrStrayMunitionPart()
|
||||
{
|
||||
using (AetheriaStores.Open(Forged<WeaponItemData>(d => d.Name == "GT 3K", _ => { }), registry: TestCatalog.Registry())) { }
|
||||
using (AetheriaStores.Open(Forged<WeaponItemData>(d => d.Name == "Guided Missile Launcher", _ => { }), registry: TestCatalog.Registry())) { }
|
||||
|
||||
foreach (var part in AllParts)
|
||||
{
|
||||
var path = Forged<WeaponItemData>(d => d.Name == "GT 3K", d => d.Behaviors.RemoveAll(b => b.GetType() == part));
|
||||
var path = Forged<WeaponItemData>(d => d.Name == "Guided Missile Launcher", d => d.Behaviors.RemoveAll(b => b.GetType() == part));
|
||||
var refusal = Assert.ThrowsAny<Exception>(() => AetheriaStores.Open(path, registry: TestCatalog.Registry()));
|
||||
Assert.Contains("GT 3K", refusal.ToString());
|
||||
Assert.Contains("Guided Missile Launcher", refusal.ToString());
|
||||
Assert.Contains(part.Name, refusal.ToString());
|
||||
}
|
||||
|
||||
|
|
@ -245,13 +245,13 @@ public sealed class MunitionPartsTests : IDisposable
|
|||
// The Longinus's own gear: two drives, a core, a cockpit and a sensor, so the ship has thrusters, a sensor and a plume
|
||||
// for any munition contribution to be seen against.
|
||||
private static readonly (string Name, int X, int Y)[] ShipGear =
|
||||
{ ("Large Drive", 1, 0), ("Large Drive", 3, 0), ("Core Power", 2, 4), ("Cockpit 2x2", 2, 6), ("not if i see you first", 3, 10) };
|
||||
{ ("Large Drive", 1, 0), ("Large Drive", 3, 0), ("Compact Reactor", 2, 4), ("Cockpit 2x2", 2, 6), ("Compact Sensor", 3, 10) };
|
||||
|
||||
// A GT 3K fitted to a Longinus launcher hardpoint beside that gear, its lot's thruster role at the given quality.
|
||||
private static EquippedItem Fit(CultCache cache, float thrusterQuality, out Ship ship)
|
||||
{
|
||||
var hull = cache.GetByName<HullData>("Longinus");
|
||||
var gt = cache.GetByName<WeaponItemData>("GT 3K");
|
||||
var gt = cache.GetByName<WeaponItemData>("Guided Missile Launcher");
|
||||
var hardpoint = hull.Hardpoints.First(h => h.Type == HardpointType.Launcher && h.IsFilledBy(gt));
|
||||
var settings = RestoredHullsTests.Settings();
|
||||
var ledger = new ProvenanceLedger();
|
||||
|
|
@ -269,7 +269,7 @@ public sealed class MunitionPartsTests : IDisposable
|
|||
zone.Admit(ship, piloted: false);
|
||||
// Settle at the item's optimal temperature, as ConditionRatioTests does, so heat and wear read their identity and only
|
||||
// the role's quality moves a stat.
|
||||
var item = ship.Equipment.Single(e => e.Data.Name == "GT 3K");
|
||||
var item = ship.Equipment.Single(e => e.Data.Name == "Guided Missile Launcher");
|
||||
foreach (var cell in item.InsetShape.Coordinates) ship.Temperature[cell.x, cell.y] = gt.OptimalTemperature;
|
||||
item.UpdatePerformance();
|
||||
item.UpdatePerformance();
|
||||
|
|
@ -280,7 +280,7 @@ public sealed class MunitionPartsTests : IDisposable
|
|||
public void PartsReadThroughTheItem()
|
||||
{
|
||||
using var cache = RestoredHullsTests.OpenCatalog();
|
||||
var design = cache.GetByName<WeaponItemData>("GT 3K");
|
||||
var design = cache.GetByName<WeaponItemData>("Guided Missile Launcher");
|
||||
var poor = Fit(cache, .2f, out var poorShip);
|
||||
var good = Fit(cache, .9f, out _);
|
||||
|
||||
|
|
@ -324,7 +324,7 @@ public sealed class MunitionPartsTests : IDisposable
|
|||
public void ShipSumsIgnoreTheFittedMunitionParts()
|
||||
{
|
||||
using var cache = RestoredHullsTests.OpenCatalog();
|
||||
var design = cache.GetByName<WeaponItemData>("GT 3K");
|
||||
var design = cache.GetByName<WeaponItemData>("Guided Missile Launcher");
|
||||
var part = Part<MunitionThrusterData>(design);
|
||||
var item = Fit(cache, .5f, out var ship);
|
||||
for (var i = 0; i < 5; i++) ship.Update(.1f);
|
||||
|
|
|
|||
|
|
@ -79,13 +79,13 @@ public sealed class PiratesFactionCommandTests : IDisposable
|
|||
var expected = new (string Design, string Name, string Description)[]
|
||||
{
|
||||
("Autocannon", "🫳🔫", "Serial number filed off. Still shoots."),
|
||||
("Earp", "🪦🤠", "The previous owner had no further use for it."),
|
||||
("FastBlast+-", "🧾🚫", "Warranty void where prohibited, which is everywhere."),
|
||||
("6k Shooter", "🎨🙈", "The logo underneath is somebody else's problem."),
|
||||
("scorched void policy", "🔥", "Turns out we did start the fire after all."),
|
||||
("Long Slug Rifle", "🪦🤠", "The previous owner had no further use for it."),
|
||||
("Cell Blaster", "🧾🚫", "Warranty void where prohibited, which is everywhere."),
|
||||
("Slug Rifle", "🎨🙈", "The logo underneath is somebody else's problem."),
|
||||
("Incendiary Rocket Pod", "🔥", "Turns out we did start the fire after all."),
|
||||
("Targeting Computer", "👀🎯", "Somebody else's eyes. They still work."),
|
||||
("Small Drive", "🔑🏃💨", "Hotwired. Do not ask about the ignition."),
|
||||
("Store-All Plus", "📦🤫", "Contents not as declared."),
|
||||
("Cargo Bay", "📦🤫", "Contents not as declared."),
|
||||
};
|
||||
Assert.Equal(expected.Select(e => e.Name).OrderBy(n => n, StringComparer.Ordinal), products.Select(p => p.Name).OrderBy(n => n, StringComparer.Ordinal));
|
||||
foreach (var (designName, name, description) in expected)
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ public sealed class PowerCurveTests : IDisposable
|
|||
|
||||
// --- F6 (docs/stats-and-power-cut.md, Soul pass 2026-09-19) named PumpedHeat as a Radiator request field
|
||||
// --- (PowerRequest's own early-out gate reads it, the exact shape Soul reproduced against the shipped
|
||||
// --- catalog's "OK Disperser": SOUL_RadiatorRequestDependsOnItsOwnGrantAndOscillates) and, at the time,
|
||||
// --- catalog's "Heat Pump": SOUL_RadiatorRequestDependsOnItsOwnGrantAndOscillates) and, at the time,
|
||||
// --- refused a PowerSupply term there for exactly that reason. The nominal-request ruling above is what
|
||||
// --- actually fixes the oscillation (the request no longer reads the live grant at all), so this shape is
|
||||
// --- accepted now -- the six shipped records this ruling exists to make legal again include exactly this
|
||||
|
|
|
|||
|
|
@ -952,7 +952,7 @@ public sealed class RestoredHullsTests
|
|||
|
||||
// Every restored thruster's particle effect is Thruster 1.prefab, by the legacy record (soul-dump.txt).
|
||||
var thruster1Guid = GuidOf("Assets/Content/Prefabs/Thrusters/Thruster 1.prefab");
|
||||
var restoredThrusterNames = new[] { "deep space burnout", "Large Drive", "Victoire", "Small Drive", "Talaria", "RevvITup 2.0", "Medium Drive" };
|
||||
var restoredThrusterNames = new[] { "Burn Drive", "Large Drive", "Racing Drive", "Small Drive", "Rugged Drive", "High-Thrust Drive", "Medium Drive" };
|
||||
foreach (var name in restoredThrusterNames)
|
||||
{
|
||||
var design = cache.GetAll<GearData>().First(g => g.Name == name);
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ using Xunit;
|
|||
// oracle, since the command produced it.
|
||||
public sealed class RolesBackfillCommandTests : IDisposable
|
||||
{
|
||||
private static readonly string[] Flattened = { "Autocannon", "LRMM72", "SRMM72", "Mine Launcher", "Large Drive", "Small Drive" };
|
||||
private static readonly string[] Flattened = { "Autocannon", "Long-Range Missile Rack", "Short-Range Missile Rack", "Mine Launcher", "Large Drive", "Small Drive" };
|
||||
|
||||
// Designs that shipped with non-flat stats whose Quality term named no role; the field is the stat to unname.
|
||||
private static readonly (string Design, string Field)[] Unnamed =
|
||||
{
|
||||
("DeathCluster", "Count"), ("Flak Gun", "Count"), ("GT 3K", "MinRange"), ("plight", "DamageSpread"),
|
||||
("MoveOnPro", "Modifier"), ("MoveOnPro Station Reactor", "Modifier"),
|
||||
("Cluster Cannon", "Count"), ("Flak Gun", "Count"), ("Guided Missile Launcher", "MinRange"), ("Lightning Projector", "DamageSpread"),
|
||||
("Muon Fusion Reactor", "Modifier"), ("Muon Fusion Station Reactor", "Modifier"),
|
||||
};
|
||||
|
||||
private readonly string _root = Path.Combine(Path.GetTempPath(), "roles-backfill-" + Guid.NewGuid().ToString("N"));
|
||||
|
|
@ -165,7 +165,7 @@ public sealed class RolesBackfillCommandTests : IDisposable
|
|||
static Dictionary<string, float> Exponents(EquippableItemData d) => CatalogRoleTests.StatsOf(d)
|
||||
.SelectMany(s => s.Stat.Terms.Where(t => t.Source == StatSource.Quality && !string.IsNullOrEmpty(t.Role)).Select(t => (s.Name, t.Exponent)))
|
||||
.ToDictionary(x => x.Name, x => x.Exponent);
|
||||
var designs = new[] { "Autocannon", "LRMM72" };
|
||||
var designs = new[] { "Autocannon", "Long-Range Missile Rack" };
|
||||
Dictionary<string, Dictionary<string, float>> shipped;
|
||||
Dictionary<string, Dictionary<string, float>> Read(EquippableItemData[] all) => all.Where(d => designs.Contains(d.Name)).ToDictionary(d => d.Name, Exponents);
|
||||
using (var catalog = RestoredHullsTests.OpenCatalog()) shipped = Read(catalog.GetAll<EquippableItemData>().ToArray());
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ public sealed partial class RunStartTests : IDisposable
|
|||
}
|
||||
|
||||
// The sold hardpoint gear the generator gives no home today: the production rule (LoadoutGenerator.HasHome over the hulls a
|
||||
// product sells). The Smoke Test Hull, which no product sells, gives ChargeBlast SG and ChargeBlast+- no home; authoring a
|
||||
// product sells). The Smoke Test Hull, which no product sells, gives Charged Scatter Blaster and Charged Blaster no home; authoring a
|
||||
// sold hull that takes one shows up here as a changed list.
|
||||
[Fact]
|
||||
public void TheSoldHardpointGearWithNoHomeToday()
|
||||
|
|
@ -456,7 +456,7 @@ public sealed partial class RunStartTests : IDisposable
|
|||
.Where(design => sold.Contains(_cache.RefOf(design).Key) && design.Price > 0)
|
||||
.Where(design => !LoadoutGenerator.HasHome(design, hulls))
|
||||
.Select(design => design.Name).OrderBy(name => name, StringComparer.Ordinal).ToArray();
|
||||
Assert.Equal(new[] { "CShot RainbowLite Lazer", "ChargeBlast SG", "ChargeBlast+-", "OK Disperser" }, homeless);
|
||||
Assert.Equal(new[] { "Charged Blaster", "Charged Scatter Blaster", "Heat Pump", "Heavy Beam Laser" }, homeless);
|
||||
}
|
||||
|
||||
// A sold weapon can be generated onto an NPC, whose combat state samples its damage at range, so every weapon a
|
||||
|
|
|
|||
|
|
@ -537,7 +537,7 @@ public sealed partial class RunStartTests
|
|||
|
||||
runs.Add(Stage(Arena(false), new Scripted(false, stage =>
|
||||
{
|
||||
var ship = stage.Player(stage.Fit("Djinni", ("Census Fitted", int2(1, 6), ItemRotation.None), ("Store-All Plus", int2(3, 6), ItemRotation.None)), float2(0, 0));
|
||||
var ship = stage.Player(stage.Fit("Djinni", ("Census Fitted", int2(1, 6), ItemRotation.None), ("Cargo Bay", int2(3, 6), ItemRotation.None)), float2(0, 0));
|
||||
stage.Cargo(ship, "Census Carried");
|
||||
})));
|
||||
Assert.Empty(UnsoldAndUnplaced(runs));
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public sealed class SmokeHullCommandTests : IDisposable
|
|||
var hulls = db.Cache.GetAll<HullData>().Where(h => h.Name == HullName).ToArray();
|
||||
var keys = hulls.Select(h => db.Cache.RefOf(h).Key).ToArray();
|
||||
var products = db.Cache.GetAll<FactionProductData>().Count(p => keys.Any(k => p.Design.Key.Equals(k)));
|
||||
var fitted = new[] { "ChargeBlast SG", "Autocannon" }
|
||||
var fitted = new[] { "Charged Scatter Blaster", "Autocannon" }
|
||||
.Select(name => db.Cache.GetAll<EquippableItemData>().Single(d => d.Name == name)).ToArray();
|
||||
return (hulls, db.Cache.GetAll<HullData>().Single(h => h.Name == "Longinus"), fitted, products);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ public sealed partial class RunStartTests
|
|||
Assert.Equal("Smoke Test Hull", _items.GetData(player.EquippedHull.EquippableItem).Name);
|
||||
|
||||
EquippedItem Mount(string design) => Assert.Single(WeaponMounts(player), item => _items.GetData(item.EquippableItem).Name == design);
|
||||
var charge = Mount("ChargeBlast SG");
|
||||
var charge = Mount("Charged Scatter Blaster");
|
||||
var autocannon = Mount("Autocannon");
|
||||
Assert.Equal((HardpointType.Energy, 2, 2), (charge.Hardpoint.Type, charge.Hardpoint.Shape.Width, charge.Hardpoint.Shape.Height));
|
||||
Assert.Equal((HardpointType.Ballistic, 2, 2), (autocannon.Hardpoint.Type, autocannon.Hardpoint.Shape.Width, autocannon.Hardpoint.Shape.Height));
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public sealed class SmokeRoundsCommandTests : IDisposable
|
|||
var smoke = db.Cache.GetAll<WeaponItemData>().Where(w => Names.Contains(w.Name)).ToArray();
|
||||
var keys = smoke.Select(w => db.Cache.RefOf(w).Key).ToArray();
|
||||
var products = db.Cache.GetAll<FactionProductData>().Count(p => keys.Any(k => p.Design.Key.Equals(k)));
|
||||
return (smoke, db.Cache.GetAll<WeaponItemData>().Single(w => w.Name == "Spectra"), db.Cache.GetAll<WeaponItemData>().Single(w => w.Name == "ChargeBlast SG"), products);
|
||||
return (smoke, db.Cache.GetAll<WeaponItemData>().Single(w => w.Name == "Light Laser"), db.Cache.GetAll<WeaponItemData>().Single(w => w.Name == "Charged Scatter Blaster"), products);
|
||||
}
|
||||
finally { db.Cache.Dispose(); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ public sealed partial class RunStartTests
|
|||
|
||||
var proximity = Carried(player, "Smoke Proximity");
|
||||
var delayed = Carried(player, "Smoke Delayed");
|
||||
var direct = Carried(player, "DeathCluster");
|
||||
var direct = Carried(player, "Cluster Cannon");
|
||||
Assert.Null(player.Target.Value.Entity);
|
||||
|
||||
// The bare hull is on the initial aim line, ahead, and inside every weapon mount's arc.
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ public sealed partial class RunStartTests
|
|||
// in this arena, so a fused weapon that does not is not a harness that cannot fire. A fused round flies slowly enough
|
||||
// to be in the air when the direct weapon kills the fragile hull (check A.3) and bursts on the first hull on the aim line.
|
||||
[Theory]
|
||||
[InlineData("DeathCluster")]
|
||||
[InlineData("Cluster Cannon")]
|
||||
[InlineData("Smoke Proximity")]
|
||||
[InlineData("Smoke Delayed")]
|
||||
public void EveryWeaponAboardFiresInTheSteppedFusedRoundsArena(string design)
|
||||
|
|
@ -42,7 +42,7 @@ public sealed partial class RunStartTests
|
|||
for (var i = 0; i < 60; i++) arena.Update(SteppedDt);
|
||||
|
||||
Assert.True(fired.Count > 0, $"{design} fired nothing in 3 s; the ship's reactor is {(player.PowerBus.TotalGeneration > 0f ? "running" : "down")}");
|
||||
if (design == "DeathCluster") return;
|
||||
if (design == "Cluster Cannon") return;
|
||||
var (at, burst) = committed.First();
|
||||
Assert.Equal(ShotResult.Burst, burst.Result);
|
||||
Assert.True(burst.HasBurstPoint);
|
||||
|
|
@ -71,7 +71,7 @@ public sealed partial class RunStartTests
|
|||
});
|
||||
|
||||
WeaponOf(proximity).Activate();
|
||||
WeaponOf(Carried(player, "DeathCluster")).Activate();
|
||||
WeaponOf(Carried(player, "Cluster Cannon")).Activate();
|
||||
float? deadAt = null;
|
||||
for (var i = 0; i < 120 && landed == null; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ public sealed partial class RunStartTests
|
|||
for (var tick = 0; tick < 10; tick++) player.Update(AllocDt);
|
||||
var thrusters = player.GetBehaviors<Thruster>().Where(t => t.Item.Active.Value).ToArray();
|
||||
var drives = thrusters.Where(t => t.Item.Data.Name == "Large Drive").ToArray();
|
||||
var flanks = thrusters.Where(t => t.Item.Data.Name == "Talaria").ToArray();
|
||||
var flanks = thrusters.Where(t => t.Item.Data.Name == "Rugged Drive").ToArray();
|
||||
Assert.Equal(2, drives.Length);
|
||||
Assert.Equal(2, flanks.Length);
|
||||
float Clockwise(IEnumerable<Thruster> of) => of.Sum(t => max(t.Column(t.Thrust).z, 0f));
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@ public static class Program
|
|||
private static (float Mean, float Dev, string Basis) AuthorProductRole(AetherDb db, FactionProductData product, string designName, string role)
|
||||
{
|
||||
var maker = db.Cache.Get(product.Manufacturer)?.Name;
|
||||
if (designName == "Arctica" && maker == "Alakrita" && role == "fins")
|
||||
if (designName == "Adaptive Radiator" && maker == "Alakrita" && role == "fins")
|
||||
return (.78f, .07f, "lore: Alakrita brands on heat efficiency (item-provenance-target.md)");
|
||||
|
||||
var hash = StableHash($"{product.Name}|{role}");
|
||||
|
|
@ -1175,10 +1175,10 @@ public static class Program
|
|||
var newDesigns = new (GearData Design, string ProductName, Faction Maker, string ProductDescription, (string Role, float Mean, float Dev)[] Roles)[]
|
||||
{
|
||||
(targetingComputer, "LockOn", FactionByShortName("NiteLife"),
|
||||
"Keeps the lights on your target. (new text)",
|
||||
"Keeps the lights on your target.",
|
||||
new[] { ("processor", .55f, .15f), ("array", .5f, .16f) }),
|
||||
(fireControlArray, "LockOn Pro", FactionByShortName("NiteLife"),
|
||||
"Same promise, sharper lock. (new text)",
|
||||
"Same promise, sharper lock.",
|
||||
new[] { ("processor", .72f, .12f), ("array", .68f, .13f) }),
|
||||
};
|
||||
|
||||
|
|
@ -1191,17 +1191,17 @@ public static class Program
|
|||
// outside this cut's brief).
|
||||
var existingDesigns = new (string DesignName, string ProductName, Faction Maker, string ProductDescription, (string Role, float Mean, float Dev)[] Roles)[]
|
||||
{
|
||||
("plight", "DragOnBreath", FactionByShortName("Lucent"),
|
||||
"The subsidiary plight's own description already namechecks: DragOnBreath, a Lucent Media property.",
|
||||
("Lightning Projector", "DragOnBreath", FactionByShortName("Lucent"),
|
||||
"Chain lightning has your enemies chain smoking while you enjoy a relaxing DragOnBreath vapepop, now available in 17! flavours (manufactured by DragOnBreath, a subsidary of Lucent Media)",
|
||||
new[] { ("focusing array", .7f, .13f), ("power coupling", .55f, .15f) }),
|
||||
("pswarm", "Leonid", FactionByShortName("AU"),
|
||||
("Swarm Rocket Pod", "Leonid", FactionByShortName("AU"),
|
||||
"A rain of pain that falls mainly on space planes.",
|
||||
new[] { ("guidance system", .65f, .14f), ("thruster", .63f, .15f), ("warhead", .7f, .13f) }),
|
||||
("Core Power", "Steadfast", FactionByShortName("R&D"),
|
||||
"Rated for continuous operation. \"Continuous\" does not imply \"uninterrupted.\" (new text)",
|
||||
("Compact Reactor", "Steadfast", FactionByShortName("R&D"),
|
||||
"It gets the job done, but that's all. Rated for continuous operation. \"Continuous\" does not imply \"uninterrupted.\"",
|
||||
new[] { ("core", .5f, .12f), ("regulator", .5f, .12f) }),
|
||||
("Large Drive", "True North", FactionByShortName("Lightsail"),
|
||||
"Gets your cargo there. Getting you there is your problem. (new text)",
|
||||
"Gets your cargo there. Getting you there is your problem.",
|
||||
Array.Empty<(string, float, float)>()),
|
||||
};
|
||||
|
||||
|
|
@ -1313,16 +1313,16 @@ public static class Program
|
|||
var newProducts = new (GearData Design, string ProductName, Faction Maker, string ProductDescription, (string Role, float Mean, float Dev)[] Roles)[]
|
||||
{
|
||||
(targetingComputer, "Panopticon", FactionByShortName("Finch"),
|
||||
"Sees everything, judges nothing. Well, mostly nothing. (new text)",
|
||||
"Sees everything, judges nothing. Well, mostly nothing.",
|
||||
new[] { ("processor", .5f, .13f), ("array", .58f, .12f) }),
|
||||
(fireControlArray, "Panopticon Prime", FactionByShortName("Finch"),
|
||||
"The upgrade nobody at Finch will admit they needed until they had it. (new text)",
|
||||
"The upgrade nobody at Finch will admit they needed until they had it.",
|
||||
new[] { ("processor", .68f, .11f), ("array", .75f, .10f) }),
|
||||
(targetingComputer, "ClapBack", FactionByShortName("Lucent"),
|
||||
"Your target won't clock it until the killcam. (new text)",
|
||||
"Your target won't clock it until the killcam.",
|
||||
new[] { ("processor", .6f, .16f), ("array", .48f, .15f) }),
|
||||
(fireControlArray, "ClapBack Ultra", FactionByShortName("Lucent"),
|
||||
"Now with main-character energy built in. (new text)",
|
||||
"Now with main-character energy built in.",
|
||||
new[] { ("processor", .78f, .14f), ("array", .65f, .13f) }),
|
||||
};
|
||||
|
||||
|
|
@ -1528,7 +1528,7 @@ public static class Program
|
|||
static void Set(PerformanceStat stat, float min, float max) { stat.Min = min; stat.Max = max; }
|
||||
static void Track(WeaponData data, float rate) => data.Tracking = new PerformanceStat { Min = rate, Max = rate, Terms = new List<StatTerm>() };
|
||||
|
||||
var gun = Copy(Template("ClearPath"), designNames[0], "Close-in defence gun: a hose of light rounds.", 40f, 80000, 60f, 1, 1, WeaponModifiers.RapidFire);
|
||||
var gun = Copy(Template("Light Machine Gun"), designNames[0], "Close-in defence gun: a hose of light rounds.", 40f, 80000, 60f, 1, 1, WeaponModifiers.RapidFire);
|
||||
var gunData = gun.Behaviors.OfType<InstantWeaponData>().Single();
|
||||
Set(gunData.Damage, 1.5f, 4f); Set(gunData.Range, 300f, 550f); Set(gunData.MinRange, 0f, 0f);
|
||||
Set(gunData.Cooldown, .06f, .025f); Set(gunData.Count, 1f, 1f); Set(gunData.Spread, 1f, .3f);
|
||||
|
|
@ -1536,14 +1536,14 @@ public static class Program
|
|||
gunData.AmmoType = db.Cache.RefOf(ammunition); gunData.MagazineSize = 250; gunData.ReloadTime = 3f;
|
||||
Track(gunData, 40f);
|
||||
|
||||
var laser = Copy(Template("Spectra"), designNames[1], "Close-in defence beam: quick, light, instant.", 30f, 110000, 30f, 1, 1, Template("Spectra").WeaponModifiers);
|
||||
var laser = Copy(Template("Light Laser"), designNames[1], "Close-in defence beam: quick, light, instant.", 30f, 110000, 30f, 1, 1, Template("Light Laser").WeaponModifiers);
|
||||
var laserData = laser.Behaviors.OfType<InstantWeaponData>().Single();
|
||||
Set(laserData.Damage, 5f, 12f); Set(laserData.Range, 400f, 750f); Set(laserData.MinRange, 0f, 0f);
|
||||
Set(laserData.Cooldown, .2f, .1f); Set(laserData.Count, 1f, 1f); Set(laserData.Spread, .05f, 0f);
|
||||
Set(laserData.Velocity, 0f, 0f); Set(laserData.Energy, 6f, 10f); Set(laserData.Heat, 300f, 150f); Set(laserData.Visibility, 300f, 100f);
|
||||
Track(laserData, 40f);
|
||||
|
||||
var flak = Copy(Template("DeathCluster"), designNames[2], "Small flak gun: a short-range pellet volley.", 120f, 180000, 80f, 1, 2, WeaponModifiers.Cluster);
|
||||
var flak = Copy(Template("Cluster Cannon"), designNames[2], "Small flak gun: a short-range pellet volley.", 120f, 180000, 80f, 1, 2, WeaponModifiers.Cluster);
|
||||
var flakData = flak.Behaviors.OfType<InstantWeaponData>().Single();
|
||||
Set(flakData.Damage, 30f, 70f); Set(flakData.Count, 6f, 8f); Set(flakData.Range, 350f, 800f); Set(flakData.MinRange, 0f, 0f);
|
||||
Set(flakData.Cooldown, .6f, .35f); Set(flakData.Spread, 4f, 2f); Set(flakData.Velocity, 900f, 1300f);
|
||||
|
|
@ -1714,11 +1714,11 @@ public static class Program
|
|||
}
|
||||
static PerformanceStat Fixed(float value) => new PerformanceStat { Min = value, Max = value, Terms = new List<StatTerm>() };
|
||||
|
||||
var proximity = Copy("Spectra", names[0], "A Spectra that bursts by proximity, blast 8. For scenarios; no one builds it.", WeaponFuse.Proximity, 8f);
|
||||
var delayed = Copy("Spectra", names[1], "A Spectra that bursts after two cells of metal, blast 4. For scenarios; no one builds it.", WeaponFuse.Delayed, 4f);
|
||||
var refused = Copy("Spectra", names[2], "A Spectra whose blast is wider than its reach, so it never fires. For scenarios; no one builds it.", WeaponFuse.Proximity, 30f);
|
||||
var charge = Copy("ChargeBlast SG", names[4], "A ChargeBlast SG whose blast is wider than its reach, so it never charges. For scenarios; no one builds it.", WeaponFuse.Proximity, 30f);
|
||||
var beam = Copy("Spectra", names[3], "A constant beam whose blast is wider than its reach, so it never starts. For scenarios; no one builds it.", WeaponFuse.Proximity, 30f);
|
||||
var proximity = Copy("Light Laser", names[0], "A Spectra that bursts by proximity, blast 8. For scenarios; no one builds it.", WeaponFuse.Proximity, 8f);
|
||||
var delayed = Copy("Light Laser", names[1], "A Spectra that bursts after two cells of metal, blast 4. For scenarios; no one builds it.", WeaponFuse.Delayed, 4f);
|
||||
var refused = Copy("Light Laser", names[2], "A Spectra whose blast is wider than its reach, so it never fires. For scenarios; no one builds it.", WeaponFuse.Proximity, 30f);
|
||||
var charge = Copy("Charged Scatter Blaster", names[4], "A ChargeBlast SG whose blast is wider than its reach, so it never charges. For scenarios; no one builds it.", WeaponFuse.Proximity, 30f);
|
||||
var beam = Copy("Light Laser", names[3], "A constant beam whose blast is wider than its reach, so it never starts. For scenarios; no one builds it.", WeaponFuse.Proximity, 30f);
|
||||
|
||||
// The Smoke Test Hull carries one 2x2 reactor. A Spectra's 20-40 energy a shot at its cadence is more than that reactor makes,
|
||||
// so two of them overload it, it overheats and shuts down within a second, and nothing aboard fires again (Fused Rounds,
|
||||
|
|
@ -1888,8 +1888,8 @@ public static class Program
|
|||
// no non-flat stat reads; DeathCluster, Flak Gun, GT 3K, plight and the two MoveOnPros because each had a non-flat stat
|
||||
// whose Quality term named no role (CB-R1: each non-flat stat reads exactly one declared role). Idempotent: a design with
|
||||
// no flat mapped stat and no unnamed one is left alone, a product with a role is left alone. Dry run unless passed "apply".
|
||||
private static readonly string[] BackfillDesigns = { "Autocannon", "LRMM72", "SRMM72", "Mine Launcher", "Large Drive", "Small Drive",
|
||||
"DeathCluster", "Flak Gun", "GT 3K", "plight", "MoveOnPro", "MoveOnPro Station Reactor" };
|
||||
private static readonly string[] BackfillDesigns = { "Autocannon", "Long-Range Missile Rack", "Short-Range Missile Rack", "Mine Launcher", "Large Drive", "Small Drive",
|
||||
"Cluster Cannon", "Flak Gun", "Guided Missile Launcher", "Lightning Projector", "Muon Fusion Reactor", "Muon Fusion Station Reactor" };
|
||||
|
||||
// Stats the backfill names but never ranges: a shot count is whole, and which way a launcher's MinRange should fall is
|
||||
// each design's own call (GT 3K authors it as a cost already).
|
||||
|
|
@ -2053,13 +2053,13 @@ public static class Program
|
|||
var rebrands = new (string Design, string Name, string Description)[]
|
||||
{
|
||||
("Autocannon", "\U0001FAF3\U0001F52B", "Serial number filed off. Still shoots."),
|
||||
("Earp", "\U0001FAA6\U0001F920", "The previous owner had no further use for it."),
|
||||
("FastBlast+-", "\U0001F9FE\U0001F6AB", "Warranty void where prohibited, which is everywhere."),
|
||||
("6k Shooter", "\U0001F3A8\U0001F648", "The logo underneath is somebody else's problem."),
|
||||
("scorched void policy", "\U0001F525", "Turns out we did start the fire after all."),
|
||||
("Long Slug Rifle", "\U0001FAA6\U0001F920", "The previous owner had no further use for it."),
|
||||
("Cell Blaster", "\U0001F9FE\U0001F6AB", "Warranty void where prohibited, which is everywhere."),
|
||||
("Slug Rifle", "\U0001F3A8\U0001F648", "The logo underneath is somebody else's problem."),
|
||||
("Incendiary Rocket Pod", "\U0001F525", "Turns out we did start the fire after all."),
|
||||
("Targeting Computer", "\U0001F440\U0001F3AF", "Somebody else's eyes. They still work."),
|
||||
("Small Drive", "\U0001F511\U0001F3C3\U0001F4A8", "Hotwired. Do not ask about the ignition."),
|
||||
("Store-All Plus", "\U0001F4E6\U0001F92B", "Contents not as declared."),
|
||||
("Cargo Bay", "\U0001F4E6\U0001F92B", "Contents not as declared."),
|
||||
};
|
||||
|
||||
var products = rebrands.Select(r =>
|
||||
|
|
@ -2365,7 +2365,7 @@ public static class Program
|
|||
// sells (rulings catalog-grows-generic-designs-branded-products, kitchen-sink-content, designs-are-tech-nodes). A
|
||||
// Renames row renames the design found under its old name and gives it the functional text; a Brands row renames the
|
||||
// maker's same-named product and sets its text and the design's functional text; ProductTexts sets the rest; every
|
||||
// shipped product text ending in the authoring note " (new text)" loses it. Dry run unless passed "apply".
|
||||
// shipped product text ending in the authoring note loses it. Dry run unless passed "apply".
|
||||
public static int GenericDesigns(bool apply, string root = null)
|
||||
{
|
||||
const string AuthoringNote = " (new text)";
|
||||
|
|
|
|||
Loading…
Reference in a new issue