Merge branch 'master' of https://git.ra3battle.cn/Kalospacer/ArachnaeSwarm
This commit is contained in:
@@ -37,6 +37,13 @@ namespace ArachnaeSwarm
|
|||||||
// Base tick handles all local targeting, cooldowns, and fuel consumption via XML.
|
// Base tick handles all local targeting, cooldowns, and fuel consumption via XML.
|
||||||
base.Tick();
|
base.Tick();
|
||||||
|
|
||||||
|
// --- Target Sanity Checks ---
|
||||||
|
// If we have a remote target, check if it's still valid. If not, stop targeting.
|
||||||
|
if (this.longTarget.HasThing && (this.longTarget.ThingDestroyed || !this.longTarget.Thing.Spawned))
|
||||||
|
{
|
||||||
|
this.longTarget = GlobalTargetInfo.Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
// If a local target is active, prevent remote targeting.
|
// If a local target is active, prevent remote targeting.
|
||||||
if (this.forcedTarget.IsValid && this.longTarget.IsValid)
|
if (this.forcedTarget.IsValid && this.longTarget.IsValid)
|
||||||
{
|
{
|
||||||
@@ -118,8 +125,9 @@ namespace ArachnaeSwarm
|
|||||||
DefDatabase<WorldObjectDef>.GetNamed("CatastropheMissile_Flying")
|
DefDatabase<WorldObjectDef>.GetNamed("CatastropheMissile_Flying")
|
||||||
);
|
);
|
||||||
missile.Tile = this.Map.Tile;
|
missile.Tile = this.Map.Tile;
|
||||||
missile.destinationTile = target.Tile;
|
missile.primaryTarget = target; // The primary target (could be a Thing)
|
||||||
missile.destinationCell = target.Cell;
|
missile.destinationTile = target.Tile; // The map tile
|
||||||
|
missile.destinationCell = target.Cell; // The fallback cell position
|
||||||
missile.Projectile = DefDatabase<ThingDef>.GetNamed("Projectile_CatastropheMissile");
|
missile.Projectile = DefDatabase<ThingDef>.GetNamed("Projectile_CatastropheMissile");
|
||||||
Find.WorldObjects.Add(missile);
|
Find.WorldObjects.Add(missile);
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ namespace ArachnaeSwarm
|
|||||||
{
|
{
|
||||||
public class WorldObject_CatastropheMissile : WorldObject
|
public class WorldObject_CatastropheMissile : WorldObject
|
||||||
{
|
{
|
||||||
public int destinationTile = -1;
|
public GlobalTargetInfo primaryTarget; // The actual target (can be a Thing)
|
||||||
public IntVec3 destinationCell = IntVec3.Invalid;
|
public int destinationTile = -1; // The map tile of the target
|
||||||
|
public IntVec3 destinationCell = IntVec3.Invalid; // The fallback cell position
|
||||||
public ThingDef Projectile;
|
public ThingDef Projectile;
|
||||||
|
|
||||||
private int initialTile = -1;
|
private int initialTile = -1;
|
||||||
@@ -18,6 +19,7 @@ namespace ArachnaeSwarm
|
|||||||
public override void ExposeData()
|
public override void ExposeData()
|
||||||
{
|
{
|
||||||
base.ExposeData();
|
base.ExposeData();
|
||||||
|
Scribe_TargetInfo.Look(ref primaryTarget, "primaryTarget");
|
||||||
Scribe_Values.Look(ref destinationTile, "destinationTile", 0);
|
Scribe_Values.Look(ref destinationTile, "destinationTile", 0);
|
||||||
Scribe_Values.Look(ref destinationCell, "destinationCell");
|
Scribe_Values.Look(ref destinationCell, "destinationCell");
|
||||||
Scribe_Defs.Look(ref Projectile, "Projectile");
|
Scribe_Defs.Look(ref Projectile, "Projectile");
|
||||||
@@ -39,6 +41,15 @@ namespace ArachnaeSwarm
|
|||||||
protected override void Tick()
|
protected override void Tick()
|
||||||
{
|
{
|
||||||
base.Tick();
|
base.Tick();
|
||||||
|
|
||||||
|
// Safety check: if the destination is invalid, log an error and remove the missile.
|
||||||
|
if (this.destinationTile < 0)
|
||||||
|
{
|
||||||
|
Log.Error("CatastropheMissile spawned with an invalid destination tile. Removing.");
|
||||||
|
Find.WorldObjects.Remove(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float distance = GenMath.SphericalDistance(StartPos.normalized, EndPos.normalized);
|
float distance = GenMath.SphericalDistance(StartPos.normalized, EndPos.normalized);
|
||||||
if(distance > 0)
|
if(distance > 0)
|
||||||
{
|
{
|
||||||
@@ -60,14 +71,23 @@ namespace ArachnaeSwarm
|
|||||||
Map targetMap = Current.Game.FindMap(this.destinationTile);
|
Map targetMap = Current.Game.FindMap(this.destinationTile);
|
||||||
if (targetMap != null)
|
if (targetMap != null)
|
||||||
{
|
{
|
||||||
// Find a random entry point at the north edge of the target map
|
// Determine the final target.
|
||||||
|
LocalTargetInfo finalTarget;
|
||||||
|
// Check if the primary target (Thing) is still valid and on the correct map.
|
||||||
|
if (primaryTarget.HasThing && primaryTarget.Thing.Spawned && primaryTarget.Thing.Map == targetMap)
|
||||||
|
{
|
||||||
|
// Target is still valid, aim at its current position.
|
||||||
|
finalTarget = new LocalTargetInfo(primaryTarget.Thing);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Target is invalid (destroyed, moved maps, etc.), use the fallback position.
|
||||||
|
finalTarget = new LocalTargetInfo(this.destinationCell);
|
||||||
|
}
|
||||||
|
|
||||||
IntVec3 entryCell = CellFinder.RandomEdgeCell(Rot4.North, targetMap);
|
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);
|
Projectile_CruiseMissile missile = (Projectile_CruiseMissile)GenSpawn.Spawn(this.Projectile, entryCell, targetMap, WipeMode.Vanish);
|
||||||
|
missile.Launch(null, entryCell.ToVector3Shifted(), finalTarget, finalTarget, ProjectileHitFlags.IntendedTarget);
|
||||||
// Launch it from the entry point towards the final destination cell
|
|
||||||
missile.Launch(null, entryCell.ToVector3Shifted(), new LocalTargetInfo(this.destinationCell), new LocalTargetInfo(this.destinationCell), ProjectileHitFlags.IntendedTarget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Find.WorldObjects.Remove(this);
|
Find.WorldObjects.Remove(this);
|
||||||
|
|||||||
Reference in New Issue
Block a user