This commit is contained in:
2025-09-25 12:32:24 +08:00
parent 4034f27c14
commit 94e1e2cd0c
21 changed files with 65 additions and 69 deletions

View File

@@ -0,0 +1,108 @@
using System.Collections.Generic;
using RimWorld;
using UnityEngine;
using Verse;
namespace ArachnaeSwarm
{
public class CompProperties_RefuelableNutrition : CompProperties_Refuelable
{
public CompProperties_RefuelableNutrition()
{
compClass = typeof(CompRefuelableNutrition);
// 默认启用这些Gizmo除非在XML中明确设置为false
this.targetFuelLevelConfigurable = true;
this.showAllowAutoRefuelToggle = true;
}
}
[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;
}
if (totalNutritionGained > 0 && Props.fuelGizmoLabel != null)
{
Messages.Message("MessageRefueled".Translate(parent.LabelShort, totalNutritionGained.ToString("0.##"), Props.fuelGizmoLabel), parent, MessageTypeDefOf.PositiveEvent);
}
}
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);
}
}
}
}