Files
ArachnaeSwarm/Source/ArachnaeSwarm/Buildings/Building_EquipmentOotheca/CompProperties_EquipmentIncubatorData.cs
2025-12-16 02:13:18 +08:00

333 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// File: Comps/CompProperties_EquipmentIncubatorData.cs
using RimWorld;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Verse;
namespace ArachnaeSwarm
{
// 装备孵化配置
public class EquipmentIncubationConfig : IExposable
{
public ThingDef thingDef;
public ResearchProjectDef requiredResearch;
public float daysRequired; // 从stat中读取
public string buttonIconPath;
// 缓存的生产时间避免重复获取stat
private float? cachedDaysRequired;
public EquipmentIncubationConfig() { }
public EquipmentIncubationConfig(ThingDef thingDef, ResearchProjectDef requiredResearch = null,
string buttonIconPath = null)
{
this.thingDef = thingDef;
this.requiredResearch = requiredResearch;
this.buttonIconPath = buttonIconPath;
cachedDaysRequired = null;
}
public void ExposeData()
{
Scribe_Defs.Look(ref thingDef, "thingDef");
Scribe_Defs.Look(ref requiredResearch, "requiredResearch");
Scribe_Values.Look(ref buttonIconPath, "buttonIconPath");
// 不保存缓存值,重新计算
if (Scribe.mode == LoadSaveMode.LoadingVars)
{
cachedDaysRequired = null;
}
}
// 获取生产时间(天)
public float DaysRequired
{
get
{
if (cachedDaysRequired.HasValue)
return cachedDaysRequired.Value;
if (thingDef == null)
{
cachedDaysRequired = 1f;
return cachedDaysRequired.Value;
}
// 从stat中读取ARA_IncubationTime
var statDef = DefDatabase<StatDef>.GetNamedSilentFail("ARA_IncubationTime");
if (statDef != null)
{
cachedDaysRequired = thingDef.GetStatValueAbstract(statDef, null);
}
else
{
// 默认值
cachedDaysRequired = 1f;
}
return cachedDaysRequired.Value;
}
}
// 检查是否满足研究要求
public bool IsResearchComplete => requiredResearch == null || requiredResearch.IsFinished;
// 获取描述
public string GetDescription()
{
var builder = new StringBuilder();
if (thingDef != null)
{
builder.AppendLine(thingDef.description ?? "ARA_EquipmentIncubator.NoDescription".Translate());
builder.AppendLine();
builder.AppendLine("ARA_EquipmentIncubator.IncubationTime".Translate(DaysRequired));
}
if (requiredResearch != null)
{
if (requiredResearch.IsFinished)
builder.AppendLine("ARA_EquipmentIncubator.ResearchCompleted".Translate(requiredResearch.LabelCap));
else
builder.AppendLine("ARA_EquipmentIncubator.ResearchRequired".Translate(requiredResearch.LabelCap));
}
return builder.ToString().TrimEndNewlines();
}
}
// 装备孵化器组件属性
public class CompProperties_EquipmentIncubatorData : CompProperties
{
// 支持手动指定配置列表(可选)
public List<EquipmentIncubationConfig> incubationConfigs;
// 默认选择索引
public int defaultIndex = 0;
// Gizmo相关配置
public string buttonLabel = "ARA_EquipmentIncubator.IncubateLabel";
public string buttonDesc = "ARA_EquipmentIncubator.ButtonDesc";
public string menuTitle = "ARA_EquipmentIncubator.MenuTitle";
public string defaultIconPath = "UI/Commands/Default";
// 是否自动扫描所有ThingDef来构建配置列表
public bool autoScanThingDefs = true;
// 手动指定要扫描的ThingDef类型可选
public List<string> thingDefCategories;
public List<ThingCategoryDef> thingCategoryDefs;
public CompProperties_EquipmentIncubatorData()
{
compClass = typeof(CompEquipmentIncubatorData);
}
}
// 装备孵化器数据组件
public class CompEquipmentIncubatorData : ThingComp
{
private CompProperties_EquipmentIncubatorData Props => (CompProperties_EquipmentIncubatorData)props;
// 当前选择的配置索引
private int selectedIndex = -1;
// 缓存的配置列表
private List<EquipmentIncubationConfig> cachedConfigs;
private bool configsBuilt = false;
// 公开获取孵化配置列表的方法
public List<EquipmentIncubationConfig> IncubationConfigs
{
get
{
if (!configsBuilt)
{
BuildIncubationConfigs();
}
return cachedConfigs ?? new List<EquipmentIncubationConfig>();
}
}
// 获取当前选择的配置
public EquipmentIncubationConfig SelectedConfig
{
get
{
var configs = IncubationConfigs;
if (configs.Count == 0) return null;
// 初始化选择
if (selectedIndex == -1)
{
selectedIndex = Mathf.Clamp(Props.defaultIndex, 0, configs.Count - 1);
}
if (selectedIndex < 0 || selectedIndex >= configs.Count)
selectedIndex = 0;
return configs[selectedIndex];
}
}
// 获取当前选择的ThingDef
public ThingDef SelectedThingDef => SelectedConfig?.thingDef;
// 构建孵化配置列表
private void BuildIncubationConfigs()
{
cachedConfigs = new List<EquipmentIncubationConfig>();
configsBuilt = true;
// 优先使用手动配置的列表
if (Props.incubationConfigs != null && Props.incubationConfigs.Count > 0)
{
foreach (var config in Props.incubationConfigs)
{
if (config?.thingDef != null)
{
cachedConfigs.Add(config);
}
}
if (cachedConfigs.Count > 0)
return;
}
// 如果没有手动配置且启用了自动扫描则扫描所有ThingDef
if (Props.autoScanThingDefs)
{
ScanThingDefsForConfigs();
}
}
// 扫描所有ThingDef来构建配置列表
private void ScanThingDefsForConfigs()
{
var allThingDefs = DefDatabase<ThingDef>.AllDefsListForReading;
foreach (var thingDef in allThingDefs)
{
// 检查该ThingDef是否包含CompProperties_ExtraIncubationInfo组件
var extraInfoProps = thingDef.comps?.FirstOrDefault(c => c is CompProperties_ExtraIncubationInfo)
as CompProperties_ExtraIncubationInfo;
if (extraInfoProps == null)
continue;
// 检查cocoonDefs是否包含当前建筑
bool isForThisCocoon = false;
if (extraInfoProps.cocoonDefs != null && extraInfoProps.cocoonDefs.Count > 0)
{
isForThisCocoon = extraInfoProps.cocoonDefs.Contains(parent.def);
}
else if (extraInfoProps.cocoonDef != null)
{
// 向后兼容检查单个cocoonDef
isForThisCocoon = extraInfoProps.cocoonDef == parent.def;
}
if (!isForThisCocoon)
continue;
// 检查是否有ARA_IncubationTime这个stat
var incubationTimeStat = DefDatabase<StatDef>.GetNamedSilentFail("ARA_IncubationTime");
if (incubationTimeStat == null)
{
Log.Warning($"ThingDef {thingDef.defName} has CompProperties_ExtraIncubationInfo but ARA_IncubationTime stat is not defined.");
continue;
}
// 获取孵化时间
float daysRequired = thingDef.GetStatValueAbstract(incubationTimeStat, null);
if (daysRequired <= 0)
{
Log.Warning($"ThingDef {thingDef.defName} has invalid incubation time: {daysRequired}");
continue;
}
// 创建配置
var config = new EquipmentIncubationConfig
{
thingDef = thingDef,
daysRequired = daysRequired,
// 可以在这里添加其他配置,比如所需研究等
// requiredResearch = ...
// buttonIconPath = ...
};
cachedConfigs.Add(config);
}
// 按物品名称排序
cachedConfigs.Sort((a, b) => string.Compare(a.thingDef?.label ?? "", b.thingDef?.label ?? ""));
Log.Message($"Built {cachedConfigs.Count} equipment incubation configs for {parent.def.defName}");
}
// 切换到特定索引
public void SwitchToConfig(int index)
{
if (index >= 0 && index < IncubationConfigs.Count)
{
selectedIndex = index;
}
}
// 检查配置是否可用(研究是否完成)
public bool IsConfigAvailable(int index)
{
if (index < 0 || index >= IncubationConfigs.Count)
return false;
var config = IncubationConfigs[index];
return config?.IsResearchComplete ?? false;
}
// 获取配置索引
public int GetSelectedIndex()
{
return selectedIndex;
}
// 存档加载
public override void PostExposeData()
{
base.PostExposeData();
Scribe_Values.Look(ref selectedIndex, "selectedIndex", -1);
Scribe_Values.Look(ref configsBuilt, "configsBuilt", false);
if (Scribe.mode == LoadSaveMode.LoadingVars)
{
// 重置缓存,在需要时重新构建
cachedConfigs = null;
configsBuilt = false;
}
}
// 在建筑信息中显示额外信息
public override string CompInspectStringExtra()
{
var current = SelectedConfig;
if (current != null && current.thingDef != null)
{
string status = "ARA_EquipmentIncubator.IncubationTarget".Translate(current.thingDef.LabelCap);
if (current.requiredResearch != null && !current.requiredResearch.IsFinished)
{
status += " (" + "ARA_EquipmentIncubator.Requires".Translate() + ": " + current.requiredResearch.LabelCap + ")";
}
return status;
}
return base.CompInspectStringExtra();
}
}
}