1
This commit is contained in:
Binary file not shown.
@@ -1,21 +1,33 @@
|
||||
{
|
||||
"Version": 1,
|
||||
"WorkspaceRootPath": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
|
||||
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
|
||||
"Documents": [
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_equipmentootheca\\building_equipmentootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_equipmentootheca\\building_equipmentootheca.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\\buildings\\building_ootheca\\compproperties_incubatordata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\compproperties_incubatordata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_ootheca\\building_ootheca.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\\buildings\\building_ootheca\\building_ootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\building_ootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_equipmentootheca\\compproperties_equipmentincubatordata.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\\buildings\\building_ootheca\\oothecaincubatorextension.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\oothecaincubatorextension.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\\buildings\\building_equipmentootheca\\itab_equipmentootheca_incubation.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_equipmentootheca\\itab_equipmentootheca_incubation.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\\buildings\\building_equipmentootheca\\building_equipmentootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_equipmentootheca\\building_equipmentootheca.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\\buildings\\building_equipmentootheca\\compproperties_equipmentincubatordata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_equipmentootheca\\compproperties_equipmentincubatordata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\ara_hediffdefof.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\\ara_hediffdefof.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:ara_hediffdefof.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
}
|
||||
],
|
||||
@@ -26,21 +38,60 @@
|
||||
"DocumentGroups": [
|
||||
{
|
||||
"DockedWidth": 200,
|
||||
"SelectedChildIndex": 1,
|
||||
"SelectedChildIndex": 0,
|
||||
"Children": [
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 0,
|
||||
"Title": "CompProperties_IncubatorData.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs*",
|
||||
"RelativeToolTip": "Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs*",
|
||||
"ViewState": "AgIAAAIBAAAAAAAAAAAawC8BAABeAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T02:36:56.126Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Bookmark",
|
||||
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 0,
|
||||
"DocumentIndex": 2,
|
||||
"Title": "OothecaIncubatorExtension.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAArAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T00:38:04.247Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 3,
|
||||
"Title": "ITab_EquipmentOotheca_Incubation.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\ITab_EquipmentOotheca_Incubation.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_EquipmentOotheca\\ITab_EquipmentOotheca_Incubation.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\ITab_EquipmentOotheca_Incubation.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_EquipmentOotheca\\ITab_EquipmentOotheca_Incubation.cs",
|
||||
"ViewState": "AgIAAIAAAAAAAAAAAADgv5AAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T00:29:36.407Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 4,
|
||||
"Title": "Building_EquipmentOotheca.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs*",
|
||||
"RelativeToolTip": "Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs*",
|
||||
"ViewState": "AgIAANoBAAAAAAAAAAAAAAACAABSAAAAAAAAAA==",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs",
|
||||
"ViewState": "AgIAAEgCAAAAAAAAAAAewF8CAABDAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-15T18:22:14.171Z",
|
||||
"EditorCaption": ""
|
||||
@@ -49,22 +100,22 @@
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"Title": "Building_Ootheca.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\Building_Ootheca.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_Ootheca\\Building_Ootheca.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==",
|
||||
"ViewState": "AgIAACkBAAAAAAAAAAAhwC0BAAApAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-15T18:22:12.217Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"DocumentIndex": 5,
|
||||
"Title": "CompProperties_EquipmentIncubatorData.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAACYAAAAaAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
@@ -73,16 +124,15 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 3,
|
||||
"DocumentIndex": 6,
|
||||
"Title": "ARA_HediffDefOf.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs",
|
||||
"RelativeDocumentMoniker": "ARA_HediffDefOf.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs",
|
||||
"RelativeToolTip": "ARA_HediffDefOf.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvxgAAAAdAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-15T17:32:18.493Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2025-12-15T17:32:18.493Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -33,12 +33,303 @@ namespace ArachnaeSwarm
|
||||
private float qualityMultiplier = 1.0f;
|
||||
private float qualityProgress = 0f;
|
||||
private float qualityTotal = 0f;
|
||||
|
||||
// === 新增:营养液消耗相关字段 ===
|
||||
private int totalNutrientCost = 0; // 总共需要的营养液地块数量
|
||||
private int consumedNutrientCount = 0; // 已消耗的营养液地块数量
|
||||
private int lastConsumeCheckTick = -1; // 上次检查消耗的时间
|
||||
private const int ConsumeCheckInterval = 250; // 检查间隔(tick)
|
||||
private const int ConsumeRadius = 5; // 搜索半径
|
||||
private List<IntVec3> consumedCells = new List<IntVec3>(); // 已消耗的单元格记录
|
||||
private bool hasStartedConsumption = false; // 是否已开始消耗
|
||||
private float consumeProgress = 0f; // 消耗进度(0-1)
|
||||
|
||||
// === 新增属性 ===
|
||||
public int TotalNutrientCost => totalNutrientCost;
|
||||
public int ConsumedNutrientCount => consumedNutrientCount;
|
||||
public float NutrientProgress => totalNutrientCost > 0 ? (float)consumedNutrientCount / totalNutrientCost : 0f;
|
||||
public bool HasEnoughNutrients => consumedNutrientCount >= totalNutrientCost;
|
||||
public bool IsConsuming => hasStartedConsumption && !HasEnoughNutrients && isIncubating;
|
||||
|
||||
|
||||
// === 新增:营养液消耗方法 ===
|
||||
|
||||
// 初始化营养液消耗需求
|
||||
private void InitializeNutrientConsumption()
|
||||
{
|
||||
if (incubatingThingDef == null)
|
||||
return;
|
||||
|
||||
// 获取孵化成本统计值
|
||||
var costStat = DefDatabase<StatDef>.GetNamedSilentFail("ARA_IncubationCost");
|
||||
if (costStat != null)
|
||||
{
|
||||
totalNutrientCost = Mathf.RoundToInt(incubatingThingDef.GetStatValueAbstract(costStat, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
totalNutrientCost = 0; // 如果统计不存在,则不需要消耗
|
||||
}
|
||||
|
||||
consumedNutrientCount = 0;
|
||||
consumedCells.Clear();
|
||||
hasStartedConsumption = false;
|
||||
consumeProgress = 0f;
|
||||
}
|
||||
|
||||
// 检查并消耗营养液
|
||||
private void CheckAndConsumeNutrients()
|
||||
{
|
||||
if (!isIncubating || incubatingThingDef == null || HasEnoughNutrients)
|
||||
return;
|
||||
// 第一次检查时标记开始消耗
|
||||
if (!hasStartedConsumption)
|
||||
{
|
||||
hasStartedConsumption = true;
|
||||
Messages.Message("ARA_EquipmentIncubator.StartedNutrientConsumption".Translate(),
|
||||
this, MessageTypeDefOf.SilentInput);
|
||||
}
|
||||
// 计算本次应该消耗的数量
|
||||
// 基于孵化进度来动态计算
|
||||
float targetProgress = AdjustedProgressPercent;
|
||||
int targetConsumed = Mathf.RoundToInt(targetProgress * totalNutrientCost);
|
||||
int toConsume = targetConsumed - consumedNutrientCount;
|
||||
if (toConsume <= 0)
|
||||
return;
|
||||
// 查找可消耗的营养液单元格
|
||||
List<IntVec3> availableCells = FindNutrientCells();
|
||||
int consumedThisTick = 0;
|
||||
for (int i = 0; i < Mathf.Min(toConsume, availableCells.Count); i++)
|
||||
{
|
||||
if (ConsumeNutrientCell(availableCells[i]))
|
||||
{
|
||||
consumedThisTick++;
|
||||
consumedNutrientCount++;
|
||||
// 添加到已消耗列表
|
||||
consumedCells.Add(availableCells[i]);
|
||||
if (HasEnoughNutrients)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (consumedThisTick > 0)
|
||||
{
|
||||
consumeProgress = NutrientProgress;
|
||||
// 如果达到需求,显示消息
|
||||
if (HasEnoughNutrients)
|
||||
{
|
||||
Messages.Message("ARA_EquipmentIncubator.NutrientRequirementsMet".Translate(),
|
||||
this, MessageTypeDefOf.PositiveEvent);
|
||||
}
|
||||
}
|
||||
else if (Ext.nutrientDeficiencyDamageEnabled && toConsume > 0)
|
||||
{
|
||||
// === 新增:没有找到营养液,造成伤害 ===
|
||||
ApplyNutrientDeficiencyDamage();
|
||||
|
||||
// === 新增:如果设置停止孵化,则暂停进度 ===
|
||||
if (Ext.stopIncubationWhenNutrientDeficient)
|
||||
{
|
||||
// 暂停孵化进度,直到找到营养液
|
||||
// 我们通过不增加incubationProgress来实现
|
||||
// 但这里需要特殊处理,我们在Tick方法中处理
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// === 新增:应用营养液不足的伤害 ===
|
||||
private void ApplyNutrientDeficiencyDamage()
|
||||
{
|
||||
if (Ext.nutrientDeficiencyDamageAmount <= 0f || Ext.nutrientDamageType == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
// 计算实际伤害量
|
||||
float damageAmount = Ext.nutrientDeficiencyDamageAmount;
|
||||
|
||||
// 如果建筑血量已经很低,减少伤害以避免立即摧毁
|
||||
float healthPercent = (float)HitPoints / MaxHitPoints;
|
||||
if (healthPercent < 0.3f)
|
||||
{
|
||||
damageAmount *= 0.5f; // 血量低于30%时,伤害减半
|
||||
}
|
||||
|
||||
if (healthPercent < 0.1f)
|
||||
{
|
||||
damageAmount *= 0.2f; // 血量低于10%时,伤害减为20%
|
||||
}
|
||||
|
||||
// 应用伤害
|
||||
DamageInfo damageInfo = new DamageInfo(
|
||||
Ext.nutrientDamageType,
|
||||
damageAmount,
|
||||
armorPenetration: 0,
|
||||
angle: -1f,
|
||||
instigator: null,
|
||||
hitPart: null,
|
||||
weapon: null,
|
||||
category: DamageInfo.SourceCategory.ThingOrUnknown,
|
||||
intendedTarget: this
|
||||
);
|
||||
|
||||
TakeDamage(damageInfo);
|
||||
|
||||
// 显示伤害消息(几率性)
|
||||
if (Ext.showDamageMessages && Rand.Chance(Ext.damageMessageChance))
|
||||
{
|
||||
Messages.Message("ARA_EquipmentIncubator.NutrientDeficiencyDamage".Translate(damageAmount.ToString("F1")),
|
||||
this, MessageTypeDefOf.NegativeEvent);
|
||||
}
|
||||
|
||||
// 更新质量乘数(因为血量变化会影响质量)
|
||||
UpdateQualityMultiplier();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"Failed to apply nutrient deficiency damage: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// 查找可消耗的营养液单元格
|
||||
public List<IntVec3> FindNutrientCells()
|
||||
{
|
||||
List<IntVec3> availableCells = new List<IntVec3>();
|
||||
var map = Map;
|
||||
if (map == null)
|
||||
return availableCells;
|
||||
// === 修改:使用ModExtension中定义的营养液检测半径 ===
|
||||
int searchRadius = Ext.NutrientSolutionRadiusInt; // 使用ModExtension中的半径
|
||||
|
||||
TerrainDef nutrientDef = DefDatabase<TerrainDef>.GetNamedSilentFail("ARA_Incubator_Nutrient_Solution");
|
||||
if (nutrientDef == null)
|
||||
return availableCells;
|
||||
// 搜索矩形区域
|
||||
for (int x = -searchRadius; x <= searchRadius; x++)
|
||||
{
|
||||
for (int z = -searchRadius; z <= searchRadius; z++)
|
||||
{
|
||||
IntVec3 cell = Position + new IntVec3(x, 0, z);
|
||||
// 排除自己的位置
|
||||
if (cell == Position)
|
||||
continue;
|
||||
// 检查是否在边界内且未被消耗过
|
||||
if (cell.InBounds(map) && !consumedCells.Contains(cell))
|
||||
{
|
||||
TerrainDef terrain = map.terrainGrid.TerrainAt(cell);
|
||||
if (terrain == nutrientDef)
|
||||
{
|
||||
availableCells.Add(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 随机排序,避免总是从固定位置开始消耗
|
||||
availableCells.Shuffle();
|
||||
return availableCells;
|
||||
}
|
||||
|
||||
// 消耗单个营养液单元格
|
||||
private bool ConsumeNutrientCell(IntVec3 cell)
|
||||
{
|
||||
var map = Map;
|
||||
if (map == null)
|
||||
return false;
|
||||
|
||||
// 获取目标地貌定义
|
||||
TerrainDef insectCreepDef = DefDatabase<TerrainDef>.GetNamedSilentFail("ARA_InsectCreep");
|
||||
TerrainDef nutrientDef = DefDatabase<TerrainDef>.GetNamedSilentFail("ARA_Incubator_Nutrient_Solution");
|
||||
|
||||
if (insectCreepDef == null || nutrientDef == null)
|
||||
return false;
|
||||
|
||||
// 记录原来的地貌
|
||||
TerrainDef originalTerrain = map.terrainGrid.TerrainAt(cell);
|
||||
|
||||
// 转换为昆虫爬行地貌
|
||||
map.terrainGrid.SetTerrain(cell, insectCreepDef);
|
||||
|
||||
// 检查是否有物品需要移除(如果有的话)
|
||||
List<Thing> thingsAtCell = map.thingGrid.ThingsListAt(cell);
|
||||
foreach (Thing thing in thingsAtCell)
|
||||
{
|
||||
// 如果物品阻碍了地貌转换,可能需要处理
|
||||
if (thing.def.passability == Traversability.Impassable)
|
||||
{
|
||||
// 可以根据需要处理阻碍物
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建营养液蓝图
|
||||
try
|
||||
{
|
||||
// 使用PlaceBlueprintForBuild方法创建蓝图
|
||||
Blueprint_Build blueprint = GenConstruct.PlaceBlueprintForBuild(
|
||||
nutrientDef,
|
||||
cell,
|
||||
map,
|
||||
Rot4.North, // 地貌没有旋转,使用默认
|
||||
Faction.OfPlayer,
|
||||
null // 地貌没有stuff
|
||||
);
|
||||
|
||||
if (blueprint != null)
|
||||
{
|
||||
// 显示转换效果
|
||||
if (Find.TickManager.TicksGame % 10 == 0) // 每10次消耗显示一次效果
|
||||
{
|
||||
MoteMaker.ThrowText(cell.ToVector3Shifted(), map,
|
||||
"ARA_Consumed".Translate(), Color.yellow);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"Failed to place nutrient solution blueprint at {cell}: {ex.Message}");
|
||||
// 如果蓝图放置失败,恢复原貌
|
||||
map.terrainGrid.SetTerrain(cell, originalTerrain);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 获取营养液消耗描述
|
||||
public string GetNutrientConsumptionDescription()
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.AppendLine("ARA_EquipmentIncubator.NutrientConsumption".Translate());
|
||||
builder.AppendLine();
|
||||
|
||||
if (totalNutrientCost == 0)
|
||||
{
|
||||
builder.AppendLine("ARA_EquipmentIncubator.NoNutrientCost".Translate());
|
||||
return builder.ToString().TrimEndNewlines();
|
||||
}
|
||||
|
||||
builder.AppendLine("ARA_EquipmentIncubator.NutrientRequirement".Translate(totalNutrientCost));
|
||||
builder.AppendLine("ARA_EquipmentIncubator.NutrientConsumed".Translate(consumedNutrientCount));
|
||||
builder.AppendLine("ARA_EquipmentIncubator.NutrientProgress".Translate(NutrientProgress.ToStringPercent()));
|
||||
|
||||
if (HasEnoughNutrients)
|
||||
{
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("ARA_EquipmentIncubator.NutrientRequirementsMet".Translate());
|
||||
}
|
||||
else if (IsConsuming)
|
||||
{
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("ARA_EquipmentIncubator.ConsumingNutrients".Translate());
|
||||
}
|
||||
|
||||
return builder.ToString().TrimEndNewlines();
|
||||
}
|
||||
|
||||
// 缓存的ModExtension
|
||||
private OothecaIncubatorExtension cachedExtension;
|
||||
|
||||
// 获取ModExtension的辅助属性
|
||||
private OothecaIncubatorExtension Ext
|
||||
public OothecaIncubatorExtension Ext
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -254,7 +545,7 @@ namespace ArachnaeSwarm
|
||||
Messages.Message("ARA_EquipmentIncubator.LarvaArrived".Translate() + " " + "ARA_EquipmentIncubator.ActivatingOotheca".Translate(),
|
||||
MessageTypeDefOf.SilentInput);
|
||||
}
|
||||
|
||||
|
||||
// 幼虫完成操作
|
||||
public void NotifyLarvaOperationComplete(Pawn larva)
|
||||
{
|
||||
@@ -263,38 +554,34 @@ namespace ArachnaeSwarm
|
||||
ArachnaeLog.Debug("Larva operation complete called with wrong larva.");
|
||||
return;
|
||||
}
|
||||
|
||||
var config = EquipmentIncubatorData?.SelectedConfig;
|
||||
if (config == null)
|
||||
{
|
||||
ArachnaeLog.Debug("No incubation config selected when larva completed operation.");
|
||||
return;
|
||||
}
|
||||
|
||||
incubatingThingDef = config.thingDef;
|
||||
incubationDuration = config.DaysRequired * 60000f;
|
||||
incubationProgress = 0f;
|
||||
isIncubating = true;
|
||||
|
||||
qualityTotal = incubationDuration;
|
||||
qualityProgress = 0f;
|
||||
UpdateQualityMultiplier();
|
||||
|
||||
UpdateSpeedMultiplier();
|
||||
|
||||
// === 新增:初始化营养液消耗 ===
|
||||
InitializeNutrientConsumption();
|
||||
assignedLarva = null;
|
||||
larvaOperateTicksRemaining = 0;
|
||||
|
||||
Messages.Message("ARA_EquipmentIncubator.IncubationStarted".Translate() + " " + incubatingThingDef.LabelCap + ". " +
|
||||
"ARA_EquipmentIncubator.ProcessWillComplete".Translate() + " " + config.DaysRequired + " " + "ARA_EquipmentIncubator.DaysBaseTime".Translate(),
|
||||
MessageTypeDefOf.PositiveEvent);
|
||||
}
|
||||
|
||||
|
||||
// 取消孵化
|
||||
private void CancelIncubation()
|
||||
{
|
||||
if (!isIncubating) return;
|
||||
|
||||
isIncubating = false;
|
||||
incubationProgress = 0f;
|
||||
incubationDuration = 0f;
|
||||
@@ -302,27 +589,29 @@ namespace ArachnaeSwarm
|
||||
qualityProgress = 0f;
|
||||
qualityTotal = 0f;
|
||||
|
||||
// === 新增:重置营养液消耗 ===
|
||||
totalNutrientCost = 0;
|
||||
consumedNutrientCount = 0;
|
||||
hasStartedConsumption = false;
|
||||
consumeProgress = 0f;
|
||||
consumedCells.Clear();
|
||||
Messages.Message("ARA_EquipmentIncubator.IncubationCancelled".Translate() + " " + "ARA_EquipmentIncubator.ContentsLost".Translate(),
|
||||
MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
|
||||
|
||||
// 完成孵化
|
||||
private void CompleteIncubation()
|
||||
{
|
||||
if (incubatingThingDef == null) return;
|
||||
|
||||
float finalQualityPercent = QualityPercent;
|
||||
|
||||
// 生成物品
|
||||
Thing thing = ThingMaker.MakeThing(incubatingThingDef);
|
||||
|
||||
|
||||
// 应用质量影响
|
||||
ApplyQualityEffects(thing, finalQualityPercent);
|
||||
|
||||
// 放置物品
|
||||
var spawnPos = Position;
|
||||
GenPlace.TryPlaceThing(thing, spawnPos, Map, ThingPlaceMode.Near);
|
||||
|
||||
// 重置状态
|
||||
isIncubating = false;
|
||||
incubationProgress = 0f;
|
||||
@@ -331,20 +620,25 @@ namespace ArachnaeSwarm
|
||||
qualityProgress = 0f;
|
||||
qualityTotal = 0f;
|
||||
|
||||
// === 新增:清理营养液消耗状态 ===
|
||||
totalNutrientCost = 0;
|
||||
consumedNutrientCount = 0;
|
||||
hasStartedConsumption = false;
|
||||
consumeProgress = 0f;
|
||||
consumedCells.Clear();
|
||||
// 显示消息
|
||||
string qualityText = finalQualityPercent >= 0.9f ? "ARA_EquipmentIncubator.QualityExcellent".Translate() :
|
||||
finalQualityPercent >= 0.7f ? "ARA_EquipmentIncubator.QualityGood".Translate() :
|
||||
finalQualityPercent >= 0.5f ? "ARA_EquipmentIncubator.QualityAverage".Translate() :
|
||||
finalQualityPercent >= 0.3f ? "ARA_EquipmentIncubator.QualityPoor".Translate() : "ARA_EquipmentIncubator.QualityVeryPoor".Translate();
|
||||
|
||||
Messages.Message("ARA_EquipmentIncubator.IncubationComplete".Translate() + " " + thing.LabelCap + " " +
|
||||
"ARA_EquipmentIncubator.HasEmergedWith".Translate() + " " + qualityText + " " +
|
||||
"ARA_EquipmentIncubator.Quality".Translate() + " (" + finalQualityPercent.ToStringPercent() + ").",
|
||||
MessageTypeDefOf.PositiveEvent);
|
||||
|
||||
Destroy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 应用质量效果
|
||||
private void ApplyQualityEffects(Thing thing, float qualityPercent)
|
||||
{
|
||||
@@ -392,40 +686,50 @@ namespace ArachnaeSwarm
|
||||
float remainingTicks = GetRemainingTicks();
|
||||
return (remainingTicks % 60000f) / 2500f;
|
||||
}
|
||||
|
||||
|
||||
// 检查字符串
|
||||
public override string GetInspectString()
|
||||
{
|
||||
var baseString = base.GetInspectString();
|
||||
var builder = new StringBuilder();
|
||||
|
||||
if (!string.IsNullOrEmpty(baseString))
|
||||
{
|
||||
builder.Append(baseString);
|
||||
}
|
||||
|
||||
if (isIncubating && incubatingThingDef != null)
|
||||
{
|
||||
float progressPercent = AdjustedProgressPercent;
|
||||
float daysRemaining = GetRemainingDays();
|
||||
float hoursRemaining = GetRemainingHours();
|
||||
|
||||
if (builder.Length > 0) builder.AppendLine();
|
||||
builder.Append("ARA_EquipmentIncubator.Incubating".Translate() + ": " + incubatingThingDef.LabelCap);
|
||||
builder.AppendLine();
|
||||
builder.Append("ARA_EquipmentIncubator.Progress".Translate() + ": " + progressPercent.ToStringPercent());
|
||||
builder.AppendLine();
|
||||
|
||||
string timeText = "ARA_EquipmentIncubator.TimeRemaining".Translate() + ": " + daysRemaining.ToString("F1") + " " + "ARA_EquipmentIncubator.Days".Translate();
|
||||
if (hoursRemaining > 0.1f && daysRemaining < 1f)
|
||||
{
|
||||
timeText += " (" + hoursRemaining.ToString("F1") + " " + "ARA_EquipmentIncubator.Hours".Translate() + ")";
|
||||
}
|
||||
builder.Append(timeText);
|
||||
|
||||
builder.AppendLine();
|
||||
builder.Append("ARA_EquipmentIncubator.Speed".Translate() + ": " + SpeedMultiplier.ToStringPercent() + ", " +
|
||||
"ARA_EquipmentIncubator.Quality".Translate() + ": " + QualityMultiplier.ToStringPercent());
|
||||
|
||||
// === 新增:显示营养液消耗信息 ===
|
||||
if (totalNutrientCost > 0)
|
||||
{
|
||||
builder.AppendLine();
|
||||
builder.Append("ARA_EquipmentIncubator.NutrientConsumption".Translate() + ": " +
|
||||
consumedNutrientCount + " / " + totalNutrientCost +
|
||||
" (" + NutrientProgress.ToStringPercent() + ")");
|
||||
|
||||
if (!HasEnoughNutrients && IsConsuming)
|
||||
{
|
||||
builder.AppendLine();
|
||||
builder.Append("ARA_EquipmentIncubator.ConsumingNutrients".Translate());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (assignedLarva != null)
|
||||
{
|
||||
@@ -447,16 +751,26 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
if (builder.Length > 0) builder.AppendLine();
|
||||
builder.Append("ARA_EquipmentIncubator.Target".Translate() + ": " + config.thingDef.LabelCap);
|
||||
|
||||
builder.AppendLine();
|
||||
builder.Append("ARA_EquipmentIncubator.SpeedMultiplier".Translate() + ": " + SpeedMultiplier.ToStringPercent() + ", " +
|
||||
"ARA_EquipmentIncubator.QualityMultiplier".Translate() + ": " + QualityMultiplier.ToStringPercent());
|
||||
|
||||
// === 新增:显示预计的营养液需求 ===
|
||||
var costStat = DefDatabase<StatDef>.GetNamedSilentFail("ARA_IncubationCost");
|
||||
if (costStat != null)
|
||||
{
|
||||
int estimatedCost = Mathf.RoundToInt(config.thingDef.GetStatValueAbstract(costStat, null));
|
||||
if (estimatedCost > 0)
|
||||
{
|
||||
builder.AppendLine();
|
||||
builder.Append("ARA_EquipmentIncubator.EstimatedNutrientCost".Translate() + ": " + estimatedCost);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToString().TrimEndNewlines();
|
||||
}
|
||||
|
||||
|
||||
// Gizmos
|
||||
public override IEnumerable<Gizmo> GetGizmos()
|
||||
{
|
||||
@@ -718,17 +1032,18 @@ namespace ArachnaeSwarm
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// 每tick更新
|
||||
// 修改Tick方法,处理营养液不足时停止孵化的逻辑
|
||||
protected override void Tick()
|
||||
{
|
||||
base.Tick();
|
||||
|
||||
|
||||
if (larvaOperateTicksRemaining > 0)
|
||||
{
|
||||
larvaOperateTicksRemaining--;
|
||||
}
|
||||
|
||||
|
||||
if (isIncubating)
|
||||
{
|
||||
if (lastMultiplierUpdateTick < 0 || Find.TickManager.TicksGame - lastMultiplierUpdateTick >= MultiplierUpdateInterval)
|
||||
@@ -736,19 +1051,57 @@ namespace ArachnaeSwarm
|
||||
UpdateSpeedMultiplier();
|
||||
UpdateQualityMultiplier();
|
||||
}
|
||||
|
||||
|
||||
float currentSpeed = SpeedMultiplier;
|
||||
incubationProgress += currentSpeed;
|
||||
|
||||
qualityProgress += currentSpeed * QualityMultiplier;
|
||||
|
||||
|
||||
// === 新增:检查是否因营养液不足而停止孵化 ===
|
||||
bool shouldProgress = true;
|
||||
|
||||
if (Ext.stopIncubationWhenNutrientDeficient &&
|
||||
!HasEnoughNutrients &&
|
||||
isIncubating &&
|
||||
hasStartedConsumption)
|
||||
{
|
||||
// 检查是否有可用的营养液
|
||||
var availableCells = FindNutrientCells();
|
||||
if (availableCells.Count == 0 && totalNutrientCost > 0 && consumedNutrientCount < totalNutrientCost)
|
||||
{
|
||||
shouldProgress = false;
|
||||
|
||||
// 显示停止消息(第一次或偶尔显示)
|
||||
if (Find.TickManager.TicksGame % 1000 == 0 && Rand.Chance(0.1f))
|
||||
{
|
||||
Messages.Message("ARA_EquipmentIncubator.IncubationPausedNoNutrients".Translate(incubatingThingDef?.LabelCap ?? "Unknown"),
|
||||
this, MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldProgress)
|
||||
{
|
||||
incubationProgress += currentSpeed;
|
||||
qualityProgress += currentSpeed * QualityMultiplier;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 孵化暂停,但仍然需要检查营养液消耗(可能营养液又出现了)
|
||||
// 并且仍然应用伤害
|
||||
}
|
||||
|
||||
// === 新增:检查营养液消耗 ===
|
||||
if (lastConsumeCheckTick < 0 || Find.TickManager.TicksGame - lastConsumeCheckTick >= ConsumeCheckInterval)
|
||||
{
|
||||
lastConsumeCheckTick = Find.TickManager.TicksGame;
|
||||
CheckAndConsumeNutrients();
|
||||
}
|
||||
|
||||
if (incubationProgress >= incubationDuration)
|
||||
{
|
||||
CompleteIncubation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 检查是否在孵化间中
|
||||
private bool IsInIncubatorRoom()
|
||||
{
|
||||
@@ -895,12 +1248,12 @@ namespace ArachnaeSwarm
|
||||
|
||||
qualityMultiplier = Mathf.Clamp(multiplier, 0f, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
// 保存/加载
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
|
||||
|
||||
Scribe_Values.Look(ref isIncubating, "isIncubating", false);
|
||||
Scribe_Values.Look(ref incubationProgress, "incubationProgress", 0f);
|
||||
Scribe_Values.Look(ref incubationDuration, "incubationDuration", 0f);
|
||||
@@ -912,6 +1265,21 @@ namespace ArachnaeSwarm
|
||||
Scribe_Values.Look(ref qualityMultiplier, "qualityMultiplier", 1.0f);
|
||||
Scribe_Values.Look(ref qualityProgress, "qualityProgress", 0f);
|
||||
Scribe_Values.Look(ref qualityTotal, "qualityTotal", 0f);
|
||||
|
||||
// === 新增:保存营养液消耗状态 ===
|
||||
Scribe_Values.Look(ref totalNutrientCost, "totalNutrientCost", 0);
|
||||
Scribe_Values.Look(ref consumedNutrientCount, "consumedNutrientCount", 0);
|
||||
Scribe_Values.Look(ref lastConsumeCheckTick, "lastConsumeCheckTick", -1);
|
||||
Scribe_Values.Look(ref hasStartedConsumption, "hasStartedConsumption", false);
|
||||
Scribe_Values.Look(ref consumeProgress, "consumeProgress", 0f);
|
||||
Scribe_Collections.Look(ref consumedCells, "consumedCells", LookMode.Value);
|
||||
|
||||
if (Scribe.mode == LoadSaveMode.PostLoadInit)
|
||||
{
|
||||
// 确保列表不为null
|
||||
if (consumedCells == null)
|
||||
consumedCells = new List<IntVec3>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,10 @@ namespace ArachnaeSwarm
|
||||
private const float SmallLabelHeight = 20f;
|
||||
private const float ButtonHeight = 25f;
|
||||
private const float TabWidth = 320f;
|
||||
private const float TabHeight = 420f;
|
||||
|
||||
private const float TabHeight = 450f; // 增加高度以容纳更多信息
|
||||
|
||||
private Vector2 scrollPosition = Vector2.zero;
|
||||
private const float ViewHeight = 450f;
|
||||
private const float ViewHeight = 480f; // 增加视图高度
|
||||
|
||||
public override bool IsVisible
|
||||
{
|
||||
@@ -46,12 +46,9 @@ namespace ArachnaeSwarm
|
||||
return;
|
||||
}
|
||||
rect = rect.ContractedBy(5f);
|
||||
|
||||
Rect viewRect = new Rect(0f, 0f, rect.width - 16f, ViewHeight);
|
||||
Rect scrollRect = new Rect(rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
Widgets.BeginScrollView(scrollRect, ref scrollPosition, viewRect);
|
||||
|
||||
float curY = 0f;
|
||||
|
||||
Rect titleRect = new Rect(0f, curY, viewRect.width, LabelHeight);
|
||||
@@ -144,8 +141,98 @@ namespace ArachnaeSwarm
|
||||
Text.Anchor = TextAnchor.UpperLeft;
|
||||
GUI.color = Color.white;
|
||||
|
||||
Widgets.FillableBar(qualityBarRect, qualityPercent, SolidColorMaterials.NewSolidColorTexture(new Color(0.1f, 0.4f, 0.8f, 0.5f)));
|
||||
|
||||
Widgets.FillableBar(qualityBarRect, qualityPercent, SolidColorMaterials.NewSolidColorTexture(new Color(0.1f, 0.4f, 0.8f, 0.5f))); curY += BarHeight + 25f;
|
||||
|
||||
// === 新增:营养液消耗显示 ===
|
||||
if (ootheca.TotalNutrientCost > 0)
|
||||
{
|
||||
// 标题
|
||||
Rect nutrientTitleRect = new Rect(0f, curY, viewRect.width, SmallLabelHeight);
|
||||
Widgets.Label(nutrientTitleRect, "ARA_EquipmentIncubator.NutrientConsumption".Translate());
|
||||
curY += SmallLabelHeight + 5f;
|
||||
|
||||
// 进度条
|
||||
Rect nutrientBarRect = new Rect(0f, curY, viewRect.width, BarHeight);
|
||||
float nutrientProgress = ootheca.NutrientProgress;
|
||||
|
||||
Widgets.FillableBar(nutrientBarRect, nutrientProgress,
|
||||
SolidColorMaterials.NewSolidColorTexture(new Color(0.8f, 0.6f, 0.1f, 0.5f)));
|
||||
|
||||
// 进度文本
|
||||
string nutrientText = $"{ootheca.ConsumedNutrientCount} / {ootheca.TotalNutrientCost} ({nutrientProgress:P0})";
|
||||
Text.Anchor = TextAnchor.MiddleCenter;
|
||||
Widgets.Label(nutrientBarRect, nutrientText);
|
||||
Text.Anchor = TextAnchor.UpperLeft;
|
||||
|
||||
curY += BarHeight + 10f;
|
||||
|
||||
// 状态描述
|
||||
Rect nutrientStatusRect = new Rect(0f, curY, viewRect.width, SmallLabelHeight);
|
||||
string statusText;
|
||||
if (ootheca.HasEnoughNutrients)
|
||||
{
|
||||
statusText = "ARA_EquipmentIncubator.NutrientRequirementsMet".Translate();
|
||||
GUI.color = Color.green;
|
||||
}
|
||||
else if (ootheca.IsConsuming)
|
||||
{
|
||||
statusText = "ARA_EquipmentIncubator.ConsumingNutrients".Translate();
|
||||
GUI.color = Color.yellow;
|
||||
}
|
||||
else
|
||||
{
|
||||
statusText = "ARA_EquipmentIncubator.WaitingForNutrients".Translate();
|
||||
GUI.color = Color.gray;
|
||||
}
|
||||
|
||||
Widgets.Label(nutrientStatusRect, statusText);
|
||||
GUI.color = Color.white;
|
||||
|
||||
curY += SmallLabelHeight + 15f;
|
||||
}
|
||||
// === 新增:营养液不足状态显示 ===
|
||||
if (ootheca.TotalNutrientCost > 0 && ootheca.IsConsuming)
|
||||
{
|
||||
curY += BarHeight + 15f;
|
||||
|
||||
// 检查是否有营养液不足的警告
|
||||
var availableCells = ootheca.FindNutrientCells();
|
||||
if (availableCells.Count == 0 && !ootheca.HasEnoughNutrients)
|
||||
{
|
||||
Rect warningRect = new Rect(0f, curY, viewRect.width, SmallLabelHeight * 2);
|
||||
|
||||
if (ootheca.Ext.stopIncubationWhenNutrientDeficient)
|
||||
{
|
||||
Widgets.Label(warningRect, "ARA_EquipmentIncubator.IncubationPausedWarning".Translate());
|
||||
GUI.color = Color.yellow;
|
||||
}
|
||||
else
|
||||
{
|
||||
Widgets.Label(warningRect, "ARA_EquipmentIncubator.NutrientDeficiencyWarning".Translate());
|
||||
GUI.color = Color.red;
|
||||
}
|
||||
|
||||
// 绘制警告背景
|
||||
Widgets.DrawHighlight(warningRect);
|
||||
GUI.color = Color.white;
|
||||
|
||||
curY += SmallLabelHeight * 2 + 10f;
|
||||
|
||||
// 显示血量警告
|
||||
float healthPercent = (float)ootheca.HitPoints / ootheca.MaxHitPoints;
|
||||
if (healthPercent < 0.5f)
|
||||
{
|
||||
Rect healthWarningRect = new Rect(0f, curY, viewRect.width, SmallLabelHeight);
|
||||
Widgets.Label(healthWarningRect, "ARA_EquipmentIncubator.LowHealthWarning".Translate(healthPercent.ToStringPercent()));
|
||||
GUI.color = new Color(1f, 0.5f, 0.5f);
|
||||
Widgets.DrawHighlight(healthWarningRect);
|
||||
GUI.color = Color.white;
|
||||
|
||||
curY += SmallLabelHeight + 5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string qualityProgressText = $"{qualityPercent:P0}";
|
||||
Text.Anchor = TextAnchor.MiddleCenter;
|
||||
Widgets.Label(qualityBarRect, qualityProgressText);
|
||||
|
||||
@@ -297,28 +297,23 @@ namespace ArachnaeSwarm
|
||||
Messages.Message("ARA_OothecaIncubator.IncubationCancelled".Translate() + " " + "ARA_OothecaIncubator.ContentsLost".Translate(),
|
||||
MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
|
||||
|
||||
// 完成孵化
|
||||
private void CompleteIncubation()
|
||||
{
|
||||
if (incubatingPawnKind == null) return;
|
||||
|
||||
// 计算最终质量百分比
|
||||
float finalQualityPercent = QualityPercent;
|
||||
|
||||
// 生成新的pawn
|
||||
var pawn = PawnGenerator.GeneratePawn(incubatingPawnKind, Faction);
|
||||
|
||||
// 应用质量影响
|
||||
// 应用质量影响(包括Hediff奖励)
|
||||
ApplyQualityEffects(pawn, finalQualityPercent);
|
||||
|
||||
// 尝试将pawn放置在地图上
|
||||
var spawnPos = Position;
|
||||
if (!pawn.Spawned)
|
||||
{
|
||||
GenSpawn.Spawn(pawn, spawnPos, Map);
|
||||
}
|
||||
|
||||
// 重置孵化状态
|
||||
isIncubating = false;
|
||||
incubationProgress = 0f;
|
||||
@@ -326,21 +321,18 @@ namespace ArachnaeSwarm
|
||||
incubatingPawnKind = null;
|
||||
qualityProgress = 0f;
|
||||
qualityTotal = 0f;
|
||||
|
||||
// 显示消息
|
||||
string qualityText = finalQualityPercent >= 0.9f ? "ARA_OothecaIncubator.QualityExcellent".Translate() :
|
||||
finalQualityPercent >= 0.7f ? "ARA_OothecaIncubator.QualityGood".Translate() :
|
||||
finalQualityPercent >= 0.5f ? "ARA_OothecaIncubator.QualityAverage".Translate() :
|
||||
finalQualityPercent >= 0.3f ? "ARA_OothecaIncubator.QualityPoor".Translate() : "ARA_OothecaIncubator.QualityVeryPoor".Translate();
|
||||
|
||||
Messages.Message("ARA_OothecaIncubator.IncubationComplete".Translate() + " " + pawn.LabelCap + " " +
|
||||
"ARA_OothecaIncubator.HasEmergedWith".Translate() + " " + qualityText + " " +
|
||||
"ARA_OothecaIncubator.Quality".Translate() + " (" + finalQualityPercent.ToStringPercent() + ").",
|
||||
MessageTypeDefOf.PositiveEvent);
|
||||
|
||||
Destroy();
|
||||
}
|
||||
|
||||
|
||||
// 显示额外信息(简化版本,只显示速率,不显示因子)
|
||||
public override string GetInspectString()
|
||||
{
|
||||
@@ -712,10 +704,54 @@ namespace ArachnaeSwarm
|
||||
// 应用质量效果到生成的pawn
|
||||
private void ApplyQualityEffects(Pawn pawn, float qualityPercent)
|
||||
{
|
||||
// 质量影响:根据质量百分比调整pawn的属性
|
||||
// 这里可以添加具体的质量效果逻辑
|
||||
ApplyHediffRewards(pawn, qualityPercent);
|
||||
}
|
||||
|
||||
// === 新增:应用Hediff奖励方法 ===
|
||||
private void ApplyHediffRewards(Pawn pawn, float qualityPercent)
|
||||
{
|
||||
var config = IncubatorData?.SelectedConfig;
|
||||
if (config == null) return;
|
||||
|
||||
// 获取应奖励的Hediff列表
|
||||
List<HediffDef> rewardHediffs = config.GetRewardHediffs(qualityPercent);
|
||||
if (rewardHediffs == null || rewardHediffs.Count == 0) return;
|
||||
|
||||
// 应用Hediff
|
||||
int appliedCount = 0;
|
||||
foreach (var hediffDef in rewardHediffs)
|
||||
{
|
||||
if (hediffDef == null) continue;
|
||||
|
||||
try
|
||||
{
|
||||
// 检查pawn是否已经有这个Hediff(避免重复)
|
||||
if (!pawn.health.hediffSet.HasHediff(hediffDef))
|
||||
{
|
||||
// 创建并添加Hediff
|
||||
Hediff hediff = HediffMaker.MakeHediff(hediffDef, pawn);
|
||||
pawn.health.AddHediff(hediff);
|
||||
appliedCount++;
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Log.Error($"Failed to apply hediff {hediffDef?.defName} to pawn {pawn.Label}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// 显示奖励消息
|
||||
if (appliedCount > 0)
|
||||
{
|
||||
string message = config.GetRewardMessage(qualityPercent);
|
||||
if (string.IsNullOrEmpty(message))
|
||||
{
|
||||
message = "ARA_QualityReward_Default".Translate(pawn.LabelShortCap, appliedCount);
|
||||
}
|
||||
|
||||
Messages.Message(message, pawn, MessageTypeDefOf.PositiveEvent);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否在孵化间中
|
||||
private bool IsInIncubatorRoom()
|
||||
{
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// File: Comps/CompProperties_IncubatorData.cs
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using RimWorld;
|
||||
@@ -6,6 +7,40 @@ using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
// 质量阈值和Hediff奖励配置
|
||||
public class QualityHediffReward : IExposable
|
||||
{
|
||||
// 质量阈值(0-1)
|
||||
public float qualityThreshold = 0f;
|
||||
|
||||
// 达到该阈值时给予的Hediff数量
|
||||
public int hediffCount = 0;
|
||||
|
||||
// 是否给予全部Hediff(true=给予列表中所有Hediff,false=随机选择指定数量的Hediff)
|
||||
public bool giveAllHediffs = false;
|
||||
|
||||
// 消息文本(可选)
|
||||
public string messageKey = null;
|
||||
|
||||
public QualityHediffReward() { }
|
||||
|
||||
public QualityHediffReward(float threshold, int count, bool giveAll = false, string message = null)
|
||||
{
|
||||
qualityThreshold = threshold;
|
||||
hediffCount = count;
|
||||
giveAllHediffs = giveAll;
|
||||
messageKey = message;
|
||||
}
|
||||
|
||||
public void ExposeData()
|
||||
{
|
||||
Scribe_Values.Look(ref qualityThreshold, "qualityThreshold", 0f);
|
||||
Scribe_Values.Look(ref hediffCount, "hediffCount", 0);
|
||||
Scribe_Values.Look(ref giveAllHediffs, "giveAllHediffs", false);
|
||||
Scribe_Values.Look(ref messageKey, "messageKey");
|
||||
}
|
||||
}
|
||||
|
||||
// IncubationConfig 保持不变
|
||||
public class IncubationConfig : IExposable
|
||||
{
|
||||
@@ -13,6 +48,10 @@ namespace ArachnaeSwarm
|
||||
public ResearchProjectDef requiredResearch;
|
||||
public float daysRequired;
|
||||
public string buttonIconPath;
|
||||
|
||||
// === 新增:每个配置可以有自己的Hediff奖励列表 ===
|
||||
public List<HediffDef> extraHediffs = new List<HediffDef>();
|
||||
public List<QualityHediffReward> hediffRewards = new List<QualityHediffReward>();
|
||||
|
||||
public IncubationConfig() { }
|
||||
|
||||
@@ -23,6 +62,20 @@ namespace ArachnaeSwarm
|
||||
this.requiredResearch = requiredResearch;
|
||||
this.daysRequired = daysRequired;
|
||||
this.buttonIconPath = buttonIconPath;
|
||||
extraHediffs = new List<HediffDef>();
|
||||
hediffRewards = CreateDefaultRewards(); // 创建默认奖励配置
|
||||
}
|
||||
|
||||
// 创建默认奖励配置(30%、50%、85%、99%阈值)
|
||||
private List<QualityHediffReward> CreateDefaultRewards()
|
||||
{
|
||||
return new List<QualityHediffReward>
|
||||
{
|
||||
new QualityHediffReward(0.30f, 1, false, "ARA_QualityReward_1Hediff"),
|
||||
new QualityHediffReward(0.50f, 2, false, "ARA_QualityReward_2Hediff"),
|
||||
new QualityHediffReward(0.85f, 3, false, "ARA_QualityReward_3Hediff"),
|
||||
new QualityHediffReward(0.99f, 4, true, "ARA_QualityReward_AllHediff")
|
||||
};
|
||||
}
|
||||
|
||||
public void ExposeData()
|
||||
@@ -31,12 +84,24 @@ namespace ArachnaeSwarm
|
||||
Scribe_Defs.Look(ref requiredResearch, "requiredResearch");
|
||||
Scribe_Values.Look(ref daysRequired, "daysRequired", 1f);
|
||||
Scribe_Values.Look(ref buttonIconPath, "buttonIconPath");
|
||||
|
||||
// === 新增:保存Hediff相关数据 ===
|
||||
Scribe_Collections.Look(ref extraHediffs, "extraHediffs", LookMode.Def);
|
||||
Scribe_Collections.Look(ref hediffRewards, "hediffRewards", LookMode.Deep);
|
||||
|
||||
if (Scribe.mode == LoadSaveMode.PostLoadInit)
|
||||
{
|
||||
if (extraHediffs == null)
|
||||
extraHediffs = new List<HediffDef>();
|
||||
if (hediffRewards == null)
|
||||
hediffRewards = CreateDefaultRewards();
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否满足研究要求
|
||||
public bool IsResearchComplete => requiredResearch == null || requiredResearch.IsFinished;
|
||||
|
||||
// 在配置描述中使用翻译
|
||||
// 获取描述 - 添加Hediff奖励信息
|
||||
public string GetDescription()
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
@@ -51,9 +116,128 @@ namespace ArachnaeSwarm
|
||||
else
|
||||
builder.AppendLine("Research".Translate() + ": " + requiredResearch.LabelCap + " (" + "Required".Translate() + ")");
|
||||
}
|
||||
|
||||
// === 新增:显示Hediff奖励信息 ===
|
||||
if (extraHediffs != null && extraHediffs.Count > 0)
|
||||
{
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("HediffRewards".Translate() + ":");
|
||||
|
||||
foreach (var hediff in extraHediffs)
|
||||
{
|
||||
if (hediff != null)
|
||||
{
|
||||
builder.AppendLine(" - " + hediff.LabelCap);
|
||||
}
|
||||
}
|
||||
|
||||
// 显示质量阈值信息
|
||||
if (hediffRewards != null && hediffRewards.Count > 0)
|
||||
{
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("QualityThresholds".Translate() + ":");
|
||||
foreach (var reward in hediffRewards)
|
||||
{
|
||||
if (reward.qualityThreshold > 0 && reward.hediffCount > 0)
|
||||
{
|
||||
string rewardText = $" {reward.qualityThreshold:P0}: ";
|
||||
if (reward.giveAllHediffs)
|
||||
{
|
||||
rewardText += "AllHediffsReward".Translate();
|
||||
}
|
||||
else
|
||||
{
|
||||
rewardText += "HediffCountReward".Translate(reward.hediffCount);
|
||||
}
|
||||
builder.AppendLine(rewardText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToString().TrimEndNewlines();
|
||||
}
|
||||
|
||||
// === 新增:获取应给予的Hediff数量 ===
|
||||
public int GetHediffCountForQuality(float qualityPercent)
|
||||
{
|
||||
if (hediffRewards == null || hediffRewards.Count == 0)
|
||||
return 0;
|
||||
|
||||
// 按阈值降序排序,找到第一个满足条件的奖励
|
||||
var sortedRewards = new List<QualityHediffReward>(hediffRewards);
|
||||
sortedRewards.Sort((a, b) => b.qualityThreshold.CompareTo(a.qualityThreshold));
|
||||
|
||||
foreach (var reward in sortedRewards)
|
||||
{
|
||||
if (qualityPercent >= reward.qualityThreshold)
|
||||
{
|
||||
if (reward.giveAllHediffs)
|
||||
{
|
||||
return extraHediffs != null ? extraHediffs.Count : 0;
|
||||
}
|
||||
return reward.hediffCount;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// === 新增:获取奖励的Hediff列表 ===
|
||||
public List<HediffDef> GetRewardHediffs(float qualityPercent)
|
||||
{
|
||||
int count = GetHediffCountForQuality(qualityPercent);
|
||||
if (count <= 0 || extraHediffs == null || extraHediffs.Count == 0)
|
||||
return new List<HediffDef>();
|
||||
|
||||
// 如果要求给予所有Hediff,返回全部
|
||||
var sortedRewards = new List<QualityHediffReward>(hediffRewards);
|
||||
sortedRewards.Sort((a, b) => b.qualityThreshold.CompareTo(a.qualityThreshold));
|
||||
|
||||
foreach (var reward in sortedRewards)
|
||||
{
|
||||
if (qualityPercent >= reward.qualityThreshold && reward.giveAllHediffs)
|
||||
{
|
||||
return new List<HediffDef>(extraHediffs);
|
||||
}
|
||||
}
|
||||
|
||||
// 否则随机选择指定数量的Hediff(不重复)
|
||||
List<HediffDef> result = new List<HediffDef>();
|
||||
List<HediffDef> available = new List<HediffDef>(extraHediffs);
|
||||
|
||||
count = Mathf.Min(count, available.Count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (available.Count == 0) break;
|
||||
|
||||
int index = Rand.Range(0, available.Count);
|
||||
result.Add(available[index]);
|
||||
available.RemoveAt(index);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// === 新增:获取奖励消息 ===
|
||||
public string GetRewardMessage(float qualityPercent)
|
||||
{
|
||||
if (hediffRewards == null || hediffRewards.Count == 0)
|
||||
return null;
|
||||
|
||||
var sortedRewards = new List<QualityHediffReward>(hediffRewards);
|
||||
sortedRewards.Sort((a, b) => b.qualityThreshold.CompareTo(a.qualityThreshold));
|
||||
|
||||
foreach (var reward in sortedRewards)
|
||||
{
|
||||
if (qualityPercent >= reward.qualityThreshold && !string.IsNullOrEmpty(reward.messageKey))
|
||||
{
|
||||
return reward.messageKey.Translate();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 组件属性定义
|
||||
@@ -69,6 +253,10 @@ namespace ArachnaeSwarm
|
||||
public string buttonDesc = "IncubatorButtonDesc"; // 按钮描述翻译键
|
||||
public string menuTitle = "IncubatorMenuTitle"; // 菜单标题翻译键
|
||||
public string defaultIconPath = "UI/Commands/Default";
|
||||
|
||||
// === 新增:全局Hediff奖励(所有配置共享)===
|
||||
public List<HediffDef> globalExtraHediffs = new List<HediffDef>();
|
||||
public List<QualityHediffReward> globalHediffRewards = new List<QualityHediffReward>();
|
||||
|
||||
public CompProperties_IncubatorData()
|
||||
{
|
||||
@@ -80,6 +268,67 @@ namespace ArachnaeSwarm
|
||||
base.ResolveReferences(parentDef);
|
||||
if (incubationConfigs == null)
|
||||
incubationConfigs = new List<IncubationConfig>();
|
||||
if (globalExtraHediffs == null)
|
||||
globalExtraHediffs = new List<HediffDef>();
|
||||
if (globalHediffRewards == null)
|
||||
globalHediffRewards = CreateDefaultGlobalRewards();
|
||||
}
|
||||
|
||||
// 创建默认的全局奖励配置
|
||||
private List<QualityHediffReward> CreateDefaultGlobalRewards()
|
||||
{
|
||||
return new List<QualityHediffReward>
|
||||
{
|
||||
new QualityHediffReward(0.30f, 1, false, "ARA_QualityReward_1Hediff"),
|
||||
new QualityHediffReward(0.50f, 2, false, "ARA_QualityReward_2Hediff"),
|
||||
new QualityHediffReward(0.85f, 3, false, "ARA_QualityReward_3Hediff"),
|
||||
new QualityHediffReward(0.99f, 4, true, "ARA_QualityReward_AllHediff")
|
||||
};
|
||||
}
|
||||
|
||||
// === 新增:配置后处理,确保每个配置都有Hediff奖励 ===
|
||||
public override void PostLoadSpecial(ThingDef parent)
|
||||
{
|
||||
base.PostLoadSpecial(parent);
|
||||
|
||||
// 确保每个配置都有默认的奖励配置
|
||||
foreach (var config in incubationConfigs)
|
||||
{
|
||||
if (config.hediffRewards == null || config.hediffRewards.Count == 0)
|
||||
{
|
||||
config.hediffRewards = new List<QualityHediffReward>
|
||||
{
|
||||
new QualityHediffReward(0.30f, 1, false, "ARA_QualityReward_1Hediff"),
|
||||
new QualityHediffReward(0.50f, 2, false, "ARA_QualityReward_2Hediff"),
|
||||
new QualityHediffReward(0.85f, 3, false, "ARA_QualityReward_3Hediff"),
|
||||
new QualityHediffReward(0.99f, 4, true, "ARA_QualityReward_AllHediff")
|
||||
};
|
||||
}
|
||||
|
||||
// 合并全局Hediff列表
|
||||
if (globalExtraHediffs != null && globalExtraHediffs.Count > 0)
|
||||
{
|
||||
if (config.extraHediffs == null)
|
||||
config.extraHediffs = new List<HediffDef>();
|
||||
|
||||
foreach (var hediff in globalExtraHediffs)
|
||||
{
|
||||
if (!config.extraHediffs.Contains(hediff))
|
||||
{
|
||||
config.extraHediffs.Add(hediff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果配置没有自己的奖励规则,使用全局规则
|
||||
if (globalHediffRewards != null && globalHediffRewards.Count > 0)
|
||||
{
|
||||
if (config.hediffRewards == null || config.hediffRewards.Count == 0)
|
||||
{
|
||||
config.hediffRewards = new List<QualityHediffReward>(globalHediffRewards);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,5 +423,48 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
return base.CompInspectStringExtra();
|
||||
}
|
||||
|
||||
// === 新增:获取当前配置的Hediff奖励信息 ===
|
||||
public string GetHediffRewardDescription()
|
||||
{
|
||||
var config = SelectedConfig;
|
||||
if (config == null || config.extraHediffs == null || config.extraHediffs.Count == 0)
|
||||
return null;
|
||||
|
||||
var builder = new StringBuilder();
|
||||
builder.AppendLine("HediffRewards".Translate() + ":");
|
||||
|
||||
foreach (var hediff in config.extraHediffs)
|
||||
{
|
||||
if (hediff != null)
|
||||
{
|
||||
builder.AppendLine(" - " + hediff.LabelCap);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.hediffRewards != null && config.hediffRewards.Count > 0)
|
||||
{
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("QualityThresholds".Translate() + ":");
|
||||
foreach (var reward in config.hediffRewards)
|
||||
{
|
||||
if (reward.qualityThreshold > 0 && reward.hediffCount > 0)
|
||||
{
|
||||
string rewardText = $" {reward.qualityThreshold:P0}: ";
|
||||
if (reward.giveAllHediffs)
|
||||
{
|
||||
rewardText += "AllHediffsReward".Translate();
|
||||
}
|
||||
else
|
||||
{
|
||||
rewardText += "HediffCountReward".Translate(reward.hediffCount);
|
||||
}
|
||||
builder.AppendLine(rewardText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToString().TrimEndNewlines();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,10 +38,29 @@ namespace ArachnaeSwarm
|
||||
|
||||
// 获取营养液检测半径的整数形式(用于循环)
|
||||
public int NutrientSolutionRadiusInt => (int)nutrientSolutionRadius;
|
||||
|
||||
|
||||
// 获取其他卵距离检测半径的整数形式
|
||||
public int NearbyOothecaRadiusInt => (int)nearbyOothecaRadius;
|
||||
|
||||
|
||||
// 是否启用营养液不足时的伤害
|
||||
public bool nutrientDeficiencyDamageEnabled = false;
|
||||
|
||||
// 每次检查间隔造成的伤害量
|
||||
public float nutrientDeficiencyDamageAmount = 1f;
|
||||
|
||||
// 伤害类型
|
||||
public DamageDef nutrientDamageType = DamageDefOf.Burn;
|
||||
|
||||
// 是否显示伤害消息
|
||||
public bool showDamageMessages = true;
|
||||
|
||||
// 伤害消息显示几率(避免刷屏)
|
||||
public float damageMessageChance = 0.1f;
|
||||
|
||||
// 是否在营养液不足时停止孵化(如果设置为true,则缺少营养液时停止孵化进度)
|
||||
public bool stopIncubationWhenNutrientDeficient = false;
|
||||
|
||||
|
||||
public static OothecaIncubatorExtension Get(Thing thing)
|
||||
{
|
||||
if (thing?.def?.GetModExtension<OothecaIncubatorExtension>() is OothecaIncubatorExtension ext)
|
||||
@@ -57,8 +76,7 @@ namespace ArachnaeSwarm
|
||||
nutrientSolutionBonusPerTile >= 0f &&
|
||||
nearbyOothecaPenaltyPerUnit >= 0f;
|
||||
}
|
||||
|
||||
// 获取默认扩展(用于兼容性)
|
||||
public static OothecaIncubatorExtension Default => new OothecaIncubatorExtension();
|
||||
// 默认实例
|
||||
public static readonly OothecaIncubatorExtension Default = new OothecaIncubatorExtension();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user