Mines are flat by data: refuse falloff on a mine layer, Lay reads no factor; clamp test
A mine layer carries no EffectiveRange or DamageAtMaxRange (StatValidation.ValidateMineLayerFlat, run wherever the other catalog rules run), so RangeFactor is 1 inside its gate for the mine, the AI and the panel without any reader branching on type; Lay's damage is the weapon's damage again. Adds a test that fails without Deliver's min(reach, MaxRange) clamp. Not built or tested yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
0c5d1f36d2
commit
aff6086c01
5 changed files with 64 additions and 20 deletions
|
|
@ -81,12 +81,14 @@ public static class CultRecordRefs
|
|||
StatValidation.ValidateHeatResponse(data);
|
||||
StatValidation.ValidateStatModifiers(data.Name, data.Behaviors);
|
||||
StatValidation.ValidateMunitionParts(data.Name, data.Behaviors);
|
||||
StatValidation.ValidateMineLayerFlat(data.Name, data.Behaviors);
|
||||
StatValidation.ValidateRoleUsage(data.Name, data.Roles, data.Behaviors);
|
||||
}
|
||||
if (document is ConsumableItemData consumable)
|
||||
{
|
||||
StatValidation.ValidateStatModifiers(consumable.Name, consumable.Behaviors);
|
||||
StatValidation.ValidateMunitionParts(consumable.Name, consumable.Behaviors);
|
||||
StatValidation.ValidateMineLayerFlat(consumable.Name, consumable.Behaviors);
|
||||
StatValidation.ValidateRoleUsage(consumable.Name, consumable.Roles, consumable.Behaviors);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -797,9 +797,9 @@ public static class FireControl
|
|||
FuseDelay = data.FuseDelay,
|
||||
Lifetime = data.Lifetime,
|
||||
BlastRadius = blastRadius,
|
||||
// A mine is laid at the layer, distance 0: it goes through the same falloff as every other payload, so a layer's
|
||||
// authored ranges decide its mines, the AI's reading of it and its panel alike.
|
||||
Damage = weapon.Damage * weapon.RangeFactor(0f),
|
||||
// Mines are flat (ruling effective-range-authoring-ruled): a mine layer carries no falloff authoring
|
||||
// (StatValidation.ValidateMineLayerFlat), so its figure is the AI's and the panel's at every distance it can engage.
|
||||
Damage = weapon.Damage,
|
||||
DamageType = weapon.WeaponData.DamageType,
|
||||
Layer = source,
|
||||
LayerFaction = source.Faction
|
||||
|
|
|
|||
|
|
@ -840,6 +840,21 @@ public static class StatValidation
|
|||
}
|
||||
}
|
||||
|
||||
// Ruling effective-range-authoring-ruled: mines are flat. A mine layer's Range and MinRange gate where it may lay; its
|
||||
// damage meets no range, so it carries no falloff authoring, and WeaponData.RangeFactor reads 1 inside the gate for the
|
||||
// mine, the AI and the panel alike. Refused here, with the other catalog rules, wherever those run.
|
||||
public static void ValidateMineLayerFlat(string ownerName, IEnumerable<BehaviorData> behaviors)
|
||||
{
|
||||
foreach (var layer in (behaviors ?? Enumerable.Empty<BehaviorData>()).OfType<MineLayerData>())
|
||||
{
|
||||
var effective = layer.EffectiveRange;
|
||||
if (effective == null || !float.IsPositiveInfinity(effective.Min) || !float.IsPositiveInfinity(effective.Max) || (effective.Terms != null && effective.Terms.Count > 0))
|
||||
throw new InvalidOperationException($"{ownerName}: {nameof(MineLayerData)}.{nameof(WeaponData.EffectiveRange)} is authored, but a mine layer carries no damage falloff");
|
||||
if (layer.DamageAtMaxRange != 0f)
|
||||
throw new InvalidOperationException($"{ownerName}: {nameof(MineLayerData)}.{nameof(WeaponData.DamageAtMaxRange)} is authored, but a mine layer carries no damage falloff");
|
||||
}
|
||||
}
|
||||
|
||||
// Cut 7 (docs/stats-and-power-cut.md): "a stat naming a role its design lacks" must be refused, not silently
|
||||
// fall back to the lot's own workmanship (Lot.QualityForRole already falls back for a role a lot never rolled
|
||||
// -- that is the intended forward-compat path for an old lot meeting a newly-authored role. This is the other
|
||||
|
|
|
|||
Loading…
Reference in a new issue