This commit is contained in:
2025-12-02 12:01:49 +08:00
parent 5e8cdce517
commit afa048df89
2 changed files with 18 additions and 149 deletions

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using RimWorld;
using Verse;
using Verse.AI;
namespace WulaFallenEmpire
{
@@ -8,85 +9,17 @@ namespace WulaFallenEmpire
{
private CompProperties_PathCostUpdater Props => (CompProperties_PathCostUpdater)props;
// 记录是否需要更新路径成本
private bool needsPathUpdate = false;
// 记录需要更新的区域
private CellRect updateRect;
public override void Initialize(CompProperties props)
{
base.Initialize(props);
if (parent.Spawned)
{
MarkForPathUpdate();
}
}
public override void PostSpawnSetup(bool respawningAfterLoad)
{
base.PostSpawnSetup(respawningAfterLoad);
// 如果组件在生成后添加,也需要标记更新
if (!respawningAfterLoad)
{
MarkForPathUpdate();
}
}
public override void CompTick()
{
base.CompTick();
// 每帧检查是否需要更新路径
if (needsPathUpdate && parent.Spawned)
if (!respawningAfterLoad && parent.Spawned)
{
// 建筑生成时更新路径
UpdatePathCosts();
needsPathUpdate = false;
}
}
/// <summary>
/// 标记需要更新路径成本
/// </summary>
public void MarkForPathUpdate()
{
if (!parent.Spawned)
return;
needsPathUpdate = true;
// 计算需要更新的区域
updateRect = parent.OccupiedRect();
// 根据建筑大小决定扩展区域
int expandBy = CalculateExpandDistance();
updateRect = updateRect.ExpandedBy(expandBy);
updateRect = updateRect.ClipInsideMap(parent.Map);
}
/// <summary>
/// 根据建筑大小计算需要扩展的距离
/// </summary>
private int CalculateExpandDistance()
{
if (Props == null || !Props.adaptiveExpansion)
return 1;
// 根据建筑尺寸决定扩展距离
int size = parent.def.size.x * parent.def.size.z;
if (size <= 1) // 1x1 建筑
return 1;
else if (size <= 4) // 2x2 或 1x4 建筑
return 2;
else if (size <= 9) // 3x3 建筑
return 3;
else // 大型建筑
return 4;
}
/// <summary>
/// 更新路径成本
/// </summary>
@@ -97,80 +30,25 @@ namespace WulaFallenEmpire
Map map = parent.Map;
// 1. 更新路径网
RecalculatePathGrid(map);
// 获取建筑占用的所有单元
CellRect occupiedRect = parent.OccupiedRect();
// 2. 更新区域网格(如果需要)
UpdateRegionGrid(map);
// 3. 清理可达性缓存
ClearReachabilityCache(map);
}
/// <summary>
/// 重新计算路径网格
/// </summary>
private void RecalculatePathGrid(Map map)
{
// 使用局部变量跟踪是否已通知过变化
bool haveNotified = false;
// 根据组件属性决定扩展范围
int expandBy = Props != null && Props.expandToAdjacent ? Props.expandDistance : 0;
CellRect updateRect = occupiedRect.ExpandedBy(expandBy).ClipInsideMap(map);
// 更新指定区域内的路径成本
bool haveNotified = false;
foreach (IntVec3 cell in updateRect)
{
if (cell.InBounds(map))
{
// 调用PathGrid的正确方法根据您提供的PathGrid代码
map.pathGrid.RecalculatePerceivedPathCostAt(cell, ref haveNotified);
// 如果是可通行变化较大的建筑,需要更新相邻单元格
if (parent.def.passability == Traversability.Impassable ||
parent.def.passability == Traversability.PassThroughOnly)
{
foreach (IntVec3 adjacent in GenAdj.AdjacentCells)
{
IntVec3 adjCell = cell + adjacent;
if (adjCell.InBounds(map))
{
map.pathGrid.RecalculatePerceivedPathCostAt(adjCell, ref haveNotified);
}
}
}
// 使用 Pathing 的正确方法
map.pathing.RecalculatePerceivedPathCostAt(cell);
}
}
}
/// <summary>
/// 更新区域网格
/// </summary>
private void UpdateRegionGrid(Map map)
{
if (Props.updateRegions && parent.def.AffectsRegions)
{
// 标记区域网格需要更新
map.regionAndRoomUpdater.Enabled = true;
map.regionAndRoomUpdater.RebuildAllRegionsAndRooms();
}
else
{
// 只更新受影响区域
foreach (IntVec3 cell in updateRect)
{
if (cell.InBounds(map))
{
// 根据PathGrid代码使用Notify_WalkabilityChanged方法
map.regionDirtyer.Notify_WalkabilityChanged(cell, map.pathGrid.WalkableFast(cell));
}
}
}
}
/// <summary>
/// 清理可达性缓存
/// </summary>
private void ClearReachabilityCache(Map map)
{
// 清理整个地图的可达性缓存
// 清理可达性缓存
map.reachability.ClearCache();
}
@@ -179,11 +57,7 @@ namespace WulaFallenEmpire
/// </summary>
public void ForceImmediateUpdate()
{
if (parent.Spawned)
{
UpdatePathCosts();
needsPathUpdate = false;
}
UpdatePathCosts();
}
public override IEnumerable<Gizmo> CompGetGizmosExtra()
@@ -203,20 +77,15 @@ namespace WulaFallenEmpire
};
}
}
// 移除PostDeSpawn方法因为不需要处理销毁
}
public class CompProperties_PathCostUpdater : CompProperties
{
// 是否启用自适应扩展(根据建筑大小决定更新区域)
public bool adaptiveExpansion = true;
// 是否扩展到相邻单元格
public bool expandToAdjacent = true;
// 是否重建区域网格(性能消耗较大)
public bool updateRegions = false;
// 固定扩展距离如果adaptiveExpansion为false
public int fixedExpansionDistance = 1;
// 扩展距离
public int expandDistance = 1;
public CompProperties_PathCostUpdater()
{