Files
ArachnaeSwarm/Source/ArachnaeSwarm/Abilities/TrackingCharge/Verb_CastAbilityTrackingCharge.cs
ProjectKoi-Kalo\Kalo 675ac8b298 创建了 ArachnaeSwarmSettings.cs - 包含 enableDebugLogs 字段
 创建了 ArachnaeLog.cs - 中央化日志类,仅检查mod设置(不检查DevMode)
 创建了 ArachnaeSwarmMod.cs - Mod主类,提供UI设置选项
 修改了 MainHarmony.cs - 移除重复的Harmony初始化(现在由ArachnaeSwarmMod处理)
 修改了 .csproj - 添加了3个新文件到编译列表
 替换了所有582个 Log.Message/Error/Warning 调用为 ArachnaeLog.Debug()
2025-12-15 13:11:45 +08:00

67 lines
2.8 KiB
C#

using RimWorld;
using Verse;
using System.Linq;
namespace ArachnaeSwarm
{
public class Verb_CastAbilityTrackingCharge : Verb_CastAbility
{
protected override bool TryCastShot()
{
var props = this.ability.def.comps?.OfType<CompProperties_TrackingCharge>().FirstOrDefault();
if (props == null)
{
ArachnaeLog.Debug("Verb_CastAbilityTrackingCharge requires CompProperties_TrackingCharge on the ability def.");
return false;
}
if (props.flyerDef == null)
{
ArachnaeLog.Debug("CompProperties_TrackingCharge requires a flyerDef.");
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)
{
ArachnaeLog.Debug($"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);
// Inject properties
trackingCharge.homingSpeed = props.homingSpeed;
trackingCharge.initialDamage = props.initialDamage;
trackingCharge.damagePerTile = props.damagePerTile;
trackingCharge.inertiaDistance = props.inertiaDistance;
trackingCharge.collisionDamageDef = props.collisionDamageDef;
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);
GenSpawn.Spawn(trackingCharge, this.CasterPawn.Position, map); // Use the cached map
// --- FIX for Comp Effects ---
// --- The Standard Pattern to trigger Comps like EffecterOnCaster ---
// After our custom verb logic (spawning the flyer) is done,
// we call the ability's Activate method with invalid targets.
// This triggers the standard Comp cycle without re-casting the verb.
this.ability.Activate(LocalTargetInfo.Invalid, LocalTargetInfo.Invalid);
return true;
}
}
}