Files
ArachnaeSwarm/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/Pawn_GestaltTracker.cs
2026-01-23 17:19:38 +08:00

356 lines
12 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.
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();
}
}
}
}