Files
WulaFallenEmpireRW/Source/WulaFallenEmpire/HarmonyPatches/WULA_MechUnit/Patch_ColonistBarMech.cs
2026-02-24 12:02:38 +08:00

182 lines
7.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// File: Patches/ColonistBarMechPatch_Fixed.cs
using HarmonyLib;
using RimWorld;
using System.Collections.Generic;
using System.Linq;
using Verse;
using Verse.AI;
namespace WulaFallenEmpire
{
[HarmonyPatch(typeof(ColonistBar), "CheckRecacheEntries")]
public static class Patch_ColonistBarMech_Fixed
{
[HarmonyPostfix]
public static void Postfix(ref List<ColonistBar.Entry> ___cachedEntries)
{
// 安全检查:只在玩家派系存在时运行
if (Faction.OfPlayer == null)
return;
try
{
// 建立机甲和驾驶员的映射关系
var mechToPilots = new Dictionary<Pawn, List<Pawn>>();
var pilotToMech = new Dictionary<Pawn, Pawn>();
var mechEntries = new HashSet<Pawn>();
// 只扫描玩家殖民地的地图
foreach (var map in Find.Maps.Where(m => m.IsPlayerHome))
{
foreach (var pawn in map.mapPawns.AllPawnsSpawned)
{
// 只处理玩家殖民地的机甲Wulamechunit
if (pawn is Wulamechunit mech &&
(mech.Faction == Faction.OfPlayer || mech.HostFaction == Faction.OfPlayer))
{
var pilotComp = mech.TryGetComp<CompMechPilotHolder>();
if (pilotComp != null && pilotComp.HasPilots)
{
var pilots = pilotComp.GetPilots()
.Where(p => p.Faction == Faction.OfPlayer || p.HostFaction == Faction.OfPlayer)
.ToList();
if (pilots.Count > 0)
{
mechToPilots[mech] = pilots;
foreach (var pilot in pilots)
{
pilotToMech[pilot] = mech;
}
}
}
}
}
}
// 如果没有找到有机甲驾驶员的机甲,直接返回
if (mechToPilots.Count == 0)
return;
// 创建新的条目列表
var newEntries = new List<ColonistBar.Entry>();
// 第一轮:处理原始条目,隐藏驾驶员
foreach (var entry in ___cachedEntries)
{
var pawn = entry.pawn;
if (pawn == null)
{
// 保留空条目
newEntries.Add(entry);
continue;
}
// 如果是驾驶员,跳过(隐藏)
if (pilotToMech.ContainsKey(pawn))
{
continue;
}
// 如果是机甲
if (mechToPilots.ContainsKey(pawn))
{
// 确保机甲还没有被添加,并且有驾驶员
if (!mechEntries.Contains(pawn) && mechToPilots[pawn].Count > 0)
{
newEntries.Add(entry);
mechEntries.Add(pawn);
}
}
else
{
// 普通殖民者(不属于任何机甲的驾驶员)
newEntries.Add(entry);
}
}
// 第二轮:确保有机甲驾驶员的机甲被添加到列表
foreach (var mech in mechToPilots.Keys)
{
// 如果机甲还没有被添加,且有驾驶员
if (!mechEntries.Contains(mech) && mechToPilots[mech].Count > 0)
{
// 需要创建一个新的Entry
var map = mech.MapHeld;
if (map != null && map.IsPlayerHome)
{
// 计算group需要找到地图对应的group
int group = GetGroupForMap(map, ___cachedEntries);
newEntries.Add(new ColonistBar.Entry(mech, map, group));
mechEntries.Add(mech);
}
else if (mechToPilots[mech].Count > 0)
{
// 如果机甲不在任何地图上(可能被携带等),但仍有驾驶员
// 使用第一个驾驶员的地图和group作为参考
var pilot = mechToPilots[mech].First();
var pilotMap = pilot.MapHeld;
if (pilotMap != null && pilotMap.IsPlayerHome)
{
int group = GetGroupForMap(pilotMap, ___cachedEntries);
newEntries.Add(new ColonistBar.Entry(mech, pilotMap, group));
mechEntries.Add(mech);
}
}
}
}
// 替换原列表
___cachedEntries = newEntries;
}
catch (System.Exception ex)
{
Log.Error($"[DD] Error in fixed ColonistBar patch: {ex}");
// 出错时不改变原列表
}
}
// 辅助方法获取地图对应的group
private static int GetGroupForMap(Map map, List<ColonistBar.Entry> originalEntries)
{
if (map == null)
return 0;
// 在原始条目中查找第一个属于该地图的条目返回它的group
var entry = originalEntries.FirstOrDefault(e => e.map == map && e.pawn != null);
if (entry.pawn != null)
{
return entry.group;
}
// 如果没有找到有pawn的条目尝试查找任何属于该地图的条目包括空条目
entry = originalEntries.FirstOrDefault(e => e.map == map);
if (entry.map != null)
{
return entry.group;
}
// 如果还是找不到返回0作为默认值
return 0;
}
// 备用方案使用更简单的方法计算group
private static int CalculateGroupForMap(Map map)
{
if (map == null)
return 0;
// 简单的计算:玩家殖民地地图的索引
// 注意:这可能不完全准确,但通常工作
var playerMaps = Find.Maps.Where(m => m.IsPlayerHome).ToList();
int index = playerMaps.IndexOf(map);
// 如果找不到返回0
if (index < 0)
return 0;
return index;
}
}
}