Files
ArachnaeSwarm/Source/ArachnaeSwarm/Building_Comps/ARA_SwarmMaintenance/Comp_SwarmMaintenance.cs
2025-12-23 14:30:48 +08:00

284 lines
9.9 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.
// File: Comps/Comp_SwarmMaintenance.cs
using System.Collections.Generic;
using RimWorld;
using UnityEngine;
using Verse;
using Verse.AI;
namespace ArachnaeSwarm
{
public class Comp_SwarmMaintenance : ThingComp
{
// 属性访问器
public CompProperties_SwarmMaintenance Props => (CompProperties_SwarmMaintenance)props;
// 当前维护度
private float currentMaintenance;
// 上次更新维护度的时间
private int lastMaintenanceTick = -99999;
// 当维护度为0时每秒受到的伤害计时器
private int nextDamageTick = -99999;
// 警告计时器
private int lastWarningTick = -99999;
private const int WarningInterval = 2500; // 警告间隔时间
private const float CriticalWarningThreshold = 0.3f; // 警告阈值(百分比)
private bool lastWarningState = false;
// 属性访问
public float CurrentMaintenance => currentMaintenance;
public float MaxMaintenance => Props.maxMaintenance;
public float MaintenancePercentage => currentMaintenance / MaxMaintenance;
public bool NeedsMaintenance => currentMaintenance < MaxMaintenance * Props.maintenanceThresholdForJob;
public bool IsCritical => currentMaintenance <= MaxMaintenance * Props.warningThreshold;
public bool IsEmpty => currentMaintenance <= 0f;
// 初始化
public override void Initialize(CompProperties props)
{
base.Initialize(props);
currentMaintenance = Props.maxMaintenance; // 初始时满维护度
lastMaintenanceTick = Find.TickManager.TicksGame;
}
// 序列化
public override void PostExposeData()
{
base.PostExposeData();
Scribe_Values.Look(ref currentMaintenance, "currentMaintenance", Props.maxMaintenance);
Scribe_Values.Look(ref lastMaintenanceTick, "lastMaintenanceTick", -99999);
Scribe_Values.Look(ref nextDamageTick, "nextDamageTick", -99999);
Scribe_Values.Look(ref lastWarningTick, "lastWarningTick", -99999);
Scribe_Values.Look(ref lastWarningState, "lastWarningState", false);
}
// 每tick更新
public override void CompTick()
{
base.CompTick();
int currentTick = Find.TickManager.TicksGame;
// 每2500tick约41.67秒)更新一次维护度递减
if (currentTick - lastMaintenanceTick >= 2500)
{
UpdateMaintenanceDecay();
lastMaintenanceTick = currentTick;
}
// 检查是否需要显示警告
if (currentTick - lastWarningTick >= WarningInterval)
{
CheckWarning();
lastWarningTick = currentTick;
}
// 如果维护度为0每秒造成伤害
if (currentMaintenance <= 0f && currentTick >= nextDamageTick)
{
ApplyDamageWhenEmpty();
nextDamageTick = currentTick + 60; // 60ticks = 1秒
}
}
// 更新维护度递减
private void UpdateMaintenanceDecay()
{
if (parent == null || parent.Map == null)
return;
// 计算基础递减量每天递减量转换为每2500tick约0.0417天)的递减量
float baseDecayAmount = Props.maintenanceDecayPerDay * (2500f / 60000f);
// 检查是否为卵囊建筑,并根据孵化状态调整消耗
float decayMultiplier = 1f;
if (parent is Building_Ootheca ootheca)
{
if (!ootheca.IsIncubating)
{
// 未孵化时维护消耗减少80%
decayMultiplier = 0.2f;
}
else
{
// 孵化时根据活性调整(活性越高消耗越多)
decayMultiplier = 0.5f + ootheca.FluxEfficiency * 0.5f;
}
}
float decayAmount = baseDecayAmount * decayMultiplier;
currentMaintenance -= decayAmount;
// 确保不低于0
if (currentMaintenance < 0f)
currentMaintenance = 0f;
}
// 检查是否需要显示警告
private void CheckWarning()
{
if (parent == null || parent.Destroyed || parent.Map == null)
return;
bool isCritical = MaintenancePercentage <= CriticalWarningThreshold;
// 如果状态改变,显示警告
if (isCritical && !lastWarningState)
{
ShowMaintenanceWarning();
lastWarningState = true;
}
else if (!isCritical && lastWarningState)
{
lastWarningState = false;
}
}
// 显示维护警告
private void ShowMaintenanceWarning()
{
if (parent == null)
return;
// 添加警告标记
if (parent.Spawned)
{
MoteMaker.ThrowText(parent.DrawPos, parent.Map, "ARA_SwarmMaintenance.NeedsMaintenance".Translate(), Color.yellow);
}
}
// 当维护度为0时应用伤害
private void ApplyDamageWhenEmpty()
{
if (parent == null || parent.Destroyed)
return;
// 每秒造成伤害
float damageAmount = Props.damagePerSecondWhenEmpty;
// 应用伤害到建筑
parent.TakeDamage(new DamageInfo(
DamageDefOf.Deterioration,
damageAmount,
armorPenetration: 999f, // 高穿甲,确保能造成伤害
instigator: null
));
}
// 添加维护度
public void AddMaintenance(float amount)
{
currentMaintenance += amount;
if (currentMaintenance > MaxMaintenance)
currentMaintenance = MaxMaintenance;
// 维护后重置警告状态
lastWarningState = false;
}
// 重置维护度
public void ResetMaintenance()
{
currentMaintenance = MaxMaintenance;
lastWarningState = false;
}
// 获取可维护的优先级用于WorkGiver排序
public float GetMaintenancePriority()
{
// 维护度越低,优先级越高
return 1f - MaintenancePercentage;
}
// 在建筑信息面板中追加维护信息
public override string CompInspectStringExtra()
{
// 基础信息
string text = "ARA_SwarmMaintenance.MaintenanceLevel".Translate(
currentMaintenance.ToString("F1"),
MaxMaintenance.ToString("F1"),
MaintenancePercentage.ToString("P1"));
// 计算实际每日消耗
float actualDecayPerDay = GetActualDecayPerDay();
text += "\n" + "ARA_SwarmMaintenance.DailyDecay".Translate(actualDecayPerDay.ToString("F1"));
// 显示维护状态
if (NeedsMaintenance)
{
text += "\n" + "ARA_SwarmMaintenance.NeedsMaintenance".Translate();
}
// 显示警告信息
if (IsCritical)
{
text += "\n<color=orange>" + "ARA_SwarmMaintenance.CriticalLevel".Translate() + "</color>";
}
return text;
}
// 获取实际每日消耗(考虑孵化活性)
private float GetActualDecayPerDay()
{
float baseDecay = Props.maintenanceDecayPerDay;
float multiplier = 1f;
if (parent is Building_Ootheca ootheca)
{
if (!ootheca.IsIncubating)
{
multiplier = 0.2f;
}
else
{
multiplier = 0.5f + ootheca.FluxEfficiency * 0.5f;
}
}
return baseDecay * multiplier;
}
// 获取Gizmos命令按钮- 只保留调试功能
public override IEnumerable<Gizmo> CompGetGizmosExtra()
{
// 只在玩家控制下显示
if (parent.Faction?.IsPlayer == true)
{
// 调试按钮 - 仅在GodMode下显示
if (DebugSettings.godMode)
{
yield return new Command_Action
{
defaultLabel = "Debug: Reset Maintenance",
action = () => ResetMaintenance()
};
yield return new Command_Action
{
defaultLabel = "Debug: Reduce 50%",
action = () => currentMaintenance = MaxMaintenance * 0.5f
};
yield return new Command_Action
{
defaultLabel = "Debug: Reduce to 0",
action = () => currentMaintenance = 0f
};
yield return new Command_Action
{
defaultLabel = "Debug: Show Priority",
action = () =>
{
Messages.Message($"维护优先级: {GetMaintenancePriority():F2}", MessageTypeDefOf.SilentInput);
}
};
}
}
}
}
}