# Plan: 天巫集群掠食 — 空投拦截系统 **TL;DR**:通过 Harmony Prefix 补丁拦截原版 `EdgeDrop` 和 `CenterDrop` 的 `Arrive()` 方法,在敌方空投仓落地前由天巫种拦截 1-3 个运输仓。击杀后尸体仍以运输仓形式落地。使用 `GameComponent` 全局管理开关状态,引航种 Pawn 通过自释放 `AbilityDef` 切换开关。拦截时生成天巫种 FlyOver 作为视觉反馈。 ## 架构概览 ``` [敌方袭击触发] IncidentWorker_RaidEnemy → Arrive(pawns, parms) ↓ Harmony Prefix [新增] Patch_DropPodIntercept → GameComponent_DropPodInterceptor.TryIntercept() ├── 检查 interceptEnabled (引航种toggle) ├── 检查 WorldComponent_AircraftManager 有可用天巫 ├── 验证 parms.faction.HostileTo(Player) ├── 随机选取 1-3 pawns → Kill → 获取 Corpse ├── 用 DropPodUtility.DropThingsNear 投掷尸体 ├── FlyOver.MakeFlyOver() 生成拦截飞越视觉 └── ReceiveLetter 通知玩家 → 原 Arrive 继续执行(剩余 pawn 正常空投) [引航种能力] ArachnaeNode_Race_Skyraider → AbilityDef: ARA_ToggleDropPodIntercept → CompAbilityEffect_ToggleDropPodIntercept.Apply() → GameComponent_DropPodInterceptor.ToggleIntercept() ``` --- ## Steps ### 1. 创建全局状态管理 `GameComponent_DropPodInterceptor` 新文件:`Source/ArachnaeSwarm/Flyover/GameComponent_DropPodInterceptor.cs` - 继承 `GameComponent`,序列化字段 `bool interceptEnabled` - 属性 `IsInterceptEnabled` — 外部查询开关状态 - 方法 `ToggleIntercept()` — 翻转开关 + `ArachnaeLog.Debug` - 方法 `HasAirborneTianwu()` — 查询 `WorldComponent_AircraftManager`:检查 `GetAvailableAircraftCount(ThingDef ARA_HiveCorvette_Entity, Faction.OfPlayer) > 0`(非全部冷却中即可,不消耗资源) - 核心方法 `TryInterceptDropPods(List pawns, IncidentParms parms, out List interceptedPawns)` — 完整拦截逻辑: - 前置条件检查(`interceptEnabled` && `HasAirborneTianwu()` && `parms.faction.HostileTo(Faction.OfPlayer)`) - 从 `pawns` 中随机移除 `Rand.RangeInclusive(1, Mathf.Min(3, pawns.Count - 1))` 个 Pawn(至少保留 1 个 pawn 正常空投,避免完全吞掉袭击) - 对每个被拦截的 Pawn:调用 `pawn.Kill(new DamageInfo(DamageDefOf.Bomb, 9999f))`,收集 `pawn.Corpse` 到尸体列表 - 将尸体通过 `DropPodUtility.DropThingsNear(parms.spawnCenter, map, corpses, leaveSlag: true)` 投掷到同一空投区域 - 调用 `SpawnInterceptionFlyOver(map, parms.spawnCenter)` 生成天巫飞越视觉 - 调用 `SendInterceptionLetter(map, interceptedCount, parms.spawnCenter)` 发送信件 - 方法 `SpawnInterceptionFlyOver(Map, IntVec3)` — 调用 `FlyOver.MakeFlyOver()` 生成 `ARA_HiveCorvette_Fake`(复用现有视觉 FlyOver ThingDef),起点从地图边缘到空投中心飞越 - 方法 `SendInterceptionLetter(Map, int count, IntVec3)` — 发送自定义 `LetterDefOf.PositiveEvent` 信件,告知玩家拦截了多少运输仓 - `ExposeData()` — `Scribe_Values.Look(ref interceptEnabled, "interceptEnabled", false)` ### 2. 创建 Harmony 补丁 `Patch_DropPodIntercept` 新文件:`Source/ArachnaeSwarm/HarmonyPatches/Patch_DropPodIntercept.cs` - `[HarmonyPatch(typeof(PawnsArrivalModeWorker_EdgeDrop), "Arrive")]` — Prefix - `[HarmonyPatch(typeof(PawnsArrivalModeWorker_CenterDrop), "Arrive")]` — Prefix - 两个 Prefix 共用同一个静态方法 `InterceptPrefix(List pawns, IncidentParms parms)` - Prefix 逻辑:获取 `Current.Game.GetComponent()`,调用 `TryInterceptDropPods(pawns, parms)` - **不 skip 原方法**(`return true`),原方法继续用被修改过的 `pawns` 列表正常空投剩余敌人 ### 3. 创建引航种切换能力 `CompAbilityEffect_ToggleDropPodIntercept` 新文件:`Source/ArachnaeSwarm/Abilities/CompAbilityEffect_ToggleDropPodIntercept.cs` - `CompProperties_ToggleDropPodIntercept` 继承 `CompProperties_AbilityEffect`,包含字段: - `string enabledMessage` / `disabledMessage` — 开启/关闭时的消息文本 key - `ThingDef requiredAircraftType` — 需要检查的战机类型(`ARA_HiveCorvette_Entity`) - `CompAbilityEffect_ToggleDropPodIntercept` 继承 `CompAbilityEffect`: - `Apply(LocalTargetInfo, LocalTargetInfo)` — 获取 `GameComponent_DropPodInterceptor`,调用 `ToggleIntercept()`,发送 `Messages.Message` 通知当前状态 - `Valid(LocalTargetInfo[], bool)` — 检查 `WorldComponent_AircraftManager.HasAvailableAircraft` 是否有天巫升空;无天巫时禁用能力并显示 "无可用天巫种" 提示 - `ExtraLabelMouseAttachment(LocalTargetInfo)` — 返回当前状态文本("掠食巡航: 开启/关闭") ### 4. 创建拦截 FlyOver 视觉 ThingDef 修改现有文件 `1.6/1.6/Defs/Thing_Misc/ARA_Flyover_Item.xml`,新增 `ARA_HiveCorvette_Intercept` ThingDef: - 以 `ARA_HiveCorvette_Fake` 为模板(纯视觉 FlyOver,无攻击 Comp) - `thingClass="ArachnaeSwarm.FlyOver"` - 设置较快的 `flightSpeed`(拦截应该是快速掠过) - 可选添加 `CompProperties_SendLetterAfterTicks` 以在飞越后发出完成通知 - 或直接复用 `ARA_HiveCorvette_Fake` defName,不新建 ThingDef ### 5. 创建能力 XML 定义 新文件:`1.6/1.6/Defs/AbilityDefs/Ability_DropPodIntercept.xml` - `AbilityDef` defName: `ARA_ToggleDropPodIntercept` - `label`: 掠食巡航(或类似命名) - `targetRequired: false`(自释放,无需目标) - `cooldownTicksRange: 0`(无冷却,即时切换) - `comps`: - `CompProperties_ToggleDropPodIntercept`(`requiredAircraftType: ARA_HiveCorvette_Entity`) ### 6. 将能力添加到引航种 查找并修改引航种 `ArachnaeNode_Race_Skyraider` 的能力列表定义(可能在 `1.6/1.6/Defs/PawnKindDef/ARA_PawnKinds.xml` 或 Race ThingDef 中),在 `abilities` 列表中添加 `ARA_ToggleDropPodIntercept` ### 7. 添加本地化文本 修改 `1.6/1.6/Languages/ChineseSimplified/Keyed/` 下的翻译文件,添加: - `ARA_ToggleDropPodIntercept_Label` — "掠食巡航" - `ARA_ToggleDropPodIntercept_Desc` — 能力描述 - `ARA_InterceptDropPod_Enabled` — "掠食巡航已启动" - `ARA_InterceptDropPod_Disabled` — "掠食巡航已关闭" - `ARA_InterceptDropPod_LetterLabel` — "天巫种拦截空投" - `ARA_InterceptDropPod_LetterText` — "天巫种在空中拦截了{0}个敌方运输仓…" - `ARA_InterceptDropPod_NoAircraft` — "没有可用的天巫种兽虫" --- ## Verification 1. MSBuild 编译:`cd "ArachnaeSwarm\Source\ArachnaeSwarm" && MSBuild ArachnaeSwarm.csproj -p:Configuration=Release` 2. 游戏内测试流程: - 建造天巫种机库 → 起飞(注册战机到 WorldComponent_AircraftManager) - 使用引航种能力开启"掠食巡航" - 使用 dev console 触发 `Raid (EdgeDrop)` → 验证 1-3 个运输仓被拦截(尸体掉落 + FlyOver 视觉 + 信件) - 使用 dev console 触发 `Raid (CenterDrop)` → 同上 - 关闭"掠食巡航" → 再次触发空投 → 验证不拦截 - 触发非空投袭击(EdgeWalkIn) → 验证不触发拦截 - 触发友方空投 → 验证不拦截(HostileTo 检查) 3. 存档/读档测试:验证 `interceptEnabled` 状态持久化 --- ## Decisions - **Harmony 挂钩点**:选 `PawnsArrivalModeWorker_EdgeDrop.Arrive` + `CenterDrop.Arrive` 而非底层 `DropPodUtility`,因为只需响应这两种袭击到场模式,不影响其他空投场景(贸易、任务奖励等) - **GameComponent vs MapComponent**:选 `GameComponent`(全局,跨地图),因为用户明确说"全局管理" - **不消耗战机资源**:只检查 `HasAvailableAircraft` 判断天巫是否升空,不调用 `TryUseAircraft` - **至少保留 1 个 pawn**:`Mathf.Min(3, pawns.Count - 1)` 确保不会完全吞掉袭击,玩家仍需应战 - **Kill + Corpse 方案**:调用 `Pawn.Kill(DamageInfo)` 后获取 `Corpse`,再通过 `DropPodUtility.DropThingsNear` 以运输仓形式投掷尸体,既有"被击杀"的反馈感,又能剥削敌方装备 - **复用 `ARA_HiveCorvette_Fake`**:优先复用现有纯视觉 FlyOver,避免新增无意义 ThingDef;若需要不同飞行参数再另建