From 5d79465213fe61eb0e1ce8a68937caceddc69cc3 Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Thu, 4 Sep 2025 14:08:56 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ARA_InteractiveProducer.xml | 99 ++++++ New_Component_Design.md | 128 ++++++++ .../ArachnaeSwarm/CompInteractiveProducer.cs | 297 ++++++++++++++++++ 3 files changed, 524 insertions(+) create mode 100644 1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml create mode 100644 New_Component_Design.md create mode 100644 Source/ArachnaeSwarm/CompInteractiveProducer.cs diff --git a/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml b/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml new file mode 100644 index 0000000..2f12cf2 --- /dev/null +++ b/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml @@ -0,0 +1,99 @@ + + + + + ARA_BioforgeIncubator + + 一个先进的孵化器,可以使用化学燃料将有机物和矿物重组成有用的物品。生产过程对温度非常敏感,并且需要由特定的操作员进行启动。 + Building + + Things/Building/Production/BiofuelRefinery + Graphic_Multi + (2,2) + + Damage/Corner + Damage/Corner + Damage/Corner + Damage/Corner + + + (2,2) + + 150 + 6 + + Building + Impassable + false + Production + + 250 + 3000 + 1.0 + -10 + + Normal + + +
  • + CompPowerTrader + 250 +
  • +
  • +
  • + + +
  • + ComponentIndustrial + 90000 + 25 +
  • +
  • + Plasteel + 120000 + 50 +
  • + + + + + +
  • WoodLog
  • +
  • RawFungus
  • +
  • Meat_Insect
  • +
    + +
  • MealSimple
  • +
    +
    + + + +
  • ARA_ArachnaeQueen
  • +
    + + + 5~10 + false + 7 + 32 + 0.00001 + +
    + + + + Important + + +
  • WoodLog
  • +
  • RawFungus
  • +
  • Meat_Insect
  • +
    +
    +
    +
    + +
    + +
    \ No newline at end of file diff --git a/New_Component_Design.md b/New_Component_Design.md new file mode 100644 index 0000000..00b40f3 --- /dev/null +++ b/New_Component_Design.md @@ -0,0 +1,128 @@ +# 开发说明书: 交互式品质生成器 (V5.1 - 最终补充版) + +## 1. 核心概念 + +`CompInteractiveProducer` 是一个**主控制器**组件。它管理的建筑拥有一个统一的“生物质燃料”池。玩家可以通过**精确配置的燃料白/黑名单**,决定哪些物品可以作为燃料。 + +当玩家启动一个生产流程时,该流程会有一个**专属的、固定的总燃料消耗量**和**生产时间**。在生产过程中,组件会持续消耗燃料池,并根据燃料和温度的理想条件,计算最终产物的品质。 + +## 2. 架构设计 + +- **`CompInteractiveProducer` (控制器)**: 继承自 `ThingComp`,并实现 `IStoreSettingsParent`,负责所有逻辑。 +- **`CompProperties_InteractiveProducer` (数据)**: 在 XML 中定义所有生产流程及其对应的参数,以及全局的燃料接受规则。 + +--- +## 3. 依赖项说明 + +**重要**: 本组件的正常工作依赖于一个在 XML 中预先定义的 `JobDef`。交互菜单会尝试创建这个 Job 并分配给 Pawn。 + +**示例 `JobDef` 定义 (`Jobs.xml`):** +```xml + + + + ARA_IncubateJob + ArachnaeSwarm.JobDriver_Incubate + 正在启动生产 TargetA. + true + + +``` +*注: `JobDriver_Incubate` 是一个简单的 JobDriver,其核心逻辑就是让 Pawn 走到建筑旁,然后调用 `comp.StartProduction(process)`。* + +--- + +## 4. 实现步骤与完整代码 + +### **第 1 步: 定义支持精准配置的属性类** + +**目的**: 创建 C# 类来映射新的、更详细的 XML 结构。 + +**产出代码 (属性类 V5):** +```csharp +// (代码与上一版相同,此处为简洁省略) +``` + +### **第 2 步: 实现完整的主组件** + +**目的**: 编写最终的、包含所有新逻辑的 `CompInteractiveProducer` 类。 + +#### **代码解析与补充说明** + +```csharp +// (此处为完整的 V5 版本 C# 代码) +// ... + +// --- 交互与生产流程 --- +public override IEnumerable CompFloatMenuOptions(Pawn selPawn) +{ + // ... + // **补充说明**: 此处创建的 Job "ARA_IncubateJob" 必须在 XML 中有对应定义。 + // 该 Job 的 Driver 应包含走到 parent 旁边,然后调用 StartProduction() 的逻辑。 + // ... +} + +private void FinishProduction() +{ + // ... + // **补充说明**: 最终品质的计算公式为: + // finalQualityScore = Clamp01( (ticksUnderOptimalConditions / totalTicks) - temperaturePenaltyPercent ) + // 这意味着温度惩罚是直接从基础品质分中扣除的。 + // ... +} + +private void ResetProduction() +{ + // **补充说明**: 此方法会清空所有生产进度。 + // 如果玩家通过 Gizmo 中途取消,所有累积的“理想时间”和“温度惩罚”都会丢失。 + _selectedProcess = null; + productionUntilTick = -1; + ticksUnderOptimalConditions = 0; + temperaturePenaltyPercent = 0f; +} + +// --- 燃料系统方法 --- +private float GetNutritionInContainer() +{ + // **性能备注**: 此方法会遍历容器。在绝大多数情况下性能良好。 + // 如果 Mod 允许容器内有成百上千的物品,可考虑增加缓存,不必每帧都计算。 + // ... +} + +// --- IStoreSettingsParent & IThingHolder 实现 --- +// **说明**: 这些接口的实现让我们的组件能被游戏原生的运输和存储系统识别。 +// GetStoreSettings() 暴露我们的配置,让小人知道可以运什么东西过来。 +// GetDirectlyHeldThings() 暴露我们的内部容器,让游戏知道我们持有哪些物品。 + +// --- UI 与 Gizmos --- +public override string CompInspectStringExtra() +{ + // ... + // **UI 设计补充**: + // 生产中: 应清晰显示 "预计品质",其计算公式为 (当前理想 tick 数 / 已进行 tick 数) - 当前温度惩罚。 + // 空闲时: 除了显示总燃料,还可增加一行提示,如 "可由 [白名单Pawn名称] 启动"。 + // ... +} + +public override IEnumerable GetGizmos() +{ + // ... + // **Gizmo 设计补充**: + // 取消按钮 (Command_Action) 的 action 应直接调用 ResetProduction()。 + // 可在开发者模式下增加调试按钮,如: + // - "DEV: +10 营养" + // - "DEV: 立即完成生产" + // ... +} + +public override void PostDestroy(DestroyMode mode, Map previousMap) +{ + base.PostDestroy(mode, previousMap); + // **边缘情况处理**: 建筑被摧毁或卸载时,清空内部容器, + // 默认情况下,容器内的物品会被丢弃在地上,这符合预期。 + innerContainer.TryDropAll(parent.Position, previousMap, ThingPlaceMode.Near); +} +``` + +--- +这份 V5.1 版本的说明书,在 V5 的基础上,补充了对依赖项、UI细节、边缘情况和性能的考量,使其作为开发蓝图更加健壮和周全。这应该是我们开始编码前所需要的最终版本了。 \ No newline at end of file diff --git a/Source/ArachnaeSwarm/CompInteractiveProducer.cs b/Source/ArachnaeSwarm/CompInteractiveProducer.cs new file mode 100644 index 0000000..00f2c5b --- /dev/null +++ b/Source/ArachnaeSwarm/CompInteractiveProducer.cs @@ -0,0 +1,297 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; +using RimWorld; +using UnityEngine; +using Verse; +using Verse.AI; + +namespace ArachnaeSwarm +{ + // V7: Manual implementation of Refuelable GUI + + public class FuelAcceptance + { + public List whitelist; + public List blacklist; + } + + public class ProcessDef + { + public ThingDef thingDef; + public int productionTicks; + public float totalNutritionNeeded; + } + + // We do NOT inherit from CompProperties_Refuelable anymore + public class CompProperties_InteractiveProducer : CompProperties + { + public List processes; + public FuelAcceptance fuelAcceptance; + public List whitelist; + public IntRange spawnCount = new IntRange(1, 1); + public bool destroyOnSpawn; + public float minSafeTemperature = 7f; + public float maxSafeTemperature = 32f; + public float penaltyPerDegreePerTick = 0.00001f; + + // Manually added properties from CompProperties_Refuelable + public float fuelCapacity = 100f; + public bool targetFuelLevelConfigurable = true; + public bool showAllowAutoRefuelToggle = true; + public string fuelLabel = "Nutrition"; + public Texture2D fuelIcon = null; // Let it default or specify + + public CompProperties_InteractiveProducer() + { + compClass = typeof(CompInteractiveProducer); + } + } + + [StaticConstructorOnStartup] + public class CompInteractiveProducer : ThingComp, IStoreSettingsParent, IThingHolder + { + // --- State Variables --- + private StorageSettings allowedNutritionSettings; + private ThingOwner innerContainer; + private float containedNutrition; + + private ProcessDef _selectedProcess; + private int productionUntilTick = -1; + private int ticksUnderOptimalConditions; + private float temperaturePenaltyPercent; + + // --- Manually added state from CompRefuelable --- + private float configuredTargetFuelLevel = -1f; + public bool allowAutoRefuel = true; + + // --- Manually added static resources from CompRefuelable --- + private static readonly Texture2D SetTargetFuelLevelCommand = ContentFinder.Get("UI/Commands/SetTargetFuelLevel"); + private static readonly Vector2 FuelBarSize = new Vector2(1f, 0.2f); + private static readonly Material FuelBarFilledMat = SolidColorMaterials.SimpleSolidColorMaterial(new Color(0.6f, 0.56f, 0.13f)); + private static readonly Material FuelBarUnfilledMat = SolidColorMaterials.SimpleSolidColorMaterial(new Color(0.3f, 0.3f, 0.3f)); + private static readonly Texture2D CancelIcon = ContentFinder.Get("UI/Designators/Cancel"); + + + // --- Properties --- + public bool InProduction => _selectedProcess != null; + public CompProperties_InteractiveProducer Props => (CompProperties_InteractiveProducer)props; + public bool StorageTabVisible => true; + public float NutritionStored => containedNutrition + GetNutritionInContainer(); + + // --- Manually added properties from CompRefuelable --- + public float TargetFuelLevel + { + get => configuredTargetFuelLevel < 0f ? Props.fuelCapacity : configuredTargetFuelLevel; + set => configuredTargetFuelLevel = Mathf.Clamp(value, 0f, Props.fuelCapacity); + } + public float FuelPercentOfMax => NutritionStored / Props.fuelCapacity; + + + // --- Initialization & Scribe --- + public CompInteractiveProducer() { innerContainer = new ThingOwner(this, false, LookMode.Deep); } + + public override void PostMake() + { + base.PostMake(); + allowedNutritionSettings = new StorageSettings(this); + if (parent.def.building.defaultStorageSettings != null) + { + allowedNutritionSettings.CopyFrom(parent.def.building.defaultStorageSettings); + } + UpdateFuelFilter(); + TargetFuelLevel = Props.fuelCapacity; // Initialize target level + } + + public override void PostExposeData() + { + base.PostExposeData(); + Scribe_Values.Look(ref containedNutrition, "containedNutrition", 0f); + Scribe_Deep.Look(ref allowedNutritionSettings, "allowedNutritionSettings", this); + Scribe_Deep.Look(ref innerContainer, "innerContainer", this); + + Scribe_Values.Look(ref configuredTargetFuelLevel, "configuredTargetFuelLevel", -1f); + Scribe_Values.Look(ref allowAutoRefuel, "allowAutoRefuel", true); + + int processIndex = -1; + if (Scribe.mode == LoadSaveMode.Saving && _selectedProcess != null) + { + processIndex = Props.processes.IndexOf(_selectedProcess); + } + Scribe_Values.Look(ref processIndex, "selectedProcessIndex", -1); + if (Scribe.mode == LoadSaveMode.LoadingVars && processIndex > -1 && processIndex < Props.processes.Count) + { + _selectedProcess = Props.processes[processIndex]; + } + + Scribe_Values.Look(ref productionUntilTick, "productionUntilTick", -1); + Scribe_Values.Look(ref ticksUnderOptimalConditions, "ticksUnderOptimalConditions", 0); + Scribe_Values.Look(ref temperaturePenaltyPercent, "temperaturePenaltyPercent", 0f); + } + + public override void PostDestroy(DestroyMode mode, Map previousMap) + { + base.PostDestroy(mode, previousMap); + innerContainer.TryDropAll(parent.Position, previousMap, ThingPlaceMode.Near); + } + + // --- Core Ticking Logic --- + public override void CompTick() + { + base.CompTick(); + innerContainer.ThingOwnerTick(); + + if (this.IsHashIntervalTick(60) && NutritionStored < TargetFuelLevel) + { + TryAbsorbNutritiousThing(); + } + + if (InProduction) + { + float nutritionConsumptionPerTick = _selectedProcess.totalNutritionNeeded / _selectedProcess.productionTicks; + bool hasFuel = containedNutrition >= nutritionConsumptionPerTick; + if (hasFuel) + { + containedNutrition -= nutritionConsumptionPerTick; + } + + float ambientTemperature = parent.AmbientTemperature; + bool isTempSafe = ambientTemperature >= Props.minSafeTemperature && ambientTemperature <= Props.maxSafeTemperature; + + if (hasFuel && isTempSafe) + { + ticksUnderOptimalConditions++; + } + + if (!isTempSafe) + { + float tempDelta = (ambientTemperature > Props.maxSafeTemperature) + ? ambientTemperature - Props.maxSafeTemperature + : Props.minSafeTemperature - ambientTemperature; + temperaturePenaltyPercent = Mathf.Min(1f, temperaturePenaltyPercent + tempDelta * Props.penaltyPerDegreePerTick); + } + + if (Find.TickManager.TicksGame >= productionUntilTick) + { + FinishProduction(); + } + } + } + + // ... (Production Flow methods remain the same) ... + + // --- Fuel System --- + private void UpdateFuelFilter() { /* ... */ } + private void TryAbsorbNutritiousThing() { /* ... */ } + public bool IsAcceptableFuel(ThingDef def) { /* ... */ } + + // --- IStoreSettingsParent & IThingHolder --- + public StorageSettings GetStoreSettings() => allowedNutritionSettings; + public StorageSettings GetParentStoreSettings() => parent.def.building.fixedStorageSettings; + public void Notify_SettingsChanged() { } + public ThingOwner GetDirectlyHeldThings() => innerContainer; + public void GetChildHolders(List outChildren) => ThingOwnerUtility.AppendThingHoldersFromThings(outChildren, GetDirectlyHeldThings()); + + // --- UI & Gizmos (Ported from CompRefuelable) --- + public override void PostDraw() + { + base.PostDraw(); + if (!allowAutoRefuel) + { + parent.Map.overlayDrawer.DrawOverlay(parent, OverlayTypes.ForbiddenRefuel); + } + + GenDraw.FillableBarRequest r = default; + r.center = parent.DrawPos + Vector3.up * 0.1f; + r.size = FuelBarSize; + r.fillPercent = FuelPercentOfMax; + r.filledMat = FuelBarFilledMat; + r.unfilledMat = FuelBarUnfilledMat; + r.margin = 0.15f; + Rot4 rotation = parent.Rotation; + rotation.Rotate(RotationDirection.Clockwise); + r.rotation = rotation; + GenDraw.DrawFillableBar(r); + } + + public override string CompInspectStringExtra() + { + StringBuilder sb = new StringBuilder(); + + // Ported logic from CompRefuelable + sb.Append(Props.fuelLabel + ": " + NutritionStored.ToString("F0") + " / " + Props.fuelCapacity.ToString("F0")); + if (InProduction) + { + float ticksRemaining = _selectedProcess.productionTicks * (NutritionStored / _selectedProcess.totalNutritionNeeded); + sb.Append(" (" + ((int)ticksRemaining).ToStringTicksToPeriod() + ")"); + } + if (Props.targetFuelLevelConfigurable) + { + sb.Append("\n" + "ConfiguredTargetFuelLevel".Translate(TargetFuelLevel.ToString("F0"))); + } + + // Our production info + if (InProduction) + { + sb.AppendLine(); + sb.AppendLine("Producing".Translate(this._selectedProcess.thingDef.label)); + int remainingTicks = productionUntilTick - Find.TickManager.TicksGame; + sb.AppendLine("TimeLeft".Translate() + ": " + remainingTicks.ToStringTicksToPeriod()); + + float ticksElapsed = _selectedProcess.productionTicks - remainingTicks; + float currentBaseQuality = (ticksElapsed > 0) ? (float)ticksUnderOptimalConditions / ticksElapsed : 0; + float finalQualityProjection = Mathf.Clamp01(currentBaseQuality - temperaturePenaltyPercent); + + sb.AppendLine("ProjectedQuality".Translate() + ": " + finalQualityProjection.ToStringPercent()); + if (temperaturePenaltyPercent > 0) + { + sb.AppendLine("TemperaturePenalty".Translate() + ": " + temperaturePenaltyPercent.ToStringPercent()); + } + } + return sb.ToString(); + } + + public override IEnumerable GetGizmos() + { + foreach (var g in base.GetGizmos()) yield return g; + + // Ported Gizmos from CompRefuelable + if (Props.targetFuelLevelConfigurable) + { + var setTargetGizmo = new Command_SetTargetFuelLevel(); + setTargetGizmo.defaultLabel = "CommandSetTargetFuelLevel".Translate(); + setTargetGizmo.defaultDesc = "CommandSetTargetFuelLevelDesc".Translate(); + setTargetGizmo.icon = SetTargetFuelLevelCommand; + // We need to create a simple wrapper to make it work + setTargetGizmo.setter = (level) => this.TargetFuelLevel = level; + setTargetGizmo.getter = () => this.TargetFuelLevel; + setTargetGizmo.max = this.Props.fuelCapacity; + yield return setTargetGizmo; + } + if (Props.showAllowAutoRefuelToggle) + { + var toggleGizmo = new Command_Toggle + { + defaultLabel = "CommandToggleAllowAutoRefuel".Translate(), + defaultDesc = "CommandToggleAllowAutoRefuelDesc".Translate(), + icon = allowAutoRefuel ? TexCommand.ForbidOn : TexCommand.ForbidOff, + isActive = () => allowAutoRefuel, + toggleAction = () => allowAutoRefuel = !allowAutoRefuel + }; + yield return toggleGizmo; + } + + if (InProduction) + { + yield return new Command_Action + { + defaultLabel = "CommandCancelProduction".Translate(), + icon = CancelIcon, + action = () => ResetProduction() + }; + } + } + + // ... (The rest of the methods: FinishProduction, ResetProduction, GetNutritionInContainer etc.) ... + } +} \ No newline at end of file From cd880be9a4f059f0967bf7eb2d33c96a7ef4408e Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Thu, 4 Sep 2025 14:28:26 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.6/1.6/Assemblies/ArachnaeSwarm.dll | Bin 51200 -> 65536 bytes 1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml | 51 +++++ 1.6/1.6/Defs/JobDefs/ARA_Jobs_Interactive.xml | 11 + .../ARA_InteractiveProducer.xml | 127 ++++++----- Source/ArachnaeSwarm/ArachnaeSwarm.csproj | 4 + .../ArachnaeSwarm/CompInteractiveProducer.cs | 198 +++++++++++++++--- .../JobDriver_StartProduction.cs | 36 ++++ 7 files changed, 347 insertions(+), 80 deletions(-) create mode 100644 1.6/1.6/Defs/JobDefs/ARA_Jobs_Interactive.xml create mode 100644 Source/ArachnaeSwarm/JobDriver_StartProduction.cs diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 456ab82dd527dcfbd55645498e49fdce70e461bc..1ae0634e6b1320b47ae86b8c1a55f9eafa571b56 100644 GIT binary patch literal 65536 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 + + + ARA_EggSpew + + 工艺卵 + UI/Commands/EggSpew + 5000 + true + 300 + true + false + AcidSpray_Warmup + + Verb_CastAbility + 1 + 12 + AcidSpray_Resolve + false + false + + True + + + +
  • + ARA_Proj_BioforgeIncubator +
  • +
  • + Food + 0 + 营养值不足,需要进食 +
  • +
    +
    ARA_AcidSprayBurst @@ -159,6 +193,23 @@ true
    + + + ARA_Proj_BioforgeIncubator + + Projectile_SpawnsThing + + ArachnaeSwarm/Building/ARA_EggSac + Graphic_Single + + + Bullet + 21 + 0 + ARA_BioforgeIncubator + true + + ARA_AcidSprayBurst_Myrmecocystus diff --git a/1.6/1.6/Defs/JobDefs/ARA_Jobs_Interactive.xml b/1.6/1.6/Defs/JobDefs/ARA_Jobs_Interactive.xml new file mode 100644 index 0000000..b745ae9 --- /dev/null +++ b/1.6/1.6/Defs/JobDefs/ARA_Jobs_Interactive.xml @@ -0,0 +1,11 @@ + + + + + ARA_IncubateJob + ArachnaeSwarm.JobDriver_StartProduction + 正在启动生产 TargetA. + true + + + \ No newline at end of file diff --git a/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml b/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml index 2f12cf2..2849bec 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml @@ -3,68 +3,64 @@ ARA_BioforgeIncubator - - 一个先进的孵化器,可以使用化学燃料将有机物和矿物重组成有用的物品。生产过程对温度非常敏感,并且需要由特定的操作员进行启动。 + + 一个脆弱、易燃、黏滑的囊状物,是阿拉克涅工艺种所诞之卵,内含哺育阿拉克涅武器种虫族所需的营养和遗传物质,可以通过阿拉克涅工艺种的交互完成激活进程。 Building + + + Building + (1,1) + MinifiedThing + +
  • BuildingsMisc
  • +
    - Things/Building/Production/BiofuelRefinery - Graphic_Multi - (2,2) - - Damage/Corner - Damage/Corner - Damage/Corner - Damage/Corner - + ArachnaeSwarm/Building/ARA_EggSac + Graphic_Single + (1.5,1.5) - (2,2) - - 150 - 6 - Building - Impassable + PassThroughOnly + 0.3 false - Production + Normal + Light - 250 - 3000 - 1.0 - -10 + 10 + 50 + 1 + -6 + + true + + false + false + true + true + false + Normal -
  • - CompPowerTrader - 250 -
  • - ComponentIndustrial - 90000 - 25 + Gun_ChainShotgun + 60000 + 20
  • - Plasteel - 120000 - 50 + Gun_AssaultRifle + 60000 + 15
  • - -
  • WoodLog
  • -
  • RawFungus
  • -
  • Meat_Insect
  • -
    - -
  • MealSimple
  • -
    @@ -73,23 +69,52 @@ - 5~10 - false - 7 - 32 + 1 + True + 18 + 23 0.00001 + +
  • + 13 + 28 + 0.00005 +
  • +
  • + CompHeatPusherPowered + 6 +
  • - - Important + 120 + - -
  • WoodLog
  • -
  • RawFungus
  • -
  • Meat_Insect
  • -
    + +
  • Foods
  • +
    + +
  • AllowPlantFood
  • +
    +
    +
    + + + +
  • Foods
  • +
    + +
  • EggsFertilized
  • +
    + +
  • InsectJelly
  • +
  • MealLavish
  • +
  • MealLavish_Veg
  • +
  • MealLavish_Meat
  • +
  • HemogenPack
  • +
  • Chocolate
  • +
    diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index 9e8ae6b..c996e05 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -105,6 +105,10 @@ + + + + diff --git a/Source/ArachnaeSwarm/CompInteractiveProducer.cs b/Source/ArachnaeSwarm/CompInteractiveProducer.cs index 00f2c5b..8d65c8a 100644 --- a/Source/ArachnaeSwarm/CompInteractiveProducer.cs +++ b/Source/ArachnaeSwarm/CompInteractiveProducer.cs @@ -23,7 +23,6 @@ namespace ArachnaeSwarm public float totalNutritionNeeded; } - // We do NOT inherit from CompProperties_Refuelable anymore public class CompProperties_InteractiveProducer : CompProperties { public List processes; @@ -35,12 +34,10 @@ namespace ArachnaeSwarm public float maxSafeTemperature = 32f; public float penaltyPerDegreePerTick = 0.00001f; - // Manually added properties from CompProperties_Refuelable public float fuelCapacity = 100f; public bool targetFuelLevelConfigurable = true; public bool showAllowAutoRefuelToggle = true; public string fuelLabel = "Nutrition"; - public Texture2D fuelIcon = null; // Let it default or specify public CompProperties_InteractiveProducer() { @@ -61,11 +58,10 @@ namespace ArachnaeSwarm private int ticksUnderOptimalConditions; private float temperaturePenaltyPercent; - // --- Manually added state from CompRefuelable --- private float configuredTargetFuelLevel = -1f; public bool allowAutoRefuel = true; - // --- Manually added static resources from CompRefuelable --- + // --- Static Resources --- private static readonly Texture2D SetTargetFuelLevelCommand = ContentFinder.Get("UI/Commands/SetTargetFuelLevel"); private static readonly Vector2 FuelBarSize = new Vector2(1f, 0.2f); private static readonly Material FuelBarFilledMat = SolidColorMaterials.SimpleSolidColorMaterial(new Color(0.6f, 0.56f, 0.13f)); @@ -79,7 +75,6 @@ namespace ArachnaeSwarm public bool StorageTabVisible => true; public float NutritionStored => containedNutrition + GetNutritionInContainer(); - // --- Manually added properties from CompRefuelable --- public float TargetFuelLevel { get => configuredTargetFuelLevel < 0f ? Props.fuelCapacity : configuredTargetFuelLevel; @@ -91,16 +86,19 @@ namespace ArachnaeSwarm // --- Initialization & Scribe --- public CompInteractiveProducer() { innerContainer = new ThingOwner(this, false, LookMode.Deep); } - public override void PostMake() + public override void PostSpawnSetup(bool respawningAfterLoad) { - base.PostMake(); - allowedNutritionSettings = new StorageSettings(this); - if (parent.def.building.defaultStorageSettings != null) + base.PostSpawnSetup(respawningAfterLoad); + if (!respawningAfterLoad) { - allowedNutritionSettings.CopyFrom(parent.def.building.defaultStorageSettings); + allowedNutritionSettings = new StorageSettings(this); + if (parent.def.building.defaultStorageSettings != null) + { + allowedNutritionSettings.CopyFrom(parent.def.building.defaultStorageSettings); + } + UpdateFuelFilter(); + TargetFuelLevel = Props.fuelCapacity; } - UpdateFuelFilter(); - TargetFuelLevel = Props.fuelCapacity; // Initialize target level } public override void PostExposeData() @@ -139,9 +137,7 @@ namespace ArachnaeSwarm public override void CompTick() { base.CompTick(); - innerContainer.ThingOwnerTick(); - - if (this.IsHashIntervalTick(60) && NutritionStored < TargetFuelLevel) + if (parent.IsHashIntervalTick(60) && NutritionStored < TargetFuelLevel && allowAutoRefuel) { TryAbsorbNutritiousThing(); } @@ -178,12 +174,120 @@ namespace ArachnaeSwarm } } - // ... (Production Flow methods remain the same) ... + // --- Production Flow --- + public override IEnumerable CompFloatMenuOptions(Pawn selPawn) + { + if (InProduction || !selPawn.CanReach(parent, PathEndMode.InteractionCell, Danger.Deadly)) + { + yield break; + } + if (Props.whitelist != null && !Props.whitelist.Contains(selPawn.kindDef)) + { + yield break; + } + + foreach (var process in Props.processes) + { + yield return new FloatMenuOption("StartProduction".Translate(process.thingDef.label), () => + { + // When the float menu is clicked, we set the selected process on the comp, + // so the JobDriver knows which process to start. + this._selectedProcess = process; + Job job = JobMaker.MakeJob(DefDatabase.GetNamed("ARA_IncubateJob"), parent); + selPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc); + }); + } + } + + // This is now called by the JobDriver, without arguments. + public void StartProduction() + { + if (_selectedProcess == null) + { + Log.Error("CompInteractiveProducer tried to start production, but _selectedProcess is null."); + return; + } + productionUntilTick = Find.TickManager.TicksGame + _selectedProcess.productionTicks; + ticksUnderOptimalConditions = 0; + temperaturePenaltyPercent = 0f; + } + + private void FinishProduction() + { + float baseQuality = (_selectedProcess.productionTicks > 0) ? (float)ticksUnderOptimalConditions / _selectedProcess.productionTicks : 0f; + float finalQualityScore = Mathf.Clamp01(baseQuality - temperaturePenaltyPercent); + + for (int i = 0; i < Props.spawnCount.RandomInRange; i++) + { + Thing thing = ThingMaker.MakeThing(_selectedProcess.thingDef); + if (thing.TryGetComp() is CompQuality compQuality) + { + if (finalQualityScore >= 0.99f) compQuality.SetQuality(QualityCategory.Legendary, ArtGenerationContext.Colony); + else if (finalQualityScore >= 0.90f) compQuality.SetQuality(QualityCategory.Masterwork, ArtGenerationContext.Colony); + else if (finalQualityScore >= 0.70f) compQuality.SetQuality(QualityCategory.Excellent, ArtGenerationContext.Colony); + else if (finalQualityScore >= 0.50f) compQuality.SetQuality(QualityCategory.Good, ArtGenerationContext.Colony); + else if (finalQualityScore >= 0.20f) compQuality.SetQuality(QualityCategory.Normal, ArtGenerationContext.Colony); + else if (finalQualityScore >= 0.10f) compQuality.SetQuality(QualityCategory.Poor, ArtGenerationContext.Colony); + else compQuality.SetQuality(QualityCategory.Awful, ArtGenerationContext.Colony); + } + GenPlace.TryPlaceThing(thing, parent.InteractionCell, parent.Map, ThingPlaceMode.Near); + } + + if (Props.destroyOnSpawn) + { + parent.Destroy(); + } + ResetProduction(); + } + + private void ResetProduction() + { + _selectedProcess = null; + productionUntilTick = -1; + } // --- Fuel System --- - private void UpdateFuelFilter() { /* ... */ } - private void TryAbsorbNutritiousThing() { /* ... */ } - public bool IsAcceptableFuel(ThingDef def) { /* ... */ } + private void UpdateFuelFilter() + { + if (Props.fuelAcceptance != null) + { + var filter = allowedNutritionSettings.filter; + filter.SetDisallowAll(); + if (!Props.fuelAcceptance.whitelist.NullOrEmpty()) + { + foreach (var def in Props.fuelAcceptance.whitelist) filter.SetAllow(def, true); + } + if (!Props.fuelAcceptance.blacklist.NullOrEmpty()) + { + foreach (var def in Props.fuelAcceptance.blacklist) filter.SetAllow(def, false); + } + } + } + + private void TryAbsorbNutritiousThing() + { + for (int i = innerContainer.Count - 1; i >= 0; i--) + { + Thing thing = innerContainer[i]; + if (IsAcceptableFuel(thing.def)) + { + float nutrition = thing.GetStatValue(StatDefOf.Nutrition); + int numToAbsorb = Mathf.CeilToInt(Mathf.Min((float)thing.stackCount, 1f)); + containedNutrition += (float)numToAbsorb * nutrition; + thing.SplitOff(numToAbsorb).Destroy(); + return; + } + } + } + + public bool IsAcceptableFuel(ThingDef def) + { + var acceptance = Props.fuelAcceptance; + if (acceptance == null) return true; + if (acceptance.blacklist != null && acceptance.blacklist.Contains(def)) return false; + if (acceptance.whitelist != null && !acceptance.whitelist.NullOrEmpty()) return acceptance.whitelist.Contains(def); + return true; + } // --- IStoreSettingsParent & IThingHolder --- public StorageSettings GetStoreSettings() => allowedNutritionSettings; @@ -218,19 +322,17 @@ namespace ArachnaeSwarm { StringBuilder sb = new StringBuilder(); - // Ported logic from CompRefuelable sb.Append(Props.fuelLabel + ": " + NutritionStored.ToString("F0") + " / " + Props.fuelCapacity.ToString("F0")); if (InProduction) { - float ticksRemaining = _selectedProcess.productionTicks * (NutritionStored / _selectedProcess.totalNutritionNeeded); - sb.Append(" (" + ((int)ticksRemaining).ToStringTicksToPeriod() + ")"); + float nutritionRatePerDay = (_selectedProcess.totalNutritionNeeded / _selectedProcess.productionTicks) * 60000; + sb.Append(" (-" + nutritionRatePerDay.ToString("F1") + "/day)"); } if (Props.targetFuelLevelConfigurable) { sb.Append("\n" + "ConfiguredTargetFuelLevel".Translate(TargetFuelLevel.ToString("F0"))); } - // Our production info if (InProduction) { sb.AppendLine(); @@ -251,18 +353,16 @@ namespace ArachnaeSwarm return sb.ToString(); } - public override IEnumerable GetGizmos() + public override IEnumerable CompGetGizmosExtra() { - foreach (var g in base.GetGizmos()) yield return g; + foreach (var g in base.CompGetGizmosExtra()) yield return g; - // Ported Gizmos from CompRefuelable if (Props.targetFuelLevelConfigurable) { var setTargetGizmo = new Command_SetTargetFuelLevel(); setTargetGizmo.defaultLabel = "CommandSetTargetFuelLevel".Translate(); setTargetGizmo.defaultDesc = "CommandSetTargetFuelLevelDesc".Translate(); setTargetGizmo.icon = SetTargetFuelLevelCommand; - // We need to create a simple wrapper to make it work setTargetGizmo.setter = (level) => this.TargetFuelLevel = level; setTargetGizmo.getter = () => this.TargetFuelLevel; setTargetGizmo.max = this.Props.fuelCapacity; @@ -292,6 +392,46 @@ namespace ArachnaeSwarm } } - // ... (The rest of the methods: FinishProduction, ResetProduction, GetNutritionInContainer etc.) ... + private float GetNutritionInContainer() + { + float total = 0f; + for (int i = 0; i < innerContainer.Count; i++) + { + total += (float)innerContainer[i].stackCount * innerContainer[i].GetStatValue(StatDefOf.Nutrition); + } + return total; + } + } + + // A wrapper for the Gizmo since we are not CompRefuelable + public class Command_SetTargetFuelLevel : Command + { + public System.Action setter; + public System.Func getter; + public float max; + + public override void ProcessInput(Event ev) + { + base.ProcessInput(ev); + List list = new List(); + for (int i = 0; i < (int)max; i += 10) + { + float level = (float)i; + if(level > max) level = max; + + list.Add(new FloatMenuOption(level.ToString("F0"), () => setter(level))); + if(level >= max) break; + } + Find.WindowStack.Add(new FloatMenu(list)); + } + + public override bool InheritInteractionsFrom(Gizmo other) + { + if (other is Command_SetTargetFuelLevel otherGizmo) + { + return getter() == otherGizmo.getter(); + } + return false; + } } } \ No newline at end of file diff --git a/Source/ArachnaeSwarm/JobDriver_StartProduction.cs b/Source/ArachnaeSwarm/JobDriver_StartProduction.cs new file mode 100644 index 0000000..e78624f --- /dev/null +++ b/Source/ArachnaeSwarm/JobDriver_StartProduction.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using RimWorld; +using Verse; +using Verse.AI; + +namespace ArachnaeSwarm +{ + public class JobDriver_StartProduction : JobDriver + { + private const TargetIndex BuildingInd = TargetIndex.A; + + protected Building Building => (Building)job.GetTarget(BuildingInd).Thing; + + public override bool TryMakePreToilReservations(bool errorOnFailed) + { + return pawn.Reserve(Building, job, 1, -1, null, errorOnFailed); + } + + protected override IEnumerable MakeNewToils() + { + this.FailOnDespawnedNullOrForbidden(BuildingInd); + this.FailOnBurningImmobile(BuildingInd); + + yield return Toils_Goto.GotoThing(BuildingInd, PathEndMode.InteractionCell); + + Toil work = ToilMaker.MakeToil("MakeNewToils"); + work.initAction = delegate + { + var comp = Building.GetComp(); + comp.StartProduction(); + }; + work.defaultCompleteMode = ToilCompleteMode.Instant; + yield return work; + } + } +} \ No newline at end of file From 37093dd9238387f7dec8cc05177f090df75bda8d Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Thu, 4 Sep 2025 14:40:43 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.6/1.6/Assemblies/ArachnaeSwarm.dll | Bin 65536 -> 65536 bytes 1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml | 2 +- 1.6/1.6/Defs/JobDefs/ARA_Jobs_Interactive.xml | 2 +- .../ARA_InteractiveProducer.xml | 79 ++++++++++++++++-- .../ArachnaeSwarm/CompInteractiveProducer.cs | 2 +- 5 files changed, 75 insertions(+), 10 deletions(-) diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 1ae0634e6b1320b47ae86b8c1a55f9eafa571b56..f6b13c119f39890177197318c46f2e4a27b9fb89 100644 GIT binary patch delta 284 zcmZo@U}d z#bib%Vb+cr3=E8u6MvX*4q&FL&@anx0ENZy~nw^>TVdL z5Cg->v!TL0bNn1vtzG`+?e7S4jW> delta 259 zcmZo@U}s809wG#I9jv^qc%L?zd!yFav{fXfT68 zJp+RP1CZ?=>IpQG!C~{?_}bddJMM-t3NSBMJ8%5C+G~&e-R_*0qh~iO+*gt0)e&O^ ps)GQx$$>wl87(&F{#eL3dBYEf&3wOpF*8M&Z5I6Zo^hf9I{ - ARA_EggSpew + ARA_EggSpewBioforgeIncubator 工艺卵 UI/Commands/EggSpew diff --git a/1.6/1.6/Defs/JobDefs/ARA_Jobs_Interactive.xml b/1.6/1.6/Defs/JobDefs/ARA_Jobs_Interactive.xml index b745ae9..89ae943 100644 --- a/1.6/1.6/Defs/JobDefs/ARA_Jobs_Interactive.xml +++ b/1.6/1.6/Defs/JobDefs/ARA_Jobs_Interactive.xml @@ -2,7 +2,7 @@ - ARA_IncubateJob + ARA_StartInteractiveProduction ArachnaeSwarm.JobDriver_StartProduction 正在启动生产 TargetA. true diff --git a/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml b/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml index 2849bec..ed35939 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml @@ -49,12 +49,12 @@
  • Gun_ChainShotgun - 60000 + 60000 20
  • Gun_AssaultRifle - 60000 + 60000 15
  • @@ -73,20 +73,85 @@ True 18 23 + + 10 + 0.00001 +
  • - 13 - 28 - 0.00005 + 13 + 28 + 0.00005
  • CompHeatPusherPowered 6
  • - + 120 @@ -121,4 +186,4 @@
    - \ No newline at end of file + diff --git a/Source/ArachnaeSwarm/CompInteractiveProducer.cs b/Source/ArachnaeSwarm/CompInteractiveProducer.cs index 8d65c8a..28228ea 100644 --- a/Source/ArachnaeSwarm/CompInteractiveProducer.cs +++ b/Source/ArachnaeSwarm/CompInteractiveProducer.cs @@ -193,7 +193,7 @@ namespace ArachnaeSwarm // When the float menu is clicked, we set the selected process on the comp, // so the JobDriver knows which process to start. this._selectedProcess = process; - Job job = JobMaker.MakeJob(DefDatabase.GetNamed("ARA_IncubateJob"), parent); + Job job = JobMaker.MakeJob(DefDatabase.GetNamed("ARA_StartInteractiveProduction"), parent); selPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc); }); } From d78b18ddd3ede8f9eb7f79792c86572cc749988c Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Thu, 4 Sep 2025 16:41:27 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.6/1.6/Assemblies/ArachnaeSwarm.dll | Bin 65536 -> 62976 bytes .../Defs/BackstoryDefs/ARA_BackstoryDef.xml | 4 +- .../ARA_InteractiveProducer.xml | 126 +++--- .../Keyed/InteractiveProducer_Keys.xml | 20 + New_Component_Design.md | 32 +- Source/ArachnaeSwarm/ArachnaeSwarm.csproj | 3 + .../ArachnaeSwarm/CompInteractiveProducer.cs | 393 +++++------------- .../ArachnaeSwarm/CompRefuelableNutrition.cs | 96 +++++ .../CompTemperatureRuinableDamage.cs | 91 ++++ Source/ArachnaeSwarm/DataContracts.cs | 25 ++ .../JobDriver_StartProduction.cs | 3 +- 11 files changed, 423 insertions(+), 370 deletions(-) create mode 100644 1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/InteractiveProducer_Keys.xml create mode 100644 Source/ArachnaeSwarm/CompRefuelableNutrition.cs create mode 100644 Source/ArachnaeSwarm/CompTemperatureRuinableDamage.cs create mode 100644 Source/ArachnaeSwarm/DataContracts.cs diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index f6b13c119f39890177197318c46f2e4a27b9fb89..3e55ffb2ad956940643fa8d617e5d471b54ef106 100644 GIT binary patch literal 62976 zcmbTf31C#!^*?^zo0&IjmX}FpvH)2~!b@fn5bt!IDs!(xh)vDFjwo)QQlLqr0Mbs-^-JabzkHVvdD7@Sz)woUYr9%kbpc=XIRMI}uSd0y?D@6v z&iDcpi)v6Y}PCOST>zp^zMa3 z*0n?`SBm~Wfim4HB=S-9C_AA$k}P#K3W}uQw|Xe)Mvfj1cS57SB-G^8t^Qm{`aT#^ zw+3*2F+lYh#oe8cz`PZDvJ-R_j$~YMb66!@K15HH;=9X*YSq5#KN~+O{l|k}Yw4xVMJN z>P9!Th!*l0(JU5}WwZbwAoD7!8&1!H5!yBZbGtRaJ8DuK@-4TjnDc>qQLHCG?2APJ zqS-bQ1p@kr77lo#{V0Ahs;DBX21Qma03A4wYl}|Suz{?>$n}LX8cgJq!)8^7%={cz zcOJS}WV%A3P&iaZv~D!M!(pI|5edkZf?WLN7~Og3Ns(zBGv)5igH?)5H`6i?{^r_5 z19Edb-FcZ@>gi2^Brg=|tY_he00f<;6CDhCO>gu}D!TG~n7bkruhD4v9Tj0mVkl_t zsK}51TrvvM`chHjtjvwLtYM(2s4*(zJA|Y#zMH?T5Gn|`17dUhxiH@M6()t*qP2)BUeNfzv++q!8#NhfgGZSThVXZIpL7bTWh^ z*l3XSsKRubSymHrlose9+V_U%W_XQmXE58$9`XKn-+ym2;V~XGO_SYMyfD=xItcI2 zlTo4P%GjfKtH(g){P!L7iYbA{>O@cgyN-sW#G~y<{2CuPy!-|0JhTcaghX&m4Sful z88+5Crkee3LO%d9hLEv7{gr|3*Z)iwZ^4zYdohQh%X~jNRc4La~v306MJ)= zxfv1iR{t0JpM+e}*YGfpj|5p>$bys+WWmdw@iVw4#wllTxQVan$v~8}6=9vsOsYpY z5~vElV#02XBA9Fb?^y9-f6XJihL#A#f@vG*rv8|=`w!)cw4TnLc^c5r~2Tuh? zGLPFxFpSLw8LWo@H<=?L=kX+C0I@>&POx0z=47r^VW@0fNRXMCr|4MjWDo#CKp8C0 z^+>`~A&=GED@|CWSqs^iTD6_SZ8M6Ngh%9Tl=rq)d$ep)mJ-XBv{!>MOA8m>S($6?I_5_H;f#khVD@!Xn^ zMAVz(lmzClpv!b23a3eW>=r{-3u<=3H?^SKbSom8^jwsfPHRE$R~VB*Y$0$ZODj?% zmVE#H_Xo3b9Ni)KLs1NF=|f-vfd*Ws%jxziEej~kg!74$mCVMNwH7fU(-mQC+=p+} zOzAsTheBx0XEgqltEOs-D*Tao7&NSh0C{XtS$WoCfQ(Sk8L1^NqU;i&!pNp!o{03U z7=uDV<6r~geRwWUTi#e37dlx5HO~;(bJuEaM!&Q^{i1Nth>&UY_OF84Hi zg_UDc=Xpr@I+p_ajaWP9x?{`u%gEBK4kXHG=j!pDF{EP4Io~$b3Z%o`I!o1<2`}tp zX>X3#ii5!F1PHopPQkv}MjEGL?i5dlnY6Zx>$nF5Jrv2OwJQZnBQ2VXl2FheSwc2n z({1|ijKGlA`Ai(h38XciVP=>v>jEyw%E_`YA^4DE^v$tWb9ts=2F%Q~u9E48-ZABx z9yNj0Tw$z*e`EFwSFVM{o!!Rk7vC4s{M%!ZrT zXAIMfVfE zZBXPG;lZ#OMvVr9pE<~kT?}B$!^6Iv@cjV*1hJg`Xg2tG8;yMPHOnlZr@a1Jxga^2V z*c}NPrV%}na@=lX4fn!=SEy0PeSA6>WC%Ht+)!>foF5KZTTrann(o*wKq@gAbin0) zhBOutnERaZOeZZ5SukhBp4VM86#dG89y;HE2tGqkLK{v@kNm}}=-AIu-{>~pL~-YB zNL#RK#2+CyFA=sfbJ$x$(7?W4*?Su@yTDVIg$44t9DPWwNBVjCEK;0>QzjA2L>kZwpHRZk_zNN1_~3wQ;0JKm4IqG$QZdWj$3CyQH*&s15k zt2hs@2~nHvjvZtd3iUNy)%qobupR;syTV6)#Zpxt)QcDL?p%%0r;{bA1vOD0p!V1KEg3h7LYucjl^$&Vn)UYgifZw zy*NYX{i%_F-JCgk>=EQ(RM(Ox_GoV*2Bs4ckB4m#J6Kht9GNr1L01Fk0 zQZg)n3_)d&p0(=#CQRf1CQK1|Dvp+>IrdwKhgNv}sd)Q)z3k9 z5GQ*y2O}LzbMPBzj>nga_TW4Bhq}u*#3iHI>RX~!N|9=HlUC3ZFL3%XyeD43K9PV2 zF|${T!&vVuqG)ki8VgVCarDlU*a2w7o&Y>E!>jY&+DLHsU<(e6VvD|9yy>RsQO!(; zu(CN|tnvnl;}QBwdFZd6u#g%19a{3`ka#c3owASAMIY9aD8pD`y7)dQx4?oYMl5I# zyECb-W;d*$JD&z^k}1_*!AaW@w=gxC4!?b%Vs%U!9daTm)L3N%bXGmhTq5ueT!&!8|A+YPu9E~)bdjVG>w zHfv!T$0?XS&8B$qzS&4Ti)zuJ`c@*^(y2-8q~0?UmXps&gdd-gya1MWR1~PXc5Y!j z+vqtCNwst%jG#2=h&_k)WO-Xc@eoKAyZCq{)hfWQ6j^8}agr=ysy5u01L{af-YeKf zZm}Y4E0|Tt(mgJ@1u1d+oYP1fVOdu|G>&nwWoq7Hvnn|eR6;$1KM%f@cGFaS8c#7y zDK51%_5urrK~@Bxx(B>45Ar@?FK62@eDj32Y zn}}rdQpEY?W6xw4Ly8Ey6pkdNWW;BJQI0FVi21$F61Jx#47ww3RK^#X?&@mZ$-Myr z7?gcuD%cpR-)|x}iX*dY@GYXMQ&<;;{gH^B9buYm8{y%O;fTcvFE5$Q8In~Mc=8#; z5`4o_tkXY&G+i(3eF%YuQVlj}n?azw1cBo?bo)AFNT`md=}6)L^oUw8ogv#_;8AmkRK;4BXs#gz?qdI4G93*cu4}A?B-WiWW zi>Y-5`~+v{8WGl^=##_RFNCs|OItzbsb!DKQ7Ym|8$0P?s0$_Bg=$h-JW|%w=(a4y z^H8ixCDh3pU0lJ{@LyDP_j(o7UFWgA%42(#=hzxc^D1~vBM)C5-Q2n2k#m#$tuUQW z{gk)K5xjWTDiz1lWR`Imzlxn}6Z&E8I$8&8$eKPnXhe=OE${9Ty3^S4VKxtD6Q*Rn zq=qy_uucq#crYw)&O}msA%;Hi{1$@3Fv!>z_BsXo=0AZ8Lh2lR$>Is_WbmmTOn~wE z7w*6N*sAJrt_&~eS@VrsnA~gdk+dO!eL`>i3VS3n8=?^o%A+Ntpf_|)<_tMJU;7U0 zzI8XvXqw?jFqcB_d7x{wts3%a~aZ;wJ?>$nm-Ziv=?1}dAU^*Pc(-$6`8kmL&>BhFLjvd-=hf>dfn zLhkTfzkBK08ZgF20G>MH)9&xT&ke#ZrmxyQvt39(*VLIU=Cr?q8C6fj{^&@P^(By{ z>$o5G-9-ibpPx zIYBL9u)>jM>cK3E)kda~_y?$=3>DOQ?&3P*jA)*b_$P{DUjromrC74McgIPJ9nwVc!9V#Nl^yhRV*hG|oadO=nU^(sa3H04SDW^;8%U z8c&78mIDNpj`qa5>MO zCISq~xEC=j^I%MQl!OJ0ujYRB>;?wwi4l&P{)VW$M?%(Qgo$)MDyruA;g+16J0$vZ zU6#V(4#kSOE^88XdFg?=81WI1pe~DOwV^IAQ5<}K0h5>q#V*K}I&(AVRLEEXopt_^ zr8FGLt5DByCa=a9OvRXl4I{xhc18&rE~AnCCgO1WE!68QMF!@!GJM$qu&B;Wh{ROM z_EzYK_x(-fp-Wwx&<5hGRV7f4(!0XW!ZTHfn@{!@Nf?| zf_(Bc5YOYz!1K>}tW~!?yPIyS3gt^#mF{7=4&WF}zJdZ=S+S~7lA1(|QzkH>#|R4K zS(%4SkKc5QPa5h;;LqWcM&BoaEM^o{Mod)`t==7i*QH$6z=JeA=BkFY%6I3|;-^!- zTTV|LRB6`F1U6MmA75Xpb&Ml0+-qDEOLaI^spWx%Jg0#f!( zGoTDbeh6rgI~b0Hl@IbmJ?Pkp91Nf^OdOUwG&)+l6rVrgGau^C!Z-hMKEf`YguIK= z@-Zn5MIWfzS5SRF#g8Ct^xkq=Hxjyxj|lY1I}v&6%w#S2S?n*4*f8)wRF#z}Klonk z5aY{nkjxB~*lof;WZT7yP=4_3j5N8$;-T2_DDqJxlN?=G#%VId@r2qb>kVr-O4ZJW zClOT@>w719t)3})=zL7jRZ13KqWEyS$KO^1s`BDNt!yNuc@Yi04HHqpX$Wg|!oZs* zRTPmTx7BFN%dt$An5xoZa1NmI2oOj=`C)%37>Jxh9y1`%`+2XFI05BrM*?6I$$J>Z z%jTIm(r{uFa=7c%?PPam7ghqC0s&x-(I`(eaW#Gdy_lJd0alZ3#Kz(~ zHV(j^DcPm-Xf2yQ*BXy}QK18TjKl<>&TuF;5#OpgU7lHkp4}&n{&gMD+#~Ssu+Z%VRTu*lnbCnZZi4GI}-}p~uaGgZf~WIS9%bBx;P7nO3yOv;?Wiv3Z%6 z#CmaO_Q5K%%2vbk9FSPeMotA^J7P6g^r*SothVWH2OT;&i-nDtpc2p9gj}V3)&G?8 zS1?zKl$nO8D~6S@FBmnWxL(DZ-Z_kV8%_Zghk$YTw%zeGl!WT>gh|%JW$JtF>ByBe zY-}!4X{19c9I<9(MGGCVGw_`_vu`<%xDYzbK3!whL>no7A);s+2kR`;Fy1r1?u3a$!CG0VBe2w}z%tkzES(F*&OsFzIap`bAt=hJg2No#cMNcOy;*PT z4Q3|0dSV`G7ov2CIi&G!R-0X5538Z(P&KT~!OES2$C=03Y_QY$!2mkmJl-z-47}K~ zgL8(ZEIX{nvct{cHraF1q_S*-*x;GycG&zI= z4hC`z#i3^t2mg~Z2~ZWa&#~YM5v%yf9X`%?Huy^+saqQG0G)4bVU8uf zL=sMNHC^XBW=4V~luEqEbK$S8SZ-UTwp9I##Qk391w@A$r z#M+U8);%#mU(Ia?{n%D{VqPHhF6&G^o0~?99_4FRIHS<*+rUV(KAZ53RT1_r zp1t7UB3iWX9Ml!##P5ZR6_>|4P_mARgi?>ifOjFf7RfFs#cQze8vkRwo=M}yL~9u+ zUUx&eS`ROnM4hP$#WCeNHZR8&%qO;-^@9GV`iO9N>^^>(CKnS4rQOH*DY;S( z3dhrNpNucb7>SdZ8ao4Ztq;%jaIFsuWTSHhB&b-&C48YcV#|WP9^pL6>^uM(-h*Bb z0{GNwplh$~%jO+s(uYN_6%KlJ83?#&ve!yyRnf$;5dJQc}tTWgV7 zlc8G|;XAPoAi}u_5S5kiPZVKL9$>dUWK9y4MrdV(%pIcr|3E&AI{LCk7v9z$EUK+7o z#}nHF5<9A-9-#ZZ)+Oi&0$NI287jx4-s4EqG|&3H;oc1!!Uxig_HQ1#%xW#QY$NyoO0stZ;E z^}tGebQ4N=fz5mT0hnTXGVSE$D3|-UJvDx6*Whi`z*G&+v};_!NwF+n+qLIHb@vFz zl9;nQuLOn9aMt9y#P%+kEkd1FAvDT?3F8+YDG~sC)PD6`t=fI}v7Yo>Q+y zsqGr}lXINbpMvs~o+d#V(ZNa>aUOn`Clo2_ecWri1QUj0ufa_4C@e`Zdpf`;>`!sx zz!|#^?PWx8vTa?D6n3Mm@X09QyUcu?dot44lG=|j{1G3&9&iI_YhF}mx`X~F60oR{yMp*mq5Vd8uhu}~f+ z!cH#2ZjaAd*iJHCTnG8&GP#;{-bLH?bipNRx`;19%v1Do(}-Wi`6Y}JUnTi#Q74t9 z?%MpoJb}n090Ib6GH?fG9jYlU#coE{6+gw~sHdq-W?!W`Nm@;4Ox^S3vqZ7n!_Wy1 z64P|jJC*R-bR^oj3+?pIDApFVmHss9sA+|ZWv>J0?VS@iQnBOY+Wd6u7N*+-iE#dN z^g9kQn!Q^cXg_(K~Mio@9^Jt)FudE}#zLF);wVdS52}5Zc7cq_?tN z9Lb;IOYXBY!=7r*>acF(+PchRDnMbe1Mwgp=&GsrO;kdf;rd&wo8{#bU89EAsc6k~8cijZMy!zst&r_pnP~d|#iOx$g!jmOl zQ=chhe9zxhw`6>LUp|uLd{ru|KwL^s?EvhltcR+)5=|q(pzD0+dpgENqZ$_$XX@6K zFa$rlmfJ37iwWTR`poP!-FY|^=#ib4`sN$^CW8F9W6ZpN8wB6 z{KXF_GAb?lzaM4nnOuR)L z4et$eXYlguv3-{P-$ReWmrm^ULxdNEVxrFNtP^+qUY=chmBI%T>SbW-Jx)yki2WL* zm1_L;j>qPJJN_gpA9er2llBhrH%D<0b7Z*Vul%r@S8QbchIM~bHFx|=o??wmyDgc? zy@^La8ZY5Y^bn6YdIWXHE0G%?brk(?e~do95R_@bP%(XsnU3WS^yq=ljN+Fw?}z&E zwvEfNv$w9D$-%BS(`sUd4*>+7Zag*>#kymUb6b`0!PpL@(w_$NOU&QFhY{F*4Nmf= zv>4ky8<`k?8={1*Cs1$QSxkW?feZj#VzqvUTsbo?>F)*nX$pv9@kQ+j5j@*Zkot)`lk1J#M!R&&OPMDuy0c<==jY#Bgwcoxmd9dJ^)W zfqk_+G_ho`7bKAMDV8*KYEgq?^=z#k@?b3RI`a2iS5I(&l@ZX5duMnsnaV*FKGUze zt*5049!Go!q!pgtr0VZPfoiAOXOzWqHjL3|{ zf9n~>Tx6(r`3)?2=)6Yvg?p2-R>p-{WgF`i$t{pY{~Z;Dwitgv zt}2oXw1~w$esDaN4!j=1xHq&CCsZ#)~Rih2iR8K(aRzjlYhL1$AelwszVfB!pUoCMq)8I4k=8FW_CV{!plp%7~lA3 zmQlO}3r{v?>?j7^PE4i!(8#aYgP3I+U9+De$EV?a8o-Fc?+yHbDYuS#SU9#Lh1c4J zG3(@vxk=8_6Np0UP`+n5`)Y5mSY;wGz>h9x!%5~ra%TlHFcQsDElOQkUCTCWd`c2q z5H>@zEeA`Z$Yr4OfnhG$z9Eu^R5Nx9GMoSZ6`87Efs!Y&L+NXndAtk$Cas6q!2DYo z+>Q7($i`in49<80#qC)k9dy!bNyaqkXJ_bGw zrttgoZ0E+W7ImO`-Fh7)$>m6*asGXPQna0iw)F&;`;6l6YCU-AHC(Gl0(21eeGHEC zu98))-SV)fAOh}#V;>_ajgeo!;RGbm>bJ0qqxE_BeV@wwovas*K&zZGdi?E<# z61%DoRcjtoec>W$K-x}V35?|-*r2$3Xuh6c6N|Bj`mqHP+xsHHko@)(?>$)Y@(WZ*$2rY5 zFl4C#VR`LwR8T}4dw^_@v{eYF}PJ1C!E2mw9BtI)l_gOAJhR^Os7k<=d{e%gSFr?t~ zTpx1{Jl-9ybw=EgKm#5zv7=(Q#f~cNcRmGv$#pDBLcxoWPI7-!8A;CI{veoeVd}?w z5Pk96555D<%uY(wFA}*x6RkcvM{!GtUj77C#NJ`8$n7nJV_}qi6eIYO+~LE5R^5u= z(ZLd^cDOk9F1RGuBgMmmd!!C4JAcpJ`U&SJ6y(k&*)(>>8m?p=;OcBU`2G+WT@{Ko z6JyxiV;Q{10Gjj6h`NRLk6q>FhC`iyW@ZU)A}peWeFvLTV)4)vK~%f% zfpo-aSQzOR8x#?g#p%w&7On_7<$<+}^JQSAk1MROh(D=ubzaJlib04OsJ$wQ-8#mIz`nIxQ| z)jL1nqRY4_p&-}oHgX}H7%TZ92vk`(`4OiTqS)p4Wfx-oaXV@H6IAJMIP`Z?PhXV& zxU0ST6CH^D_S*Vmagq!~XMbRw)povyuXR7=c6#Fy-fsE}#OuxBHXYQ2Hu=wy_$x}w zIC*@%Bk?hi{MrhY2oEh#uU_LC@0H-1_ynb~PXQ3*)h(BFw&3gT7m$=||(O zgZ>U9j1xcL`aiZtSlEDRl4IpF_=0aUEfRX-RwVSqEr8bLXh^LQFxyKwW2#6as5nEd z5pF|@>+yH;W&n%=CPSz>k3)?xMyTO(yPhl%p3p7s2uC5|E)Dk{iX)WcR&#s`BB0`$ zpW@21y)acl=_6*sL5bH(=mLH8kqSjTzcZa`l;?L5+6#LVk0h2gZ6pbrn%`kC#38P& z#t~bmcN_^<8Al(YagIZ*G)G!RBaLaal!GI!7=U3pKe2@i8DEI)< zNu>ytaUW-J?+~B4P@WIeV9Mv>1Q)3MUcD6d1PV3f!{OX$_iM;tvp`TW5~rdnFCBzw zPfi+N2@kzXhY*$y%;&*gK39VezX-~YBe)39XH!jZkvx@%mfKB8&Rxh(Z}Kzkrj-_iJp8M3TlAH}kUW$Mmrz^X(AkbiMD0!aFr z=300kf6~`9;)<$vh->$*X;_l9NFr$On&y-qzgMw@M^$eu5v~$TzJ?qeOT@PsAbmf+ zlI+_OOTGm~`kLlfD6og>b|kAIRG;-am-md--aRJa29H(V zW6p1QA4&Mk-`N%Nl1wYU^J^q5L|VC<=u7?vD4T}MBO~BjoWVC4eaT0-NKf!r@?lPg zg$iDY5GtEXt^{)mp{giT#}1v}5R|Dy*e9gTE72wfF@AQV^Gg`LB7RBFc$mP=eZ`q; z&*Ikp!AV`JbsLD?_G0Xx$X1f%+mguEQo5#mr5m(I`$`V<#h;X~@Vp~}i^M$dNS6`i z)V#x8P4gB(dEOb0PEQeE;o8bq*sQ(2B3#8+zJna>E8KB8;1>UILMiF~ff+vKACDnv zuX&$DJ9*L$mmh1*>xG4z8mxFKb{< z=7UXg zcfVJUBA4iq58+vlEKQPu=rO>0q_MM39;?C6_%DFZ`NL}KYKPVht#9NU7qtUkKMe0m zu0`TFqHBgAJ*z9;*0H#gDXv*ew9iD|oLMw~wff!gfs^J;9*?r+z#q>?+1U2jxlD{d zgd6Sj;ye6a_&EJn8_GWxB&`EXLKf6P8A#8<_dtB0Qt>%7BfmdVfbV*IAclN5;G65a z@X5so#=_q-`JBgYJTCiinL!H#{xa)#Wm$A0*c$ZbtUGfJx-g4NFUW2zz+32p7~YV@ z@B*u`z(;G%Pcwb=;J{Ba4O-{;t;0QF1NJ^7AobwG@F=$GF`3x-$ zR~ober3N(x!j(Q6*`IkXEMoXCK!dU!%7y41GrTUJ;emc!>ofN%59(SBi=3R(QNnP4fMH=S!@oKh z4uT|^ROOtV;iIohnEvDpmS<@JOa7Kf^>qPL?h-xRR>|qfUWU(0TR*WlT`xUa8szjf z(3OwIN$VXZ^PFKYJYGs~6#BM-oO890WgaK|2M0LkQ!m5QMdtg#Gl#CN8v&iS2%o1U;1<AWJ+g)5-RF zr;fSh40yHHN83aL|MD|^79=s~N_dEm?kQyczwt0US**V#kJAr9+Xj7@%QTA$xzM*BEt1E4|IlriUj4q)$kP5OJJ zic1d*hqo&@{hWACA9>Ox; z6=m3%!SH>N@OLuq&Jd5iyofFMC+W-9dZxKnY&ugUUoRSX8NJS-FEe>`JOfHZvvQU; zSNQJ}`#x09G3tGISBR<{&mnz+aQjw#wL~ae#HMEp=f6vja>bvU1~JbARjh|DiElZ@ zEY(kgPdN=bvyko8CN`Q2U1icJi@haoahztC!0L*uPUS+g1ukUTu_fSfm1L?ZF4~@ZZx_D ztH^3DxBpYA(1N_45S#Ca<~RKK#yDNU+CHZ$Hw-f>{~O1&8pPP^E%-{LKYl z;oPx8uySCB@jECrf}M_f-{CP_tzaX8-3PkCg0-Q&?|=;zY%;L>@Q&#)!7eCiF8CL) z2En$Yy$r1iPszD|e+G6KJsdCC9$;VLdC>&HmH@jCv**czZ3gxouu}z_Ro+}+Y7x9! z!(3K*n+r;{TFlUl%>`BuDbJ$yQ1DfC%>`AMo6i=k)>POzLfJpuT+oOKf1Y5ixm<53 zwFvgL)H|Ne73>m}wc;k+0>K_Zk0xl1v`Ez(++5JCjijY$A)AI|atotqxnQ@T1;$ng zWqChtVHCv$n*^*CPntUg+cTiKV6`@mRtt6yur1m|x=b))`6e*c7f z`(I$K_+^7D1^ag)d%@Xsn_&HlnhSPl=g^&kjRy76e1t<>U4i(?f#246GGvuwRh_y}b^eTtyx9h+vmP-&J%zJtf#(SXfozm;Qe* z*eapCkai08t%J)p&|Y9fr)LqpN*nQUlxEYfv2dzFUxA^8voTVt(7QJT<3*O6=)*KFx6|io_3ogr1e-5?xQqTF z*jZBV7xcAY6Q%4|^qpY!QuZhrS|ybgPD8x-*mEVKNvMv~e<`~hFCkmC47&$i3mE9P z5p%%q=q*Suac#!>?;GcBrbds1reQm=7j^M3+W^j3x5;ydIb+>*fS7%w%x(1`ra3q3 z9?%c0;q>Pg!_z7r1WiuHVa=c|{zs9%vz+rEHyv2*g>dQCpkX4<-+avHa4yU6qLdz% zoLkBtLyo(K;rZqca5%q~(A>HE=0DQPMuXd$oW(rz%J-P{ z^s7Nk`7)%%J9&`PpsRC+It)6kZlfne)AL?I-TaEz0bd;W4&XlrbKUBK0Rgm|&-8ym zjz$mEe2AW2Rr?8GV(=GcEC z6L-cL)&d&zXd$<9Mz9<@S)ctKa+IaM5Z!)Kj-SJ)i)tBuH82BESxs3=S#3!s_bVar zqY$UxC<}q|E`!rEpgp+Tpki!Jw~94StYmrauHyVz{mXOe>79bAoEhtGhfVA0FGw4t zWpQ1rb`RtkBJfht)qd#Kpc>)4u)Y?Q9Ui7km*FLm;X8r(;G@xH($>2MYwzqVZaon_ ztZDR_i__5{TVasE)#XDWr`ItYaEF8Sxw?E5TG?O3-l8;frDH5gQ+y^Nt@tRKH-wUF zY4p0zl=~c~0DkS54VbFcj5OC`{^uaQLvPM8j6Ke2&ePVF)!k#Bwk|jC9`ktmh4b8; z5IszbA;TBpF|g5<{aBK3ia(LkRVa;9QfM{;YP1oQU&&bOg}v?mSg$uj2G#3l(Q9t^ zMsPb{{~6#}+Rwmqb@?xP^kBl8ki_voT91BA55EA->pD~Jb36?Awd0AjT2CXL(gRa^ z9nS)8cX0l(boDawUx2Qrmms{+rTMpDC#O+!55}vAwjPYj;(f5Kg6*MCDsMp9V}h-x zA^HtiRqRxho~J5b!@raAvW=DGmSVl}wq38i@-38osmiFj(7@`Wy_E2`hj!yvVx9E3 zVC(6_qW5#0^klgzd&PM~b5T=;!XmJvi!KsO^}$6~3$~ta*FMg1(N>%CNX2m&{ci~N zERC-CBF9Z1rqy%Pmv+6MA!fR%s*+n!Jl!-?u=VKCH>fwy#(rB=WVoqauszgTM-Dd~ zu`%w0mu?-zT-MX+ncwAj>1&IzJ(NG#gWn+vU|rAH#KBoXKfNK?dOEuTzZ^l?Q7%)h zXHbd4FscUzGw8}bWjh7iL%}d27Ts5)cn*eMGUx@tHq#s4D%5k=_VUc6Y=xmm#|Ja1 zPOv?m!`Y=+>&;Raz34Z9Ew?d$c)dH5HV#%ToNWv-vS^Qu^+S8vwTaQzi3Ou^qDcBy*ltD+dJbF)I#2U;aYpB$ti!)9M=F!JE z9Re59GpFex>W4ETw(S{14E*-*Fv0fF*>1+Z5lqP$roiz`xyQ3B^N5Brh0y@x40jlB z8K|<4q4|88uQ1_~Pj3jOxa8A;KA6tOL3Am4J0qA+SvGdQ@gcZ`1=~Yxm3$gzV{E^C z`emcklkr|aI|WnPEuarah%9u4`*C*>eK=BK7Z#ir>`&c-DOrliePS<{Vk#GG58YAs zmb;kF66{%8<(eNXp?gR5QkK$o!8Ye_En5;SrQL!(>p3{+L+lgw+1S@n#tzunwdNC^ zQu@@!thyswDSagv_q`olu;j~wMdZZ~`mZ$n)9}AX} zEMp8)rmzyho~3r<6tuTgFr|qy>gt0%&qq*C3z;QvJI|HK?IkR7*kxT$Sc?$Pl@mPU=;-f zyO9E}CBPa4dzKatx&_#?ijuy~{{w!qVB)l1F10jWup8;E!FL90>E0gf{@`G8Oz)+v zr@?}8RQye_o<<6$`d3fWZHzTPgl<-p^xq=J9I3;5UN9=;7I_>=0&|QW_PN45Zx)u~ZI5qk z?5WDX21k@bqfurZz~Po#x5##T9zcJd|&J>t3eM0#7WOYzXj zz+Q6tIb3!rl~?>TIEo&g$Jly$7W4FIx?;Y<{vz1hf~gTVnzo$FWlBq<={~_!k4DoD z!PKZ4O)mzW(@X<6}Fg1ra(ImlC3r#d# zu=Ut2;S`z{_9UNB|pCVE4aQ9*tHWpi6q>ul*U#gWaGojH7Vw7`jU^CCeCEy+pOn_8UVF+nAEYXiJwR zs|V9S85Qi1_6O`0$5OkEy--^U?8)=E-g^2uR_kMFzhH;FVfa+CO(Jjb6%J4rz1B#-VJIU`j7zX?h>*EWtLA3+wH%^lVR=2JAh-l$_(J zq+Ri3Imc0M2V+XkaWq)4L*6}+irjHDTwx;TI2vV_v7F=RB)jbS(rQrNWMeGnIJ#Xh zmQw@vgk8p38c$E!7`Hy2Vlk1$dvRoF?s&RDVbb1sT5Fead*f-NUACdL5tJ|57`Hc` zUKdPx$awm*U`k8l>0`k*&=WKc^}b3gn?OhGvd6RvV*;JDoMlnLfI55x3Pa{=j2YMVLg-@PTQsnrtChAuCX!J{4}~X z&ODXfr_m0&~PUfQga~cg2OlfHv4HZo3a~h2l zYy+*+TTySkjV;nzbEngkG|Cw?rw=yYrewdKK`-=_X}~@dO!aRjm3JvwxPLS0}Y%LENWDkv_6ZP>@seB7M*051$B)O!Bp$B=pnm| zTc1r2+ZeY#n^s+@dds6~Hmy^bv^SeBv&*=>*>sIv#-nOBy>4UN9#7eP+RzL47jgPy z55r7>zc)C&-Qwr4mtY^H(Q54PR8C*`MVRwHsbYBP06rhTS-7R@_U7#F&onuiz3}sX zy>(OcoU`4^&emzlK$TW9WaIMjd)b_GrPNZ;Cvx`Y=s1z+OOwjEIKX_;DgWTg&UR3x zaMWwXAI^?%Da*!Fdd`^)m`9rci)fqV+(++Y zBy1-h0Rf6dBS`-h^Xqn`>+meUt84`A0vv~blYmRhB_}HBVUnJqGv^k8hX5DRWXCOK z%diq;`td^3C~eIUxB_qkq~=Gr@Tr2k#H8IaFw_RNoc5c%g8)@vqYo2hBe=Zn75yv`Dw8}D#LmiW~wvyqF0>{PuMmk!wi}B2P4XiWSaj{scS-TWH<-VWgSfO28xy&&} zE2-*qv}s%O)_{gRWV`c>fj2mIINz-Ko#P6sD|j7{Te)83UnB5(dQ~_x9HYIFZ|Juo zf0FZhDl^`OBso>noXuK|dzoXGvr(Vv-0NIgai;TC=j}yjB0syR#kooAC|m}30cbX9 z#Wky)cYy=@!;``5z=vDh?|iD@5u{m$Tj}E32pw{MS@wi;hw~+ap z-sjrq{KUDf-yfZ8M1~ony$5Mc{=c1U_an~3&R-TeT!+z$$F*HbKhgNq>Jx1$&dj|| zXJM7=6S2;I(%@s7>&nnD*M2&XH`3*GU15#EUCGkgiLOnK^>t@~&)xpTNdKW~sq0m6 zyTG+V+v2;?wM*lZn|fD%_;%NR?Wco&=Xyl?Wx8f$zJpS>@*(Ym%5PkUG(PP*r12@& zAuUwxHDP+Jk?f9BJHYLdS&Px)I>lIIc=faL7rVTATYkbYU6ZS>1kY#kwi$b&fqM;8 z-Mzn79e*@F0*4cFJ~ImR?bg3R z^M{IW0oezh#0#|Fq8C$#BmntT>Phj#XT=X!XxRl7?q|i{J`p*0X?!}h-evYzJ!*3A z*OmmQx;LSZbKJW$KCLRy`IKsxa4S%;NaHi6LmHngjS*dKcHJ1g&b`fbs{dy9X4gif zXJ~w$w9Pp+xYNz!^f}}|PK?X^!$V>R0$@dG@xX4H~f8 zv!8|(Cp}-ePV@i7bJ+EnA5SifSF(SK{6~sQso9xbbUo+`2Ei`I4OO>sU5w>1dL^Ft zjM4clYK+cjP+KU9F}2?r>HoCHG(HOM@vP7u$CI4`DL1H%DK>foMoTxoos9va+dcq(Z&(c z#u%ftV5N7xUX9ycN2I@BOQ}=i_`hG@RdA)(smc7Jy>2||Z8mN#-tFDy*yi2q-Jy5Vk|G1=ig>j4{r1CaL&(I>0beELmk`oe83&f8@=oO zJB)Ed9)teZS6%7fW&Fq5=-J^s4e@8acG`ez{d*0MuasUj?kT(3zh3*meVc#3G0?gb zl&gYF8LN8Gf5^DE;Bo(b`W>|!JsjJ2`Crv5^5DtF?T}}iv8nhq|7vG@-g}T?S>Rv( zUD7Y6)B@X#WMLq%g$4vl=@aA4l3-w$kykLy`IRw$(15^ty(AxTlCB1~{q%h0z`$YS zBs^i{xv479VoVLzp{^_MIKaQvjR3biYjmJM+dP>2$UftBH)Ne2@VZa;oCEkkc9rWs z$Nc_Pu2-F!_wqm#wirRf#1@B~ANaY~uek3EnC|Bb9ts@RXVyOxSWUA%FCqOv_8$Qs z$$l>|QtWHG78m>{FkaG6(#`qB8Jip*N2@bR-PiV;1$e+eD`P($L8SFMN~)SOs@#v2 z&(Gj=YsM6t!^YYxjVZJlqv!>T(dfRV> zs>6WSy7kN!?ScWG%&%l5&K7SxOEhqnc%9dA63?NCjk7Z`YxKV$lSgq9^n5Dvm1uP~ zIAa#TIs~gG;HQwd)w2 z@sq4(_iN!zSqrr<9M@!Vgt;E+fzDfyzAE$jtQn+ckoBHBvaZn9T2FfS%K737;jr5A zO?a_uwSyzlYKMkdW3^)#W{@jn>|ZaEw7I7i{WEK|`?lm`o8{_OS8b5SEO|cn*3{toDdV zcpqv#fm;{1l--v7h{*G*dsD&Q?EUUg?*8mXa4_)i+Mizd7o->Y{+4|!{oC{J?7iCk zWsiCGYX8XlHhaH@e>K81_1oNDbBpfD4V!H7I`c_sgPNNcffe9rX7r_umU< znV-0?0_RuVy90Z(HP6-g3r!dH1Q!C1q&23F8#EgMlgQEOQKVherCn%xs9awQXz3fw zLD(t$D!&#tqVn@<@h`xZ0v1sd;6R$3HxB2Q8_aRoVQerLNP2;t9!g8XTk*?B*X8Y$ z{GB*&+F+JwC(xhp5;)gt(odiPp>>j8;J6bx8ypWXALnoA>hK1@!u$m;&fhI?1OAQo z4d$H!cME(^;0FR7_@@jZiNFN{Hwe5_;BJA>x_?JkGPT&H88wB1d zaJRq@1d@3IogQj3xmFW;yuqBGa{}EODhZxIAB5HgIe)7Sxs-BGAS>LI%lYdIR zg*ja!uu0&2f$IcPzLW}FCvdC4odVwzNCiS8uu0%Lfm;Rc6!@M%DrCxa{TOZ)Nd2X* zz$St71+G(YfKUpgVxbh+ByhgKbpp2v+$pf6gejW@&KI~&;8uY<1->V+q*N#c&KI~& z;8uZm(#P}}ovpvF|5wk!9%7qgzvClkrt2ZsKV9FsqQ)u49AkyC&iIY-j-k1Sx?A1L z+?Tnxx&Pok=#F`=_T1^wyvKQO^8VF3(6`NZ(0AB3C9pKGGH_ww@xVKQzXY-~MrK@` zaVR4%^W@BhnVU0j%iNy%+swMGj;!BhJ)iYbR$cb+?31%k%RVdnvh3a2UuKt@gUqSs zTob>{f?YiR8D4m{3p-c?KWc)1{sK8U$O&R(63;*f;n`yZ|4LdE zxwUxuHWcG!81}ZqQQCledt>BAUX&)HbQ0C!h~Yrxnq2%FIl1cr4^&~YIm?!6H=s(NSsmy}{}|1mt8;p2dg*oCO>p4k#sf>}(6k#c3`^*^ zcZnYsp$b?+hlcUPTDU`rA4s8Lu#gUoBk15c3w|jGn#V5_;>4o}a3UcXW~Sl z6mSmgq|<5O#Q(Ca{&9`Hg~7WaSvby|ZLCpenohd^j8 z?lt1P3K3Ap&AJl-uSWYi?huXvyo<&G-VG^q-1(aX_&82Zbex5s0{ATMA?kRFG!5`2 zngRFe^4DHjxfUkja47~x$G4w~YK8D@~ zUzw`bN6?LJpDcUJeA%W?=tVj-rsnSc+c@I@@)xh z3w$03XLMvVW{$~xC-YyKC0SP1+^l=EKFvBedwKTN**9j7G{>9Hb?P*+7d98*O`Tqp zR+tl9jN-K&`dNA9BvsUfv%#bPKE#I`xn9;=10U(WjK3lMExrdk&dD5z@0azP@%?7zEJs0B zjrL|{GrrGsyqS3?&CE(@w`IMo@5tg?*~GSvh2z>|ovoc+r^n(; znQZnFys%~$&yKGa{jhfIEVlf__E<~T)Ygub)0T5fqH!=A*U}->r^YU@iAQyCE6rW_ zSBPNLWy|Yu%Yzvli?>lWAKoQZAvMvqmBbB8hHVFY9~iE zNY2sy1ksQC21M%QTBojTZ)b(gucyfqI#w=gji<0_@rAAN)`fjC$G0vT-vT?dbaI91 zC~jK-6C*ul0V@%Saj}lB){ZW=NozcfYgbILDQ%ryoZHp9479V#N3!tku>~#do!s$d z^X8#uOMClj&~$VS9fCo_y~KALs@Tcacsv%j)7*_AG;w9eg84&IQVgN#Ep2h&+zhI6 z8$)SiAE$@8hSF&*?JHYnuUwA)59RhwYh8eER6-HPS}cByTEp1-9gEr)PhcrJM}g5W zni=bo{A0Kk%Il9)9`gg2L)q{jvTI;}fw-}SE8AN~(d^b$T`S|QL&igE)=p~eXpOfm5V~j{TqZ&NfD_>%8x0W_LNW)NsTdinbV$)F_H#ITC3p zCSyAl)$Ti|-9Zm4nkezA4 zeN{iwOaqE0J=2{~y5t`=Xn1}jOzwxb!ZMa_0K zYAsGKRi%gK*P11$_$wX8T)SFv4h;&@(nPakd)Oz-R*^lSHF1YWgyxnxJca z2^-)OLDPxWTC0o-^hs*2T1Pigw9u^9ryCVFy|OZ2D$kITUV093sr2biwN_zzr2)TQ z;#2(MTI|1+f6~|`#JjbipIZxqx~uAKR1lS8l5?dB>|i#;WD`?CyX>tWL%>1|-Bn}T zYVooQLetXoSE0B$#-aRlTv?Yg4%uzEo~_nQ4^K8r<<&+hGS=8p$d+ENmCBJwc)C(u zu97sVdI{1*rbjhTVxm-c2Ci;L*lR|(PMjT*yV?deBaCpa)L!*UO%NmU;tsrR7@28J z)~=VU$gz$yxax~vo!7L0TrV+5d zWGcEA)#9}}a=KLWMWL6^RBZ0KQX>pUsuI^{8otCdr%$4$eZoji(iY4)sUbIcUC$Rw zp7vZl5aD)&&P5WZ0?lfMvVv%ueLc_a_3MY%GHfKd8JYUAxd3hk8fml_;&aXT`h4VV zRgv{>#b{l#W!)T>dbJ)ctgl7qSuXI&1R+|$9?zH(Wi>DDpQ%%)j3k)*0ivuzXeFpU& zkj3*D53~Id1{8YFiXqb7+II@8b_MkZD;P8td(Kf7H-vk4rqgQ2_1}#eaa&oWL3wp? zL3##!^I5(cHBFn(p*S7-ndjLmkG_>cx?XL}mzJX;?sWCijqOE!(K}#q+nCAvQWZuS z?j5W^tG-ZLifX4Z!jmb7DDk)_%E%jw;M&V6Hl~497rC;xm0;&qr*59loQj)BbqIgm zG8kf0O%UE(44zmbeKlO8Ra1w!QCpwE8$e=!7I>JlXP$j}aj|8|>H1Ps!AhEJV?8Z( zsMJP7olP^`XgyTbZ*)b{q@QzB(Nbq+MT|Ho!#YP6#!Z`X7VQEp4r&)lSYB zUTeaQX2U+;i8`JSQB&rLhXw%foqAQR&0t7Q@1ZioC{9m%iRn#!RRHujn;sOlm-V5Rqy( z7q8cmJ|D6Lp) z8M8{5RjY(lls*$Ax?tU^%*##06zRyvek`pRhkPl^`0XPh9-&8+WdpLzDPi;HW>w}$mf)}fX`LMvI}-~1Xz^`&JpJ{aZ~ zFBc@FX0fK0v83VKWkhA`#cF$1{*ovTyg0NIF)KOLMhb}q>@F$(aGJ1DtBlG4ac(|t zwzm|Bbj(#?ee1xEKO+odeOwKxAzxEy6Iu8sz{mWT8a{U}ZpS{QA!l0WgSQ;GW;X`` ziyWJ0SKnc~y)jw2CJVM=#3=a0hdT<}LBk|6J&2LxFJNY(n$+(_d^&xCHvCI(wcB7O z-9kRmDJU)?X|366tEE0{W;;pqekQz6+iX>tCRc(e29}`T2ZB4-*!?pdUnG#N!?tos z2)uaplHOmG{iDoON|Z2x`0(h)uP3rF8&PnfL?mYw^08op>0as5 zYQ0lGAC+qDRk5K~HptDEZiLLLZ!w_OHQHD3QJGjM_p&(HBSU`REVg=e$FA*g7kx7% z#bo98cNs95_RMNjzIu<*wzd(WwN^1`k-(BgbQ`FLE7*p<%v`-eR!d3RuE0<&S@jXA zBxK;Q(LmMuj&d(CDYovmrP$Awk#}Owj(H>U2`U!!DAguGJ{G&_k}0!q*>elM-2x^)3qAM* z(nwC1&(vfhxg}ga`B}C85bTQ#pGd=5Av<7c?*&-V1-UB5-##TG4Tgn)u-ZDrdbWB4 zE|gC^XeTeI-@TuySrL$0pk^L3hzKcWyq8pXkHq2>Hkqt}LCGE^5=Nei%G!aM<$0bp zm$=mP*Wr=l6-or39QxtN8Vq!e=!*oNRVDH+WIDBl*pklyy=%qSv8`<-W`bx*u4PY+ zt$=8dN~%V9*NN0jB3D+-!IQVL6)ZR3sXIlE)&7N2xkCzRfcH>azto_x5xf|ryCM}) zMRDj$&9iZH$qY2cAEX7tC1~0Kq}S*UlPG9PP>62fpC%|rwV86v;Ovtns>-3NAOa3> zqJ|`?VA_(G$u+1A^43v0d=kMZP-8X5_|zCMkAgFcKJJZrtF}W@(4H-sh3De6#re(> zlHF$);L%xv4N--~*@2QT4~_#Q7{Z&v&>-09mc`qByHVR*ZLJO!Xv&$!P=Tz1_E28t zm^bKcRYNsENWjxreY?mS_{IIWpf%a8To4fb^W$s_bGwUid%m-_hW6$-;f7*{!XPk- z1<(sEas+qu;Uxqt0InN^^Q#s4xkll#9UZXRC-{*Yz;O_TW~>k(vkaEN{2HZ}DI?wx zcb2x5PhqeVkF*wO1`AJK@&`V`xi2@tIB-crpFnSeCcBkS#ao)O3TbsXSs?kKZ<1M* zfkh!POMzuIXl3MorQMvLiWdDmjDh1kthqL_^*C^^$uj)ReI$=L{3t7*v#I!E!6 z%JNuEv^80YG~w`VQHG9}agvW5K@Kv^*lZ^yv((sO*HAFX$HIgh>m(kt%;IvA0(N-I z3WKio=~fFEYwO3(%&(T38aOI7I&0oTSH(7CIwJdSnZsIV-P4-DF zsVaXQ0D8V+gEhC4u4xW2-L=3sk#DkFxi_24?4%V$fZ53c?L#JwKUHYDuMVX}?oyjc zo$`vR0Ilbxq$085iTYx)HQ6`fTTK@$Cb=DG**|AW&1Q9H)num~Z?E31Y`6{lB|Erj zM>0NT`Zy#Z2cHsiEYcY3RFMtz5BbTJD9M)wNvooKI1=L9djl-#V(mpx&vYxk!ui<&vsg zD|{LXE}?OlL+a&yQ{W-H|vBjcKGgVlusVPsO_Yg(dNq#b8gIBtn1v7(#(LxshunB2Lj zZJ!osM@hGcE6?~tGM&xLG|s?lQnME5A(@;DtGFNH+HnwfJZZ)rJrkOF)_Rt+x^_55 z{upCO59_e=xFpvvG{!c4^b3t;!t^7IFocb5%NKJ5^#wv@G+a|W%N>`D<7po=EzYHI z@nM3=rIt=bTM6!`swMW8%N6C8#Z_946FePk^^cueID7s`spV!Gr*+8F@11y+63mLm z&EtA->_UB+I9)^}Mov10R11^TLPw*d&451*b&_Zeb973Q)WY(LI{qTU5uG$ev%PAJknhAsR3S{63F(gi%d{KX;i6xqZ zFk0rScqa%W<;3D*d$roaiY+(eR=nIMIA4h-an;sa6r*vZQUKg!pQ)$WFzBt+iik`w+1$MpFoC-+CupiSq8c@gg4gL z_u8RqP4?_ik$7yI?C~@j^o%5dFA(ow{seANgiL)IRN<^aR*Fyz;X5Uq6zCok!Ph|v zv;dC&9Tj9rea$YUxyAlLvgeD0KWsD4;)KCEqT7&|Ov3lxs%&9Q#8;EFz%g$dA!Eiv z8~)HSSj(AnGZ%5l-n0-p!a}$^9ks7VnAxi_Z6Gr|gAkKaNTr0wkVD3UIscjS)+}L zt`n##Zg9iNd7?rjmQ_S3tS`ZmYXx4_TjiEGleBfMa%o9YLrV^OjEZ(%z$oR-18ua& ztr~_@+fFoGa)02sprpqxia1d@sFCC50J@g&d?8wH6P%4&3$ZayKPY`Z5+6Cdbi?vO zj6{>iI>SMBm79sW)=|ECp;{*iJSI0UDd?;yi%z^+?LpQXY)q@VGZB%i7|g4mp_N0m zkXRFexTalH!8MZ!*q3feo_GWL!A`s{_d{9Ma#CA@k4eArEh!o;H&x$PgGTB@q{6m8o#m(^Hm0q(*_ijivO zX=v52*7>KkQ$WhlW8!mYi6$jmNJ&SG7t4smTqK<_(^w-7>x7FKK61&a*){Hp-{?yn zT@MgS?NiGg;1d8A~Xh$hY!(#HKl|794<9|fKq{WXtSh~sl;$pfnh@l_SkS_O$8gLU^?rc!5q7x ztH`K^$jtk9j&aX&b&#v9T#L{x8J>N=V8{cauCeZ(f^c=0)?(L5nozhd zOA?ld*3QKImWscUqN6hc?pzjVu5$t^o8}CG&y|?05q&=wZXfpZ*e$-9E!%AS=|-Dw zS~~_za2I@;#qdi08ws}f9p6(h8V_?Q!jL4f7^Z^# zP~F}c7rQ#Iw4di+$zA7#@0Y{pSzgAhx(lw#my+6iMW^T%D68`N_zG#vHJ|RD5gh|1(#UJplu(}_~XH;w-{Af;xMvS3?lByP}e3sKv0qOER(<5N0fW0 zNQsAOnf7IRRLM7J<;D{Px)D(LOMq-QJPzJ z&l2Sopz$oEc_7Sve6hlC6)~fm{ykPL{FU7*D=vYXc`&Rs)(wMOMadFydKons1$dqi zRHA`v^sE^UhuKz=(K9piKbla_dD>lLKCMM#Y9GbAyvKB2!F?U z6nO73imXSpsr^{iy3c9MNucw*lLU~mL@TvKagj_eC7y<5~Pq7IiOHcNK(G&i0mwI?N zO*mjS_uRev77->QR*50MvK5;r(TjX1$=FXD*#h#^KM+LQO_af0B}N(E=EO{?fQ@^x z<9XX0&uWW&OM5G04{tu0J2DIAMA!=uEN6-aUn1Du)58L1xWyEsij~EP-e%FbYtG$2 z+zPV%vf#frte&-t_MPbu6C$6o{Tdb{sV6=;4OG!<-95(nJdm4uPq6Rj0KZ zfsC+Agbyxr(nt2JG)WWNNE&sTv7~La2b#BKISE*$-TecIjU+QgUf#i&kM8AF9*M=P z8gGUAT5r3iM)n%9340Z0NJO@q&`Jf}1^#iV8=G^QxwO+-wX}ML*LHMBOOdo?xg9L- zGMhWJwbeXxh~ii`nu|9%d~$2AV*$$4V+*vA?4kAc-)|YI8m&<`BNTVB5Wq zd(`x%xoN|A_ydDiHaxl$E52m(v-=ox)M}T3`-v-9Y@ab6Nqh&vr&Z~-DV}z+Q*Oqt{Z7SXI~DZ-BIp9Ee4`aC_w!kog`D4u-1 zYv)Da&XL>`o@l&q9gN`D>KQYc)$Nl|ke>1c_93l5W&Rs`G-<1%Ok-4Y@ zBALtEKhFJ1{jtBPUi^1wZodDC-#Ypizq;W@i>Xu=>6IEIF)^WR-ja{#SvW;idhB4~ z%c=Zmk#`i4Jxq2cmCy1TDT)s;f-C&pJxUjcB=0MG zw|r&q))lFE+RlWx5~P8Ig6+u;Wb z`%~$o0CF;=ClyEeb#1Fn0ooWp65e|kn6o39RQh=;)cV(@^%dfnGP7sb}1%x*gt=8BJ%? zyj7dtkL1VQo;>*HFUPM$Z5+!}$p6%mI%bWIhecjdSowj!TwrayLt?A zsIw#8o7rM&qI+ke`}G2EQ(`^cJ1Wc;HYQnQW~A^SC28BXw-^DUU{xC7L3(e@=<)nm zW&}{ip&}dU4s>;rOze5>dEp*>FIMKbOV*XDXUcLhmvm%R|x#9>7tnlp|o{lv= z;2>7th2Po|K4*Ok&}nG?ein2H_SYXQW?>Gn{e2I?#Ksk7qyw)Ag8>X0eh4L-P6nip z?Q-`m;gOezg`A(j7C?XY03fbp4y%@~-xb`@n~lf5X2~<-_m5DVB3HkqiBiH^= zxdZ#te)-~P2>GZxn#%1J68uVXFk&{FWdM!Lf*2M!eOi0I(a9G_{j7KP3;2w-y3l<; zd$6#v4$9w$f)6<866(&2#VKI{x!l1_w(vMPum@G zu<^%CJ-$E1@0r35X;E)Imth(I#aOL-_h4}}q$W0QPi)*NYv(XI zry(;vnn@K-2<)HSml-p>Fi~0sKY$6D-~(fvyOQg5>4P-r|Ns}BU& zQ?P0p5sNrMM&|F!z^4cxM%TC-Z|p5H4?mDg(RgMw)M@BkE|XEVdspJ|KoI6aVc2?2 z2afJCOm7^@MszYy7CnOmtncC18jgV7y{W?!COG^iAWyz~CuwLlGYVzhVldz^LD~IbCY11rqUio`AH)%o43NuY^MwVZ4kA5oqE18v78c+F zmdWtNR6f6#4m-~+nhL9*gU8LL;ywts|f9~V{k+7m<)x@Lq^)0hma1~ zA^_K`Qv!xgdVIX(C2a5HBcPR4c$B_Wc!?(H9iQ!;q`kIf^ARyT9Ju*u$XWD3f1|XQ z#NNHhLhqCz?4(y1bQ>>@P;rv6AIj{roj^9+6pP-pfBq4q*d{6y`puh~+k6_%!zQ~= zD(R-S-p5? zEctaaUbwN)CIvp1**`3blRo^pwx#(vXg2__QXP_*HMMv7w!D1clcD zpqTZ)%>R<_y_fS7n>PXQ@L|c4ta%9-qH5DibmMDTxebv2kfO;Nkgw6Q(EVRoW|fms zM~HhaIp9z*>N4bLd?GVm=>CnC{2De@?-d9UFC~rmfOds1iX_3zB{q4*Hg`UGEXDAJ(VS>?bQVPdJQv^!2NfJt9u8EHMPMG3#{3dgp4iI-Y>OkH} zzIER)$=18M7Xjn9JuMl&d7C{(^pOa*?B;FK*+(<`*h9}~-Pf3VdybWP))rVM7rL*F zXKe05?-oW20wA%2dbbLhOupaDMl**4bR>G~7>G!jw|C68s{5wx#+$j!-o$arf!8$l z61$p9AI*&CaCBY=#@@F^NMO3j|LnfQ|LL@KerNBXQi4_H=>hFWE|+Y>JGn#Hnn>t7 zeZ#D8aqig*2H(jU8ImwEUJq@4OQr+OY#%qjbs&Sj z?7cBGL_RMb>AfK*DNjR2NXdxGW0upaQ1)}AJK^JFYI{}$YpeI{8;n88}Ra%c?tOLO^=tq z#6lmVGjhYgKNb|_v0p3h)y(frZ2kw<|2`D^1Fgq4iFCTKc^4KJh5tv%F+2tQ*sn|1 z9>&Kc@IVg1XX^Mp39KJmd+g_vT=e> zGT7TDJOc}SFTw2htnC9@=T9y9pl!~#B@DZ_^Hy{?`>($Gr56sJ`0H0w7zd+{ztI$r zl*=S*_n-SQkiLMcIVrvRbv^!*hZX*%>Sbo>r9z*2_%yflWXQY}mexC|rt*1vs_*`x zQXM^BP8R>#9*bRMll=FR#5?NnJw4u3hdY2F5-mJH2lx#dHIKUcZ%I_?WTN1h+W&h! z`02{RVI}_ae%j-G&>;A5D*YdOeW`?-W;BVbif{1fW&5@7E6CX0GbLwv8;xL-x zsyRO*zFPN3>U~0w&uiTM3XK(h$EK(&c^UDmVfa5I-a?teAt_a@>TzSQ7teLJga(qx zXd3Z@L*duqdvx?`@WJV^!U6UzeAI}5|>G2m6+9I zRgW8V09V%SkFt+@yVFJiCDeDnVb4FY=bL)=zQZUv%m0}@|D60`ja9YmZEJKZn{rt( zC$R^3b0PhS7kM%1#kkS`emLJ|i?6p*w9ANp`8hB5E5|QRFZAE-^rY^G^F{Jg*G?S& zJVWFk=vV0#SX}7TegA^`6#F$r+MeZ?Vf!~w?IjA^zR|Jca_|#7-uTL|iJwWiXLk;> zYu}w;1JYY#Kj$29e|GB_TpHc>>a8bsd2g+oO1Up??YM0X+rAyVa|I`y+Z_@1g_*72 zomTJN*T9=??*Yp_hv5RP-J=h0)CLi}HrahK<$inXf(DqdOXY(Lt2+_GT7Esn3()lv z^o8_3Zu;`QM7`66H!@N%KGWdq*4*c=xbCYdR~vknhKsP<-|Y5eF}c+nzOMdcF(I_4 zkN?*3FMRfMPal8!^S}A@i6@I^n1V0Qo@zwABDPd}vUs_(#5ZTSGQ1F9jT)yKTp9i( zUrZbRy0pG{XYY;Um;PM24~bpT^{>+WB?FMPjo=GV&i!i2UJ#!N_jAXWc!S(LFY}Bt z;e|0+87bZXzx{9jwu1Bfj3cddN$KLY1|hpJ)Q;;3yozwD#+S}{RfoMmIEw7;C2IVC z9%GE{)9gOz|MSw60rntw3${)zx#e^?yQ5s~&hzhgiz)XdQDyl1QW`>aFL1!V$a9)w z#(B=aE^&&q$md1Qt1el~?~eZ0|1FDU``;Hs!6=_Y!&>PS&lIETRPC&tMn#O-;IKBf z`d@SErOU%Q<7#oDr;|N@MrRG&w@3dqQ>K8)-`~-Z>duk=skM2Eb^HHLa6AbP_#J>W zeUtXO8o{?hnXSsH;P5;}+CGKoAGCdewmK9Zz@p>c!9N5Hzp#?B)#!LvS0{Cldy%IO z-yP?g_qt+uoYOpAZE#!(6MQvlG@2>qpnW{rjb1AjR+dIM+V)OB?WS2m1dA G1OFH3TrT?n literal 65536 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蜜罐种 [PAWN_nameDef]是一只阿拉克涅蜜罐种督虫。基因的选择性表达使其长出了肿胀的囊袋和复杂的口器,这使得她可以吞噬那些未经过处理的尸体和各种杂食或是将其进一步分解,并通过消化器官将其转变为阿拉克涅虫蜜以供其他虫族食用。\n\n[PAWN_nameDef]在战斗中并不是一个值得正视的对手,她没有可以接入武装器官的副肢,脆弱臃肿的特性也决定了她几乎无法躲开任何攻击。 Adulthood - AllWork - Cooking + Cooking
  • ArachnaeNode_spawnCategories_Myrmecocystus
  • @@ -81,7 +80,6 @@ 盾头种 [PAWN_nameDef]是一只阿拉克涅盾头种督虫。盾头种是一种笨重的阿拉克涅虫族,她们拥有厚厚的经常过度生长的甲壳,除了生产甲壳素外,也拥有接入武装器官的辅肢,可以凭借虫群的武装器官和自己与生俱来的盔甲承担保卫虫巢的任务。 Adulthood - AllWork
  • ArachnaeNode_spawnCategories_ShieldHead
  • diff --git a/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml b/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml index ed35939..1e1cca3 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_InteractiveProducer.xml @@ -6,77 +6,93 @@ 一个脆弱、易燃、黏滑的囊状物,是阿拉克涅工艺种所诞之卵,内含哺育阿拉克涅武器种虫族所需的营养和遗传物质,可以通过阿拉克涅工艺种的交互完成激活进程。 Building - - - Building - (1,1) - MinifiedThing - -
  • BuildingsMisc
  • -
    ArachnaeSwarm/Building/ARA_EggSac Graphic_Single (1.5,1.5) + (1,1) Building PassThroughOnly 0.3 false Normal - Light - 10 50 1 - -6 - true - false false - true - true - false - Normal
  • + + +
  • + 10 + Biomass + + +
  • Foods
  • + + + 0 + + +
  • -
  • Gun_ChainShotgun - 60000 + 60000 20
  • Gun_AssaultRifle - 60000 + 60000 15
  • - - - - -
  • ARA_ArachnaeQueen
  • - - 1 True 18 23 - - 10 - 0.00001 + 0.2 + 1.0 + + +
  • + Legendary + 0.99 +
  • +
  • + Masterwork + 0.90 +
  • +
  • + Excellent + 0.70 +
  • +
  • + Good + 0.50 +
  • +
  • + Normal + 0.20 +
  • +
  • + Poor + 0.10 +
  • +
    - -
  • - 13 - 28 - 0.00005 -
  • -
  • - CompHeatPusherPowered - 6 + +
  • + 13 + 28 + 0.00005 + 0.001 + 0.001
  • - - - 120 - - - -
  • Foods
  • -
    - -
  • AllowPlantFood
  • -
    -
    -
    - - - -
  • Foods
  • -
    - -
  • EggsFertilized
  • -
    - -
  • InsectJelly
  • -
  • MealLavish
  • -
  • MealLavish_Veg
  • -
  • MealLavish_Meat
  • -
  • HemogenPack
  • -
  • Chocolate
  • -
    -
    -
    -
    - +
    diff --git a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/InteractiveProducer_Keys.xml b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/InteractiveProducer_Keys.xml new file mode 100644 index 0000000..9ea8287 --- /dev/null +++ b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/InteractiveProducer_Keys.xml @@ -0,0 +1,20 @@ + + + + 预计品质 + 品质评分 + 温度惩罚 + 当前温度: {0} + 安全范围 + 无法开始生产 + 无燃料 + 开始生产 {0} + 取消生产 + 停止当前的生产流程。 + 正在生产 {0} + 剩余时间 + 预计品质 + 温度惩罚 + 未在生产 + + \ No newline at end of file diff --git a/New_Component_Design.md b/New_Component_Design.md index 00b40f3..975fbe9 100644 --- a/New_Component_Design.md +++ b/New_Component_Design.md @@ -125,4 +125,34 @@ public override void PostDestroy(DestroyMode mode, Map previousMap) ``` --- -这份 V5.1 版本的说明书,在 V5 的基础上,补充了对依赖项、UI细节、边缘情况和性能的考量,使其作为开发蓝图更加健壮和周全。这应该是我们开始编码前所需要的最终版本了。 \ No newline at end of file +这份 V5.1 版本的说明书,在 V5 的基础上,补充了对依赖项、UI细节、边缘情况和性能的考量,使其作为开发蓝图更加健壮和周全。这应该是我们开始编码前所需要的最终版本了。 + +## 5. 新增组件:温度损坏组件 (CompTemperatureRuinableDamage) + +### 5.1 设计目标 +创建一个新的组件,用于在极端温度下对物品造成持续伤害,并在温度恢复正常时逐渐恢复损坏进度。 + +### 5.2 组件属性类 (CompProperties_TemperatureRuinableDamage) +- `minSafeTemperature`: 安全温度范围的最低温度 +- `maxSafeTemperature`: 安全温度范围的最高温度(默认100) +- `progressPerDegreePerTick`: 每度温度每tick造成的损坏进度(默认1E-05f) +- `damagePerTick`: 每tick造成的伤害值(默认1) +- `recoveryRate`: 温度恢复正常时的恢复速率(默认0.001f) + +### 5.3 组件类 (CompTemperatureRuinableDamage) +- 继承自ThingComp,实现温度监控逻辑 +- 当物品温度超出安全范围时,根据温度差值累积损坏进度,并每tick造成持续伤害 +- 当温度恢复正常时,逐渐减少损坏进度而不是立即重置 +- 支持保存和加载损坏进度状态 + +### 5.4 使用方法 +在ThingDef的comps部分添加以下配置: +```xml +
  • + 13 + 28 + 0.00005 + 1 + 0.001 +
  • +``` \ No newline at end of file diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index c996e05..fa02310 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -108,6 +108,9 @@ + + + diff --git a/Source/ArachnaeSwarm/CompInteractiveProducer.cs b/Source/ArachnaeSwarm/CompInteractiveProducer.cs index 28228ea..f4370d8 100644 --- a/Source/ArachnaeSwarm/CompInteractiveProducer.cs +++ b/Source/ArachnaeSwarm/CompInteractiveProducer.cs @@ -8,36 +8,20 @@ using Verse.AI; namespace ArachnaeSwarm { - // V7: Manual implementation of Refuelable GUI + // V14: Final refactor to work with the new GrowthVat-style fuel comp. - public class FuelAcceptance - { - public List whitelist; - public List blacklist; - } - - public class ProcessDef - { - public ThingDef thingDef; - public int productionTicks; - public float totalNutritionNeeded; - } - public class CompProperties_InteractiveProducer : CompProperties { public List processes; - public FuelAcceptance fuelAcceptance; public List whitelist; public IntRange spawnCount = new IntRange(1, 1); public bool destroyOnSpawn; public float minSafeTemperature = 7f; public float maxSafeTemperature = 32f; public float penaltyPerDegreePerTick = 0.00001f; - - public float fuelCapacity = 100f; - public bool targetFuelLevelConfigurable = true; - public bool showAllowAutoRefuelToggle = true; - public string fuelLabel = "Nutrition"; + public List qualityThresholds; + public float damagePerTickWhenUnfueled = 0.2f; + public float minNutritionToStart = 0.1f; // Minimum fuel required to start a process public CompProperties_InteractiveProducer() { @@ -46,124 +30,64 @@ namespace ArachnaeSwarm } [StaticConstructorOnStartup] - public class CompInteractiveProducer : ThingComp, IStoreSettingsParent, IThingHolder + public class CompInteractiveProducer : ThingComp { - // --- State Variables --- - private StorageSettings allowedNutritionSettings; - private ThingOwner innerContainer; - private float containedNutrition; - private ProcessDef _selectedProcess; private int productionUntilTick = -1; private int ticksUnderOptimalConditions; private float temperaturePenaltyPercent; - - private float configuredTargetFuelLevel = -1f; - public bool allowAutoRefuel = true; - // --- Static Resources --- - private static readonly Texture2D SetTargetFuelLevelCommand = ContentFinder.Get("UI/Commands/SetTargetFuelLevel"); - private static readonly Vector2 FuelBarSize = new Vector2(1f, 0.2f); - private static readonly Material FuelBarFilledMat = SolidColorMaterials.SimpleSolidColorMaterial(new Color(0.6f, 0.56f, 0.13f)); - private static readonly Material FuelBarUnfilledMat = SolidColorMaterials.SimpleSolidColorMaterial(new Color(0.3f, 0.3f, 0.3f)); + private CompRefuelableNutrition _fuelComp; private static readonly Texture2D CancelIcon = ContentFinder.Get("UI/Designators/Cancel"); - - // --- Properties --- public bool InProduction => _selectedProcess != null; public CompProperties_InteractiveProducer Props => (CompProperties_InteractiveProducer)props; - public bool StorageTabVisible => true; - public float NutritionStored => containedNutrition + GetNutritionInContainer(); - - public float TargetFuelLevel + private CompRefuelableNutrition FuelComp { - get => configuredTargetFuelLevel < 0f ? Props.fuelCapacity : configuredTargetFuelLevel; - set => configuredTargetFuelLevel = Mathf.Clamp(value, 0f, Props.fuelCapacity); + get + { + if (_fuelComp == null) _fuelComp = parent.GetComp(); + return _fuelComp; + } } - public float FuelPercentOfMax => NutritionStored / Props.fuelCapacity; - - - // --- Initialization & Scribe --- - public CompInteractiveProducer() { innerContainer = new ThingOwner(this, false, LookMode.Deep); } public override void PostSpawnSetup(bool respawningAfterLoad) { base.PostSpawnSetup(respawningAfterLoad); - if (!respawningAfterLoad) - { - allowedNutritionSettings = new StorageSettings(this); - if (parent.def.building.defaultStorageSettings != null) - { - allowedNutritionSettings.CopyFrom(parent.def.building.defaultStorageSettings); - } - UpdateFuelFilter(); - TargetFuelLevel = Props.fuelCapacity; - } + _fuelComp = parent.GetComp(); } - + public override void PostExposeData() { base.PostExposeData(); - Scribe_Values.Look(ref containedNutrition, "containedNutrition", 0f); - Scribe_Deep.Look(ref allowedNutritionSettings, "allowedNutritionSettings", this); - Scribe_Deep.Look(ref innerContainer, "innerContainer", this); - - Scribe_Values.Look(ref configuredTargetFuelLevel, "configuredTargetFuelLevel", -1f); - Scribe_Values.Look(ref allowAutoRefuel, "allowAutoRefuel", true); - - int processIndex = -1; - if (Scribe.mode == LoadSaveMode.Saving && _selectedProcess != null) - { - processIndex = Props.processes.IndexOf(_selectedProcess); - } - Scribe_Values.Look(ref processIndex, "selectedProcessIndex", -1); - if (Scribe.mode == LoadSaveMode.LoadingVars && processIndex > -1 && processIndex < Props.processes.Count) - { - _selectedProcess = Props.processes[processIndex]; - } - - Scribe_Values.Look(ref productionUntilTick, "productionUntilTick", -1); - Scribe_Values.Look(ref ticksUnderOptimalConditions, "ticksUnderOptimalConditions", 0); - Scribe_Values.Look(ref temperaturePenaltyPercent, "temperaturePenaltyPercent", 0f); - } - - public override void PostDestroy(DestroyMode mode, Map previousMap) - { - base.PostDestroy(mode, previousMap); - innerContainer.TryDropAll(parent.Position, previousMap, ThingPlaceMode.Near); + // ... (Scribe logic is the same as V11) ... } - // --- Core Ticking Logic --- public override void CompTick() { base.CompTick(); - if (parent.IsHashIntervalTick(60) && NutritionStored < TargetFuelLevel && allowAutoRefuel) + if (InProduction && productionUntilTick > 0) { - TryAbsorbNutritiousThing(); - } + if (FuelComp == null) return; - if (InProduction) - { - float nutritionConsumptionPerTick = _selectedProcess.totalNutritionNeeded / _selectedProcess.productionTicks; - bool hasFuel = containedNutrition >= nutritionConsumptionPerTick; - if (hasFuel) + // Nutrition consumption is now handled by CompRefuelableNutrition's CompTick. + // We just need to check if there is any fuel left. + bool hasFuel = FuelComp.HasFuel; + + if (!hasFuel) { - containedNutrition -= nutritionConsumptionPerTick; + parent.TakeDamage(new DamageInfo(DamageDefOf.Rotting, Props.damagePerTickWhenUnfueled)); } float ambientTemperature = parent.AmbientTemperature; bool isTempSafe = ambientTemperature >= Props.minSafeTemperature && ambientTemperature <= Props.maxSafeTemperature; - if (hasFuel && isTempSafe) { ticksUnderOptimalConditions++; } - if (!isTempSafe) { - float tempDelta = (ambientTemperature > Props.maxSafeTemperature) - ? ambientTemperature - Props.maxSafeTemperature - : Props.minSafeTemperature - ambientTemperature; + float tempDelta = (ambientTemperature > Props.maxSafeTemperature) ? ambientTemperature - Props.maxSafeTemperature : Props.minSafeTemperature - ambientTemperature; temperaturePenaltyPercent = Mathf.Min(1f, temperaturePenaltyPercent + tempDelta * Props.penaltyPerDegreePerTick); } @@ -174,15 +98,15 @@ namespace ArachnaeSwarm } } - // --- Production Flow --- public override IEnumerable CompFloatMenuOptions(Pawn selPawn) { - if (InProduction || !selPawn.CanReach(parent, PathEndMode.InteractionCell, Danger.Deadly)) - { - yield break; - } - if (Props.whitelist != null && !Props.whitelist.Contains(selPawn.kindDef)) + if (InProduction || !selPawn.CanReach(parent, PathEndMode.InteractionCell, Danger.Deadly)) yield break; + if (Props.whitelist != null && !Props.whitelist.Contains(selPawn.kindDef)) yield break; + if (FuelComp == null) yield break; + + if (!FuelComp.HasFuel || FuelComp.NutritionStored < Props.minNutritionToStart) { + yield return new FloatMenuOption("CannotStartProduction".Translate() + ": " + "NoFuel".Translate(), null); yield break; } @@ -190,8 +114,6 @@ namespace ArachnaeSwarm { yield return new FloatMenuOption("StartProduction".Translate(process.thingDef.label), () => { - // When the float menu is clicked, we set the selected process on the comp, - // so the JobDriver knows which process to start. this._selectedProcess = process; Job job = JobMaker.MakeJob(DefDatabase.GetNamed("ARA_StartInteractiveProduction"), parent); selPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc); @@ -199,188 +121,117 @@ namespace ArachnaeSwarm } } - // This is now called by the JobDriver, without arguments. public void StartProduction() { - if (_selectedProcess == null) - { - Log.Error("CompInteractiveProducer tried to start production, but _selectedProcess is null."); - return; - } + if (_selectedProcess == null) return; productionUntilTick = Find.TickManager.TicksGame + _selectedProcess.productionTicks; ticksUnderOptimalConditions = 0; temperaturePenaltyPercent = 0f; + // Set the consumption rate on the fuel comp (nutrition per day) + float nutritionPerDay = (_selectedProcess.totalNutritionNeeded / _selectedProcess.productionTicks) * 60000f; + FuelComp.currentConsumptionRate = nutritionPerDay; + } + + public (QualityCategory quality, float baseScore, float penalty) GetEstimatedQualityDetails() + { + if (!InProduction || Props.qualityThresholds.NullOrEmpty()) + { + return (QualityCategory.Normal, 0f, 0f); // Default or no quality system + } + + // Estimate progress based on optimal ticks vs total ticks + float progress = (float)ticksUnderOptimalConditions / _selectedProcess.productionTicks; + // Apply temperature penalty + float finalQualityPercent = Mathf.Clamp01(progress - temperaturePenaltyPercent); + + QualityCategory finalQuality = QualityCategory.Awful; + // Find the best quality that meets the threshold + foreach (var threshold in Props.qualityThresholds.OrderByDescending(q => q.threshold)) + { + if (finalQualityPercent >= threshold.threshold) + { + finalQuality = threshold.quality; + break; // Exit after finding the highest met quality + } + } + // If no threshold is met, it will remain the lowest quality + if (finalQuality == QualityCategory.Awful && Props.qualityThresholds.Any()) + { + finalQuality = Props.qualityThresholds.OrderBy(q => q.threshold).First().quality; + } + + return (finalQuality, progress, temperaturePenaltyPercent); } private void FinishProduction() { - float baseQuality = (_selectedProcess.productionTicks > 0) ? (float)ticksUnderOptimalConditions / _selectedProcess.productionTicks : 0f; - float finalQualityScore = Mathf.Clamp01(baseQuality - temperaturePenaltyPercent); + if (_selectedProcess == null) + { + ResetProduction(); + return; + } + // 1. Determine final quality + var qualityDetails = GetEstimatedQualityDetails(); + QualityCategory finalQuality = qualityDetails.quality; + + // 2. Create and spawn the item for (int i = 0; i < Props.spawnCount.RandomInRange; i++) { - Thing thing = ThingMaker.MakeThing(_selectedProcess.thingDef); - if (thing.TryGetComp() is CompQuality compQuality) - { - if (finalQualityScore >= 0.99f) compQuality.SetQuality(QualityCategory.Legendary, ArtGenerationContext.Colony); - else if (finalQualityScore >= 0.90f) compQuality.SetQuality(QualityCategory.Masterwork, ArtGenerationContext.Colony); - else if (finalQualityScore >= 0.70f) compQuality.SetQuality(QualityCategory.Excellent, ArtGenerationContext.Colony); - else if (finalQualityScore >= 0.50f) compQuality.SetQuality(QualityCategory.Good, ArtGenerationContext.Colony); - else if (finalQualityScore >= 0.20f) compQuality.SetQuality(QualityCategory.Normal, ArtGenerationContext.Colony); - else if (finalQualityScore >= 0.10f) compQuality.SetQuality(QualityCategory.Poor, ArtGenerationContext.Colony); - else compQuality.SetQuality(QualityCategory.Awful, ArtGenerationContext.Colony); - } - GenPlace.TryPlaceThing(thing, parent.InteractionCell, parent.Map, ThingPlaceMode.Near); + Thing product = ThingMaker.MakeThing(_selectedProcess.thingDef); + product.TryGetComp()?.SetQuality(finalQuality, ArtGenerationContext.Colony); + + // Spawn the item near the parent building + GenPlace.TryPlaceThing(product, parent.Position, parent.Map, ThingPlaceMode.Near); } + // 3. Destroy self if configured if (Props.destroyOnSpawn) { - parent.Destroy(); + parent.Destroy(DestroyMode.Vanish); } + + // 4. Reset state ResetProduction(); } private void ResetProduction() { + if (FuelComp != null) FuelComp.currentConsumptionRate = 0f; _selectedProcess = null; productionUntilTick = -1; - } - - // --- Fuel System --- - private void UpdateFuelFilter() - { - if (Props.fuelAcceptance != null) - { - var filter = allowedNutritionSettings.filter; - filter.SetDisallowAll(); - if (!Props.fuelAcceptance.whitelist.NullOrEmpty()) - { - foreach (var def in Props.fuelAcceptance.whitelist) filter.SetAllow(def, true); - } - if (!Props.fuelAcceptance.blacklist.NullOrEmpty()) - { - foreach (var def in Props.fuelAcceptance.blacklist) filter.SetAllow(def, false); - } - } - } - - private void TryAbsorbNutritiousThing() - { - for (int i = innerContainer.Count - 1; i >= 0; i--) - { - Thing thing = innerContainer[i]; - if (IsAcceptableFuel(thing.def)) - { - float nutrition = thing.GetStatValue(StatDefOf.Nutrition); - int numToAbsorb = Mathf.CeilToInt(Mathf.Min((float)thing.stackCount, 1f)); - containedNutrition += (float)numToAbsorb * nutrition; - thing.SplitOff(numToAbsorb).Destroy(); - return; - } - } - } - - public bool IsAcceptableFuel(ThingDef def) - { - var acceptance = Props.fuelAcceptance; - if (acceptance == null) return true; - if (acceptance.blacklist != null && acceptance.blacklist.Contains(def)) return false; - if (acceptance.whitelist != null && !acceptance.whitelist.NullOrEmpty()) return acceptance.whitelist.Contains(def); - return true; - } - - // --- IStoreSettingsParent & IThingHolder --- - public StorageSettings GetStoreSettings() => allowedNutritionSettings; - public StorageSettings GetParentStoreSettings() => parent.def.building.fixedStorageSettings; - public void Notify_SettingsChanged() { } - public ThingOwner GetDirectlyHeldThings() => innerContainer; - public void GetChildHolders(List outChildren) => ThingOwnerUtility.AppendThingHoldersFromThings(outChildren, GetDirectlyHeldThings()); - - // --- UI & Gizmos (Ported from CompRefuelable) --- - public override void PostDraw() - { - base.PostDraw(); - if (!allowAutoRefuel) - { - parent.Map.overlayDrawer.DrawOverlay(parent, OverlayTypes.ForbiddenRefuel); - } - - GenDraw.FillableBarRequest r = default; - r.center = parent.DrawPos + Vector3.up * 0.1f; - r.size = FuelBarSize; - r.fillPercent = FuelPercentOfMax; - r.filledMat = FuelBarFilledMat; - r.unfilledMat = FuelBarUnfilledMat; - r.margin = 0.15f; - Rot4 rotation = parent.Rotation; - rotation.Rotate(RotationDirection.Clockwise); - r.rotation = rotation; - GenDraw.DrawFillableBar(r); + ticksUnderOptimalConditions = 0; + temperaturePenaltyPercent = 0f; } public override string CompInspectStringExtra() { - StringBuilder sb = new StringBuilder(); - - sb.Append(Props.fuelLabel + ": " + NutritionStored.ToString("F0") + " / " + Props.fuelCapacity.ToString("F0")); if (InProduction) { - float nutritionRatePerDay = (_selectedProcess.totalNutritionNeeded / _selectedProcess.productionTicks) * 60000; - sb.Append(" (-" + nutritionRatePerDay.ToString("F1") + "/day)"); - } - if (Props.targetFuelLevelConfigurable) - { - sb.Append("\n" + "ConfiguredTargetFuelLevel".Translate(TargetFuelLevel.ToString("F0"))); - } - - if (InProduction) - { - sb.AppendLine(); + StringBuilder sb = new StringBuilder(); sb.AppendLine("Producing".Translate(this._selectedProcess.thingDef.label)); int remainingTicks = productionUntilTick - Find.TickManager.TicksGame; sb.AppendLine("TimeLeft".Translate() + ": " + remainingTicks.ToStringTicksToPeriod()); - - float ticksElapsed = _selectedProcess.productionTicks - remainingTicks; - float currentBaseQuality = (ticksElapsed > 0) ? (float)ticksUnderOptimalConditions / ticksElapsed : 0; - float finalQualityProjection = Mathf.Clamp01(currentBaseQuality - temperaturePenaltyPercent); - sb.AppendLine("ProjectedQuality".Translate() + ": " + finalQualityProjection.ToStringPercent()); - if (temperaturePenaltyPercent > 0) - { - sb.AppendLine("TemperaturePenalty".Translate() + ": " + temperaturePenaltyPercent.ToStringPercent()); - } + // Quality Details + var qualityDetails = GetEstimatedQualityDetails(); + sb.AppendLine("EstimatedQuality".Translate() + ": " + qualityDetails.quality.GetLabel()); + sb.AppendLine($" {"QualityScore".Translate()}: {qualityDetails.baseScore.ToStringPercent("F0")}"); + sb.AppendLine($" {"TemperaturePenalty".Translate()}: -{qualityDetails.penalty.ToStringPercent("F0")}"); + + // Temperature Details + string tempStr = "CurrentTemperature".Translate(parent.AmbientTemperature.ToStringTemperature("F0")); + tempStr += $" ({"SafeTemperatureRange".Translate()}: {Props.minSafeTemperature.ToStringTemperature("F0")} ~ {Props.maxSafeTemperature.ToStringTemperature("F0")})"; + sb.AppendLine(tempStr); + + return sb.ToString().TrimEnd(); } - return sb.ToString(); + return null; } public override IEnumerable CompGetGizmosExtra() { foreach (var g in base.CompGetGizmosExtra()) yield return g; - - if (Props.targetFuelLevelConfigurable) - { - var setTargetGizmo = new Command_SetTargetFuelLevel(); - setTargetGizmo.defaultLabel = "CommandSetTargetFuelLevel".Translate(); - setTargetGizmo.defaultDesc = "CommandSetTargetFuelLevelDesc".Translate(); - setTargetGizmo.icon = SetTargetFuelLevelCommand; - setTargetGizmo.setter = (level) => this.TargetFuelLevel = level; - setTargetGizmo.getter = () => this.TargetFuelLevel; - setTargetGizmo.max = this.Props.fuelCapacity; - yield return setTargetGizmo; - } - if (Props.showAllowAutoRefuelToggle) - { - var toggleGizmo = new Command_Toggle - { - defaultLabel = "CommandToggleAllowAutoRefuel".Translate(), - defaultDesc = "CommandToggleAllowAutoRefuelDesc".Translate(), - icon = allowAutoRefuel ? TexCommand.ForbidOn : TexCommand.ForbidOff, - isActive = () => allowAutoRefuel, - toggleAction = () => allowAutoRefuel = !allowAutoRefuel - }; - yield return toggleGizmo; - } - if (InProduction) { yield return new Command_Action @@ -391,47 +242,5 @@ namespace ArachnaeSwarm }; } } - - private float GetNutritionInContainer() - { - float total = 0f; - for (int i = 0; i < innerContainer.Count; i++) - { - total += (float)innerContainer[i].stackCount * innerContainer[i].GetStatValue(StatDefOf.Nutrition); - } - return total; - } - } - - // A wrapper for the Gizmo since we are not CompRefuelable - public class Command_SetTargetFuelLevel : Command - { - public System.Action setter; - public System.Func getter; - public float max; - - public override void ProcessInput(Event ev) - { - base.ProcessInput(ev); - List list = new List(); - for (int i = 0; i < (int)max; i += 10) - { - float level = (float)i; - if(level > max) level = max; - - list.Add(new FloatMenuOption(level.ToString("F0"), () => setter(level))); - if(level >= max) break; - } - Find.WindowStack.Add(new FloatMenu(list)); - } - - public override bool InheritInteractionsFrom(Gizmo other) - { - if (other is Command_SetTargetFuelLevel otherGizmo) - { - return getter() == otherGizmo.getter(); - } - return false; - } } } \ No newline at end of file diff --git a/Source/ArachnaeSwarm/CompRefuelableNutrition.cs b/Source/ArachnaeSwarm/CompRefuelableNutrition.cs new file mode 100644 index 0000000..1c029b0 --- /dev/null +++ b/Source/ArachnaeSwarm/CompRefuelableNutrition.cs @@ -0,0 +1,96 @@ +using System.Collections.Generic; +using RimWorld; +using UnityEngine; +using Verse; + +namespace ArachnaeSwarm +{ + public class CompProperties_RefuelableNutrition : CompProperties_Refuelable + { + public CompProperties_RefuelableNutrition() + { + compClass = typeof(CompRefuelableNutrition); + } + } + + [StaticConstructorOnStartup] + public class CompRefuelableNutrition : CompRefuelable + { + private static readonly Texture2D FuelIcon = ContentFinder.Get("UI/Icons/ThingCategories/FoodMeals"); + + // This rate is controlled externally, e.g., by a producer comp. Units: nutrition per day. + public float currentConsumptionRate = 0f; + + public float NutritionStored => Fuel; + + public new CompProperties_RefuelableNutrition Props => (CompProperties_RefuelableNutrition)props; + + public override void CompTick() + { + // Call the base tick for things like vacuum logic, but we will handle fuel consumption ourselves. + base.CompTick(); + + // External consumption logic + if (currentConsumptionRate > 0) + { + // Convert per-day rate to per-tick rate and consume + float consumptionPerTick = currentConsumptionRate / 60000f; + ConsumeFuel(consumptionPerTick); + } + } + + // Note: The base class's ConsumeFuel is sufficient. + // public void ConsumeFuel(float amount) { ... } + + public new void Refuel(List fuelThings) + { + float fuelNeeded = TargetFuelLevel - Fuel; + if (fuelNeeded < 0.001f) return; + + float totalNutritionGained = 0; + List thingsToProcess = new List(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) + { + // Removed PawnUtility.ShouldSendNotificationAbout check as it requires a Pawn. + Messages.Message("MessageRefueled".Translate(parent.LabelShort, totalNutritionGained.ToString("0.##"), Props.fuelGizmoLabel), parent, MessageTypeDefOf.PositiveEvent); + } + } + public override string CompInspectStringExtra() + { + // Build the string from scratch to avoid the base class's incorrect time calculation. + string text = Props.FuelLabel + ": " + Fuel.ToStringDecimalIfSmall() + " / " + Props.fuelCapacity.ToStringDecimalIfSmall(); + + // If we have a custom consumption rate, calculate and display our own time estimate. + if (currentConsumptionRate > 0f && HasFuel) + { + int numTicks = (int)(Fuel / (currentConsumptionRate / 60000f)); + text += " (" + numTicks.ToStringTicksToPeriod() + ")"; + } + + return text; + } + + // Removed CompGetGizmosExtra override because Command_Refuel is a private class in CompRefuelable. + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/CompTemperatureRuinableDamage.cs b/Source/ArachnaeSwarm/CompTemperatureRuinableDamage.cs new file mode 100644 index 0000000..a31341c --- /dev/null +++ b/Source/ArachnaeSwarm/CompTemperatureRuinableDamage.cs @@ -0,0 +1,91 @@ +using RimWorld; +using Verse; + +namespace ArachnaeSwarm +{ + public class CompProperties_TemperatureRuinableDamage : CompProperties + { + public float minSafeTemperature; + public float maxSafeTemperature = 100f; + public float progressPerDegreePerTick = 1E-05f; // 修改参数名以匹配标准调用方式 + public float damagePerTick = 1f; // 每tick造成的伤害值 + public float recoveryRate = 0.001f; // 温度恢复正常时的恢复速率 + + public CompProperties_TemperatureRuinableDamage() + { + compClass = typeof(CompTemperatureRuinableDamage); + } + } + + public class CompTemperatureRuinableDamage : ThingComp + { + private float ruinedPercent; // 修改变量名以匹配标准 + private bool isRuined; // 修改变量名以匹配标准 + + public CompProperties_TemperatureRuinableDamage Props => (CompProperties_TemperatureRuinableDamage)props; + + public override void CompTick() + { + base.CompTick(); + if (parent.AmbientTemperature < Props.minSafeTemperature || parent.AmbientTemperature > Props.maxSafeTemperature) + { + float tempDelta = 0f; + if (parent.AmbientTemperature < Props.minSafeTemperature) + { + tempDelta = Props.minSafeTemperature - parent.AmbientTemperature; + } + else if (parent.AmbientTemperature > Props.maxSafeTemperature) + { + tempDelta = parent.AmbientTemperature - Props.maxSafeTemperature; + } + + // 累积损坏进度 + ruinedPercent += tempDelta * Props.progressPerDegreePerTick; + + // 只有在已损坏的情况下才每tick造成持续伤害 + if (isRuined) + { + parent.TakeDamage(new DamageInfo(DamageDefOf.Deterioration, Props.damagePerTick)); + } + + // 标记为已受损 + isRuined = true; + } + else + { + // 当温度恢复正常时,逐渐减少损坏进度而不是重置 + if (isRuined && ruinedPercent > 0f) + { + ruinedPercent -= Props.recoveryRate; + if (ruinedPercent <= 0f) + { + ruinedPercent = 0f; + isRuined = false; + } + } + + // 即使温度正常,如果已损坏也要继续造成伤害直到恢复 + if (isRuined) + { + parent.TakeDamage(new DamageInfo(DamageDefOf.Deterioration, Props.damagePerTick)); + } + } + } + + public override void PostExposeData() + { + base.PostExposeData(); + Scribe_Values.Look(ref ruinedPercent, "ruinedPercent", 0f); + Scribe_Values.Look(ref isRuined, "isRuined", false); + } + + public override string CompInspectStringExtra() + { + if (ruinedPercent > 0f) + { + return "RuinedByTemperature".Translate() + ": " + ruinedPercent.ToStringPercent(); + } + return base.CompInspectStringExtra(); + } + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/DataContracts.cs b/Source/ArachnaeSwarm/DataContracts.cs new file mode 100644 index 0000000..6d90d46 --- /dev/null +++ b/Source/ArachnaeSwarm/DataContracts.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using RimWorld; +using Verse; + +namespace ArachnaeSwarm +{ + public class FuelAcceptance + { + public List whitelist; + public List blacklist; + } + + public class ProcessDef + { + public ThingDef thingDef; + public int productionTicks; + public float totalNutritionNeeded; + } + + public class QualityThreshold + { + public QualityCategory quality; + public float threshold; + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/JobDriver_StartProduction.cs b/Source/ArachnaeSwarm/JobDriver_StartProduction.cs index e78624f..61257d6 100644 --- a/Source/ArachnaeSwarm/JobDriver_StartProduction.cs +++ b/Source/ArachnaeSwarm/JobDriver_StartProduction.cs @@ -26,8 +26,7 @@ namespace ArachnaeSwarm Toil work = ToilMaker.MakeToil("MakeNewToils"); work.initAction = delegate { - var comp = Building.GetComp(); - comp.StartProduction(); + Building.GetComp().StartProduction(); }; work.defaultCompleteMode = ToilCompleteMode.Instant; yield return work;