Files
ArachnaeSwarm/Source/ArachnaeSwarm/Buildings/IncubatorUtils.cs
2025-12-23 16:52:06 +08:00

276 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.
using RimWorld;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Verse;
namespace ArachnaeSwarm
{
/// <summary>
/// 孵化器通用工具类
/// 统一核心算法,保持各孵化器行为一致
/// </summary>
public static class IncubatorUtils
{
// ============================================
// 通量系统
// ============================================
/// <summary>
/// 计算通量效率0-1之间通量越高效率越高
/// </summary>
public static float GetFluxEfficiency(float neutronFlux)
{
// 与 IFluxControllerExtensions.GetEfficiency 保持一致
return Mathf.Pow(neutronFlux, 0.7f);
}
/// <summary>
/// 判断是否处于休眠状态
/// </summary>
public static bool IsDormant(float neutronFlux)
{
return neutronFlux < 0.05f;
}
/// <summary>
/// 获取模式名称
/// </summary>
public static string GetFluxModeName(FluxMode mode)
{
return mode switch
{
FluxMode.Manual => "手动",
FluxMode.Quality => "品质",
FluxMode.Balance => "平衡",
FluxMode.Speed => "速度",
_ => "?"
};
}
/// <summary>
/// 获取模式简称
/// </summary>
public static string GetFluxModeShort(FluxMode mode)
{
return mode switch
{
FluxMode.Manual => "M",
FluxMode.Quality => "Q",
FluxMode.Balance => "B",
FluxMode.Speed => "S",
_ => "?"
};
}
// ============================================
// 品质系统
// ============================================
/// <summary>
/// 计算品质增长(低通量时增长更快)
/// 公式qualityGain = speedFactor * (1 + (1 - flux) * 0.5)
/// </summary>
public static float CalculateQualityGain(float neutronFlux, float speedFactor)
{
float qualityBonus = 1f + (1f - neutronFlux) * 0.5f;
return speedFactor * qualityBonus;
}
/// <summary>
/// 计算休眠时品质衰减10%/天)
/// </summary>
public static float CalculateQualityDecay(float qualityTotal)
{
return (qualityTotal * 0.1f) / 60000f;
}
/// <summary>
/// 根据品质百分比获取品质等级
/// </summary>
public static QualityCategory GetQualityFromPercent(float qualityPercent, List<QualityThreshold> thresholds)
{
if (thresholds.NullOrEmpty()) return QualityCategory.Normal;
foreach (var threshold in thresholds.OrderByDescending(q => q.threshold))
{
if (qualityPercent >= threshold.threshold)
return threshold.quality;
}
return thresholds.OrderBy(q => q.threshold).First().quality;
}
/// <summary>
/// 默认品质阈值
/// </summary>
public static List<QualityThreshold> GetDefaultQualityThresholds()
{
return new List<QualityThreshold>
{
new QualityThreshold { quality = QualityCategory.Legendary, threshold = 0.99f },
new QualityThreshold { quality = QualityCategory.Masterwork, threshold = 0.90f },
new QualityThreshold { quality = QualityCategory.Excellent, threshold = 0.70f },
new QualityThreshold { quality = QualityCategory.Good, threshold = 0.50f },
new QualityThreshold { quality = QualityCategory.Normal, threshold = 0.20f },
new QualityThreshold { quality = QualityCategory.Poor, threshold = 0.10f },
new QualityThreshold { quality = QualityCategory.Awful, threshold = 0f }
};
}
// ============================================
// 幼虫系统
// ============================================
/// <summary>
/// 搜索可用幼虫
/// </summary>
public static Pawn FindLarva(Map map, IntVec3 position, Faction faction, float searchRadius = 50f)
{
if (map == null) return null;
foreach (var pawn in map.mapPawns.AllPawnsSpawned)
{
if (pawn.def.defName == "ArachnaeBase_Race_Larva" &&
!pawn.Downed && !pawn.Dead &&
pawn.Faction == faction &&
position.DistanceTo(pawn.Position) <= searchRadius)
{
return pawn;
}
}
return null;
}
/// <summary>
/// 搜索多个可用幼虫
/// </summary>
public static List<Pawn> FindLarvae(Map map, IntVec3 position, Faction faction, int maxCount, float searchRadius = 50f, List<Pawn> exclude = null)
{
var result = new List<Pawn>();
if (map == null) return result;
foreach (var pawn in map.mapPawns.AllPawnsSpawned)
{
if (result.Count >= maxCount) break;
if (pawn.def.defName == "ArachnaeBase_Race_Larva" &&
!pawn.Downed && !pawn.Dead &&
pawn.Faction == faction &&
(exclude == null || !exclude.Contains(pawn)) &&
position.DistanceTo(pawn.Position) <= searchRadius)
{
result.Add(pawn);
}
}
return result;
}
// ============================================
// 自动通量计算
// ============================================
/// <summary>
/// 计算自动通量目标值
/// </summary>
/// <param name="mode">通量模式</param>
/// <param name="qualityPercent">当前品质百分比</param>
/// <param name="progressPercent">当前进度百分比</param>
/// <param name="currentFuel">当前燃料量</param>
/// <returns>目标通量值</returns>
public static float CalculateAutoFlux(FluxMode mode, float qualityPercent, float progressPercent, float currentFuel)
{
if (mode == FluxMode.Manual) return -1f; // 手动模式不计算
float gap = qualityPercent - progressPercent;
float targetFlux;
switch (mode)
{
case FluxMode.Quality:
// 品质优先:保持品质领先
if (qualityPercent >= 0.98f) targetFlux = 1.0f;
else if (gap > 0.2f) targetFlux = 0.6f;
else if (gap > 0.1f) targetFlux = 0.45f;
else if (gap > 0f) targetFlux = 0.35f;
else targetFlux = 0.2f;
break;
case FluxMode.Speed:
// 速度优先:尽快完成,必要时降速保品质
if (qualityPercent >= 0.95f) targetFlux = 1.0f;
else if (qualityPercent < 0.3f && progressPercent > 0.5f) targetFlux = 0.7f;
else if (qualityPercent < 0.2f && progressPercent > 0.7f) targetFlux = 0.5f;
else targetFlux = 1.0f;
break;
case FluxMode.Balance:
default:
// 平衡模式:动态调节
if (qualityPercent >= 0.95f) targetFlux = 1.0f;
else if (gap > 0.15f) targetFlux = 0.8f;
else if (gap > 0.05f) targetFlux = 0.6f;
else if (gap > -0.05f) targetFlux = 0.5f;
else if (gap > -0.15f) targetFlux = 0.35f;
else targetFlux = 0.2f;
break;
}
// 燃料保护
if (currentFuel < 20f)
targetFlux = Mathf.Min(targetFlux, 0.3f);
else if (currentFuel < 50f)
targetFlux = Mathf.Min(targetFlux, 0.5f);
return targetFlux;
}
/// <summary>
/// 平滑调节通量(用于自动模式)
/// </summary>
public static float SmoothFlux(float currentFlux, float targetFlux, float lerpSpeed = 0.05f)
{
return Mathf.Lerp(currentFlux, targetFlux, lerpSpeed);
}
// ============================================
// 燃料消耗
// ============================================
/// <summary>
/// 计算每tick燃料消耗
/// </summary>
/// <param name="baseFuelPerDay">每天基础消耗</param>
/// <param name="fluxEfficiency">通量效率</param>
/// <param name="orderCount">正在处理的订单数</param>
public static float CalculateFuelConsumption(float baseFuelPerDay, float fluxEfficiency, int orderCount = 1)
{
return (baseFuelPerDay * fluxEfficiency * orderCount) / 60000f;
}
// ============================================
// 速度计算
// ============================================
/// <summary>
/// 计算实际进度速度
/// </summary>
public static float CalculateProgressSpeed(float fluxEfficiency, float speedFactor, float baseMultiplier = 5f)
{
return speedFactor * fluxEfficiency * baseMultiplier;
}
/// <summary>
/// 计算需要减少的ticks带随机
/// </summary>
public static int CalculateExtraTicks(float progressSpeed)
{
float extra = progressSpeed - 1f;
if (extra <= 0) return 0;
int extraTicks = Mathf.FloorToInt(extra);
if (Rand.Value < (extra - extraTicks)) extraTicks++;
return extraTicks;
}
}
}