Require a targeting system on every armed loadout; AI aims through reveal

LoadoutGenerator.FillInterior equips a targeting-system product,
required: true, on any entity EquipHardpoints already gave a weapon --
Q4's "not an upgrade" ruling made structural. CombatState now selects
the target's most dangerous revealed weapon item each tick through the
same IsRevealed predicate and TrySelectTargetItem writer the player path
uses, instead of never touching TargetItem at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-19 13:02:37 +02:00
commit 52a18efcdc
2 changed files with 39 additions and 0 deletions

View file

@ -258,6 +258,26 @@ public class LoadoutGenerator
capacitor.Rotation = capacitorRotation;
if (!entity.TryEquip(capacitor, capacitorPosition))
throw new InvalidLoadoutException("Failed to equip selected capacitor!");
// Cut 2 (docs/fire-control-cut.md, Q4): required equipment for anything that can fire -- unaided
// fire is a last resort, not an alternative loadout choice. EquipHardpoints runs before FillInterior
// (OutfitEntity), so entity.Weapons is already populated here. Zenith and anything else with no
// weapon hardpoints gets none.
if (entity.Weapons.Any())
{
emptyShape = entity.UnoccupiedSpace;
var (targetingProduct, targetingData) = RandomProduct<GearData>(2, item =>
item.Behaviors.Any(b => b is TargetingSystemData) &&
item.Shape.FitsWithin(emptyShape, out _, out _), required: true);
if (targetingData == null) throw new InvalidLoadoutException("No compatible targeting system found for entity!");
targetingData.Shape.FitsWithin(emptyShape, out var targetingRotation, out var targetingPosition);
var targetingSystem = ItemManager.CreateInstance(targetingProduct) as EquippableItem;
targetingSystem.Rotation = targetingRotation;
if (!entity.TryEquip(targetingSystem, targetingPosition))
throw new InvalidLoadoutException("Failed to equip selected targeting system!");
}
}
}