暂存
This commit is contained in:
Binary file not shown.
@@ -5,17 +5,17 @@
|
|||||||
<defName>ARA_NutrientNetworkTower</defName>
|
<defName>ARA_NutrientNetworkTower</defName>
|
||||||
<label>阿拉克涅营养供给塔</label>
|
<label>阿拉克涅营养供给塔</label>
|
||||||
<description>一个中央营养供给设施。它可以自动为链接到的、需要营养的建筑补充燃料。它本身需要被手动填充大量的生物质。</description>
|
<description>一个中央营养供给设施。它可以自动为链接到的、需要营养的建筑补充燃料。它本身需要被手动填充大量的生物质。</description>
|
||||||
<size>(3,3)</size>
|
<size>(5,5)</size>
|
||||||
<graphicData>
|
<graphicData>
|
||||||
<texPath>ArachnaeSwarm/Building/ARA_ResearchBench</texPath>
|
<texPath>ArachnaeSwarm/Building/ARA_ResearchBench</texPath>
|
||||||
<graphicClass>Graphic_Multi</graphicClass>
|
<graphicClass>Graphic_Multi</graphicClass>
|
||||||
<shaderType>CutoutComplex</shaderType>
|
<shaderType>CutoutComplex</shaderType>
|
||||||
<drawSize>(3,4.5)</drawSize>
|
<drawSize>(5,6.7)</drawSize>
|
||||||
</graphicData>
|
</graphicData>
|
||||||
<altitudeLayer>Building</altitudeLayer>
|
<altitudeLayer>Building</altitudeLayer>
|
||||||
<passability>PassThroughOnly</passability>
|
<passability>PassThroughOnly</passability>
|
||||||
<pathCost>70</pathCost>
|
<pathCost>70</pathCost>
|
||||||
<tickerType>Rare</tickerType>
|
<tickerType>Normal</tickerType> <!-- 改为 Normal 以匹配 CompRefuelable 的要求 -->
|
||||||
<fillPercent>0.5</fillPercent>
|
<fillPercent>0.5</fillPercent>
|
||||||
<statBases>
|
<statBases>
|
||||||
<MaxHitPoints>300</MaxHitPoints>
|
<MaxHitPoints>300</MaxHitPoints>
|
||||||
@@ -57,8 +57,6 @@
|
|||||||
|
|
||||||
<!-- 开关 -->
|
<!-- 开关 -->
|
||||||
<li Class="CompProperties_Flickable"/>
|
<li Class="CompProperties_Flickable"/>
|
||||||
|
|
||||||
<!-- 接收增效器的加成 -->
|
|
||||||
<li Class="CompProperties_AffectedByFacilities">
|
<li Class="CompProperties_AffectedByFacilities">
|
||||||
<linkableFacilities>
|
<linkableFacilities>
|
||||||
<li>ARA_GrowthVat</li>
|
<li>ARA_GrowthVat</li>
|
||||||
@@ -370,12 +368,6 @@
|
|||||||
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
|
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li Class="CompProperties_AffectedByFacilities">
|
|
||||||
<linkableFacilities>
|
|
||||||
<li>ARA_NutrientNetworkTower</li>
|
|
||||||
</linkableFacilities>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<!-- 燃料槽 2: 肉类 -->
|
<!-- 燃料槽 2: 肉类 -->
|
||||||
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition_WithKey">
|
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition_WithKey">
|
||||||
<saveKeysPrefix>meat_vat</saveKeysPrefix>
|
<saveKeysPrefix>meat_vat</saveKeysPrefix>
|
||||||
@@ -390,6 +382,12 @@
|
|||||||
<fuelConsumptionRate>12.5</fuelConsumptionRate>
|
<fuelConsumptionRate>12.5</fuelConsumptionRate>
|
||||||
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
|
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li Class="CompProperties_AffectedByFacilities">
|
||||||
|
<linkableFacilities>
|
||||||
|
<li>ARA_NutrientNetworkTower</li>
|
||||||
|
</linkableFacilities>
|
||||||
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
|
|
||||||
</ThingDef>
|
</ThingDef>
|
||||||
@@ -448,8 +446,8 @@
|
|||||||
<workTableRoomRole>Laboratory</workTableRoomRole>
|
<workTableRoomRole>Laboratory</workTableRoomRole>
|
||||||
</building>
|
</building>
|
||||||
<constructionSkillPrerequisite>4</constructionSkillPrerequisite>
|
<constructionSkillPrerequisite>4</constructionSkillPrerequisite>
|
||||||
<!-- ... 其他建筑属性 ... -->
|
|
||||||
<comps>
|
<comps>
|
||||||
|
<!-- 1. 作为消费者,自己也需要燃料 -->
|
||||||
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition">
|
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition">
|
||||||
<fuelCapacity>100.0</fuelCapacity>
|
<fuelCapacity>100.0</fuelCapacity>
|
||||||
<fuelFilter>
|
<fuelFilter>
|
||||||
@@ -461,25 +459,21 @@
|
|||||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||||
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
|
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<!-- 2. 作为动态增效器,为其他建筑提供加成 -->
|
||||||
<li Class="ArachnaeSwarm.CompProperties_GrowthVatBooster">
|
<li Class="ArachnaeSwarm.CompProperties_GrowthVatBooster">
|
||||||
<linkableBuildings>
|
<linkableBuildings>
|
||||||
<li>ARA_NutrientNetworkTower</li>
|
<li>ARA_NutrientNetworkTower</li>
|
||||||
</linkableBuildings>
|
|
||||||
<statOffset>
|
|
||||||
<stat>NutrientTransmissionEfficiency</stat>
|
|
||||||
<value>0.05</value>
|
|
||||||
</statOffset>
|
|
||||||
</li>
|
|
||||||
<li Class="ArachnaeSwarm.CompProperties_GrowthVatBooster">
|
|
||||||
<linkableBuildings>
|
|
||||||
<li>ARA_BioforgeIncubator</li>
|
<li>ARA_BioforgeIncubator</li>
|
||||||
<li>ARA_BioforgeIncubator_Thing</li>
|
<li>ARA_BioforgeIncubator_Thing</li>
|
||||||
</linkableBuildings>
|
</linkableBuildings>
|
||||||
<statOffset>
|
<statOffsets>
|
||||||
<stat>ARA_IncubationSpeedFactor</stat>
|
<NutrientTransmissionEfficiency>0.05</NutrientTransmissionEfficiency>
|
||||||
<value>0.1</value>
|
<ARA_IncubationSpeedFactor>0.1</ARA_IncubationSpeedFactor>
|
||||||
</statOffset>
|
</statOffsets>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<!-- 3. 作为消费者,接收来自供能塔的燃料 -->
|
||||||
<li Class="CompProperties_AffectedByFacilities">
|
<li Class="CompProperties_AffectedByFacilities">
|
||||||
<linkableFacilities>
|
<linkableFacilities>
|
||||||
<li>ARA_NutrientNetworkTower</li>
|
<li>ARA_NutrientNetworkTower</li>
|
||||||
|
|||||||
Binary file not shown.
@@ -6,7 +6,8 @@ namespace ArachnaeSwarm
|
|||||||
{
|
{
|
||||||
public class CompProperties_GrowthVatBooster : CompProperties_Facility
|
public class CompProperties_GrowthVatBooster : CompProperties_Facility
|
||||||
{
|
{
|
||||||
public StatModifier statOffset; // 从XML读取
|
// We will use the base class's statOffsets field.
|
||||||
|
// public List<StatModifier> statOffsets;
|
||||||
|
|
||||||
public CompProperties_GrowthVatBooster()
|
public CompProperties_GrowthVatBooster()
|
||||||
{
|
{
|
||||||
@@ -16,30 +17,31 @@ namespace ArachnaeSwarm
|
|||||||
|
|
||||||
public class CompFacility_GrowthVatBooster : CompFacility
|
public class CompFacility_GrowthVatBooster : CompFacility
|
||||||
{
|
{
|
||||||
private new CompProperties_GrowthVatBooster Props => (CompProperties_GrowthVatBooster)props;
|
|
||||||
|
|
||||||
private List<StatModifier> cachedStatOffsets = new List<StatModifier>();
|
|
||||||
private bool lastHadPawn = false;
|
|
||||||
|
|
||||||
private Building_NutrientVat Vat => parent as Building_NutrientVat;
|
private Building_NutrientVat Vat => parent as Building_NutrientVat;
|
||||||
|
|
||||||
public override List<StatModifier> StatOffsets
|
public override List<StatModifier> StatOffsets
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
// Building_Enterable 使用 innerContainer 存放 Pawn
|
// If the vat contains a pawn, return the stat offsets defined in XML.
|
||||||
bool hasPawn = Vat != null && Vat.innerContainer.Any;
|
if (Vat != null && Vat.innerContainer.Any)
|
||||||
if (cachedStatOffsets.Count == 0 || hasPawn != lastHadPawn)
|
|
||||||
{
|
{
|
||||||
cachedStatOffsets.Clear();
|
return base.StatOffsets; // Returns the list from Props.statOffsets
|
||||||
if (hasPawn && Props.statOffset != null)
|
|
||||||
{
|
|
||||||
cachedStatOffsets.Add(Props.statOffset);
|
|
||||||
}
|
|
||||||
lastHadPawn = hasPawn;
|
|
||||||
}
|
}
|
||||||
return cachedStatOffsets;
|
|
||||||
|
// Otherwise, return an empty list, providing no bonus.
|
||||||
|
return new List<StatModifier>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string CompInspectStringExtra()
|
||||||
|
{
|
||||||
|
// If we are not providing any bonus, don't call the base method to avoid empty lines.
|
||||||
|
if (StatOffsets.NullOrEmpty())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return base.CompInspectStringExtra();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ using RimWorld;
|
|||||||
using Verse;
|
using Verse;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace ArachnaeSwarm
|
namespace ArachnaeSwarm
|
||||||
{
|
{
|
||||||
@@ -15,37 +16,90 @@ namespace ArachnaeSwarm
|
|||||||
selfRefuelable = parent.GetComp<CompRefuelableNutrition>();
|
selfRefuelable = parent.GetComp<CompRefuelableNutrition>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void CompTickRare()
|
public override string CompInspectStringExtra()
|
||||||
{
|
{
|
||||||
base.CompTickRare();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
float efficiency = Mathf.Clamp(parent.GetStatValue(StatDef.Named("NutrientTransmissionEfficiency")), 0f, 0.1f);
|
||||||
|
sb.AppendLine("生物质传输效率".Translate() + ": " + efficiency.ToStringPercent());
|
||||||
|
|
||||||
|
sb.AppendLine("链接的建筑".Translate() + ":");
|
||||||
|
|
||||||
|
if (LinkedBuildings.NullOrEmpty())
|
||||||
|
{
|
||||||
|
sb.AppendLine(" (" + "None".Translate() + ")");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var building in LinkedBuildings)
|
||||||
|
{
|
||||||
|
var comp = (building as ThingWithComps)?.GetComp<CompRefuelableNutrition>();
|
||||||
|
if (comp != null)
|
||||||
|
{
|
||||||
|
bool needsFuel = NeedsFuel(comp);
|
||||||
|
sb.AppendLine($" - {building.LabelCap}: {comp.Fuel:F0}/{comp.Props.fuelCapacity:F0} (目标: {comp.TargetFuelLevel:F0}) -> {(needsFuel ? "需要" : "不需要")}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString().TrimEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CompTick()
|
||||||
|
{
|
||||||
|
base.CompTick();
|
||||||
|
// Log.Message($"[NutrientProvider] CompTick called for {parent.Label}."); // This will be too spammy
|
||||||
|
|
||||||
|
if (!parent.IsHashIntervalTick(250))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Message($"[NutrientProvider] Rare Tick Logic executing for {parent.Label}.");
|
||||||
|
|
||||||
if (selfRefuelable == null || !selfRefuelable.HasFuel)
|
if (selfRefuelable == null || !selfRefuelable.HasFuel)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 找到最需要燃料的已连接建筑
|
|
||||||
var targetBuilding = LinkedBuildings
|
var targetBuilding = LinkedBuildings
|
||||||
.Select(b => new { Building = b, Comp = (b as ThingWithComps)?.GetComp<CompRefuelableNutrition>() })
|
.Select(b => new { Building = b, Comp = (b as ThingWithComps)?.GetComp<CompRefuelableNutrition>() })
|
||||||
.Where(x => x.Comp != null && x.Comp.Fuel < x.Comp.TargetFuelLevel)
|
.Where(x => x.Comp != null && NeedsFuel(x.Comp))
|
||||||
.OrderBy(x => x.Comp.Fuel / x.Comp.Props.fuelCapacity) // 按燃料百分比排序
|
.OrderBy(x => x.Comp.Fuel / x.Comp.Props.fuelCapacity)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
|
||||||
if (targetBuilding != null)
|
if (targetBuilding != null)
|
||||||
{
|
{
|
||||||
var consumerComp = targetBuilding.Comp;
|
var consumerComp = targetBuilding.Comp;
|
||||||
float fuelNeeded = consumerComp.TargetFuelLevel - consumerComp.Fuel;
|
float desiredLevel = GetDesiredFuelLevel(consumerComp);
|
||||||
|
float fuelNeeded = desiredLevel - consumerComp.Fuel;
|
||||||
float fuelToTransfer = Mathf.Min(fuelNeeded, selfRefuelable.Fuel);
|
float fuelToTransfer = Mathf.Min(fuelNeeded, selfRefuelable.Fuel);
|
||||||
|
|
||||||
// 计算效率加成,并设置上限为 10%
|
|
||||||
float efficiency = Mathf.Clamp(parent.GetStatValue(StatDef.Named("NutrientTransmissionEfficiency")), 0f, 0.1f);
|
float efficiency = Mathf.Clamp(parent.GetStatValue(StatDef.Named("NutrientTransmissionEfficiency")), 0f, 0.1f);
|
||||||
float finalCost = fuelToTransfer * (1 - efficiency);
|
float finalCost = fuelToTransfer * (1 - efficiency);
|
||||||
|
|
||||||
|
Log.Message($"[NutrientProvider] Found target: {targetBuilding.Building.Label}. Fuel: {consumerComp.Fuel:F0}/{consumerComp.Props.fuelCapacity:F0}. Needs: {fuelNeeded:F2}. Transferring: {fuelToTransfer:F2}. Final cost: {finalCost:F2}");
|
||||||
|
|
||||||
selfRefuelable.ConsumeFuel(finalCost);
|
selfRefuelable.ConsumeFuel(finalCost);
|
||||||
consumerComp.ReceiveFuel(fuelToTransfer);
|
consumerComp.ReceiveFuel(fuelToTransfer);
|
||||||
|
|
||||||
// 可以在这里添加一个 Mote 来显示传输效果
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool NeedsFuel(CompRefuelableNutrition comp)
|
||||||
|
{
|
||||||
|
if (comp == null) return false;
|
||||||
|
return comp.Fuel < GetDesiredFuelLevel(comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float GetDesiredFuelLevel(CompRefuelableNutrition comp)
|
||||||
|
{
|
||||||
|
// If target is 0 (initial default) or max (UI default), treat as "fill to full".
|
||||||
|
if (comp.TargetFuelLevel <= 0.01f || comp.TargetFuelLevel >= comp.Props.fuelCapacity * 0.99f)
|
||||||
|
{
|
||||||
|
return comp.Props.fuelCapacity;
|
||||||
|
}
|
||||||
|
// Otherwise, respect the player's custom setting.
|
||||||
|
return comp.TargetFuelLevel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user