暂存
This commit is contained in:
Binary file not shown.
@@ -6,8 +6,8 @@
|
|||||||
<defName>ARA_Flyer_TrackingCharge</defName>
|
<defName>ARA_Flyer_TrackingCharge</defName>
|
||||||
<thingClass>ArachnaeSwarm.PawnFlyer_TrackingCharge</thingClass>
|
<thingClass>ArachnaeSwarm.PawnFlyer_TrackingCharge</thingClass>
|
||||||
<pawnFlyer>
|
<pawnFlyer>
|
||||||
<flightSpeed>0.1</flightSpeed>
|
<flightSpeed>0.5</flightSpeed>
|
||||||
<heightFactor>0.1</heightFactor>
|
<heightFactor>0</heightFactor>
|
||||||
</pawnFlyer>
|
</pawnFlyer>
|
||||||
</ThingDef>
|
</ThingDef>
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<defName>ARA_Ability_TrackingCharge</defName>
|
<defName>ARA_Ability_TrackingCharge</defName>
|
||||||
<label>追踪冲撞</label>
|
<label>追踪冲撞</label>
|
||||||
<description>阿拉克涅盾头种对目标发起蓄势冲撞,对路径上的一切造成伤害。飞行的距离越远,伤害越高。</description>
|
<description>阿拉克涅盾头种对目标发起蓄势冲撞,对路径上的一切造成伤害。飞行的距离越远,伤害越高。</description>
|
||||||
<iconPath>UI/Abilities/Charge</iconPath> <!-- Placeholder Icon -->
|
<iconPath>UI/Commands/WarTrumpet</iconPath> <!-- Placeholder Icon -->
|
||||||
<cooldownTicksRange>600</cooldownTicksRange>
|
<cooldownTicksRange>600</cooldownTicksRange>
|
||||||
<verbProperties>
|
<verbProperties>
|
||||||
<verbClass>ArachnaeSwarm.Verb_CastAbilityTrackingCharge</verbClass>
|
<verbClass>ArachnaeSwarm.Verb_CastAbilityTrackingCharge</verbClass>
|
||||||
@@ -36,8 +36,8 @@
|
|||||||
<homingSpeed>1.5</homingSpeed>
|
<homingSpeed>1.5</homingSpeed>
|
||||||
<initialDamage>15</initialDamage>
|
<initialDamage>15</initialDamage>
|
||||||
<damagePerTile>2</damagePerTile>
|
<damagePerTile>2</damagePerTile>
|
||||||
<inertiaDistance>4</inertiaDistance>
|
<inertiaDistance>6</inertiaDistance>
|
||||||
<collisionDamageDef>Crush</collisionDamageDef>
|
<collisionDamageDef>Blunt</collisionDamageDef>
|
||||||
<flyerDef>ARA_Flyer_TrackingCharge</flyerDef>
|
<flyerDef>ARA_Flyer_TrackingCharge</flyerDef>
|
||||||
</li>
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace ArachnaeSwarm
|
|||||||
public float inertiaDistance;
|
public float inertiaDistance;
|
||||||
public DamageDef collisionDamageDef;
|
public DamageDef collisionDamageDef;
|
||||||
public LocalTargetInfo primaryTarget;
|
public LocalTargetInfo primaryTarget;
|
||||||
|
public int maxFlightTicks;
|
||||||
|
|
||||||
// --- Internal state ---
|
// --- Internal state ---
|
||||||
private Vector3 currentSpeed;
|
private Vector3 currentSpeed;
|
||||||
@@ -24,6 +25,7 @@ namespace ArachnaeSwarm
|
|||||||
private bool homing = true;
|
private bool homing = true;
|
||||||
private int inertiaTicks = -1;
|
private int inertiaTicks = -1;
|
||||||
private Vector3 exactPosition;
|
private Vector3 exactPosition;
|
||||||
|
private bool hasHitPrimaryTarget = false;
|
||||||
|
|
||||||
// --- Reflection Fields ---
|
// --- Reflection Fields ---
|
||||||
private static FieldInfo TicksFlyingInfo;
|
private static FieldInfo TicksFlyingInfo;
|
||||||
@@ -112,8 +114,9 @@ namespace ArachnaeSwarm
|
|||||||
float calculatedDamage = this.initialDamage + (this.distanceTraveled * this.damagePerTile);
|
float calculatedDamage = this.initialDamage + (this.distanceTraveled * this.damagePerTile);
|
||||||
var dinfo = new DamageInfo(this.collisionDamageDef, calculatedDamage, 1f, -1, this.FlyingPawn);
|
var dinfo = new DamageInfo(this.collisionDamageDef, calculatedDamage, 1f, -1, this.FlyingPawn);
|
||||||
|
|
||||||
if (homing && primaryTarget.HasThing && (this.exactPosition - primaryTarget.Thing.DrawPos).sqrMagnitude < 1.5f * 1.5f)
|
if (!hasHitPrimaryTarget && homing && primaryTarget.HasThing && primaryTarget.Thing.Spawned && (this.exactPosition - primaryTarget.Thing.DrawPos).sqrMagnitude < 1.5f * 1.5f)
|
||||||
{
|
{
|
||||||
|
hasHitPrimaryTarget = true; // Mark as hit to prevent re-triggering
|
||||||
primaryTarget.Thing.TakeDamage(dinfo);
|
primaryTarget.Thing.TakeDamage(dinfo);
|
||||||
homing = false;
|
homing = false;
|
||||||
this.inertiaTicks = (int)(this.inertiaDistance / this.currentSpeed.magnitude);
|
this.inertiaTicks = (int)(this.inertiaDistance / this.currentSpeed.magnitude);
|
||||||
@@ -121,7 +124,9 @@ namespace ArachnaeSwarm
|
|||||||
|
|
||||||
foreach (var thing in GenRadial.RadialDistinctThingsAround(this.exactPosition.ToIntVec3(), this.Map, 1.0f, false))
|
foreach (var thing in GenRadial.RadialDistinctThingsAround(this.exactPosition.ToIntVec3(), this.Map, 1.0f, false))
|
||||||
{
|
{
|
||||||
if (thing == this.FlyingPawn || thing == this || thing == primaryTarget.Thing) continue;
|
// Avoid damaging self or the primary target (which is handled above)
|
||||||
|
if (thing == this.FlyingPawn || thing == this || (hasHitPrimaryTarget && thing == primaryTarget.Thing)) continue;
|
||||||
|
|
||||||
if (thing is Pawn pawn && !pawn.Downed && pawn.HostileTo(this.FlyingPawn)) pawn.TakeDamage(dinfo);
|
if (thing is Pawn pawn && !pawn.Downed && pawn.HostileTo(this.FlyingPawn)) pawn.TakeDamage(dinfo);
|
||||||
else if (thing.def.destroyable && thing.def.building != null) thing.TakeDamage(dinfo);
|
else if (thing.def.destroyable && thing.def.building != null) thing.TakeDamage(dinfo);
|
||||||
}
|
}
|
||||||
@@ -129,8 +134,10 @@ namespace ArachnaeSwarm
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// We still need to update the destination for the base flyer logic to work correctly
|
||||||
DestCellInfo.SetValue(this, this.exactPosition.ToIntVec3());
|
DestCellInfo.SetValue(this, this.exactPosition.ToIntVec3());
|
||||||
TicksFlightTimeInfo.SetValue(this, ticksFlying + 2);
|
// --- FIX for infinite flight ---
|
||||||
|
// The old TicksFlightTimeInfo update logic is removed.
|
||||||
}
|
}
|
||||||
catch (System.Exception ex)
|
catch (System.Exception ex)
|
||||||
{
|
{
|
||||||
@@ -139,8 +146,8 @@ namespace ArachnaeSwarm
|
|||||||
|
|
||||||
TicksFlyingInfo.SetValue(this, ticksFlying + 1);
|
TicksFlyingInfo.SetValue(this, ticksFlying + 1);
|
||||||
|
|
||||||
int flightTime = (int)TicksFlightTimeInfo.GetValue(this);
|
// --- RELIABLE TIMEOUT & BOUNDS CHECK ---
|
||||||
if (!this.exactPosition.ToIntVec3().InBounds(this.Map) || ticksFlying > flightTime * 2)
|
if (ticksFlying > this.maxFlightTicks || !this.exactPosition.ToIntVec3().InBounds(this.Map))
|
||||||
{
|
{
|
||||||
Land();
|
Land();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,16 @@ namespace ArachnaeSwarm
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Best Practice: Cache Map and Position FIRST ---
|
||||||
|
// Per MCP analysis, Caster.Map is the most reliable source.
|
||||||
|
// Cache this before ANY other logic.
|
||||||
|
Map map = this.Caster.Map;
|
||||||
|
if (map == null)
|
||||||
|
{
|
||||||
|
Log.Error($"Verb_CastAbilityTrackingCharge: Caster {this.Caster.LabelCap} has a null map. Cannot cast.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.CasterPawn == null || !this.CasterPawn.Spawned)
|
if (this.CasterPawn == null || !this.CasterPawn.Spawned)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -37,9 +47,20 @@ namespace ArachnaeSwarm
|
|||||||
trackingCharge.collisionDamageDef = props.collisionDamageDef;
|
trackingCharge.collisionDamageDef = props.collisionDamageDef;
|
||||||
trackingCharge.primaryTarget = this.currentTarget;
|
trackingCharge.primaryTarget = this.currentTarget;
|
||||||
|
|
||||||
|
// --- Dynamic Timeout Calculation ---
|
||||||
|
float flightSpeed = props.flyerDef.pawnFlyer.flightSpeed;
|
||||||
|
if (flightSpeed <= 0)
|
||||||
|
{
|
||||||
|
Log.Error("flyerDef has no flightSpeed, cannot calculate timeout.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Timeout is twice the time it would take to fly the max range in a straight line
|
||||||
|
int maxTicks = (int)((this.verbProps.range / flightSpeed) * 2.0f);
|
||||||
|
trackingCharge.maxFlightTicks = maxTicks;
|
||||||
|
|
||||||
// Setup and spawn
|
// Setup and spawn
|
||||||
trackingCharge.StartFlight(this.CasterPawn, this.currentTarget.Cell);
|
trackingCharge.StartFlight(this.CasterPawn, this.currentTarget.Cell);
|
||||||
GenSpawn.Spawn(trackingCharge, this.CasterPawn.Position, this.CasterPawn.Map);
|
GenSpawn.Spawn(trackingCharge, this.CasterPawn.Position, map); // Use the cached map
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user