119 lines
3.9 KiB
C#
119 lines
3.9 KiB
C#
using System.Collections.Generic;
|
||
using RimWorld;
|
||
using UnityEngine;
|
||
using Verse;
|
||
|
||
namespace ArachnaeSwarm
|
||
{
|
||
public class CompProperties_RefuelableNutrition : CompProperties_Refuelable
|
||
{
|
||
public bool silent = false;
|
||
|
||
public CompProperties_RefuelableNutrition()
|
||
{
|
||
compClass = typeof(CompRefuelableNutrition);
|
||
this.targetFuelLevelConfigurable = true;
|
||
this.showAllowAutoRefuelToggle = true;
|
||
}
|
||
|
||
public override IEnumerable<StatDrawEntry> SpecialDisplayStats(StatRequest req)
|
||
{
|
||
if (silent)
|
||
{
|
||
yield break; // If silent, return nothing.
|
||
}
|
||
|
||
foreach (var stat in base.SpecialDisplayStats(req))
|
||
{
|
||
yield return stat;
|
||
}
|
||
}
|
||
}
|
||
|
||
[StaticConstructorOnStartup]
|
||
public class CompRefuelableNutrition : CompRefuelable, IFuelSource
|
||
{
|
||
public float currentConsumptionRate = 0f;
|
||
public float NutritionStored => Fuel;
|
||
public new CompProperties_RefuelableNutrition Props => (CompProperties_RefuelableNutrition)props;
|
||
|
||
public override void CompTick()
|
||
{
|
||
// 调用基类的Tick,让它处理真空等情况。
|
||
// 基类的燃料消耗逻辑将因为 fuelConsumptionRate 为0而无效。
|
||
base.CompTick();
|
||
|
||
// 我们自己的动态消耗逻辑
|
||
if (currentConsumptionRate > 0 && HasFuel)
|
||
{
|
||
float consumptionPerTick = currentConsumptionRate / 60000f;
|
||
ConsumeFuel(consumptionPerTick);
|
||
}
|
||
}
|
||
|
||
public new void Refuel(List<Thing> fuelThings)
|
||
{
|
||
float fuelNeeded = TargetFuelLevel - Fuel;
|
||
if (fuelNeeded < 0.001f) return;
|
||
|
||
float totalNutritionGained = 0;
|
||
var thingsToProcess = new List<Thing>(fuelThings);
|
||
|
||
foreach (var thing in thingsToProcess)
|
||
{
|
||
if (fuelNeeded <= 0) break;
|
||
float nutritionPerUnit = thing.GetStatValue(StatDefOf.Nutrition);
|
||
if (nutritionPerUnit <= 0) continue;
|
||
|
||
int numToTake = Mathf.CeilToInt(fuelNeeded / nutritionPerUnit);
|
||
numToTake = Mathf.Min(numToTake, thing.stackCount);
|
||
|
||
float nutritionFromThis = numToTake * nutritionPerUnit;
|
||
|
||
base.Refuel(nutritionFromThis);
|
||
totalNutritionGained += nutritionFromThis;
|
||
|
||
thing.SplitOff(numToTake).Destroy();
|
||
fuelNeeded = TargetFuelLevel - Fuel;
|
||
}
|
||
|
||
// Let the job driver handle the message. This component should only handle logic.
|
||
}
|
||
|
||
public void ReceiveFuel(float amount)
|
||
{
|
||
base.Refuel(amount);
|
||
}
|
||
|
||
public override string CompInspectStringExtra()
|
||
{
|
||
string fuelLabel = string.IsNullOrEmpty(Props.FuelLabel) ? "Nutrition" : Props.FuelLabel;
|
||
string text = fuelLabel + ": " + Fuel.ToStringDecimalIfSmall() + " / " + Props.fuelCapacity.ToStringDecimalIfSmall();
|
||
|
||
if (currentConsumptionRate > 0f && HasFuel)
|
||
{
|
||
int numTicks = (int)(Fuel / (currentConsumptionRate / 60000f));
|
||
text += " (" + numTicks.ToStringTicksToPeriod() + ")";
|
||
}
|
||
else if (!HasFuel && !Props.outOfFuelMessage.NullOrEmpty())
|
||
{
|
||
text += "\n" + Props.outOfFuelMessage;
|
||
}
|
||
|
||
if (Props.targetFuelLevelConfigurable)
|
||
{
|
||
text += "\n" + "ConfiguredTargetFuelLevel".Translate(TargetFuelLevel.ToStringDecimalIfSmall());
|
||
}
|
||
|
||
return text;
|
||
}
|
||
|
||
public new void Notify_UsedThisTick()
|
||
{
|
||
if (Props.consumeFuelOnlyWhenUsed)
|
||
{
|
||
ConsumeFuel(Props.fuelConsumptionRate / 60000f);
|
||
}
|
||
}
|
||
}
|
||
} |