356 lines
12 KiB
C#
356 lines
12 KiB
C#
using ArachnaeSwarm;
|
||
using RimWorld;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using UnityEngine;
|
||
using Verse;
|
||
|
||
namespace ArachnaeSwarm
|
||
{
|
||
public class Pawn_GestaltTracker : IExposable
|
||
{
|
||
private Pawn pawn;
|
||
private List<GestaltControlGroup> controlGroups = new List<GestaltControlGroup>();
|
||
private List<Pawn> controlledPawns = new List<Pawn>();
|
||
|
||
// 添加网络超载相关字段
|
||
private int currentOverloadLevel = 0;
|
||
private int ticksSinceLastOverloadCheck = 0;
|
||
private const int OVERLOAD_CHECK_INTERVAL = 60; // 每60tick检查一次
|
||
|
||
// 超载Hediff相关字段
|
||
private Hediff networkOverloadHediff;
|
||
private int ticksSinceLastHediffUpdate = 0;
|
||
private const int HEDIFF_UPDATE_INTERVAL = 120; // 每120tick更新一次Hediff严重性
|
||
|
||
// 公开属性
|
||
public Pawn Pawn => pawn;
|
||
public List<GestaltControlGroup> ControlGroups => controlGroups;
|
||
public List<Pawn> ControlledPawns => controlledPawns;
|
||
|
||
// 计算已使用的带宽(包括超载部分)
|
||
public int UsedBandwidth => (int)ControlledPawns.Sum(p => p.GetStatValue(ARA_StatDefOf.ARA_GestaltBandwidthCost));
|
||
|
||
// 计算基础带宽限制
|
||
public int TotalBandwidth => (int)pawn.GetStatValue(ARA_StatDefOf.ARA_GestaltBandwidth);
|
||
|
||
// 计算总可用控制组
|
||
public int TotalAvailableControlGroups => (int)pawn.GetStatValue(StatDefOf.MechControlGroups);
|
||
|
||
// 计算网络超载程度(超出带宽的部分)
|
||
public int NetworkOverload => Mathf.Max(0, UsedBandwidth - TotalBandwidth);
|
||
|
||
// 获取当前超载层数
|
||
public int CurrentOverloadLevel => currentOverloadLevel;
|
||
|
||
public AcceptanceReport CanControlPawns
|
||
{
|
||
get
|
||
{
|
||
if (pawn.Downed)
|
||
return "GestaltControllerDowned".Translate(pawn.Named("PAWN"));
|
||
if (pawn.IsPrisoner)
|
||
return "GestaltControllerImprisoned".Translate(pawn.Named("PAWN"));
|
||
if (!pawn.Spawned)
|
||
return false;
|
||
if (pawn.InMentalState)
|
||
return "GestaltControllerMentalState".Translate(pawn.Named("PAWN"), pawn.MentalStateDef.Named("MENTALSTATE"));
|
||
return true;
|
||
}
|
||
}
|
||
|
||
public Pawn_GestaltTracker() { }
|
||
|
||
public Pawn_GestaltTracker(Pawn pawn)
|
||
{
|
||
this.pawn = pawn;
|
||
Notify_ControlGroupAmountChanged();
|
||
}
|
||
|
||
public bool CanControlPawn(Pawn targetPawn)
|
||
{
|
||
// 移除带宽检查,允许超载连接
|
||
if (targetPawn.GetOverlord() != null)
|
||
return false;
|
||
|
||
// 检查是否在同一地图
|
||
if (pawn.Map != null && targetPawn.Map != null && pawn.Map != targetPawn.Map)
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
public GestaltControlGroup GetControlGroup(Pawn targetPawn)
|
||
{
|
||
foreach (GestaltControlGroup group in controlGroups)
|
||
{
|
||
if (group.AssignedPawns.Contains(targetPawn))
|
||
return group;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public void AssignPawnToControlGroup(Pawn targetPawn)
|
||
{
|
||
if (controlGroups.Count == 0)
|
||
{
|
||
Notify_ControlGroupAmountChanged();
|
||
if (controlGroups.Count == 0)
|
||
{
|
||
Log.Warning("Wants to assign pawn to a control group, but there are none!");
|
||
return;
|
||
}
|
||
}
|
||
|
||
// 分配到第一个可用的控制组
|
||
controlGroups[0].Assign(targetPawn);
|
||
Notify_BandwidthChanged();
|
||
UpdateNetworkOverload();
|
||
}
|
||
|
||
public void UnassignPawnFromAnyControlGroup(Pawn targetPawn)
|
||
{
|
||
foreach (GestaltControlGroup group in controlGroups)
|
||
{
|
||
if (group.TryUnassign(targetPawn))
|
||
{
|
||
Notify_BandwidthChanged();
|
||
UpdateNetworkOverload();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
public void Notify_ControlGroupAmountChanged()
|
||
{
|
||
int availableGroups = TotalAvailableControlGroups;
|
||
|
||
// 添加缺少的控制组
|
||
while (controlGroups.Count < availableGroups)
|
||
{
|
||
controlGroups.Add(new GestaltControlGroup(this));
|
||
}
|
||
|
||
// 移除多余的控制组(但如果有超载连接,可以保留额外的组)
|
||
if (!IsNetworkOverloaded())
|
||
{
|
||
while (controlGroups.Count > availableGroups)
|
||
{
|
||
GestaltControlGroup groupToRemove = controlGroups[controlGroups.Count - 1];
|
||
|
||
if (!groupToRemove.AssignedPawns.NullOrEmpty())
|
||
{
|
||
// 将pawn重新分配到其他组
|
||
foreach (Pawn pawn in groupToRemove.AssignedPawns)
|
||
{
|
||
if (controlGroups.Count > 1)
|
||
{
|
||
controlGroups[0].Assign(pawn);
|
||
}
|
||
}
|
||
}
|
||
|
||
controlGroups.RemoveAt(controlGroups.Count - 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
public void Notify_BandwidthChanged()
|
||
{
|
||
controlledPawns.Clear();
|
||
|
||
// 收集所有被控制的pawn
|
||
foreach (GestaltControlGroup group in controlGroups)
|
||
{
|
||
controlledPawns.AddRange(group.AssignedPawns.Where(p => !controlledPawns.Contains(p)));
|
||
}
|
||
|
||
// 不再自动断开超出带宽的连接
|
||
UpdateNetworkOverload();
|
||
}
|
||
|
||
public void UpdateNetworkOverload()
|
||
{
|
||
int newOverloadLevel = NetworkOverload;
|
||
|
||
// 如果超载级别发生变化
|
||
if (newOverloadLevel != currentOverloadLevel)
|
||
{
|
||
int oldLevel = currentOverloadLevel;
|
||
currentOverloadLevel = newOverloadLevel;
|
||
|
||
// 发送消息通知
|
||
if (currentOverloadLevel > 0 && oldLevel == 0)
|
||
{
|
||
Messages.Message("ARA_GestaltBandwidthExceeded".Translate(),
|
||
pawn, MessageTypeDefOf.NegativeEvent);
|
||
}
|
||
else if (currentOverloadLevel == 0 && oldLevel > 0)
|
||
{
|
||
Messages.Message("ARA_NetworkOverloadCleared".Translate(pawn.LabelShort),
|
||
pawn, MessageTypeDefOf.PositiveEvent);
|
||
// 移除超载Hediff
|
||
RemoveNetworkOverloadHediff();
|
||
}
|
||
}
|
||
|
||
// 更新Hediff严重性
|
||
UpdateNetworkOverloadHediff();
|
||
}
|
||
|
||
private void UpdateNetworkOverloadHediff()
|
||
{
|
||
if (currentOverloadLevel <= 0)
|
||
{
|
||
RemoveNetworkOverloadHediff();
|
||
return;
|
||
}
|
||
|
||
// 计算超载百分比
|
||
float overloadPercentage = 0f;
|
||
if (TotalBandwidth > 0)
|
||
{
|
||
overloadPercentage = (float)currentOverloadLevel / TotalBandwidth;
|
||
}
|
||
else
|
||
{
|
||
// 如果总带宽为0,则超载100%
|
||
overloadPercentage = 1.0f;
|
||
}
|
||
|
||
// 确保百分比不超过100%
|
||
overloadPercentage = Mathf.Clamp01(overloadPercentage);
|
||
|
||
// 获取或创建超载Hediff
|
||
HediffDef overloadHediffDef = ARA_HediffDefOf.ARA_GestaltNetworkOverload;
|
||
if (overloadHediffDef == null)
|
||
{
|
||
Log.Error("ARA_GestaltNetworkOverload hediff def not found!");
|
||
return;
|
||
}
|
||
|
||
if (networkOverloadHediff == null)
|
||
{
|
||
// 添加新的超载Hediff
|
||
networkOverloadHediff = pawn.health.AddHediff(overloadHediffDef);
|
||
if (networkOverloadHediff == null)
|
||
{
|
||
Log.Error("Failed to add network overload hediff to " + pawn.LabelShort);
|
||
return;
|
||
}
|
||
}
|
||
|
||
// 设置Hediff严重性
|
||
networkOverloadHediff.Severity = overloadPercentage;
|
||
}
|
||
|
||
private void RemoveCriticalOverloadEffects()
|
||
{
|
||
HediffDef criticalOverloadDef = ARA_HediffDefOf.ARA_GestaltNetworkOverload;
|
||
if (criticalOverloadDef != null)
|
||
{
|
||
Hediff criticalHediff = pawn.health.hediffSet.GetFirstHediffOfDef(criticalOverloadDef);
|
||
if (criticalHediff != null)
|
||
{
|
||
pawn.health.RemoveHediff(criticalHediff);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void RemoveNetworkOverloadHediff()
|
||
{
|
||
if (networkOverloadHediff != null)
|
||
{
|
||
pawn.health.RemoveHediff(networkOverloadHediff);
|
||
networkOverloadHediff = null;
|
||
}
|
||
|
||
// 同时移除严重的超载效果
|
||
RemoveCriticalOverloadEffects();
|
||
}
|
||
|
||
public bool IsNetworkOverloaded()
|
||
{
|
||
return currentOverloadLevel > 0;
|
||
}
|
||
|
||
public void Notify_ApparelChanged()
|
||
{
|
||
Notify_BandwidthChanged();
|
||
Notify_ControlGroupAmountChanged();
|
||
}
|
||
|
||
public void Notify_HediffStateChange(Hediff hediff)
|
||
{
|
||
if (hediff != null)
|
||
{
|
||
Notify_BandwidthChanged();
|
||
Notify_ControlGroupAmountChanged();
|
||
}
|
||
}
|
||
|
||
public void GameComponentTick()
|
||
{
|
||
if (pawn == null || pawn.Dead || !pawn.Spawned)
|
||
return;
|
||
|
||
ticksSinceLastOverloadCheck++;
|
||
if (ticksSinceLastOverloadCheck >= OVERLOAD_CHECK_INTERVAL)
|
||
{
|
||
ticksSinceLastOverloadCheck = 0;
|
||
|
||
// 定期更新超载状态
|
||
UpdateNetworkOverload();
|
||
}
|
||
|
||
// 定期更新Hediff严重性
|
||
ticksSinceLastHediffUpdate++;
|
||
if (ticksSinceLastHediffUpdate >= HEDIFF_UPDATE_INTERVAL)
|
||
{
|
||
ticksSinceLastHediffUpdate = 0;
|
||
|
||
if (IsNetworkOverloaded())
|
||
{
|
||
UpdateNetworkOverloadHediff();
|
||
}
|
||
}
|
||
}
|
||
|
||
public IEnumerable<Gizmo> GetGizmos()
|
||
{
|
||
yield return new GestaltBandwidthGizmo(this);
|
||
|
||
foreach (GestaltControlGroup group in controlGroups)
|
||
{
|
||
yield return new GestaltControlGroupGizmo(group);
|
||
}
|
||
}
|
||
|
||
public void ExposeData()
|
||
{
|
||
Scribe_References.Look(ref pawn, "pawn");
|
||
Scribe_Collections.Look(ref controlGroups, "controlGroups", LookMode.Deep, this);
|
||
Scribe_Collections.Look(ref controlledPawns, "controlledPawns", LookMode.Reference);
|
||
Scribe_Values.Look(ref currentOverloadLevel, "currentOverloadLevel", 0);
|
||
Scribe_Values.Look(ref ticksSinceLastOverloadCheck, "ticksSinceLastOverloadCheck", 0);
|
||
Scribe_Values.Look(ref ticksSinceLastHediffUpdate, "ticksSinceLastHediffUpdate", 0);
|
||
|
||
// 注意:我们不保存Hediff引用,因为Hediff会在加载时重新添加
|
||
|
||
if (Scribe.mode == LoadSaveMode.PostLoadInit)
|
||
{
|
||
if (controlledPawns == null)
|
||
controlledPawns = new List<Pawn>();
|
||
else
|
||
controlledPawns.RemoveAll(x => x == null);
|
||
|
||
if (controlGroups == null)
|
||
controlGroups = new List<GestaltControlGroup>();
|
||
|
||
// 重新连接后更新超载状态
|
||
UpdateNetworkOverload();
|
||
}
|
||
}
|
||
}
|
||
}
|