暂存
This commit is contained in:
Binary file not shown.
@@ -39,8 +39,9 @@
|
|||||||
<inertiaDistance>6</inertiaDistance>
|
<inertiaDistance>6</inertiaDistance>
|
||||||
<collisionDamageDef>Blunt</collisionDamageDef>
|
<collisionDamageDef>Blunt</collisionDamageDef>
|
||||||
<flyerDef>ARA_Flyer_TrackingCharge</flyerDef>
|
<flyerDef>ARA_Flyer_TrackingCharge</flyerDef>
|
||||||
<collisionRadius>2.5</collisionRadius> <!-- Larger collision radius -->
|
<collisionRadius>1.5</collisionRadius> <!-- Larger collision radius -->
|
||||||
<impactSound>Pawn_Melee_BigBash_HitPawn</impactSound>
|
<impactSound>Pawn_Melee_BigBash_HitPawn</impactSound>
|
||||||
|
<damageHostileOnly>true</damageHostileOnly> <!-- Set to false to damage everyone in the path -->
|
||||||
</li>
|
</li>
|
||||||
<li Class="CompProperties_AbilityEffecterOnCaster">
|
<li Class="CompProperties_AbilityEffecterOnCaster">
|
||||||
<effecterDef>WarTrumpet</effecterDef>
|
<effecterDef>WarTrumpet</effecterDef>
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ namespace ArachnaeSwarm
|
|||||||
public ThingDef flyerDef;
|
public ThingDef flyerDef;
|
||||||
public float collisionRadius = 1.5f;
|
public float collisionRadius = 1.5f;
|
||||||
public SoundDef impactSound;
|
public SoundDef impactSound;
|
||||||
|
public bool damageHostileOnly = true;
|
||||||
|
|
||||||
public CompProperties_TrackingCharge()
|
public CompProperties_TrackingCharge()
|
||||||
{
|
{
|
||||||
this.compClass = typeof(CompAbilityEffect_TrackingCharge);
|
this.compClass = typeof(CompAbilityEffect_TrackingCharge);
|
||||||
|
|||||||
@@ -18,9 +18,10 @@ namespace ArachnaeSwarm
|
|||||||
public float inertiaDistance;
|
public float inertiaDistance;
|
||||||
public DamageDef collisionDamageDef;
|
public DamageDef collisionDamageDef;
|
||||||
public LocalTargetInfo primaryTarget;
|
public LocalTargetInfo primaryTarget;
|
||||||
public int maxFlightTicks;
|
|
||||||
public float collisionRadius;
|
public float collisionRadius;
|
||||||
public SoundDef impactSound;
|
public SoundDef impactSound;
|
||||||
|
public bool damageHostileOnly;
|
||||||
|
public int maxFlightTicks;
|
||||||
|
|
||||||
// --- Internal state ---
|
// --- Internal state ---
|
||||||
private bool homing = true;
|
private bool homing = true;
|
||||||
@@ -68,7 +69,7 @@ namespace ArachnaeSwarm
|
|||||||
pawn.Destroy();
|
pawn.Destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SpawnSetup(Map map, bool respawningAfterLoad)
|
public override void SpawnSetup(Map map, bool respawningAfterLoad)
|
||||||
{
|
{
|
||||||
base.SpawnSetup(map, respawningAfterLoad);
|
base.SpawnSetup(map, respawningAfterLoad);
|
||||||
@@ -77,14 +78,14 @@ namespace ArachnaeSwarm
|
|||||||
this.exactPosition = base.DrawPos;
|
this.exactPosition = base.DrawPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Tick()
|
protected override void Tick()
|
||||||
{
|
{
|
||||||
// --- THE CORRECT APPROACH ---
|
// --- THE CORRECT APPROACH ---
|
||||||
// Let the base class handle all flight mechanics (position, timing, etc.)
|
// Let the base class handle all flight mechanics (position, timing, etc.)
|
||||||
// We only intervene to do two things:
|
// We only intervene to do two things:
|
||||||
// 1. Continuously update the destination to "steer" the flyer.
|
// 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)
|
if (homing && primaryTarget.HasThing && primaryTarget.Thing.Spawned)
|
||||||
{
|
{
|
||||||
@@ -92,10 +93,9 @@ namespace ArachnaeSwarm
|
|||||||
DestCellInfo.SetValue(this, primaryTarget.Thing.Position);
|
DestCellInfo.SetValue(this, primaryTarget.Thing.Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform our custom collision check.
|
// --- Primary Target Collision Check ---
|
||||||
if (!hasHitPrimaryTarget && primaryTarget.HasThing && primaryTarget.Thing.Spawned)
|
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)
|
if ((this.DrawPos - primaryTarget.Thing.DrawPos).sqrMagnitude < this.collisionRadius * this.collisionRadius)
|
||||||
{
|
{
|
||||||
// --- Impact! ---
|
// --- Impact! ---
|
||||||
@@ -104,8 +104,6 @@ namespace ArachnaeSwarm
|
|||||||
SoundStarter.PlayOneShot(this.impactSound, new TargetInfo(this.Position, this.Map));
|
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);
|
Vector3 startPosition = (Vector3)StartVecInfo.GetValue(this);
|
||||||
float distance = (this.DrawPos - startPosition).magnitude;
|
float distance = (this.DrawPos - startPosition).magnitude;
|
||||||
float calculatedDamage = this.initialDamage + (distance * this.damagePerTile);
|
float calculatedDamage = this.initialDamage + (distance * this.damagePerTile);
|
||||||
@@ -114,11 +112,8 @@ namespace ArachnaeSwarm
|
|||||||
primaryTarget.Thing.TakeDamage(dinfo);
|
primaryTarget.Thing.TakeDamage(dinfo);
|
||||||
hasHitPrimaryTarget = true;
|
hasHitPrimaryTarget = true;
|
||||||
|
|
||||||
// Stop homing. The flyer will now continue to its last set destination.
|
|
||||||
homing = false;
|
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;
|
Vector3 direction = (this.DrawPos - startPosition).normalized;
|
||||||
IntVec3 inertiaEndPos = (this.DrawPos + (direction * this.inertiaDistance)).ToIntVec3();
|
IntVec3 inertiaEndPos = (this.DrawPos + (direction * this.inertiaDistance)).ToIntVec3();
|
||||||
DestCellInfo.SetValue(this, inertiaEndPos);
|
DestCellInfo.SetValue(this, inertiaEndPos);
|
||||||
@@ -126,35 +121,36 @@ namespace ArachnaeSwarm
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- AOE Damage Logic ---
|
// --- AOE Damage Logic ---
|
||||||
// Damage other hostiles in the path.
|
|
||||||
float distanceTravelled = ((Vector3)StartVecInfo.GetValue(this) - this.DrawPos).magnitude;
|
float distanceTravelled = ((Vector3)StartVecInfo.GetValue(this) - this.DrawPos).magnitude;
|
||||||
float currentAOEDamage = this.initialDamage + (distanceTravelled * this.damagePerTile);
|
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 != 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);
|
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.
|
// 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();
|
base.Tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void RespawnPawn()
|
protected override void RespawnPawn()
|
||||||
{
|
{
|
||||||
// This is the correct place to call the base method.
|
// 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();
|
base.RespawnPawn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ namespace ArachnaeSwarm
|
|||||||
trackingCharge.primaryTarget = this.currentTarget;
|
trackingCharge.primaryTarget = this.currentTarget;
|
||||||
trackingCharge.collisionRadius = props.collisionRadius;
|
trackingCharge.collisionRadius = props.collisionRadius;
|
||||||
trackingCharge.impactSound = props.impactSound;
|
trackingCharge.impactSound = props.impactSound;
|
||||||
|
trackingCharge.damageHostileOnly = props.damageHostileOnly;
|
||||||
|
|
||||||
// Setup and spawn
|
// Setup and spawn
|
||||||
trackingCharge.StartFlight(this.CasterPawn, this.currentTarget.Cell);
|
trackingCharge.StartFlight(this.CasterPawn, this.currentTarget.Cell);
|
||||||
|
|||||||
Reference in New Issue
Block a user