zc
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -186,5 +186,6 @@
|
|||||||
<WULA_AIOverwatch_EngagingMinigun>[P.I.A 轨道监视] 对敌方({0} 个目标)发射链炮扫射。</WULA_AIOverwatch_EngagingMinigun>
|
<WULA_AIOverwatch_EngagingMinigun>[P.I.A 轨道监视] 对敌方({0} 个目标)发射链炮扫射。</WULA_AIOverwatch_EngagingMinigun>
|
||||||
<WULA_AIOverwatch_FleetCalled>[P.I.A 轨道监视] 帝国舰队已抵达轨道。</WULA_AIOverwatch_FleetCalled>
|
<WULA_AIOverwatch_FleetCalled>[P.I.A 轨道监视] 帝国舰队已抵达轨道。</WULA_AIOverwatch_FleetCalled>
|
||||||
<WULA_AIOverwatch_FleetCleared>[P.I.A 轨道监视] 航道已净空。</WULA_AIOverwatch_FleetCleared>
|
<WULA_AIOverwatch_FleetCleared>[P.I.A 轨道监视] 航道已净空。</WULA_AIOverwatch_FleetCleared>
|
||||||
|
<WULA_AIOverwatch_EngagingBuilding>[P.I.A 轨道监视] 对敌方建筑/炮台发射炮击。</WULA_AIOverwatch_EngagingBuilding>
|
||||||
|
|
||||||
</LanguageData>
|
</LanguageData>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace WulaFallenEmpire
|
|||||||
public class CompProperties_AbilityEnableOverwatch : CompProperties_AbilityEffect
|
public class CompProperties_AbilityEnableOverwatch : CompProperties_AbilityEffect
|
||||||
{
|
{
|
||||||
public int durationSeconds = 180; // Default 3 minutes
|
public int durationSeconds = 180; // Default 3 minutes
|
||||||
|
public bool useArtilleryVersion = false; // Both use normal mothership by default
|
||||||
|
|
||||||
public CompProperties_AbilityEnableOverwatch()
|
public CompProperties_AbilityEnableOverwatch()
|
||||||
{
|
{
|
||||||
@@ -37,7 +38,7 @@ namespace WulaFallenEmpire
|
|||||||
map.components.Add(overwatch);
|
map.components.Add(overwatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
overwatch.EnableOverwatch(Props.durationSeconds);
|
overwatch.EnableOverwatch(Props.durationSeconds, Props.useArtilleryVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanApplyOn(LocalTargetInfo target, LocalTargetInfo dest)
|
public override bool CanApplyOn(LocalTargetInfo target, LocalTargetInfo dest)
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ namespace WulaFallenEmpire.EventSystem.AI
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EnableOverwatch(int durationSeconds)
|
// useArtilleryVersion: false = WULA_MotherShip (normal), true = WULA_MotherShip_Planet_Interdiction (artillery)
|
||||||
|
public void EnableOverwatch(int durationSeconds, bool useArtilleryVersion = false)
|
||||||
{
|
{
|
||||||
if (this.enabled)
|
if (this.enabled)
|
||||||
{
|
{
|
||||||
@@ -43,7 +44,7 @@ namespace WulaFallenEmpire.EventSystem.AI
|
|||||||
this.globalCooldownTicks = 0;
|
this.globalCooldownTicks = 0;
|
||||||
|
|
||||||
// Call fleet when overwatch starts
|
// Call fleet when overwatch starts
|
||||||
TryCallFleet();
|
TryCallFleet(useArtilleryVersion);
|
||||||
|
|
||||||
Messages.Message("WULA_AIOverwatch_Engaged".Translate(clampedDuration), MessageTypeDefOf.PositiveEvent);
|
Messages.Message("WULA_AIOverwatch_Engaged".Translate(clampedDuration), MessageTypeDefOf.PositiveEvent);
|
||||||
}
|
}
|
||||||
@@ -59,14 +60,16 @@ namespace WulaFallenEmpire.EventSystem.AI
|
|||||||
Messages.Message("WULA_AIOverwatch_Disengaged".Translate(), MessageTypeDefOf.NeutralEvent);
|
Messages.Message("WULA_AIOverwatch_Disengaged".Translate(), MessageTypeDefOf.NeutralEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TryCallFleet()
|
private void TryCallFleet(bool useArtilleryVersion)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var flyOverDef = DefDatabase<ThingDef>.GetNamedSilentFail("WULA_MotherShip_Planet_Interdiction");
|
// Choose mothership version based on parameter
|
||||||
|
string defName = useArtilleryVersion ? "WULA_MotherShip_Planet_Interdiction" : "WULA_MotherShip";
|
||||||
|
var flyOverDef = DefDatabase<ThingDef>.GetNamedSilentFail(defName);
|
||||||
if (flyOverDef == null)
|
if (flyOverDef == null)
|
||||||
{
|
{
|
||||||
WulaLog.Debug("[AI Overwatch] Could not find WULA_MotherShip_Planet_Interdiction ThingDef.");
|
WulaLog.Debug($"[AI Overwatch] Could not find {defName} ThingDef.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,14 +83,14 @@ namespace WulaFallenEmpire.EventSystem.AI
|
|||||||
startPos,
|
startPos,
|
||||||
endPos,
|
endPos,
|
||||||
map,
|
map,
|
||||||
speed: 0.02f, // Slower for mothership
|
speed: useArtilleryVersion ? 0.02f : 0.01f, // Artillery version slower
|
||||||
height: 20f
|
height: 20f
|
||||||
);
|
);
|
||||||
|
|
||||||
if (flyOver != null)
|
if (flyOver != null)
|
||||||
{
|
{
|
||||||
Messages.Message("WULA_AIOverwatch_FleetCalled".Translate(), MessageTypeDefOf.PositiveEvent);
|
Messages.Message("WULA_AIOverwatch_FleetCalled".Translate(), MessageTypeDefOf.PositiveEvent);
|
||||||
WulaLog.Debug($"[AI Overwatch] Called fleet: WULA_MotherShip_Planet_Interdiction spawned from {startPos} to {endPos}.");
|
WulaLog.Debug($"[AI Overwatch] Called fleet: {defName} spawned from {startPos} to {endPos}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -206,26 +209,65 @@ namespace WulaFallenEmpire.EventSystem.AI
|
|||||||
|
|
||||||
private void PerformScanAndStrike()
|
private void PerformScanAndStrike()
|
||||||
{
|
{
|
||||||
// Gather all valid hostile targets
|
// Gather all valid hostile pawn targets
|
||||||
List<Pawn> hostiles = map.mapPawns.AllPawnsSpawned
|
List<Pawn> hostilePawns = map.mapPawns.AllPawnsSpawned
|
||||||
.Where(p => !p.Dead && !p.Downed && p.HostileTo(Faction.OfPlayer) && !p.IsPrisoner)
|
.Where(p => !p.Dead && !p.Downed && p.HostileTo(Faction.OfPlayer) && !p.IsPrisoner)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (hostiles.Count == 0) return;
|
// Gather all hostile buildings (turrets, etc.)
|
||||||
|
List<Building> hostileBuildings = map.listerBuildings.allBuildingsColonist
|
||||||
|
.Concat(map.listerThings.ThingsInGroup(ThingRequestGroup.BuildingArtificial).OfType<Building>())
|
||||||
|
.Where(b => b != null && !b.Destroyed && b.Faction != null && b.Faction.HostileTo(Faction.OfPlayer))
|
||||||
|
.Distinct()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
// Simple clustering: Group hostiles that are close to each other
|
// Convert building positions to "virtual targets" for processing
|
||||||
var clusters = ClusterPawns(hostiles, 12f); // 12 tile radius for a cluster
|
List<IntVec3> buildingTargets = hostileBuildings.Select(b => b.Position).ToList();
|
||||||
|
|
||||||
// Prioritize larger clusters
|
|
||||||
clusters.Sort((a, b) => b.Count.CompareTo(a.Count)); // Descending order
|
|
||||||
|
|
||||||
// Process clusters
|
|
||||||
_strikesThisScan = 0;
|
_strikesThisScan = 0;
|
||||||
|
|
||||||
foreach (var cluster in clusters)
|
// Process hostile pawns first (clustered)
|
||||||
|
if (hostilePawns.Count > 0)
|
||||||
{
|
{
|
||||||
if (globalCooldownTicks > 0) break;
|
var clusters = ClusterPawns(hostilePawns, 12f);
|
||||||
ProcessCluster(cluster);
|
clusters.Sort((a, b) => b.Count.CompareTo(a.Count));
|
||||||
|
|
||||||
|
foreach (var cluster in clusters)
|
||||||
|
{
|
||||||
|
if (globalCooldownTicks > 0) break;
|
||||||
|
if (_strikesThisScan >= 3) break;
|
||||||
|
ProcessCluster(cluster);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process hostile buildings (each as individual target)
|
||||||
|
foreach (var buildingPos in buildingTargets)
|
||||||
|
{
|
||||||
|
if (globalCooldownTicks > 0) break;
|
||||||
|
if (_strikesThisScan >= 3) break;
|
||||||
|
ProcessBuildingTarget(buildingPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessBuildingTarget(IntVec3 target)
|
||||||
|
{
|
||||||
|
if (!target.InBounds(map)) return;
|
||||||
|
|
||||||
|
float safetyRadius = 9.9f; // Medium safety for building strikes
|
||||||
|
if (IsFriendlyFireRisk(target, safetyRadius))
|
||||||
|
{
|
||||||
|
Messages.Message("WULA_AIOverwatch_FriendlyFireAbort".Translate(target.ToString()), new TargetInfo(target, map), MessageTypeDefOf.CautionInput);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use cannon salvo for buildings (good balance of damage and precision)
|
||||||
|
var cannonDef = DefDatabase<AbilityDef>.GetNamedSilentFail("WULA_Firepower_Cannon_Salvo");
|
||||||
|
if (cannonDef != null)
|
||||||
|
{
|
||||||
|
Messages.Message("WULA_AIOverwatch_EngagingBuilding".Translate(), new TargetInfo(target, map), MessageTypeDefOf.PositiveEvent);
|
||||||
|
WulaLog.Debug($"[AI Overwatch] Engaging hostile building at {target} with Cannon Salvo.");
|
||||||
|
FireAbility(cannonDef, target, Rand.Range(0, 360));
|
||||||
|
_strikesThisScan++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user