diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 235b38d..961cec6 100644 Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ diff --git a/1.6/1.6/Defs/AbilityDefs/Ability_Morph.xml b/1.6/1.6/Defs/AbilityDefs/Ability_Morph.xml index bf34421..00ffd0f 100644 --- a/1.6/1.6/Defs/AbilityDefs/Ability_Morph.xml +++ b/1.6/1.6/Defs/AbilityDefs/Ability_Morph.xml @@ -93,11 +93,17 @@
  • Foods
  • - 10.0 + 2.0 false 营养 没有营养 + +
  • + +
  • ARA_NutrientNetworkTower
  • + + diff --git a/1.6/1.6/Defs/Stats/ARA_Stats.xml b/1.6/1.6/Defs/Stats/ARA_Stats.xml index ffd3c86..b6cbc01 100644 --- a/1.6/1.6/Defs/Stats/ARA_Stats.xml +++ b/1.6/1.6/Defs/Stats/ARA_Stats.xml @@ -12,4 +12,15 @@ false + + NutrientTransmissionEfficiency + + 减少无线传输生物质时的燃料消耗。最终消耗量将乘以 (1 - 效率)。 + Building + 0 + 0 + PercentZero + 8000 + + \ No newline at end of file diff --git a/1.6/1.6/Defs/Thing_building/ARA_BioforgeIncubator.xml b/1.6/1.6/Defs/Thing_building/ARA_NutrientNetworkBuilding.xml similarity index 64% rename from 1.6/1.6/Defs/Thing_building/ARA_BioforgeIncubator.xml rename to 1.6/1.6/Defs/Thing_building/ARA_NutrientNetworkBuilding.xml index a0dd17c..b49ef62 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_BioforgeIncubator.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_NutrientNetworkBuilding.xml @@ -1,29 +1,71 @@ - - ARA_IncubationAccelerator - - 一个辅助性的生物机械装置,当放置在大型孵化池旁边时,可以加速其内部的孵化过程。 + ARA_NutrientNetworkTower + + 一个中央营养供给设施。它可以自动为链接到的、需要营养的建筑补充燃料。它本身需要被手动填充大量的生物质。 + (3,3) - Things/Building/Misc/ToolCabinet + ArachnaeSwarm/Building/ARA_ResearchBench Graphic_Multi - - (0.7, 0.4, 0.7) - (0,0,-0.1) - + CutoutComplex + (3,4.5) - (1,1) + Building + PassThroughOnly + 70 + Rare + 0.5 + + 300 + 3000 + 20 + 0.5 + + + 50 + - -
  • - - - 0.60 - + +
  • + + + +
  • ARA_BioforgeIncubator
  • +
  • ARA_BioforgeIncubator_Thing
  • +
  • ARA_JellyVat
  • +
  • ARA_GrowthVat
  • +
  • ARA_MorphableResearchBench
  • + + 80 + + + +
  • + 1000.0 + + +
  • Foods
  • +
  • Corpses
  • + + + 生物质 + true + true + + + +
  • + + +
  • + +
  • ARA_GrowthVat
  • +
    + ARA_Buildings
    @@ -79,7 +121,7 @@ 3 1.0 -
  • ArachnaeNode_Race_WeaponSmith
  • +
  • ArachnaeNode_Race_WeaponSmith
  • @@ -146,7 +188,8 @@
  • -
  • ARA_IncubationAccelerator
  • +
  • ARA_NutrientNetworkTower
  • +
  • ARA_GrowthVat
  • @@ -242,7 +285,8 @@
  • -
  • ARA_IncubationAccelerator
  • +
  • ARA_NutrientNetworkTower
  • +
  • ARA_GrowthVat
  • @@ -250,7 +294,7 @@ - ARA_JellyVat + ARA_JellyVat 一个活体虫族器官,通过分别消化植物和肉类物质,来缓慢培育出营养丰富的阿拉克涅虫蜜。需要同时填充素食和肉类才能工作。 Building @@ -300,7 +344,7 @@
  • - 120000 + 120000 120000 @@ -325,7 +369,13 @@ 12.5 true
  • - + +
  • + +
  • ARA_NutrientNetworkTower
  • + + +
  • meat_vat @@ -343,4 +393,107 @@ + + + ARA_GrowthVat + + 用来存放猎物的茧。 + ArachnaeSwarm.Building_NutrientVat + true + Normal + + ArachnaeSwarm/Building/ARA_GrowthVat + Graphic_Single + CutoutComplex + (2.5,2.5) + + (0.85, 0.3, 1.7) + + + true + North + (1,2) + + 500 + 8000 + 30 + 0.5 + + + 150 + 4 + + Building + PassThroughOnly + 42 + true + MapMeshAndRealTime + 0.5 + false + ARA_Buildings + 2200 + true + (0,0,-1) + false + +
  • ITab_BiosculpterNutritionStorage
  • +
  • ITab_Genes
  • + + +
  • GrowthVats
  • +
    + + false + 120 + Laboratory + + 4 + + +
  • + 100.0 + + +
  • Foods
  • + + + 生物质 + true + true + +
  • + +
  • ARA_NutrientNetworkTower
  • + + + NutrientTransmissionEfficiency + 0.05 + + +
  • + +
  • ARA_BioforgeIncubator
  • +
  • ARA_BioforgeIncubator_Thing
  • + + + ARA_IncubationSpeedFactor + 0.1 + + +
  • + +
  • ARA_NutrientNetworkTower
  • + + +
    + +
  • + + ArachnaeSwarm/Building/ARA_GrowthVatTop + + Graphic_Single +
  • +
    +
    +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/Thing_building/Building_SmartThermostat.xml b/1.6/1.6/Defs/Thing_building/Building_SmartThermostat.xml index bb8b505..71a92fa 100644 --- a/1.6/1.6/Defs/Thing_building/Building_SmartThermostat.xml +++ b/1.6/1.6/Defs/Thing_building/Building_SmartThermostat.xml @@ -65,82 +65,4 @@ - - ARA_GrowthVat - - 用来存放猎物的茧。 - ArachnaeSwarm.Building_NutrientVat - true - Normal - - ArachnaeSwarm/Building/ARA_GrowthVat - Graphic_Single - CutoutComplex - (2.5,2.5) - - (0.85, 0.3, 1.7) - - - true - North - (1,2) - - 500 - 8000 - 30 - 0.5 - - - 150 - 4 - - Building - PassThroughOnly - 42 - true - MapMeshAndRealTime - 0.5 - false - ARA_Buildings - 2200 - true - (0,0,-1) - false - -
  • ITab_BiosculpterNutritionStorage
  • -
  • ITab_Genes
  • -
    - -
  • GrowthVats
  • -
    - - false - 120 - Laboratory - - 4 - - -
  • - 100.0 - - -
  • Foods
  • - - - 生物质 - true - true - -
    - -
  • - - ArachnaeSwarm/Building/ARA_GrowthVatTop - - Graphic_Single -
  • -
    -
    - \ No newline at end of file diff --git a/Nutrient_Network_Design.md b/Nutrient_Network_Design.md new file mode 100644 index 0000000..9282b2e --- /dev/null +++ b/Nutrient_Network_Design.md @@ -0,0 +1,134 @@ +# 中央营养供给网络设计文档 (v2) + +## 1. 概述 + +为了解决需要手动为大量建筑补充营养(燃料)的繁琐操作,本项目旨在设计并实现一个“中央营养供给网络”。该网络由一个或多个“中央供能塔”组成,它们能够自动、无线地为地图上所有需要营养的建筑进行补给。此外,系统还支持通过辅助建筑来提升供能塔的燃料传输效率。 + +## 2. 设计目标 + +* **自动化**: 消除手动为每个建筑“加油”的需求。 +* **策略性**: 引入效率加成建筑,鼓励玩家进行更优化的基地布局。 +* **可扩展性**: 系统应支持多个供能塔、消费者和增效器建筑。 +* **性能友好**: 设计应考虑到性能,避免在游戏后期造成明显的卡顿。 +* **用户友好**: 玩家应能轻松理解网络的工作状态,并对其进行基本控制。 + +## 3. 系统架构 + +本系统采用**去中心化**的设计。每个“中央供能塔”都是一个独立的网络节点。同时,它也作为一个可以被其他设施影响的单位,以接收效率加成。 + +### 3.1. 主要组件与建筑 + +#### a. `CompNutrientNetworkFeeder` (供能塔核心组件) + +* **职责**: + 1. **扫描与链接**: 定期扫描地图,查找所有在范围内的消费者建筑,并维护一个持久化的 `linkedConsumers` 列表。 + 2. **计算效率**: 检查自身 `Stat`,获取由“增效器”提供的 `NutrientTransmissionEfficiency` 总加成。 + 3. **分配与供能**: 从 `linkedConsumers` 列表中选择目标,计算需要补充的燃料量 `X`。根据效率加成,从自身燃料库中扣除 `X * (1 - EfficiencyBonus)` 的燃料。 + 4. **冲突避免**: 使用一个临时标记 `isBeingFueledNow` 来防止多个供能塔同时为一个目标补充。 + 5. **视觉效果**: 借鉴原版 `CompFacility`,在选中供能塔时,持续绘制到所有已连接消费者的连接线。 +* **依附于**: 中央供能塔 (`Building_NutrientTower`)。 + +#### b. `CompRefuelableNutrition` (修改现有组件) + +* **职责**: + 1. **接收燃料**: 增加一个新的公共方法 `ReceiveFuelFromNetwork(float amount)`。 + 2. **状态标记**: 增加一个临时的 `bool isBeingFueledNow` 字段。 + +#### c. “营养网络增效器” (新建筑) +* **`ThingDef`**: 一个新的建筑,例如 `ARA_NutrientNetworkBooster`。 +* **`comps`**: + * 拥有 `
  • `。 + * 在 `statOffsets` 中提供一个新的 `StatDef` 加成:`0.1`。 + +#### d. “中央供能塔” (修改) +* **`comps`**: + * 除了原计划的组件,新增 `
  • `,使其可以链接到“增效器”。 + +### 3.2. 工作流程 (Mermaid) + +```mermaid +graph TD + subgraph "增效器 (Booster)" + C(Building_Booster) + C -- 提供加成 --> B + end + + subgraph "中央供能塔 (Provider)" + B(Building_NutrientTower) + B -- 拥有 --> B1[CompAffectedByFacilities] + B -- 拥有 --> B2[CompNutrientNetworkFeeder] + end + + subgraph "消费者建筑 (Consumer)" + A(Building_Existing) + end + + B2 -- 1. 扫描并连接 --> A + B2 -- 2. 选中时绘制连接线 --> A + C -- "statOffsets" --> B1 + B2 -- 3. 从B1读取效率加成 --> B1 + B2 -- 4. 根据效率进行供能 --> A +``` + +## 4. 实现细节与挑战 + +* **自定义StatDef**: 需要在XML中创建一个新的 `StatDef`,名为 `NutrientTransmissionEfficiency`。 +* **性能优化**: 保持合理的扫描间隔。 +* **范围限制**: 供能塔的服务范围和增效器的影响范围都应是可配置的。 +* **视觉反馈**: + * 供能塔 -> 消费者:绘制连接线,颜色可根据消费者燃料状态变化。 + * 增效器 -> 供能塔:使用原版的 `CompFacility` 机制,在选中增效器时会自动显示其影响的供能塔。 + +## 5. XML 定义 (示例) + +#### a. 新的 StatDef +```xml + + NutrientTransmissionEfficiency + + Reduces the amount of fuel consumed when transfering nutrients wirelessly. The final cost is multiplied by (1 - efficiency). + Building + 0 + 0 + PercentZero + +``` + +#### b. 增效器 ThingDef +```xml + + ARA_NutrientNetworkBooster + + +
  • + +
  • ARA_NutrientNetworkTower
  • + + + 0.1 + + + + +``` + +#### c. 供能塔 ThingDef +```xml + + ARA_NutrientNetworkTower + + +
  • ...
  • +
  • ...
  • +
  • + +
  • ARA_NutrientNetworkBooster
  • + + + +
    +
    +``` + +--- +这份文档现在包含了我们所有的设计决策,形成了一个完整且强大的功能蓝图。 \ No newline at end of file diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index f40909c..e4961eb 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -121,6 +121,9 @@ + + + diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompRefuelableNutrition.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompRefuelableNutrition.cs index 52e59be..f3f8362 100644 --- a/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompRefuelableNutrition.cs +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompRefuelableNutrition.cs @@ -68,6 +68,11 @@ namespace ArachnaeSwarm 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() { diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientNetwork/CompFacility_GrowthVatBooster.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientNetwork/CompFacility_GrowthVatBooster.cs new file mode 100644 index 0000000..f110ef2 --- /dev/null +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientNetwork/CompFacility_GrowthVatBooster.cs @@ -0,0 +1,45 @@ +using RimWorld; +using Verse; +using System.Collections.Generic; + +namespace ArachnaeSwarm +{ + public class CompProperties_GrowthVatBooster : CompProperties_Facility + { + public StatModifier statOffset; // 从XML读取 + + public CompProperties_GrowthVatBooster() + { + compClass = typeof(CompFacility_GrowthVatBooster); + } + } + + public class CompFacility_GrowthVatBooster : CompFacility + { + private new CompProperties_GrowthVatBooster Props => (CompProperties_GrowthVatBooster)props; + + private List cachedStatOffsets = new List(); + private bool lastHadPawn = false; + + private Building_NutrientVat Vat => parent as Building_NutrientVat; + + public override List StatOffsets + { + get + { + // Building_Enterable 使用 innerContainer 存放 Pawn + bool hasPawn = Vat != null && Vat.innerContainer.Any; + if (cachedStatOffsets.Count == 0 || hasPawn != lastHadPawn) + { + cachedStatOffsets.Clear(); + if (hasPawn && Props.statOffset != null) + { + cachedStatOffsets.Add(Props.statOffset); + } + lastHadPawn = hasPawn; + } + return cachedStatOffsets; + } + } + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientNetwork/CompNutrientProvider.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientNetwork/CompNutrientProvider.cs new file mode 100644 index 0000000..4f230d0 --- /dev/null +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientNetwork/CompNutrientProvider.cs @@ -0,0 +1,51 @@ +using RimWorld; +using Verse; +using System.Linq; +using UnityEngine; + +namespace ArachnaeSwarm +{ + public class CompNutrientProvider : CompFacility + { + private CompRefuelableNutrition selfRefuelable; + + public override void PostSpawnSetup(bool respawningAfterLoad) + { + base.PostSpawnSetup(respawningAfterLoad); + selfRefuelable = parent.GetComp(); + } + + public override void CompTickRare() + { + base.CompTickRare(); + + if (selfRefuelable == null || !selfRefuelable.HasFuel) + { + return; + } + + // 找到最需要燃料的已连接建筑 + var targetBuilding = LinkedBuildings + .Select(b => new { Building = b, Comp = (b as ThingWithComps)?.GetComp() }) + .Where(x => x.Comp != null && x.Comp.Fuel < x.Comp.TargetFuelLevel) + .OrderBy(x => x.Comp.Fuel / x.Comp.Props.fuelCapacity) // 按燃料百分比排序 + .FirstOrDefault(); + + if (targetBuilding != null) + { + var consumerComp = targetBuilding.Comp; + float fuelNeeded = consumerComp.TargetFuelLevel - consumerComp.Fuel; + float fuelToTransfer = Mathf.Min(fuelNeeded, selfRefuelable.Fuel); + + // 计算效率加成,并设置上限为 10% + float efficiency = Mathf.Clamp(parent.GetStatValue(StatDef.Named("NutrientTransmissionEfficiency")), 0f, 0.1f); + float finalCost = fuelToTransfer * (1 - efficiency); + + selfRefuelable.ConsumeFuel(finalCost); + consumerComp.ReceiveFuel(fuelToTransfer); + + // 可以在这里添加一个 Mote 来显示传输效果 + } + } + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientNetwork/CompProperties_NutrientProvider.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientNetwork/CompProperties_NutrientProvider.cs new file mode 100644 index 0000000..9e3677b --- /dev/null +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientNetwork/CompProperties_NutrientProvider.cs @@ -0,0 +1,12 @@ +using RimWorld; + +namespace ArachnaeSwarm +{ + public class CompProperties_NutrientProvider : CompProperties_Facility + { + public CompProperties_NutrientProvider() + { + compClass = typeof(CompNutrientProvider); + } + } +} \ No newline at end of file