using RimWorld;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Verse;
namespace ArachnaeSwarm
{
///
/// 孵化器通用工具类
/// 统一核心算法,保持各孵化器行为一致
///
public static class IncubatorUtils
{
// ============================================
// 通量系统
// ============================================
///
/// 计算通量效率(0-1之间,通量越高效率越高)
///
public static float GetFluxEfficiency(float neutronFlux)
{
// 与 IFluxControllerExtensions.GetEfficiency 保持一致
return Mathf.Pow(neutronFlux, 0.7f);
}
///
/// 判断是否处于休眠状态
///
public static bool IsDormant(float neutronFlux)
{
return neutronFlux < 0.05f;
}
///
/// 获取模式名称
///
public static string GetFluxModeName(FluxMode mode)
{
return mode switch
{
FluxMode.Manual => "手动",
FluxMode.Quality => "品质",
FluxMode.Balance => "平衡",
FluxMode.Speed => "速度",
_ => "?"
};
}
///
/// 获取模式简称
///
public static string GetFluxModeShort(FluxMode mode)
{
return mode switch
{
FluxMode.Manual => "M",
FluxMode.Quality => "Q",
FluxMode.Balance => "B",
FluxMode.Speed => "S",
_ => "?"
};
}
// ============================================
// 品质系统
// ============================================
///
/// 计算品质增长(低通量时增长更快)
/// 公式:qualityGain = speedFactor * (1 + (1 - flux) * 0.5)
///
public static float CalculateQualityGain(float neutronFlux, float speedFactor)
{
float qualityBonus = 1f + (1f - neutronFlux) * 0.5f;
return speedFactor * qualityBonus;
}
///
/// 计算休眠时品质衰减(10%/天)
///
public static float CalculateQualityDecay(float qualityTotal)
{
return (qualityTotal * 0.1f) / 60000f;
}
///
/// 根据品质百分比获取品质等级
///
public static QualityCategory GetQualityFromPercent(float qualityPercent, List 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;
}
///
/// 默认品质阈值
///
public static List GetDefaultQualityThresholds()
{
return new List
{
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 }
};
}
// ============================================
// 幼虫系统
// ============================================
///
/// 搜索可用幼虫
///
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;
}
///
/// 搜索多个可用幼虫
///
public static List FindLarvae(Map map, IntVec3 position, Faction faction, int maxCount, float searchRadius = 50f, List exclude = null)
{
var result = new List();
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;
}
// ============================================
// 自动通量计算
// ============================================
///
/// 计算自动通量目标值
///
/// 通量模式
/// 当前品质百分比
/// 当前进度百分比
/// 当前燃料量
/// 目标通量值
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;
}
///
/// 平滑调节通量(用于自动模式)
///
public static float SmoothFlux(float currentFlux, float targetFlux, float lerpSpeed = 0.05f)
{
return Mathf.Lerp(currentFlux, targetFlux, lerpSpeed);
}
// ============================================
// 燃料消耗
// ============================================
///
/// 计算每tick燃料消耗
///
/// 每天基础消耗
/// 通量效率
/// 正在处理的订单数
public static float CalculateFuelConsumption(float baseFuelPerDay, float fluxEfficiency, int orderCount = 1)
{
return (baseFuelPerDay * fluxEfficiency * orderCount) / 60000f;
}
// ============================================
// 速度计算
// ============================================
///
/// 计算实际进度速度
///
public static float CalculateProgressSpeed(float fluxEfficiency, float speedFactor, float baseMultiplier = 5f)
{
return speedFactor * fluxEfficiency * baseMultiplier;
}
///
/// 计算需要减少的ticks(带随机)
///
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;
}
}
}