276 lines
9.9 KiB
C#
276 lines
9.9 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|