diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll
index bb89772..a3f0ccc 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/AbilityDefs/Abilities_TrackingCharge.xml b/1.6/1.6/Defs/AbilityDefs/Abilities_TrackingCharge.xml
index 035eb3a..9d0b745 100644
--- a/1.6/1.6/Defs/AbilityDefs/Abilities_TrackingCharge.xml
+++ b/1.6/1.6/Defs/AbilityDefs/Abilities_TrackingCharge.xml
@@ -39,8 +39,9 @@
6
Blunt
ARA_Flyer_TrackingCharge
- 2.5
+ 1.5
Pawn_Melee_BigBash_HitPawn
+ true
WarTrumpet
diff --git a/Source/ArachnaeSwarm/Abilities/CompProperties_TrackingCharge.cs b/Source/ArachnaeSwarm/Abilities/CompProperties_TrackingCharge.cs
index 2ab22a9..2865f46 100644
--- a/Source/ArachnaeSwarm/Abilities/CompProperties_TrackingCharge.cs
+++ b/Source/ArachnaeSwarm/Abilities/CompProperties_TrackingCharge.cs
@@ -13,6 +13,8 @@ namespace ArachnaeSwarm
public ThingDef flyerDef;
public float collisionRadius = 1.5f;
public SoundDef impactSound;
+ public bool damageHostileOnly = true;
+
public CompProperties_TrackingCharge()
{
this.compClass = typeof(CompAbilityEffect_TrackingCharge);
diff --git a/Source/ArachnaeSwarm/Abilities/PawnFlyer_TrackingCharge.cs b/Source/ArachnaeSwarm/Abilities/PawnFlyer_TrackingCharge.cs
index 378472c..e1767a8 100644
--- a/Source/ArachnaeSwarm/Abilities/PawnFlyer_TrackingCharge.cs
+++ b/Source/ArachnaeSwarm/Abilities/PawnFlyer_TrackingCharge.cs
@@ -18,9 +18,10 @@ namespace ArachnaeSwarm
public float inertiaDistance;
public DamageDef collisionDamageDef;
public LocalTargetInfo primaryTarget;
- public int maxFlightTicks;
public float collisionRadius;
public SoundDef impactSound;
+ public bool damageHostileOnly;
+ public int maxFlightTicks;
// --- Internal state ---
private bool homing = true;
@@ -68,7 +69,7 @@ namespace ArachnaeSwarm
pawn.Destroy();
}
}
-
+
public override void SpawnSetup(Map map, bool respawningAfterLoad)
{
base.SpawnSetup(map, respawningAfterLoad);
@@ -77,14 +78,14 @@ namespace ArachnaeSwarm
this.exactPosition = base.DrawPos;
}
}
-
+
protected override void Tick()
{
// --- THE CORRECT APPROACH ---
// Let the base class handle all flight mechanics (position, timing, etc.)
// We only intervene to do two things:
// 1. Continuously update the destination to "steer" the flyer.
- // 2. Perform our own collision check.
+ // 2. Perform our own collision checks (for primary target and AOE).
if (homing && primaryTarget.HasThing && primaryTarget.Thing.Spawned)
{
@@ -92,10 +93,9 @@ namespace ArachnaeSwarm
DestCellInfo.SetValue(this, primaryTarget.Thing.Position);
}
- // Perform our custom collision check.
+ // --- Primary Target Collision Check ---
if (!hasHitPrimaryTarget && primaryTarget.HasThing && primaryTarget.Thing.Spawned)
{
- // Use DrawPos for accurate distance checking, not Position.
if ((this.DrawPos - primaryTarget.Thing.DrawPos).sqrMagnitude < this.collisionRadius * this.collisionRadius)
{
// --- Impact! ---
@@ -104,8 +104,6 @@ namespace ArachnaeSwarm
SoundStarter.PlayOneShot(this.impactSound, new TargetInfo(this.Position, this.Map));
}
- // Calculate damage based on distance traveled so far.
- // We need to get the distance from the base class now.
Vector3 startPosition = (Vector3)StartVecInfo.GetValue(this);
float distance = (this.DrawPos - startPosition).magnitude;
float calculatedDamage = this.initialDamage + (distance * this.damagePerTile);
@@ -114,11 +112,8 @@ namespace ArachnaeSwarm
primaryTarget.Thing.TakeDamage(dinfo);
hasHitPrimaryTarget = true;
- // Stop homing. The flyer will now continue to its last set destination.
homing = false;
- // To create the "inertia" effect, we now set the destination to be a point
- // past the target.
Vector3 direction = (this.DrawPos - startPosition).normalized;
IntVec3 inertiaEndPos = (this.DrawPos + (direction * this.inertiaDistance)).ToIntVec3();
DestCellInfo.SetValue(this, inertiaEndPos);
@@ -126,35 +121,36 @@ namespace ArachnaeSwarm
}
// --- AOE Damage Logic ---
- // Damage other hostiles in the path.
float distanceTravelled = ((Vector3)StartVecInfo.GetValue(this) - this.DrawPos).magnitude;
float currentAOEDamage = this.initialDamage + (distanceTravelled * this.damagePerTile);
- foreach (var thing in GenRadial.RadialDistinctThingsAround(this.Position, this.Map, 1.0f, false))
+ foreach (var thing in GenRadial.RadialDistinctThingsAround(this.Position, this.Map, this.collisionRadius, false))
{
if (thing != this.FlyingPawn && thing != this && thing != primaryTarget.Thing)
{
- if (thing is Pawn pawn && !pawn.Downed && pawn.HostileTo(this.FlyingPawn))
+ if (thing is Pawn pawn && !pawn.Downed)
+ {
+ if (!this.damageHostileOnly || pawn.HostileTo(this.FlyingPawn))
+ {
+ var aoeDinfo = new DamageInfo(this.collisionDamageDef, currentAOEDamage, 1f, -1, this.FlyingPawn);
+ pawn.TakeDamage(aoeDinfo);
+ }
+ }
+ else if (thing.def.destroyable && thing.def.building != null)
{
- // --- CRITICAL FIX ---
- // Create a *new* DamageInfo object for each target.
- // Reusing the same dinfo object causes its damage value to be modified (e.g., by armor),
- // resulting in subsequent targets taking zero damage.
var aoeDinfo = new DamageInfo(this.collisionDamageDef, currentAOEDamage, 1f, -1, this.FlyingPawn);
- pawn.TakeDamage(aoeDinfo);
+ thing.TakeDamage(aoeDinfo);
}
}
}
// Let the base class do its thing. This is crucial.
- // It will handle the movement, timing, and eventual landing based on its calculated ticksFlightTime.
base.Tick();
}
protected override void RespawnPawn()
{
// This is the correct place to call the base method.
- // The base class's TickInterval will call this method before destroying the flyer.
base.RespawnPawn();
}
}
diff --git a/Source/ArachnaeSwarm/Abilities/Verb_CastAbilityTrackingCharge.cs b/Source/ArachnaeSwarm/Abilities/Verb_CastAbilityTrackingCharge.cs
index e69a855..d4225f1 100644
--- a/Source/ArachnaeSwarm/Abilities/Verb_CastAbilityTrackingCharge.cs
+++ b/Source/ArachnaeSwarm/Abilities/Verb_CastAbilityTrackingCharge.cs
@@ -48,6 +48,7 @@ namespace ArachnaeSwarm
trackingCharge.primaryTarget = this.currentTarget;
trackingCharge.collisionRadius = props.collisionRadius;
trackingCharge.impactSound = props.impactSound;
+ trackingCharge.damageHostileOnly = props.damageHostileOnly;
// Setup and spawn
trackingCharge.StartFlight(this.CasterPawn, this.currentTarget.Cell);