几个comps修改
This commit is contained in:
Binary file not shown.
@@ -1388,7 +1388,7 @@
|
||||
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Suicide_Ability</iconPath>
|
||||
<cooldownTicksRange>1</cooldownTicksRange>
|
||||
<aiCanUse>true</aiCanUse>
|
||||
<displayOrder>300</displayOrder>
|
||||
<displayOrder>9900</displayOrder>
|
||||
<displayGizmoWhileUndrafted>true</displayGizmoWhileUndrafted>
|
||||
<disableGizmoWhileUndrafted>false</disableGizmoWhileUndrafted>
|
||||
<warmupStartSound>AcidSpray_Warmup</warmupStartSound>
|
||||
@@ -1419,7 +1419,7 @@
|
||||
<cooldownTicksRange>144000</cooldownTicksRange>
|
||||
<targetRequired>false</targetRequired>
|
||||
<casterMustBeCapableOfViolence>false</casterMustBeCapableOfViolence>
|
||||
<displayOrder>301</displayOrder>
|
||||
<displayOrder>9901</displayOrder>
|
||||
<verbProperties>
|
||||
<verbClass>Verb_CastAbility</verbClass>
|
||||
<drawAimPie>false</drawAimPie>
|
||||
|
||||
@@ -229,6 +229,13 @@
|
||||
<customLabel>温度要求</customLabel>
|
||||
<showCurrentTemperature>true</showCurrentTemperature>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AbilityShowInteractiveThing">
|
||||
<cocoonBuildingDef>ARA_Cocoon_Cloth</cocoonBuildingDef>
|
||||
<customLabel>可孵化物品列表</customLabel>
|
||||
<showResearchRequirements>true</showResearchRequirements>
|
||||
<showNutritionCost>true</showNutritionCost>
|
||||
<showIncubationTime>true</showIncubationTime>
|
||||
</li>
|
||||
</comps>
|
||||
</AbilityDef>
|
||||
<AbilityDef ParentName="ARA_CocoonSpew_Base">
|
||||
@@ -245,6 +252,13 @@
|
||||
<customLabel>温度要求</customLabel>
|
||||
<showCurrentTemperature>true</showCurrentTemperature>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AbilityShowInteractiveThing">
|
||||
<cocoonBuildingDef>ARA_Cocoon_Weapon</cocoonBuildingDef>
|
||||
<customLabel>可孵化物品列表</customLabel>
|
||||
<showResearchRequirements>true</showResearchRequirements>
|
||||
<showNutritionCost>true</showNutritionCost>
|
||||
<showIncubationTime>true</showIncubationTime>
|
||||
</li>
|
||||
</comps>
|
||||
</AbilityDef>
|
||||
<!-- T1 -->
|
||||
@@ -262,6 +276,13 @@
|
||||
<customLabel>温度要求</customLabel>
|
||||
<showCurrentTemperature>true</showCurrentTemperature>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AbilityShowInteractiveThing">
|
||||
<cocoonBuildingDef>ARA_Cocoon_Cloth_1Stage</cocoonBuildingDef>
|
||||
<customLabel>可孵化物品列表</customLabel>
|
||||
<showResearchRequirements>true</showResearchRequirements>
|
||||
<showNutritionCost>true</showNutritionCost>
|
||||
<showIncubationTime>true</showIncubationTime>
|
||||
</li>
|
||||
</comps>
|
||||
</AbilityDef>
|
||||
<AbilityDef ParentName="ARA_CocoonSpew_Base">
|
||||
@@ -278,6 +299,13 @@
|
||||
<customLabel>温度要求</customLabel>
|
||||
<showCurrentTemperature>true</showCurrentTemperature>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AbilityShowInteractiveThing">
|
||||
<cocoonBuildingDef>ARA_Cocoon_Weapon_1Stage</cocoonBuildingDef>
|
||||
<customLabel>可孵化物品列表</customLabel>
|
||||
<showResearchRequirements>true</showResearchRequirements>
|
||||
<showNutritionCost>true</showNutritionCost>
|
||||
<showIncubationTime>true</showIncubationTime>
|
||||
</li>
|
||||
</comps>
|
||||
</AbilityDef>
|
||||
<!-- T2 -->
|
||||
@@ -295,10 +323,17 @@
|
||||
<customLabel>温度要求</customLabel>
|
||||
<showCurrentTemperature>true</showCurrentTemperature>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AbilityShowInteractiveThing">
|
||||
<cocoonBuildingDef>ARA_Cocoon_Cloth_2Stage</cocoonBuildingDef>
|
||||
<customLabel>可孵化物品列表</customLabel>
|
||||
<showResearchRequirements>true</showResearchRequirements>
|
||||
<showNutritionCost>true</showNutritionCost>
|
||||
<showIncubationTime>true</showIncubationTime>
|
||||
</li>
|
||||
</comps>
|
||||
</AbilityDef>
|
||||
<AbilityDef ParentName="ARA_CocoonSpew_Base">
|
||||
<defName>ARA_Cocoon_Weapon_2Stage_Ability</defName>
|
||||
<defName>ARA_Cocoon_Weapon_2Stage</defName>
|
||||
<label>武装器官孵化茧——等级2</label>
|
||||
<description>投放一枚武装器官茧,内含可以孵化一套基础武装器官的营养和遗传物质——参阅茧的超链接,了解其能生产的所有装备的特点。</description>
|
||||
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Cocoon_Weapon_2Stage</iconPath>
|
||||
@@ -311,6 +346,13 @@
|
||||
<customLabel>温度要求</customLabel>
|
||||
<showCurrentTemperature>true</showCurrentTemperature>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AbilityShowInteractiveThing">
|
||||
<cocoonBuildingDef>ARA_Cocoon_Weapon_2Stage</cocoonBuildingDef>
|
||||
<customLabel>可孵化物品列表</customLabel>
|
||||
<showResearchRequirements>true</showResearchRequirements>
|
||||
<showNutritionCost>true</showNutritionCost>
|
||||
<showIncubationTime>true</showIncubationTime>
|
||||
</li>
|
||||
</comps>
|
||||
</AbilityDef>
|
||||
|
||||
|
||||
@@ -319,7 +319,7 @@
|
||||
<li Class="HediffCompProperties_GiveAbility">
|
||||
<abilityDefs>
|
||||
<li>ARA_Cocoon_Cloth_2Stage</li>
|
||||
<li>ARA_Cocoon_Weapon_2Stage_Ability</li>
|
||||
<li>ARA_Cocoon_Weapon_2Stage</li>
|
||||
</abilityDefs>
|
||||
</li>
|
||||
</comps>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<takeFootprints>True</takeFootprints>
|
||||
<avoidWander>false</avoidWander>
|
||||
<statBases>
|
||||
<Beauty>-6</Beauty>
|
||||
<Beauty>0</Beauty>
|
||||
<CleaningTimeFactor>0.25</CleaningTimeFactor>
|
||||
<Cleanliness>0</Cleanliness>
|
||||
<Flammability>0</Flammability>
|
||||
@@ -75,7 +75,7 @@
|
||||
<li>Substructure</li>
|
||||
</affordances>
|
||||
<statBases>
|
||||
<Beauty>-6</Beauty>
|
||||
<Beauty>0</Beauty>
|
||||
<CleaningTimeFactor>0.25</CleaningTimeFactor>
|
||||
<Cleanliness>0</Cleanliness>
|
||||
<Flammability>0</Flammability>
|
||||
@@ -122,7 +122,7 @@
|
||||
<staticSunShadowHeight>0</staticSunShadowHeight>
|
||||
<statBases>
|
||||
<MarketValue>0</MarketValue>
|
||||
<Beauty>-6</Beauty>
|
||||
<Beauty>0</Beauty>
|
||||
<MaxHitPoints>1000</MaxHitPoints>
|
||||
<WorkToBuild>1500</WorkToBuild>
|
||||
<Flammability>0</Flammability>
|
||||
@@ -198,7 +198,7 @@
|
||||
<MaxHitPoints>1200</MaxHitPoints>
|
||||
<Flammability>0</Flammability>
|
||||
<WorkToBuild>1000</WorkToBuild>
|
||||
<Beauty>-10</Beauty>
|
||||
<Beauty>0</Beauty>
|
||||
<DoorOpenSpeed>2</DoorOpenSpeed>
|
||||
</statBases>
|
||||
<costStuffCount>10</costStuffCount>
|
||||
@@ -687,7 +687,7 @@
|
||||
<WorkToBuild>750</WorkToBuild>
|
||||
<Mass>5</Mass>
|
||||
<Flammability>1.0</Flammability>
|
||||
<Beauty>-5</Beauty>
|
||||
<Beauty>0</Beauty>
|
||||
<Comfort>0.70</Comfort>
|
||||
<StyleDominance MayRequire="Ludeon.RimWorld.Ideology">5</StyleDominance>
|
||||
</statBases>
|
||||
@@ -760,7 +760,7 @@
|
||||
<WorkToBuild>750</WorkToBuild>
|
||||
<Mass>10</Mass>
|
||||
<Flammability>1.0</Flammability>
|
||||
<Beauty>5</Beauty>
|
||||
<Beauty>1</Beauty>
|
||||
<StyleDominance MayRequire="Ludeon.RimWorld.Ideology">10</StyleDominance>
|
||||
</statBases>
|
||||
<researchPrerequisites>
|
||||
|
||||
@@ -727,7 +727,7 @@
|
||||
<li>InsectJelly</li>
|
||||
</disallowedThingDefs>
|
||||
</fuelFilter>
|
||||
<fuelCapacity>50</fuelCapacity>
|
||||
<fuelCapacity>20</fuelCapacity>
|
||||
<fuelConsumptionRate>0</fuelConsumptionRate>
|
||||
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
|
||||
|
||||
@@ -757,7 +757,7 @@
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_NutritionToFuelConverter">
|
||||
<checkInterval>200</checkInterval>
|
||||
<nutritionCost>1</nutritionCost>
|
||||
<nutritionCost>0.25</nutritionCost>
|
||||
<workAmount>2000</workAmount>
|
||||
<fuelAmount>1</fuelAmount>
|
||||
</li>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LanguageData>
|
||||
|
||||
<ARA_AlertUnlinkedDroneLabel>未连接的虫群工蜂</ARA_AlertUnlinkedDroneLabel>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LanguageData>
|
||||
|
||||
<EstimatedQuality>预计品质</EstimatedQuality>
|
||||
<QualityScore>品质评分</QualityScore>
|
||||
<TemperaturePenalty>温度惩罚</TemperaturePenalty>
|
||||
@@ -8,17 +7,20 @@
|
||||
<SafeTemperatureRange>安全范围</SafeTemperatureRange>
|
||||
<CannotStartProduction>无法开始生产</CannotStartProduction>
|
||||
<NoFuel>无燃料</NoFuel>
|
||||
<StartProduction>开始生产 {0}</StartProduction>
|
||||
<StartProduction>开始生产 {0}({1} 营养)</StartProduction>
|
||||
<CommandCancelProduction>取消生产</CommandCancelProduction>
|
||||
<CommandCancelProductionDesc>停止当前的生产流程。</CommandCancelProductionDesc>
|
||||
<Producing>正在生产 {0}</Producing>
|
||||
<TimeLeft>剩余时间</TimeLeft>
|
||||
<ProjectedQuality>预计品质</ProjectedQuality>
|
||||
<NotProducing>未在生产</NotProducing>
|
||||
<ARA_NeedArachnaeToStartIncubation>未孵化,需要阿拉克涅工艺种交互</ARA_NeedArachnaeToStartIncubation>
|
||||
<ARA_NeedSpecificArachnaeToStartIncubation>未孵化,需要 {0} 交互({1})</ARA_NeedSpecificArachnaeToStartIncubation>
|
||||
<ARA_AnyArachnaeRace>任何阿拉克涅虫族</ARA_AnyArachnaeRace>
|
||||
<ARA_ItemsAvailable>{0} 个物品可用</ARA_ItemsAvailable>
|
||||
|
||||
<!-- Added for CompQueuedPawnSpawner -->
|
||||
<NutritionNeeded>所需营养</NutritionNeeded>
|
||||
<ARA_Incubate>孵化 {0}</ARA_Incubate>
|
||||
|
||||
<ARA_CocoonCooldown>茧正在稳定中:{0}</ARA_CocoonCooldown>
|
||||
</LanguageData>
|
||||
Binary file not shown.
@@ -3,8 +3,16 @@
|
||||
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
|
||||
"Documents": [
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_queenability\\compabilityeffect_needcost.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_queenability\\compabilityeffect_needcost.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\ara_compinteractiveproducer\\compinteractiveproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_compinteractiveproducer\\compinteractiveproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\hediffs\\moharhediffs\\hediffcomp_spawner.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\moharhediffs\\hediffcomp_spawner.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\ara_showtemperaturerange\\compabilityeffect_abilityshowtemperaturerange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_showtemperaturerange\\compabilityeffect_abilityshowtemperaturerange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
}
|
||||
],
|
||||
"DocumentGroupContainers": [
|
||||
@@ -23,14 +31,40 @@
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 0,
|
||||
"Title": "CompAbilityEffect_NeedCost.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_QueenAbility\\CompAbilityEffect_NeedCost.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_QueenAbility\\CompAbilityEffect_NeedCost.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_QueenAbility\\CompAbilityEffect_NeedCost.cs",
|
||||
"RelativeToolTip": "Abilities\\ARA_QueenAbility\\CompAbilityEffect_NeedCost.cs",
|
||||
"ViewState": "AgIAACUAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAA==",
|
||||
"Title": "CompInteractiveProducer.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs",
|
||||
"RelativeDocumentMoniker": "Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs",
|
||||
"RelativeToolTip": "Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs",
|
||||
"ViewState": "AgIAAEgAAAAAAAAAAAA4wDcAAABHAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-08T08:23:27.533Z",
|
||||
"WhenOpened": "2025-10-09T03:57:32.708Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"Title": "HediffComp_Spawner.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\MoharHediffs\\HediffComp_Spawner.cs",
|
||||
"RelativeDocumentMoniker": "Hediffs\\MoharHediffs\\HediffComp_Spawner.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\MoharHediffs\\HediffComp_Spawner.cs",
|
||||
"RelativeToolTip": "Hediffs\\MoharHediffs\\HediffComp_Spawner.cs",
|
||||
"ViewState": "AgIAAAQAAAAAAAAAAAAswBIAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-09T03:45:03.599Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"Title": "CompAbilityEffect_AbilityShowTemperatureRange.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs",
|
||||
"RelativeToolTip": "Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs",
|
||||
"ViewState": "AgIAAC8AAAAAAAAAAAAUwAYAAAAXAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-09T02:18:27.532Z",
|
||||
"EditorCaption": ""
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class CompAbilityEffect_ShowInteractiveThing : CompAbilityEffect
|
||||
{
|
||||
public new CompProperties_AbilityShowInteractiveThing Props => (CompProperties_AbilityShowInteractiveThing)props;
|
||||
|
||||
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
|
||||
{
|
||||
// 这个组件只用于显示信息,不执行实际效果
|
||||
}
|
||||
|
||||
public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 重写工具提示方法,显示可孵化的物品列表
|
||||
public override string ExtraTooltipPart()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
// 获取所有可孵化的物品
|
||||
var incubatableItems = GetIncubatableItems();
|
||||
if (incubatableItems.Count == 0)
|
||||
{
|
||||
return null; // 没有可显示的内容
|
||||
}
|
||||
|
||||
stringBuilder.AppendLine(Props.customLabel + ":");
|
||||
stringBuilder.AppendLine();
|
||||
|
||||
// 显示每个可孵化的物品
|
||||
foreach (var item in incubatableItems)
|
||||
{
|
||||
string entryText = $" • {item.thingDef.LabelCap}";
|
||||
|
||||
// 显示营养需求
|
||||
if (Props.showNutritionCost)
|
||||
{
|
||||
float nutritionCost = GetIncubationCost(item.thingDef);
|
||||
entryText += $" ({nutritionCost.ToString("F1")} 营养)";
|
||||
}
|
||||
|
||||
// 显示孵化时间
|
||||
if (Props.showIncubationTime)
|
||||
{
|
||||
int incubationTicks = GetIncubationTimeTicks(item.thingDef);
|
||||
entryText += $" [{incubationTicks.ToStringTicksToPeriod()}]";
|
||||
}
|
||||
|
||||
// 显示科技需求
|
||||
if (Props.showResearchRequirements && item.requiredResearch != null)
|
||||
{
|
||||
bool researched = item.requiredResearch.IsFinished;
|
||||
string researchStatus = researched ? "✓" : "✗";
|
||||
entryText += $" <color={(researched ? "green" : "red")}>[{researchStatus}{item.requiredResearch.LabelCap}]</color>";
|
||||
}
|
||||
|
||||
stringBuilder.AppendLine(entryText);
|
||||
}
|
||||
|
||||
return stringBuilder.ToString().TrimEndNewlines();
|
||||
}
|
||||
|
||||
// 获取所有可孵化的物品(基于 CompExtraIncubationInfo)
|
||||
private List<ProcessDef> GetIncubatableItems()
|
||||
{
|
||||
var result = new List<ProcessDef>();
|
||||
|
||||
if (Props.cocoonBuildingDef == null)
|
||||
{
|
||||
Log.Error("CompAbilityEffect_ShowInteractiveThing: cocoonBuildingDef is null");
|
||||
return result;
|
||||
}
|
||||
|
||||
// 扫描所有定义了 CompExtraIncubationInfo 的物品
|
||||
foreach (ThingDef thingDef in DefDatabase<ThingDef>.AllDefs)
|
||||
{
|
||||
var incubationCompProps = thingDef.GetCompProperties<CompProperties_ExtraIncubationInfo>();
|
||||
if (incubationCompProps != null)
|
||||
{
|
||||
bool isMatch = false;
|
||||
if (!incubationCompProps.cocoonDefs.NullOrEmpty())
|
||||
{
|
||||
isMatch = incubationCompProps.cocoonDefs.Contains(Props.cocoonBuildingDef);
|
||||
}
|
||||
else if (incubationCompProps.cocoonDef != null)
|
||||
{
|
||||
isMatch = incubationCompProps.cocoonDef == Props.cocoonBuildingDef;
|
||||
}
|
||||
|
||||
if (isMatch)
|
||||
{
|
||||
// 获取研究前提
|
||||
ResearchProjectDef researchPrerequisite = GetResearchPrerequisite(thingDef);
|
||||
|
||||
// 创建 ProcessDef(与 CompInteractiveProducer 中的结构一致)
|
||||
ProcessDef process = new ProcessDef
|
||||
{
|
||||
thingDef = thingDef,
|
||||
productionTicks = GetIncubationTimeTicks(thingDef),
|
||||
totalNutritionNeeded = GetIncubationCost(thingDef),
|
||||
requiredResearch = researchPrerequisite
|
||||
};
|
||||
|
||||
result.Add(process);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 按物品名称排序
|
||||
result.SortBy(p => p.thingDef.label);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 获取研究前提(与 CompInteractiveProducer 中的逻辑一致)
|
||||
private ResearchProjectDef GetResearchPrerequisite(ThingDef thingDef)
|
||||
{
|
||||
ResearchProjectDef researchPrerequisite = null;
|
||||
|
||||
// 方法1:从 recipeMaker.researchPrerequisite 获取
|
||||
if (thingDef.recipeMaker?.researchPrerequisite != null)
|
||||
{
|
||||
researchPrerequisite = thingDef.recipeMaker.researchPrerequisite;
|
||||
}
|
||||
// 方法2:从 recipeMaker.researchPrerequisites 获取第一个
|
||||
else if (thingDef.recipeMaker?.researchPrerequisites?.Count > 0)
|
||||
{
|
||||
researchPrerequisite = thingDef.recipeMaker.researchPrerequisites[0];
|
||||
}
|
||||
// 方法3:从 thingDef.researchPrerequisites 获取(备用)
|
||||
else if (thingDef.researchPrerequisites?.Count > 0)
|
||||
{
|
||||
researchPrerequisite = thingDef.researchPrerequisites[0];
|
||||
}
|
||||
|
||||
return researchPrerequisite;
|
||||
}
|
||||
|
||||
// 获取孵化时间(与 CompInteractiveProducer 中的逻辑一致)
|
||||
private int GetIncubationTimeTicks(ThingDef thingDef)
|
||||
{
|
||||
StatDef incubationTimeStat = DefDatabase<StatDef>.GetNamedSilentFail("ARA_IncubationTime");
|
||||
if (incubationTimeStat != null && thingDef.statBases != null)
|
||||
{
|
||||
var statValue = thingDef.statBases.FirstOrDefault(s => s.stat == incubationTimeStat);
|
||||
if (statValue != null)
|
||||
{
|
||||
// ARA_IncubationTime 是以天为单位,转换为 ticks (1天 = 60000 ticks)
|
||||
return Mathf.RoundToInt(statValue.value * 60000f);
|
||||
}
|
||||
}
|
||||
|
||||
// 默认值:1 天
|
||||
return 60000;
|
||||
}
|
||||
|
||||
// 获取孵化所需营养(与 CompInteractiveProducer 中的逻辑一致)
|
||||
private float GetIncubationCost(ThingDef thingDef)
|
||||
{
|
||||
StatDef incubationCostStat = DefDatabase<StatDef>.GetNamedSilentFail("ARA_IncubationCost");
|
||||
if (incubationCostStat != null && thingDef.statBases != null)
|
||||
{
|
||||
var statValue = thingDef.statBases.FirstOrDefault(s => s.stat == incubationCostStat);
|
||||
if (statValue != null)
|
||||
{
|
||||
return statValue.value;
|
||||
}
|
||||
}
|
||||
|
||||
// 默认值:10 营养
|
||||
return 10f;
|
||||
}
|
||||
|
||||
// 获取所有可孵化的物品种类(用于其他用途)
|
||||
public List<ThingDef> GetIncubatableThingDefs()
|
||||
{
|
||||
var incubatableItems = GetIncubatableItems();
|
||||
var result = new List<ThingDef>();
|
||||
|
||||
foreach (var item in incubatableItems)
|
||||
{
|
||||
if (item.thingDef != null && (item.requiredResearch == null || item.requiredResearch.IsFinished))
|
||||
{
|
||||
result.Add(item.thingDef);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 检查特定物品是否可孵化
|
||||
public bool CanIncubateThingDef(ThingDef thingDef)
|
||||
{
|
||||
var incubatableItems = GetIncubatableItems();
|
||||
foreach (var item in incubatableItems)
|
||||
{
|
||||
if (item.thingDef == thingDef &&
|
||||
(item.requiredResearch == null || item.requiredResearch.IsFinished))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class CompProperties_AbilityShowInteractiveThing : CompProperties_AbilityEffect
|
||||
{
|
||||
public ThingDef cocoonBuildingDef; // 指向的茧建筑定义
|
||||
public string customLabel = "可孵化物品"; // 自定义标签
|
||||
public bool showResearchRequirements = true; // 是否显示科技需求
|
||||
public bool showNutritionCost = true; // 是否显示营养需求
|
||||
public bool showIncubationTime = true; // 是否显示孵化时间
|
||||
|
||||
public CompProperties_AbilityShowInteractiveThing()
|
||||
{
|
||||
this.compClass = typeof(CompAbilityEffect_ShowInteractiveThing);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using RimWorld;
|
||||
using Verse;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
@@ -19,7 +20,7 @@ namespace ArachnaeSwarm
|
||||
return true;
|
||||
}
|
||||
|
||||
// Override tooltip method to display temperature range information
|
||||
// Override tooltip method to display temperature range information with progress bar
|
||||
public override string ExtraTooltipPart()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
@@ -31,23 +32,84 @@ namespace ArachnaeSwarm
|
||||
return null; // No content to display
|
||||
}
|
||||
|
||||
// 第一行:安全温度范围
|
||||
stringBuilder.AppendLine(Props.customLabel.Translate() + ":");
|
||||
stringBuilder.AppendLine();
|
||||
|
||||
// Display temperature range
|
||||
stringBuilder.AppendLine(" " + "AbilityCheckSafeTemperatureRange".Translate(tempCompProps.minSafeTemperature, tempCompProps.maxSafeTemperature));
|
||||
// 第二行:当前温度
|
||||
float currentTemp = parent.pawn != null && parent.pawn.Map != null ?
|
||||
GenTemperature.GetTemperatureForCell(parent.pawn.Position, parent.pawn.Map) : 0f;
|
||||
stringBuilder.AppendLine($" 当前温度: {currentTemp:0.0}°C");
|
||||
|
||||
// Display current temperature (if enabled)
|
||||
if (Props.showCurrentTemperature && parent.pawn != null && parent.pawn.Map != null)
|
||||
{
|
||||
float currentTemp = GenTemperature.GetTemperatureForCell(parent.pawn.Position, parent.pawn.Map);
|
||||
// 第三行和第四行:温度标签和进度条
|
||||
var (tempLabels, progressBar) = GetTemperatureProgressBar(currentTemp, tempCompProps.minSafeTemperature, tempCompProps.maxSafeTemperature);
|
||||
stringBuilder.AppendLine(tempLabels);
|
||||
stringBuilder.AppendLine(progressBar);
|
||||
|
||||
// 第五行:温度状态
|
||||
string tempStatus = GetTemperatureStatus(currentTemp, tempCompProps.minSafeTemperature, tempCompProps.maxSafeTemperature);
|
||||
stringBuilder.AppendLine();
|
||||
stringBuilder.AppendLine("AbilityCheckCurrentTemperature".Translate(currentTemp.ToString("F1"), tempStatus));
|
||||
}
|
||||
string statusColor = GetTemperatureStatusColor(currentTemp, tempCompProps.minSafeTemperature, tempCompProps.maxSafeTemperature);
|
||||
stringBuilder.AppendLine($" <color={statusColor}>{tempStatus}</color>");
|
||||
|
||||
return stringBuilder.ToString().TrimEndNewlines();
|
||||
}
|
||||
|
||||
// Get temperature progress bar display
|
||||
private (string tempLabels, string progressBar) GetTemperatureProgressBar(float currentTemp, float minSafe, float maxSafe)
|
||||
{
|
||||
const int barLength = 20;
|
||||
|
||||
// Use only the safe temperature range for display
|
||||
float displayMin = minSafe;
|
||||
float displayMax = maxSafe;
|
||||
|
||||
// Calculate current position in the bar
|
||||
float normalizedPos = Mathf.Clamp01((currentTemp - displayMin) / (displayMax - displayMin));
|
||||
int currentPos = Mathf.RoundToInt(normalizedPos * (barLength - 1));
|
||||
|
||||
// Build temperature labels line (第三行)
|
||||
string minTempLabel = $"{displayMin:0}°C";
|
||||
string maxTempLabel = $"{displayMax:0}°C";
|
||||
|
||||
// Calculate spacing to align labels with progress bar
|
||||
int totalSpaces = barLength + 2 - minTempLabel.Length - maxTempLabel.Length; // +2 for brackets
|
||||
string spacing = new string(' ', Mathf.Max(1, totalSpaces));
|
||||
|
||||
string tempLabels = $" {minTempLabel}{spacing}{maxTempLabel}";
|
||||
|
||||
// Build progress bar (第四行)
|
||||
StringBuilder bar = new StringBuilder();
|
||||
bar.Append(" [");
|
||||
|
||||
for (int i = 0; i < barLength; i++)
|
||||
{
|
||||
if (i == currentPos)
|
||||
{
|
||||
// Current temperature indicator - color based on position
|
||||
string markerColor = GetMarkerColor(currentTemp, minSafe, maxSafe);
|
||||
bar.Append($"<color={markerColor}>|</color>");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Regular segment - always green since we're only showing the safe range
|
||||
bar.Append("<color=green>─</color>");
|
||||
}
|
||||
}
|
||||
bar.Append("]");
|
||||
|
||||
return (tempLabels, bar.ToString());
|
||||
}
|
||||
|
||||
// Get color for the current temperature marker
|
||||
private string GetMarkerColor(float currentTemp, float minSafe, float maxSafe)
|
||||
{
|
||||
if (currentTemp < minSafe)
|
||||
return "blue"; // Below minimum - blue
|
||||
else if (currentTemp > maxSafe)
|
||||
return "red"; // Above maximum - red
|
||||
else
|
||||
return "green"; // Within safe range - green
|
||||
}
|
||||
|
||||
// Get temperature status description
|
||||
private string GetTemperatureStatus(float currentTemp, float minSafe, float maxSafe)
|
||||
{
|
||||
@@ -59,6 +121,17 @@ namespace ArachnaeSwarm
|
||||
return "AbilityCheckTemperatureSafe".Translate();
|
||||
}
|
||||
|
||||
// Get color for temperature status
|
||||
private string GetTemperatureStatusColor(float currentTemp, float minSafe, float maxSafe)
|
||||
{
|
||||
if (currentTemp < minSafe)
|
||||
return "blue";
|
||||
else if (currentTemp > maxSafe)
|
||||
return "red";
|
||||
else
|
||||
return "green";
|
||||
}
|
||||
|
||||
// Get temperature control component from building definition
|
||||
private CompProperties_TemperatureRuinableDamage GetTemperatureCompFromBuilding()
|
||||
{
|
||||
|
||||
@@ -95,6 +95,8 @@
|
||||
<Compile Include="Abilities\ARA_QueenAbility\CompAbilityEffect_ResearchPrereq.cs" />
|
||||
<Compile Include="Abilities\ARA_QueenAbility\CompAbilityEffect_SprayLiquidMulti.cs" />
|
||||
<Compile Include="Abilities\ARA_QueenAbility\CompProperties_AbilitySprayLiquidMulti.cs" />
|
||||
<Compile Include="Abilities\ARA_ShowInteractiveThing\CompAbilityEffect_ShowInteractiveThing.cs" />
|
||||
<Compile Include="Abilities\ARA_ShowInteractiveThing\CompProperties_AbilityShowInteractiveThing.cs" />
|
||||
<Compile Include="Abilities\ARA_ShowSpawnablePawnsList\CompAbilityEffect_AbilityShowSpawnablePawns.cs" />
|
||||
<Compile Include="Abilities\ARA_ShowSpawnablePawnsList\CompProperties_AbilityShowSpawnablePawns.cs" />
|
||||
<Compile Include="Buildings\Building_TurretGunHasSpeed.cs" />
|
||||
|
||||
@@ -35,13 +35,28 @@ namespace ArachnaeSwarm
|
||||
private int ticksUnderOptimalConditions;
|
||||
private float temperaturePenaltyPercent;
|
||||
private List<ProcessDef> _cachedProcesses;
|
||||
private int spawnTick = -1; // 新增:记录生成时间
|
||||
private const int COOLDOWN_TICKS = 120; // 新增:120 tick冷却时间
|
||||
|
||||
private CompRefuelableNutrition _fuelComp;
|
||||
private static readonly Texture2D CancelIcon = ContentFinder<Texture2D>.Get("UI/Designators/Cancel");
|
||||
|
||||
public bool InProduction => _selectedProcess != null;
|
||||
public bool InCooldown => spawnTick > 0 && Find.TickManager.TicksGame < spawnTick + COOLDOWN_TICKS; // 新增:冷却状态检查
|
||||
public CompProperties_InteractiveProducer Props => (CompProperties_InteractiveProducer)props;
|
||||
|
||||
// 生产进度(0-1)
|
||||
public float ProductionProgress
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!InProduction || productionUntilTick <= 0) return 0f;
|
||||
int totalTicks = _selectedProcess.productionTicks;
|
||||
int elapsedTicks = totalTicks - (productionUntilTick - Find.TickManager.TicksGame);
|
||||
return Mathf.Clamp01((float)elapsedTicks / totalTicks);
|
||||
}
|
||||
}
|
||||
|
||||
// 自动生成的 ProcessDef 列表
|
||||
public List<ProcessDef> Processes
|
||||
{
|
||||
@@ -69,6 +84,12 @@ namespace ArachnaeSwarm
|
||||
base.PostSpawnSetup(respawningAfterLoad);
|
||||
_fuelComp = parent.GetComp<CompRefuelableNutrition>();
|
||||
BuildProcessList(); // 确保进程列表在生成时构建
|
||||
|
||||
// 新增:记录生成时间(仅在首次生成时,不是加载后)
|
||||
if (!respawningAfterLoad)
|
||||
{
|
||||
spawnTick = Find.TickManager.TicksGame;
|
||||
}
|
||||
}
|
||||
|
||||
public override void PostExposeData()
|
||||
@@ -82,6 +103,7 @@ namespace ArachnaeSwarm
|
||||
Scribe_Values.Look(ref productionUntilTick, "productionUntilTick", -1);
|
||||
Scribe_Values.Look(ref ticksUnderOptimalConditions, "ticksUnderOptimalConditions", 0);
|
||||
Scribe_Values.Look(ref temperaturePenaltyPercent, "temperaturePenaltyPercent", 0f);
|
||||
Scribe_Values.Look(ref spawnTick, "spawnTick", -1); // 新增:序列化生成时间
|
||||
|
||||
// 加载时重建 selectedProcess
|
||||
if (Scribe.mode == LoadSaveMode.LoadingVars && selectedProcessThingDef != null)
|
||||
@@ -264,27 +286,38 @@ namespace ArachnaeSwarm
|
||||
|
||||
public override IEnumerable<FloatMenuOption> CompFloatMenuOptions(Pawn selPawn)
|
||||
{
|
||||
// 新增:冷却期内不提供任何交互选项
|
||||
if (InCooldown)
|
||||
{
|
||||
int remainingTicks = (spawnTick + COOLDOWN_TICKS) - Find.TickManager.TicksGame;
|
||||
yield return new FloatMenuOption($"ARA_CocoonCooldown".Translate(remainingTicks.ToStringTicksToPeriod()), null);
|
||||
yield break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
// 使用自动生成的 Processes 列表
|
||||
foreach (var process in Processes)
|
||||
{
|
||||
// 获取营养需求 - 直接从 ProcessDef 中读取
|
||||
float nutritionCost = process.totalNutritionNeeded;
|
||||
|
||||
if (process.requiredResearch != null && !process.requiredResearch.IsFinished)
|
||||
{
|
||||
string disabledText = "StartProduction".Translate(process.thingDef.label) + " (" + "Requires".Translate() + ": " + process.requiredResearch.label + ")";
|
||||
// 修改:在未研究完成的情况下也显示营养需求
|
||||
string disabledText = "StartProduction".Translate(process.thingDef.label, nutritionCost.ToString("F1")) +
|
||||
" (" + "Requires".Translate() + ": " + process.requiredResearch.label + ")";
|
||||
yield return new FloatMenuOption(disabledText, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new FloatMenuOption("StartProduction".Translate(process.thingDef.label), () =>
|
||||
// 修改:使用新的翻译键显示营养需求
|
||||
yield return new FloatMenuOption("StartProduction".Translate(process.thingDef.label, nutritionCost.ToString("F1")), () =>
|
||||
{
|
||||
this._selectedProcess = process;
|
||||
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("ARA_StartInteractiveProduction"), parent);
|
||||
@@ -296,6 +329,13 @@ namespace ArachnaeSwarm
|
||||
|
||||
public void StartProduction()
|
||||
{
|
||||
// 新增:冷却期内不允许开始生产
|
||||
if (InCooldown)
|
||||
{
|
||||
Log.Warning("Attempted to start production during cooldown period.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_selectedProcess == null) return;
|
||||
productionUntilTick = Find.TickManager.TicksGame + _selectedProcess.productionTicks;
|
||||
ticksUnderOptimalConditions = 0;
|
||||
@@ -377,38 +417,173 @@ namespace ArachnaeSwarm
|
||||
temperaturePenaltyPercent = 0f;
|
||||
}
|
||||
|
||||
// 新增:绘制进度条的方法
|
||||
private string GetProgressBar(float progress, int barLength = 20)
|
||||
{
|
||||
int filledLength = Mathf.RoundToInt(progress * barLength);
|
||||
int emptyLength = barLength - filledLength;
|
||||
|
||||
StringBuilder bar = new StringBuilder();
|
||||
bar.Append("[");
|
||||
for (int i = 0; i < filledLength; i++)
|
||||
{
|
||||
bar.Append("=");
|
||||
}
|
||||
for (int i = 0; i < emptyLength; i++)
|
||||
{
|
||||
bar.Append("-");
|
||||
}
|
||||
bar.Append("]");
|
||||
|
||||
return bar.ToString();
|
||||
}
|
||||
|
||||
// 新增:绘制质量进度条的方法
|
||||
private string GetQualityProgressBar(float baseScore, float penalty, int barLength = 20)
|
||||
{
|
||||
int baseLength = Mathf.RoundToInt(baseScore * barLength);
|
||||
int penaltyLength = Mathf.RoundToInt(penalty * barLength);
|
||||
int actualLength = Mathf.Max(0, baseLength - penaltyLength);
|
||||
int penaltyStart = actualLength;
|
||||
int emptyLength = barLength - baseLength;
|
||||
|
||||
StringBuilder bar = new StringBuilder();
|
||||
bar.Append("[");
|
||||
|
||||
// 实际质量部分(绿色)
|
||||
for (int i = 0; i < actualLength; i++)
|
||||
{
|
||||
bar.Append("=");
|
||||
}
|
||||
|
||||
// 温度惩罚部分(黄色)
|
||||
for (int i = penaltyStart; i < baseLength; i++)
|
||||
{
|
||||
bar.Append("-");
|
||||
}
|
||||
|
||||
// 剩余部分(灰色)
|
||||
for (int i = baseLength; i < barLength; i++)
|
||||
{
|
||||
bar.Append(".");
|
||||
}
|
||||
|
||||
bar.Append("]");
|
||||
|
||||
return bar.ToString();
|
||||
}
|
||||
|
||||
public override string CompInspectStringExtra()
|
||||
{
|
||||
// 新增:显示冷却信息
|
||||
if (InCooldown)
|
||||
{
|
||||
int remainingTicks = (spawnTick + COOLDOWN_TICKS) - Find.TickManager.TicksGame;
|
||||
return "ARA_CocoonCooldown".Translate(remainingTicks.ToStringTicksToPeriod());
|
||||
}
|
||||
|
||||
if (InProduction)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("Producing".Translate(this._selectedProcess.thingDef.label));
|
||||
|
||||
// 生产进度条
|
||||
float progress = ProductionProgress;
|
||||
int remainingTicks = productionUntilTick - Find.TickManager.TicksGame;
|
||||
sb.AppendLine("Progress".Translate() + ": " + GetProgressBar(progress) + " " + progress.ToStringPercent("F0"));
|
||||
sb.AppendLine("TimeLeft".Translate() + ": " + remainingTicks.ToStringTicksToPeriod());
|
||||
|
||||
// 质量进度条
|
||||
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")}");
|
||||
sb.AppendLine("QualityProgress".Translate() + ": " +
|
||||
GetQualityProgressBar(qualityDetails.baseScore, qualityDetails.penalty) + " " +
|
||||
(qualityDetails.baseScore - qualityDetails.penalty).ToStringPercent("F0"));
|
||||
|
||||
// 温度信息
|
||||
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();
|
||||
}
|
||||
|
||||
if (!InProduction)
|
||||
{
|
||||
// 显示可生产的物品数量
|
||||
int availableProcesses = Processes.Count(p => p.requiredResearch == null || p.requiredResearch.IsFinished);
|
||||
return "ARA_NeedArachnaeToStartIncubation".Translate() + $" ({availableProcesses} items available)";
|
||||
|
||||
// 构建可交互的种族名称列表
|
||||
string allowedRaces = "";
|
||||
if (Props.whitelist != null && Props.whitelist.Count > 0)
|
||||
{
|
||||
// 获取所有可交互种族的显示名称
|
||||
var raceNames = Props.whitelist.Select(pkd => pkd.LabelCap).Distinct();
|
||||
allowedRaces = string.Join(", ", raceNames);
|
||||
}
|
||||
else
|
||||
{
|
||||
allowedRaces = "ARA_AnyArachnaeRace".Translate(); // 如果没有白名单,显示"任何阿拉克涅虫族"
|
||||
}
|
||||
|
||||
// 使用新的翻译键,包含种族信息和物品数量
|
||||
return "ARA_NeedSpecificArachnaeToStartIncubation".Translate(allowedRaces, availableProcesses);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 新增:在物体上方绘制进度条
|
||||
public override void PostDraw()
|
||||
{
|
||||
base.PostDraw();
|
||||
|
||||
if (InProduction)
|
||||
{
|
||||
// 在物体上方绘制生产进度条
|
||||
Vector3 drawPos = parent.DrawPos;
|
||||
drawPos.y += 0.15f; // 稍微抬高一点
|
||||
|
||||
float progress = ProductionProgress;
|
||||
GenDraw.DrawFillableBar(new GenDraw.FillableBarRequest
|
||||
{
|
||||
center = drawPos,
|
||||
size = new Vector2(1f, 0.15f),
|
||||
fillPercent = progress,
|
||||
filledMat = SolidColorMaterials.SimpleSolidColorMaterial(Color.green),
|
||||
unfilledMat = SolidColorMaterials.SimpleSolidColorMaterial(Color.gray),
|
||||
margin = 0.1f,
|
||||
rotation = Rot4.North
|
||||
});
|
||||
|
||||
// 在进度条上方绘制质量进度条
|
||||
if (Props.qualityThresholds != null && Props.qualityThresholds.Count > 0)
|
||||
{
|
||||
var qualityDetails = GetEstimatedQualityDetails();
|
||||
float qualityProgress = Mathf.Clamp01(qualityDetails.baseScore - qualityDetails.penalty);
|
||||
|
||||
drawPos.y += 0.2f;
|
||||
|
||||
GenDraw.DrawFillableBar(new GenDraw.FillableBarRequest
|
||||
{
|
||||
center = drawPos,
|
||||
size = new Vector2(1f, 0.1f),
|
||||
fillPercent = qualityProgress,
|
||||
filledMat = SolidColorMaterials.SimpleSolidColorMaterial(Color.blue),
|
||||
unfilledMat = SolidColorMaterials.SimpleSolidColorMaterial(Color.gray),
|
||||
margin = 0.1f,
|
||||
rotation = Rot4.North
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<Gizmo> CompGetGizmosExtra()
|
||||
{
|
||||
foreach (var g in base.CompGetGizmosExtra()) yield return g;
|
||||
|
||||
// 新增:冷却期内不显示任何Gizmo
|
||||
if (InCooldown) yield break;
|
||||
|
||||
if (InProduction)
|
||||
{
|
||||
yield return new Command_Action
|
||||
@@ -426,6 +601,19 @@ namespace ArachnaeSwarm
|
||||
defaultLabel = "Debug: Force Finish",
|
||||
action = () => FinishProduction()
|
||||
};
|
||||
|
||||
// 调试命令:显示详细进度信息
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "Debug: Show Progress Info",
|
||||
action = () =>
|
||||
{
|
||||
float progress = ProductionProgress;
|
||||
var qualityDetails = GetEstimatedQualityDetails();
|
||||
Messages.Message($"Progress: {progress:P0}\nBase Score: {qualityDetails.baseScore:P0}\nPenalty: {qualityDetails.penalty:P0}\nFinal: {qualityDetails.quality}",
|
||||
MessageTypeDefOf.SilentInput);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,6 +350,10 @@ namespace ArachnaeSwarm.MoharHediffs
|
||||
public bool TryDoSpawn()
|
||||
{
|
||||
Pawn pawn = this.parent.pawn;
|
||||
|
||||
if (this.Props.animalThing)
|
||||
{
|
||||
// 动物生成逻辑保持不变
|
||||
if (this.Props.spawnMaxAdjacent > 0 && pawn.Map.mapPawns.AllPawns.Where(delegate(Pawn mP)
|
||||
{
|
||||
ThingDef defToCompare = this.Props.animalThing ? this.Props.animalToSpawn?.race : this.Props.thingToSpawn;
|
||||
@@ -362,12 +366,12 @@ namespace ArachnaeSwarm.MoharHediffs
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.Props.animalThing)
|
||||
{
|
||||
|
||||
if (this.Props.animalToSpawn == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Faction faction = this.Props.factionOfPlayerAnimal ? Faction.OfPlayer : null;
|
||||
int i = 0;
|
||||
while (i < this.calculatedQuantity)
|
||||
@@ -401,22 +405,47 @@ namespace ArachnaeSwarm.MoharHediffs
|
||||
}
|
||||
else
|
||||
{
|
||||
IntVec3 intVec2;
|
||||
if (!this.TryFindSpawnCell(out intVec2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// 修改:物品直接添加到pawn的物品栏中
|
||||
Thing thing = ThingMaker.MakeThing(this.Props.thingToSpawn, null);
|
||||
if (thing == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
thing.stackCount = this.calculatedQuantity;
|
||||
|
||||
// 检查pawn是否有物品栏
|
||||
if (pawn.inventory == null)
|
||||
{
|
||||
Tools.Warn($"Pawn {pawn.Label} does not have an inventory to receive spawned items", this.myDebug);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 尝试将物品添加到pawn的物品栏
|
||||
if (pawn.inventory.innerContainer.TryAdd(thing))
|
||||
{
|
||||
if (PawnUtility.ShouldSendNotificationAbout(pawn))
|
||||
{
|
||||
Messages.Message(this.Props.spawnVerb.Translate(pawn.Named("PAWN"), thing.Named("THING")), pawn, MessageTypeDefOf.PositiveEvent, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果物品栏添加失败,回退到原来的地面生成方式
|
||||
Tools.Warn($"Failed to add {thing.Label} to {pawn.Label}'s inventory, falling back to ground spawn", this.myDebug);
|
||||
|
||||
IntVec3 intVec2;
|
||||
if (!this.TryFindSpawnCell(out intVec2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.Props.spawnForbidden)
|
||||
{
|
||||
thing.SetForbidden(true, true);
|
||||
}
|
||||
GenPlace.TryPlaceThing(thing, intVec2, pawn.Map, ThingPlaceMode.Direct, null, null, default(Rot4));
|
||||
|
||||
if (PawnUtility.ShouldSendNotificationAbout(pawn))
|
||||
{
|
||||
Messages.Message(this.Props.spawnVerb.Translate(pawn.Named("PAWN"), thing.Named("THING")), thing, MessageTypeDefOf.PositiveEvent, true);
|
||||
@@ -424,6 +453,7 @@ namespace ArachnaeSwarm.MoharHediffs
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryFindSpawnCell(out IntVec3 result)
|
||||
{
|
||||
@@ -442,19 +472,19 @@ namespace ArachnaeSwarm.MoharHediffs
|
||||
}
|
||||
else
|
||||
{
|
||||
// 修改这里:将半径从5减少到2,让生成位置更靠近pawn
|
||||
// 修改这里:将半径从5减少到2,让生成位置更靠近pawn
|
||||
int searchRadius = 2;
|
||||
|
||||
// 首先尝试在pawn的相邻单元格生成(半径为1)
|
||||
// 首先尝试在pawn的相邻单元格生成(半径为1)
|
||||
result = CellFinder.RandomClosewalkCellNear(this.pawn.Position, map, 1, null);
|
||||
|
||||
// 如果相邻单元格找不到合适位置,再尝试稍远一点(半径为2)
|
||||
// 如果相邻单元格找不到合适位置,再尝试稍远一点(半径为2)
|
||||
if (!result.IsValid)
|
||||
{
|
||||
result = CellFinder.RandomClosewalkCellNear(this.pawn.Position, map, searchRadius, null);
|
||||
}
|
||||
|
||||
// 如果还是找不到,尝试pawn当前位置(作为最后手段)
|
||||
// 如果还是找不到,尝试pawn当前位置(作为最后手段)
|
||||
if (!result.IsValid && this.pawn.Position.IsValid && this.pawn.Position.Walkable(map))
|
||||
{
|
||||
result = this.pawn.Position;
|
||||
|
||||
Reference in New Issue
Block a user