This commit is contained in:
2026-02-24 12:02:38 +08:00
parent 1af5f0c1d8
commit 96bc1d4c5a
57 changed files with 6595 additions and 1170 deletions

View File

@@ -0,0 +1,181 @@
// 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;
}
}
}