diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll
index 87f0f72..d171064 100644
Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ
diff --git a/1.6/1.6/Defs/ThingDefs_Buildings/ThingDef_Building_CatastropheMissileSilo.xml b/1.6/1.6/Defs/ThingDefs_Buildings/ThingDef_Building_CatastropheMissileSilo.xml
index e09d0ef..0919108 100644
--- a/1.6/1.6/Defs/ThingDefs_Buildings/ThingDef_Building_CatastropheMissileSilo.xml
+++ b/1.6/1.6/Defs/ThingDefs_Buildings/ThingDef_Building_CatastropheMissileSilo.xml
@@ -51,6 +51,7 @@
+
CatastropheMissile_Weapon
diff --git a/Source/ArachnaeSwarm/Buildings/Building_CatastropheMissileSilo.cs b/Source/ArachnaeSwarm/Buildings/Building_CatastropheMissileSilo.cs
index 591e1a5..23d082c 100644
--- a/Source/ArachnaeSwarm/Buildings/Building_CatastropheMissileSilo.cs
+++ b/Source/ArachnaeSwarm/Buildings/Building_CatastropheMissileSilo.cs
@@ -31,20 +31,13 @@ namespace ArachnaeSwarm
public override void ExposeData()
{
base.ExposeData();
- // We no longer save/load longTarget here. It is only set by player action.
- // Scribe_TargetInfo.Look(ref this.longTarget, "longTarget"); // REMOVED
+ Scribe_TargetInfo.Look(ref this.longTarget, "longTarget");
}
protected override void Tick()
{
- // --- Attack Priority Logic ---
- // Prio 1: Forced Local Target. Let the base class handle it.
- if (this.forcedTarget.IsValid)
- {
- base.Tick();
- return;
- }
- // Prio 2: Remote Target
+ // --- Attack Priority Logic (Remote Target has higher priority) ---
+ // Prio 1: Remote Target
if (this.longTarget.IsValid)
{
if (base.Active && this.burstCooldownTicksLeft <= 0 && CanFireGlobal(out _))
@@ -58,10 +51,15 @@ namespace ArachnaeSwarm
this.top.TurretTopTick();
}
}
- // Prio 3: No manual target, fall back to base auto-targeting.
+ // Prio 2: Forced Local Target (Only if no remote target)
+ else if (this.forcedTarget.IsValid)
+ {
+ base.Tick(); // Let base class handle it
+ }
+ // Prio 3: Auto Target (if no manual targets)
else
{
- base.Tick();
+ base.Tick(); // Let base class handle it
}
}
@@ -78,7 +76,7 @@ namespace ArachnaeSwarm
public override IEnumerable GetGizmos()
{
- // Yield base gizmos first, which includes "Set forced target"
+ // Yield base gizmos first, which includes "Set forced target" and other standard buttons.
foreach (var g in base.GetGizmos())
{
yield return g;
@@ -97,7 +95,7 @@ namespace ArachnaeSwarm
{
fireGlobal.Disable(reason);
}
- // Disable if a local forced target is already set
+ // Global Strike button is disabled if a forced target is already set, to ensure mutual exclusivity.
if (this.forcedTarget.IsValid)
{
fireGlobal.Disable("LocalTargetForced".Translate());
@@ -134,11 +132,12 @@ namespace ArachnaeSwarm
missile.Projectile = DefDatabase.GetNamed("Projectile_CatastropheMissile");
Find.WorldObjects.Add(missile);
- if (CellFinder.TryFindRandomEdgeCellWith(c => this.Map.reachability.CanReach(this.Position, c, PathEndMode.OnCell, TraverseParms.For(TraverseMode.NoPassClosedDoors, Danger.Deadly)), this.Map, 0f, out IntVec3 edgeCell))
- {
- Projectile_CruiseMissile dummy = (Projectile_CruiseMissile)GenSpawn.Spawn(DefDatabase.GetNamed("Projectile_CatastropheMissile_Fake"), this.Position, this.Map);
- dummy?.Launch(this, this.DrawPos, new LocalTargetInfo(edgeCell), new LocalTargetInfo(edgeCell), ProjectileHitFlags.None);
- }
+ // Rimatomics style: dummy projectile flies off-map in the direction the turret is facing.
+ Vector3 shellDirection = Vector3.forward.RotatedBy(this.top.CurRotation);
+ IntVec3 outcell = (this.DrawPos + shellDirection * 500f).ToIntVec3();
+
+ Projectile_CruiseMissile dummy = (Projectile_CruiseMissile)GenSpawn.Spawn(DefDatabase.GetNamed("Projectile_CatastropheMissile_Fake"), this.Position, this.Map);
+ dummy?.Launch(this, this.DrawPos, new LocalTargetInfo(outcell), new LocalTargetInfo(outcell), ProjectileHitFlags.None);
var refuelableComp = this.TryGetComp();
if(refuelableComp != null)
@@ -154,7 +153,7 @@ namespace ArachnaeSwarm
private bool CanFireGlobal(out string reason)
{
var refuelableComp = this.TryGetComp();
- if (refuelableComp != null && !refuelableComp.HasFuel)
+ if (refuelableComp != null && !this.refuelableComp.HasFuel)
{
reason = "NoFuel".Translate().CapitalizeFirst();
return false;
@@ -189,7 +188,6 @@ namespace ArachnaeSwarm
return false;
}
- // Allow targeting Pawns and Buildings on the world map
if (target.WorldObject is MapParent mapParent && mapParent.HasMap)
{
var originalMap = this.Map;
@@ -215,6 +213,7 @@ namespace ArachnaeSwarm
{
this.longTarget = new GlobalTargetInfo(localTarget.Cell, mapParent.Map);
}
+ this.forcedTarget = LocalTargetInfo.Invalid; // Clear local target when setting remote
},
null, onFinished, FireMissionTex, true);
diff --git a/Source/ArachnaeSwarm/World/WorldObject_CatastropheMissile.cs b/Source/ArachnaeSwarm/World/WorldObject_CatastropheMissile.cs
index 4d5a3d0..c3169da 100644
--- a/Source/ArachnaeSwarm/World/WorldObject_CatastropheMissile.cs
+++ b/Source/ArachnaeSwarm/World/WorldObject_CatastropheMissile.cs
@@ -60,8 +60,8 @@ namespace ArachnaeSwarm
Map targetMap = Current.Game.FindMap(this.destinationTile);
if (targetMap != null)
{
- // Find a random entry point at the edge of the target map
- IntVec3 entryCell = CellFinder.RandomEdgeCell(targetMap);
+ // Find a random entry point at the north edge of the target map
+ IntVec3 entryCell = CellFinder.RandomEdgeCell(Rot4.North, targetMap);
// Spawn the final projectile (the cruise missile) at the entry point
Projectile_CruiseMissile missile = (Projectile_CruiseMissile)GenSpawn.Spawn(this.Projectile, entryCell, targetMap, WipeMode.Vanish);