11
This commit is contained in:
@@ -5,20 +5,43 @@ using System.Linq;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm {
|
||||
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(StatDefOf.BandwidthCost));
|
||||
|
||||
// 计算基础带宽限制
|
||||
public int TotalBandwidth => (int)pawn.GetStatValue(StatDefOf.MechBandwidth);
|
||||
|
||||
// 计算总可用控制组
|
||||
public int TotalAvailableControlGroups => (int)pawn.GetStatValue(StatDefOf.MechControlGroups);
|
||||
|
||||
// 计算网络超载程度(超出带宽的部分)
|
||||
public int NetworkOverload => Mathf.Max(0, UsedBandwidth - TotalBandwidth);
|
||||
|
||||
// 获取当前超载层数
|
||||
public int CurrentOverloadLevel => currentOverloadLevel;
|
||||
|
||||
public AcceptanceReport CanControlPawns
|
||||
{
|
||||
@@ -46,11 +69,15 @@ namespace ArachnaeSwarm {
|
||||
|
||||
public bool CanControlPawn(Pawn targetPawn)
|
||||
{
|
||||
// 移除带宽检查,允许超载连接
|
||||
if (targetPawn.GetOverlord() != null)
|
||||
return false;
|
||||
|
||||
float bandwidthCost = targetPawn.GetStatValue(StatDefOf.BandwidthCost);
|
||||
return UsedBandwidth + bandwidthCost <= TotalBandwidth;
|
||||
// 检查是否在同一地图
|
||||
if (pawn.Map != null && targetPawn.Map != null && pawn.Map != targetPawn.Map)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public GestaltControlGroup GetControlGroup(Pawn targetPawn)
|
||||
@@ -78,13 +105,19 @@ namespace ArachnaeSwarm {
|
||||
// 分配到第一个可用的控制组
|
||||
controlGroups[0].Assign(targetPawn);
|
||||
Notify_BandwidthChanged();
|
||||
UpdateNetworkOverload();
|
||||
}
|
||||
|
||||
public void UnassignPawnFromAnyControlGroup(Pawn targetPawn)
|
||||
{
|
||||
foreach (GestaltControlGroup group in controlGroups)
|
||||
{
|
||||
group.TryUnassign(targetPawn);
|
||||
if (group.TryUnassign(targetPawn))
|
||||
{
|
||||
Notify_BandwidthChanged();
|
||||
UpdateNetworkOverload();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,24 +131,27 @@ namespace ArachnaeSwarm {
|
||||
controlGroups.Add(new GestaltControlGroup(this));
|
||||
}
|
||||
|
||||
// 移除多余的控制组
|
||||
while (controlGroups.Count > availableGroups)
|
||||
// 移除多余的控制组(但如果有超载连接,可以保留额外的组)
|
||||
if (!IsNetworkOverloaded())
|
||||
{
|
||||
GestaltControlGroup groupToRemove = controlGroups[controlGroups.Count - 1];
|
||||
|
||||
if (!groupToRemove.AssignedPawns.NullOrEmpty())
|
||||
while (controlGroups.Count > availableGroups)
|
||||
{
|
||||
// 将pawn重新分配到其他组
|
||||
foreach (Pawn pawn in groupToRemove.AssignedPawns)
|
||||
GestaltControlGroup groupToRemove = controlGroups[controlGroups.Count - 1];
|
||||
|
||||
if (!groupToRemove.AssignedPawns.NullOrEmpty())
|
||||
{
|
||||
if (controlGroups.Count > 1)
|
||||
// 将pawn重新分配到其他组
|
||||
foreach (Pawn pawn in groupToRemove.AssignedPawns)
|
||||
{
|
||||
controlGroups[0].Assign(pawn);
|
||||
if (controlGroups.Count > 1)
|
||||
{
|
||||
controlGroups[0].Assign(pawn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
controlGroups.RemoveAt(controlGroups.Count - 1);
|
||||
controlGroups.RemoveAt(controlGroups.Count - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,28 +165,113 @@ namespace ArachnaeSwarm {
|
||||
controlledPawns.AddRange(group.AssignedPawns.Where(p => !controlledPawns.Contains(p)));
|
||||
}
|
||||
|
||||
// 检查带宽限制,移除超出带宽的pawn
|
||||
List<Pawn> toRemove = new List<Pawn>();
|
||||
float currentBandwidth = 0f;
|
||||
// 不再自动断开超出带宽的连接
|
||||
UpdateNetworkOverload();
|
||||
}
|
||||
|
||||
foreach (Pawn controlledPawn in controlledPawns)
|
||||
public void UpdateNetworkOverload()
|
||||
{
|
||||
int newOverloadLevel = NetworkOverload;
|
||||
|
||||
// 如果超载级别发生变化
|
||||
if (newOverloadLevel != currentOverloadLevel)
|
||||
{
|
||||
float cost = controlledPawn.GetStatValue(StatDefOf.BandwidthCost);
|
||||
if (currentBandwidth + cost <= TotalBandwidth)
|
||||
int oldLevel = currentOverloadLevel;
|
||||
currentOverloadLevel = newOverloadLevel;
|
||||
|
||||
// 发送消息通知
|
||||
if (currentOverloadLevel > 0 && oldLevel == 0)
|
||||
{
|
||||
currentBandwidth += cost;
|
||||
Messages.Message("ARA_GestaltBandwidthExceeded".Translate(),
|
||||
pawn, MessageTypeDefOf.NegativeEvent);
|
||||
}
|
||||
else
|
||||
else if (currentOverloadLevel == 0 && oldLevel > 0)
|
||||
{
|
||||
toRemove.Add(controlledPawn);
|
||||
Messages.Message("ARA_NetworkOverloadCleared".Translate(pawn.LabelShort),
|
||||
pawn, MessageTypeDefOf.PositiveEvent);
|
||||
// 移除超载Hediff
|
||||
RemoveNetworkOverloadHediff();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新Hediff严重性
|
||||
UpdateNetworkOverloadHediff();
|
||||
}
|
||||
|
||||
foreach (Pawn pawnToRemove in toRemove)
|
||||
private void UpdateNetworkOverloadHediff()
|
||||
{
|
||||
if (currentOverloadLevel <= 0)
|
||||
{
|
||||
UnassignPawnFromAnyControlGroup(pawnToRemove);
|
||||
pawnToRemove.relations.RemoveDirectRelation(ARA_PawnRelationDefOf.ARA_GestaltOverseer, this.pawn);
|
||||
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()
|
||||
@@ -168,6 +289,33 @@ namespace ArachnaeSwarm {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -180,15 +328,28 @@ namespace ArachnaeSwarm {
|
||||
|
||||
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)
|
||||
{
|
||||
controlledPawns?.RemoveAll(x => x == null);
|
||||
if (controlledPawns == null)
|
||||
controlledPawns = new List<Pawn>();
|
||||
else
|
||||
controlledPawns.RemoveAll(x => x == null);
|
||||
|
||||
if (controlGroups == null)
|
||||
controlGroups = new List<GestaltControlGroup>();
|
||||
|
||||
// 重新连接后更新超载状态
|
||||
UpdateNetworkOverload();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user