暂存
This commit is contained in:
Binary file not shown.
@@ -6,8 +6,8 @@
|
||||
<defName>ARA_Flyer_TrackingCharge</defName>
|
||||
<thingClass>ArachnaeSwarm.PawnFlyer_TrackingCharge</thingClass>
|
||||
<pawnFlyer>
|
||||
<flightSpeed>0.1</flightSpeed>
|
||||
<heightFactor>0.1</heightFactor>
|
||||
<flightSpeed>0.5</flightSpeed>
|
||||
<heightFactor>0</heightFactor>
|
||||
</pawnFlyer>
|
||||
</ThingDef>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<defName>ARA_Ability_TrackingCharge</defName>
|
||||
<label>追踪冲撞</label>
|
||||
<description>阿拉克涅盾头种对目标发起蓄势冲撞,对路径上的一切造成伤害。飞行的距离越远,伤害越高。</description>
|
||||
<iconPath>UI/Abilities/Charge</iconPath> <!-- Placeholder Icon -->
|
||||
<iconPath>UI/Commands/WarTrumpet</iconPath> <!-- Placeholder Icon -->
|
||||
<cooldownTicksRange>600</cooldownTicksRange>
|
||||
<verbProperties>
|
||||
<verbClass>ArachnaeSwarm.Verb_CastAbilityTrackingCharge</verbClass>
|
||||
@@ -36,8 +36,8 @@
|
||||
<homingSpeed>1.5</homingSpeed>
|
||||
<initialDamage>15</initialDamage>
|
||||
<damagePerTile>2</damagePerTile>
|
||||
<inertiaDistance>4</inertiaDistance>
|
||||
<collisionDamageDef>Crush</collisionDamageDef>
|
||||
<inertiaDistance>6</inertiaDistance>
|
||||
<collisionDamageDef>Blunt</collisionDamageDef>
|
||||
<flyerDef>ARA_Flyer_TrackingCharge</flyerDef>
|
||||
</li>
|
||||
</comps>
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace ArachnaeSwarm
|
||||
public float inertiaDistance;
|
||||
public DamageDef collisionDamageDef;
|
||||
public LocalTargetInfo primaryTarget;
|
||||
public int maxFlightTicks;
|
||||
|
||||
// --- Internal state ---
|
||||
private Vector3 currentSpeed;
|
||||
@@ -24,6 +25,7 @@ namespace ArachnaeSwarm
|
||||
private bool homing = true;
|
||||
private int inertiaTicks = -1;
|
||||
private Vector3 exactPosition;
|
||||
private bool hasHitPrimaryTarget = false;
|
||||
|
||||
// --- Reflection Fields ---
|
||||
private static FieldInfo TicksFlyingInfo;
|
||||
@@ -112,8 +114,9 @@ namespace ArachnaeSwarm
|
||||
float calculatedDamage = this.initialDamage + (this.distanceTraveled * this.damagePerTile);
|
||||
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);
|
||||
homing = false;
|
||||
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))
|
||||
{
|
||||
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);
|
||||
else if (thing.def.destroyable && thing.def.building != null) thing.TakeDamage(dinfo);
|
||||
}
|
||||
@@ -129,8 +134,10 @@ namespace ArachnaeSwarm
|
||||
|
||||
try
|
||||
{
|
||||
// We still need to update the destination for the base flyer logic to work correctly
|
||||
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)
|
||||
{
|
||||
@@ -138,9 +145,9 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
|
||||
TicksFlyingInfo.SetValue(this, ticksFlying + 1);
|
||||
|
||||
int flightTime = (int)TicksFlightTimeInfo.GetValue(this);
|
||||
if (!this.exactPosition.ToIntVec3().InBounds(this.Map) || ticksFlying > flightTime * 2)
|
||||
|
||||
// --- RELIABLE TIMEOUT & BOUNDS CHECK ---
|
||||
if (ticksFlying > this.maxFlightTicks || !this.exactPosition.ToIntVec3().InBounds(this.Map))
|
||||
{
|
||||
Land();
|
||||
}
|
||||
|
||||
@@ -21,11 +21,21 @@ namespace ArachnaeSwarm
|
||||
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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// --- This is now a fully custom Thing, so we spawn it directly ---
|
||||
var trackingCharge = (PawnFlyer_TrackingCharge)ThingMaker.MakeThing(props.flyerDef);
|
||||
|
||||
@@ -37,9 +47,20 @@ namespace ArachnaeSwarm
|
||||
trackingCharge.collisionDamageDef = props.collisionDamageDef;
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user