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);