This commit is contained in:
Tourswen
2026-01-21 00:27:36 +08:00
parent 49e5c38818
commit 99c1d87210
37 changed files with 3471 additions and 153 deletions

View File

@@ -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();
}
}
}
}
}