diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 2f0a627..bd681c5 100644 Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ diff --git a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Incubator_Reward.xml b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Incubator_Reward.xml index 8808eaa..c8af12d 100644 --- a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Incubator_Reward.xml +++ b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Incubator_Reward.xml @@ -216,4 +216,163 @@ + + + + ARA_Incubator_5_Flaw_Hediffs + + 急速的孵化使得该阿拉克涅督虫的肌肉组织发育不全,力量远低于正常个体。\n\n由于较差的孵化质量,阿拉克涅督虫获得了这个不利突变。 + HediffWithComps + false + (0.9, 0.2 , 0.1) + true + +
  • + + 0.5 + 0.6 + +
  • +
    +
    + + + ARA_Incubator_6_Flaw_Hediffs + + 急速的孵化导致该阿拉克涅督虫的凝血机制异常,一旦受伤就会大量失血。\n\n由于较差的孵化质量,阿拉克涅督虫获得了这个不利突变。 + HediffWithComps + false + (0.9, 0.2 , 0.1) + true + +
  • + 3.0 +
  • +
    +
    + + + ARA_Incubator_7_Flaw_Hediffs + + 急速的孵化使得该阿拉克涅督虫的内骨骼异常脆弱,更容易受到致命伤害。\n\n由于较差的孵化质量,阿拉克涅督虫获得了这个不利突变。 + HediffWithComps + false + (0.9, 0.2 , 0.1) + true + +
  • + + 1.5 + +
  • +
    +
    + + + ARA_Incubator_8_Flaw_Hediffs + + 急速的孵化使得该阿拉克涅督虫的免疫系统发育不良,对疾病的抵抗力极差。\n\n由于较差的孵化质量,阿拉克涅督虫获得了这个不利突变。 + HediffWithComps + false + (0.9, 0.2 , 0.1) + true + +
  • + + 0.5 + +
  • +
    +
    + + + + + ARA_Incubator_Elite_Regeneration + + 该阿拉克涅督虫的甲壳密度远超常规个体,几乎坚不可摧,同时还具有优秀的热抗性。\n\n由于极佳的孵化质量,阿拉克涅督虫获得了这个稀有突变。 + HediffWithComps + false + (0.8, 0.6, 0.0) + true + +
  • + + 1.0 + 1.0 + 0.8 + +
  • +
    +
    + + + + ARA_Incubator_Elite_AdaptiveArmor + + 该阿拉克涅督虫的腺体异常发达,持续分泌高浓度激素,使其处于极度亢奋状态,攻击速度惊人。\n\n由于极佳的孵化质量,阿拉克涅督虫获得了这个稀有突变。 + HediffWithComps + false + (0.8, 0.6, 0.0) + true + +
  • + + 1.5 + + + 0.4 + 0.5 + +
  • +
    +
    + + + + ARA_Incubator_Elite_BerserkGlands + + 该阿拉克涅督虫的肌肉组织经过完美发育,力量远超同类,近战攻击威力惊人,负重能力也大幅提升。\n\n由于极佳的孵化质量,阿拉克涅督虫获得了这个稀有突变。 + HediffWithComps + false + (0.8, 0.6, 0.0) + true + +
  • + + 5 + 3 + +
  • +
    +
    + + + + ARA_Incubator_Elite_PsychicResonance + + 该阿拉克涅督虫的神经系统经过完美发育,意识、视觉、听觉等各项感知能力都大幅超越同类。\n\n由于极佳的孵化质量,阿拉克涅督虫获得了这个稀有突变。 + HediffWithComps + false + (0.8, 0.6, 0.0) + true + +
  • + +
  • + Consciousness + 0.5 +
  • +
  • + Sight + 0.5 +
  • +
  • + Hearing + 0.5 +
  • + + +
    +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/MiscSettingDefs/ARA_TieredHediffRewards.xml b/1.6/1.6/Defs/MiscSettingDefs/ARA_TieredHediffRewards.xml new file mode 100644 index 0000000..6405530 --- /dev/null +++ b/1.6/1.6/Defs/MiscSettingDefs/ARA_TieredHediffRewards.xml @@ -0,0 +1,180 @@ + + + + + ARA_DefaultIncubatorRewards + + 阿拉克涅虫群的默认孵化特质奖励规则。根据孵化品质分为7个阶段,不同阶段从不同特质池中抽取奖励。品质上限150%。 + + + + +
  • + bad + + +
  • ARA_Incubator_1_Flaw_Hediffs
  • +
  • ARA_Incubator_2_Flaw_Hediffs
  • +
  • ARA_Incubator_3_Flaw_Hediffs
  • +
  • ARA_Incubator_4_Flaw_Hediffs
  • +
  • ARA_Incubator_5_Flaw_Hediffs
  • +
  • ARA_Incubator_6_Flaw_Hediffs
  • +
  • ARA_Incubator_7_Flaw_Hediffs
  • +
  • ARA_Incubator_8_Flaw_Hediffs
  • + + + + +
  • + normal + + +
  • ARA_Incubator_1_Reward_Hediffs
  • +
  • ARA_Incubator_2_Reward_Hediffs
  • +
  • ARA_Incubator_3_Reward_Hediffs
  • +
  • ARA_Incubator_4_Reward_Hediffs
  • +
  • ARA_Incubator_5_Reward_Hediffs
  • +
  • ARA_Incubator_6_Reward_Hediffs
  • +
  • ARA_Incubator_7_Reward_Hediffs
  • +
  • ARA_Incubator_8_Reward_Hediffs
  • + + + + +
  • + elite + + +
  • ARA_Incubator_Elite_Regeneration
  • +
  • ARA_Incubator_Elite_AdaptiveArmor
  • +
  • ARA_Incubator_Elite_BerserkGlands
  • +
  • ARA_Incubator_Elite_PsychicResonance
  • + + +
    + + + + +
  • + 1 + 0.00 + 0.20 + 极差 + ARA_Tier_Bad + +
  • + bad + 3 +
  • + + + + +
  • + 2 + 0.20 + 0.40 + 较差 + ARA_Tier_Poor + +
  • + bad + 2 +
  • + + + + +
  • + 3 + 0.40 + 0.60 + 普通 + ARA_Tier_Normal + +
  • + normal + 1 +
  • +
  • + bad + 1 +
  • + + + + +
  • + 4 + 0.60 + 0.80 + 良好 + ARA_Tier_Good + +
  • + normal + 2 +
  • + + + + +
  • + 5 + 0.80 + 1.20 + 极佳 + ARA_Tier_Excellent + +
  • + normal + 3 +
  • + + + + +
  • + 6 + 1.20 + 1.40 + 大师 + ARA_Tier_Elite + +
  • + normal + 3 +
  • +
  • + elite + 1 +
  • + + + + +
  • + 7 + 1.40 + 1.51 + 传奇 + ARA_Tier_Legendary + +
  • + normal + 3 +
  • +
  • + elite + 2 +
  • + + +
    +
    +
    diff --git a/1.6/1.6/Defs/Thing_building/ARA_Ootheca.xml b/1.6/1.6/Defs/Thing_building/ARA_Ootheca.xml index 24c62cd..1b6a34a 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_Ootheca.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_Ootheca.xml @@ -149,52 +149,16 @@
  • - - 0 + + ARA_DefaultIncubatorRewards + + 孵化··· 选择孵化的阿拉克涅督虫··· 孵化菜单 ArachnaeSwarm/UI/Commands/ARA_NodeSwarmIcon - - - -
  • ARA_Incubator_1_Reward_Hediffs
  • -
  • ARA_Incubator_2_Reward_Hediffs
  • -
  • ARA_Incubator_3_Reward_Hediffs
  • -
  • ARA_Incubator_4_Reward_Hediffs
  • -
  • ARA_Incubator_5_Reward_Hediffs
  • -
  • ARA_Incubator_6_Reward_Hediffs
  • -
  • ARA_Incubator_7_Reward_Hediffs
  • -
  • ARA_Incubator_8_Reward_Hediffs
  • - - - -
  • - 0.30 - 1 - false - ARA_QualityReward_1Hediff -
  • -
  • - 0.50 - 2 - false - ARA_QualityReward_2Hediff -
  • -
  • - 0.85 - 3 - false - ARA_QualityReward_3Hediff -
  • -
  • - 0.99 - 4 - false - ARA_QualityReward_4Hediff -
  • -
    +
  • ArachnaeNode_Race_ShieldHead @@ -621,45 +585,10 @@
  • - - -
  • ARA_Incubator_1_Reward_Hediffs
  • -
  • ARA_Incubator_2_Reward_Hediffs
  • -
  • ARA_Incubator_3_Reward_Hediffs
  • -
  • ARA_Incubator_4_Reward_Hediffs
  • -
  • ARA_Incubator_5_Reward_Hediffs
  • -
  • ARA_Incubator_6_Reward_Hediffs
  • -
  • ARA_Incubator_7_Reward_Hediffs
  • -
  • ARA_Incubator_8_Reward_Hediffs
  • - - - -
  • - 0.30 - 1 - false - ARA_QualityReward_1Hediff -
  • -
  • - 0.50 - 2 - false - ARA_QualityReward_2Hediff -
  • -
  • - 0.85 - 3 - false - ARA_QualityReward_3Hediff -
  • -
  • - 0.99 - 4 - false - ARA_QualityReward_4Hediff -
  • -
    + + ARA_DefaultIncubatorRewards +
  • ArachnaeNode_Race_ShieldHead diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompInteractiveProducer.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompInteractiveProducer.cs index c4719bf..1e32b39 100644 --- a/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompInteractiveProducer.cs +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompInteractiveProducer.cs @@ -466,7 +466,7 @@ namespace ArachnaeSwarm } float progress = (float)ticksUnderOptimalConditions / _selectedProcess.productionTicks; - float finalQualityPercent = Mathf.Clamp01(progress - temperaturePenaltyPercent); + float finalQualityPercent = Mathf.Clamp(progress - temperaturePenaltyPercent, 0f, 1.5f); QualityCategory finalQuality = QualityCategory.Awful; foreach (var threshold in Props.qualityThresholds.OrderByDescending(q => q.threshold)) @@ -766,7 +766,7 @@ namespace ArachnaeSwarm if (Props.qualityThresholds != null && Props.qualityThresholds.Count > 0) { var qualityDetails = GetEstimatedQualityDetails(); - float qualityProgress = Mathf.Clamp01(qualityDetails.baseScore - qualityDetails.penalty); + float qualityProgress = Mathf.Clamp(qualityDetails.baseScore - qualityDetails.penalty, 0f, 1.5f); drawPos.y += 0.2f; diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompQueuedInteractiveProducer.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompQueuedInteractiveProducer.cs index 63e1854..6ecc402 100644 --- a/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompQueuedInteractiveProducer.cs +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompQueuedInteractiveProducer.cs @@ -208,7 +208,7 @@ namespace ArachnaeSwarm return (QualityCategory.Normal, 0f, 0f); } float progress = (order.process.productionTicks > 0) ? (float)order.ticksUnderOptimalConditions / order.process.productionTicks : 1f; - float finalQualityPercent = Mathf.Clamp01(progress - order.temperaturePenaltyPercent); + float finalQualityPercent = Mathf.Clamp(progress - order.temperaturePenaltyPercent, 0f, 1.5f); QualityCategory finalQuality = QualityCategory.Awful; foreach (var threshold in Props.qualityThresholds.OrderByDescending(q => q.threshold)) { diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_SpawnPawnFromList/CompQueuedPawnSpawnerWithFlux.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_SpawnPawnFromList/CompQueuedPawnSpawnerWithFlux.cs index f599339..5295c93 100644 --- a/Source/ArachnaeSwarm/Building_Comps/ARA_SpawnPawnFromList/CompQueuedPawnSpawnerWithFlux.cs +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_SpawnPawnFromList/CompQueuedPawnSpawnerWithFlux.cs @@ -365,18 +365,22 @@ namespace ArachnaeSwarm private void ApplyQualityEffects(Pawn pawn, float qualityPercent, IncubationConfig config) { - // 应用 Hediff 奖励 - if (config != null && config.extraHediffs != null) + // 使用新的分层奖励系统(优先)或回退到旧系统 + List rewardHediffs = IncubatorDataComp?.DrawRewardsForQuality(qualityPercent); + + // 如果新系统没有返回结果,回退到旧系统 + if ((rewardHediffs == null || rewardHediffs.Count == 0) && config?.extraHediffs != null) { - var rewardHediffs = config.GetRewardHediffs(qualityPercent); - if (rewardHediffs != null) + rewardHediffs = config.GetRewardHediffs(qualityPercent); + } + + if (rewardHediffs != null) + { + foreach (var hediffDef in rewardHediffs) { - foreach (var hediffDef in rewardHediffs) + if (hediffDef != null) { - if (hediffDef != null) - { - pawn.health.AddHediff(hediffDef); - } + pawn.health.AddHediff(hediffDef); } } } diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_TieredHediffReward/CompTieredIncubatorData.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_TieredHediffReward/CompTieredIncubatorData.cs new file mode 100644 index 0000000..122a1cc --- /dev/null +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_TieredHediffReward/CompTieredIncubatorData.cs @@ -0,0 +1,263 @@ +// File: Building_Comps/ARA_TieredHediffReward/CompTieredIncubatorData.cs +// 分层孵化器数据组件 +using System.Collections.Generic; +using System.Text; +using RimWorld; +using UnityEngine; +using Verse; + +namespace ArachnaeSwarm +{ + /// + /// 分层孵化器组件属性 - 只需引用 TieredHediffRewardDef + /// + public class CompProperties_TieredIncubatorData : CompProperties + { + // === 孵化配置 === + /// 孵化配置列表(可孵化的 PawnKind) + public List incubationConfigs = new List(); + + /// 默认选择索引 + public int defaultIndex = 0; + + // === UI 配置 === + /// 按钮标签翻译键 + public string buttonLabel = "IncubatorButtonLabel"; + + /// 按钮描述翻译键 + public string buttonDesc = "IncubatorButtonDesc"; + + /// 菜单标题翻译键 + public string menuTitle = "IncubatorMenuTitle"; + + /// 默认图标路径 + public string defaultIconPath = "UI/Commands/Default"; + + // === 引用奖励 Def === + /// 分层奖励配置的 Def 引用 + public TieredHediffRewardDef rewardDef; + + public CompProperties_TieredIncubatorData() + { + compClass = typeof(CompTieredIncubatorData); + } + + public override void ResolveReferences(ThingDef parentDef) + { + base.ResolveReferences(parentDef); + + if (incubationConfigs == null) + incubationConfigs = new List(); + } + + public override IEnumerable ConfigErrors(ThingDef parentDef) + { + foreach (var error in base.ConfigErrors(parentDef)) + yield return error; + + if (rewardDef == null) + yield return "rewardDef is null - no tiered hediff reward configuration"; + + if (incubationConfigs == null || incubationConfigs.Count == 0) + yield return "incubationConfigs is empty"; + } + } + + /// + /// 分层孵化器数据组件 - 管理当前选择状态和奖励抽取 + /// + public class CompTieredIncubatorData : ThingComp + { + // === 属性访问 === + private CompProperties_TieredIncubatorData Props => (CompProperties_TieredIncubatorData)props; + + // === 状态 === + /// 当前选择的配置索引 (-1 表示未选择) + private int selectedIndex = -1; + + // === 公开属性 === + + /// 获取孵化配置列表 + public List IncubationConfigs => Props?.incubationConfigs ?? new List(); + + /// 获取奖励 Def + public TieredHediffRewardDef RewardDef => Props?.rewardDef; + + /// 获取当前选中的配置 + public IncubationConfig SelectedConfig + { + get + { + var configs = IncubationConfigs; + if (configs.Count == 0) return null; + + // 未选择时返回 null + if (selectedIndex == -1) + return null; + + if (selectedIndex < 0 || selectedIndex >= configs.Count) + return null; + + return configs[selectedIndex]; + } + } + + /// 获取当前选择的 PawnKind + public PawnKindDef SelectedPawnKind => SelectedConfig?.pawnKind; + + /// 获取当前选择的索引 + public int GetSelectedIndex() => selectedIndex; + + // === 方法 === + + /// + /// 切换到指定配置 (-1 表示清除选择) + /// + public void SwitchToConfig(int index) + { + if (index == -1) + { + selectedIndex = -1; + } + else 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; + } + + /// + /// 根据品质抽取 Hediff 奖励 + /// + public List DrawRewardsForQuality(float quality) + { + if (RewardDef == null) + { + Log.Warning($"[CompTieredIncubatorData] No rewardDef configured for {parent.def.defName}"); + return new List(); + } + + return RewardDef.DrawRewardsForQuality(quality); + } + + /// + /// 获取品质对应的阶段信息 + /// + public QualityTier GetTierForQuality(float quality) + { + return RewardDef?.GetTierForQuality(quality); + } + + /// + /// 显示目标选择浮动菜单 + /// + public void ShowFloatMenu() + { + var configs = IncubationConfigs; + if (configs == null || configs.Count == 0) return; + + List options = new List(); + + for (int i = 0; i < configs.Count; i++) + { + var cfg = configs[i]; + int index = i; + + string label = cfg.pawnKind.LabelCap; + if (cfg.requiredResearch != null && !cfg.requiredResearch.IsFinished) + { + label += " (" + "ARA_Menu_RequiresResearch".Translate(cfg.requiredResearch.LabelCap) + ")"; + options.Add(new FloatMenuOption(label, null)); // 灰显 + } + else + { + label += " (" + "ARA_Menu_Days".Translate(cfg.daysRequired.ToString("F1")) + ")"; + options.Add(new FloatMenuOption(label, () => SwitchToConfig(index))); + } + } + + if (options.Count > 0) + Find.WindowStack.Add(new FloatMenu(options, "ARA_Menu_SelectIncubationTarget".Translate())); + } + + /// + /// 获取奖励系统的描述文本 + /// + public string GetRewardSystemDescription() + { + if (RewardDef == null) + return null; + + var builder = new StringBuilder(); + builder.AppendLine("ARA_TieredReward_Title".Translate()); + builder.AppendLine(); + + // 显示各阶段信息 + if (RewardDef.qualityTiers != null) + { + foreach (var tier in RewardDef.qualityTiers) + { + string qualityRange = $"{tier.minQuality:P0} - {tier.maxQuality:P0}"; + builder.AppendLine($" {tier.tierLabel ?? $"阶段{tier.tier}"}: {qualityRange}"); + + if (tier.drawRules != null) + { + foreach (var rule in tier.drawRules) + { + var pool = RewardDef.GetPool(rule.poolId); + string poolLabel = pool?.label ?? rule.poolId; + builder.AppendLine($" - {poolLabel} x{rule.count}"); + } + } + } + } + + return builder.ToString().TrimEndNewlines(); + } + + // === 存档 === + + public override void PostExposeData() + { + base.PostExposeData(); + Scribe_Values.Look(ref selectedIndex, "selectedIndex", -1); + + if (Scribe.mode == LoadSaveMode.PostLoadInit) + { + // 验证索引有效性 + if (selectedIndex >= IncubationConfigs.Count) + selectedIndex = Mathf.Clamp(Props.defaultIndex, 0, IncubationConfigs.Count - 1); + } + } + + // === 检查面板 === + + public override string CompInspectStringExtra() + { + var current = SelectedConfig; + if (current != null) + { + string status = "ARA_Status_Target".Translate(current.pawnKind.LabelCap); + + if (current.requiredResearch != null && !current.requiredResearch.IsFinished) + { + status += " (" + "ARA_Menu_RequiresResearch".Translate(current.requiredResearch.LabelCap) + ")"; + } + + return status; + } + return null; + } + } +} diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_TieredHediffReward/TieredHediffRewardDef.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_TieredHediffReward/TieredHediffRewardDef.cs new file mode 100644 index 0000000..ee113e0 --- /dev/null +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_TieredHediffReward/TieredHediffRewardDef.cs @@ -0,0 +1,280 @@ +// File: Defs/TieredHediffRewardDef.cs +// 分层特质奖励系统 - Def 定义 +using System.Collections.Generic; +using RimWorld; +using UnityEngine; +using Verse; + +namespace ArachnaeSwarm +{ + /// + /// 特质池 - 定义一组可抽取的 Hediff + /// + public class HediffPool + { + /// 池ID,如 "bad", "normal", "elite" + public string poolId; + + /// 显示名称,如 "劣质特质" + public string label; + + /// 池中的 Hediff 列表 + public List hediffs = new List(); + + /// + /// 从池中随机抽取指定数量的 Hediff + /// + /// 抽取数量 + /// 是否允许重复 + /// 抽取的 Hediff 列表 + public List DrawRandom(int count, bool allowDuplicates = false) + { + var result = new List(); + + if (hediffs == null || hediffs.Count == 0 || count <= 0) + return result; + + if (allowDuplicates) + { + // 允许重复:直接随机抽取 + for (int i = 0; i < count; i++) + { + result.Add(hediffs.RandomElement()); + } + } + else + { + // 不允许重复:从可用列表中移除已抽取的 + var available = new List(hediffs); + int actualCount = Mathf.Min(count, available.Count); + + for (int i = 0; i < actualCount; i++) + { + var selected = available.RandomElement(); + result.Add(selected); + available.Remove(selected); + } + } + + return result; + } + } + + /// + /// 从池中抽取的规则 + /// + public class PoolDrawRule + { + /// 从哪个池抽取(池ID) + public string poolId; + + /// 抽取数量 + public int count = 1; + + /// 是否允许重复抽取同一个 Hediff + public bool allowDuplicates = false; + } + + /// + /// 品质阶段配置 - 定义某个品质范围内的抽取规则 + /// + public class QualityTier + { + /// 阶段编号 (1-7) + public int tier; + + /// 最低品质阈值 (0-1),包含 + public float minQuality; + + /// 最高品质阈值 (0-1),不包含(除非是最后一个阶段) + public float maxQuality; + + /// 阶段标签,如 "劣质", "普通", "传奇" + public string tierLabel; + + /// 消息翻译键,孵化完成时显示 + public string messageKey; + + /// 该阶段的抽取规则列表(可从多个池抽取) + public List drawRules = new List(); + + /// + /// 检查品质值是否属于该阶段 + /// + public bool Contains(float quality) + { + return quality >= minQuality && quality < maxQuality; + } + } + + /// + /// 分层特质奖励配置的 Def 类 + /// 定义特质池和品质阶段规则,可被多个建筑共享 + /// + public class TieredHediffRewardDef : Def + { + // === 特质池定义 === + /// 所有特质池列表 + public List hediffPools = new List(); + + // === 品质阶段定义 === + /// 所有品质阶段列表 + public List qualityTiers = new List(); + + // === 缓存 === + private Dictionary poolCache; + + /// + /// 配置错误检查 + /// + public override IEnumerable ConfigErrors() + { + foreach (var error in base.ConfigErrors()) + yield return error; + + if (hediffPools == null || hediffPools.Count == 0) + yield return "hediffPools is empty"; + + if (qualityTiers == null || qualityTiers.Count == 0) + yield return "qualityTiers is empty"; + + // 检查池ID是否重复 + var poolIds = new HashSet(); + foreach (var pool in hediffPools) + { + if (string.IsNullOrEmpty(pool.poolId)) + yield return "A hediffPool has empty poolId"; + else if (!poolIds.Add(pool.poolId)) + yield return $"Duplicate poolId: {pool.poolId}"; + } + + // 检查阶段配置 + foreach (var tier in qualityTiers) + { + if (tier.minQuality >= tier.maxQuality) + yield return $"Tier {tier.tier}: minQuality ({tier.minQuality}) >= maxQuality ({tier.maxQuality})"; + + if (tier.drawRules != null) + { + foreach (var rule in tier.drawRules) + { + if (!poolIds.Contains(rule.poolId)) + yield return $"Tier {tier.tier}: references unknown poolId '{rule.poolId}'"; + } + } + } + } + + /// + /// 解析引用后的初始化 + /// + public override void ResolveReferences() + { + base.ResolveReferences(); + + // 构建池缓存 + poolCache = new Dictionary(); + if (hediffPools != null) + { + foreach (var pool in hediffPools) + { + if (!string.IsNullOrEmpty(pool.poolId)) + { + poolCache[pool.poolId] = pool; + } + } + } + + // 按 minQuality 排序阶段 + qualityTiers?.Sort((a, b) => a.minQuality.CompareTo(b.minQuality)); + } + + /// + /// 根据池ID获取特质池 + /// + public HediffPool GetPool(string poolId) + { + if (poolCache != null && poolCache.TryGetValue(poolId, out var pool)) + return pool; + + return hediffPools?.Find(p => p.poolId == poolId); + } + + /// + /// 根据品质百分比获取对应阶段 + /// + public QualityTier GetTierForQuality(float quality) + { + if (qualityTiers == null || qualityTiers.Count == 0) + return null; + + // 限制在 0-1.5 范围 (支持150%品质上限) + quality = Mathf.Clamp(quality, 0f, 1.5f); + + foreach (var tier in qualityTiers) + { + if (tier.Contains(quality)) + return tier; + } + + // 如果是 100%,返回最后一个阶段 + if (quality >= 1f) + return qualityTiers[qualityTiers.Count - 1]; + + return null; + } + + /// + /// 根据品质抽取 Hediff 奖励 + /// + /// 品质值 (0-1) + /// 抽取的 Hediff 列表 + public List DrawRewardsForQuality(float quality) + { + var result = new List(); + var tier = GetTierForQuality(quality); + + if (tier?.drawRules == null) + return result; + + foreach (var rule in tier.drawRules) + { + var pool = GetPool(rule.poolId); + if (pool == null) + { + Log.Warning($"[TieredHediffReward] Pool '{rule.poolId}' not found in def '{defName}'"); + continue; + } + + var drawn = pool.DrawRandom(rule.count, rule.allowDuplicates); + result.AddRange(drawn); + } + + return result; + } + + /// + /// 获取品质阶段的描述文本 + /// + public string GetTierDescription(float quality) + { + var tier = GetTierForQuality(quality); + if (tier == null) + return null; + + return tier.tierLabel ?? $"阶段 {tier.tier}"; + } + + /// + /// 获取品质阶段的消息 + /// + public string GetTierMessage(float quality) + { + var tier = GetTierForQuality(quality); + if (tier == null || string.IsNullOrEmpty(tier.messageKey)) + return null; + + return tier.messageKey.Translate(); + } + } +} diff --git a/Source/ArachnaeSwarm/Buildings/Building_Ootheca/Building_Ootheca.cs b/Source/ArachnaeSwarm/Buildings/Building_Ootheca/Building_Ootheca.cs index 05adacb..e6c472e 100644 --- a/Source/ArachnaeSwarm/Buildings/Building_Ootheca/Building_Ootheca.cs +++ b/Source/ArachnaeSwarm/Buildings/Building_Ootheca/Building_Ootheca.cs @@ -341,7 +341,8 @@ namespace ArachnaeSwarm // 品质增长(新公式:50%通量时与进度同步) float qualityGain = IncubatorUtils.CalculateQualityGainNew(fluxSpeed, neutronFlux); - qualityProgress = Mathf.Min(qualityProgress + qualityGain, qualityTotal); + // 不限制上限,允许超过100%(最高150%) + qualityProgress += qualityGain; } if (incubationProgress >= incubationDuration) @@ -405,10 +406,8 @@ namespace ArachnaeSwarm private void ApplyHediffRewards(Pawn pawn, float qualityPercent) { - var config = IncubatorData?.SelectedConfig; - if (config == null) return; - - List rewardHediffs = config.GetRewardHediffs(qualityPercent); + // 使用新的分层奖励系统(优先)或回退到旧系统 + List rewardHediffs = IncubatorData?.DrawRewardsForQuality(qualityPercent); if (rewardHediffs == null || rewardHediffs.Count == 0) return; int appliedCount = 0; @@ -424,9 +423,17 @@ namespace ArachnaeSwarm if (appliedCount > 0) { - string message = config.GetRewardMessage(qualityPercent); + // 使用分层系统的消息 + var tier = IncubatorData?.GetTierForQuality(qualityPercent); + string message = null; + if (tier != null && !string.IsNullOrEmpty(tier.messageKey)) + { + message = tier.messageKey.Translate(pawn.LabelShortCap, appliedCount); + } if (string.IsNullOrEmpty(message)) + { message = "ARA_QualityReward_Default".Translate(pawn.LabelShortCap, appliedCount); + } Messages.Message(message, pawn, MessageTypeDefOf.PositiveEvent); } } diff --git a/Source/ArachnaeSwarm/Buildings/Building_Ootheca/CompProperties_IncubatorData.cs b/Source/ArachnaeSwarm/Buildings/Building_Ootheca/CompProperties_IncubatorData.cs index a887979..0028688 100644 --- a/Source/ArachnaeSwarm/Buildings/Building_Ootheca/CompProperties_IncubatorData.cs +++ b/Source/ArachnaeSwarm/Buildings/Building_Ootheca/CompProperties_IncubatorData.cs @@ -247,7 +247,10 @@ namespace ArachnaeSwarm public string menuTitle = "IncubatorMenuTitle"; // 菜单标题翻译键 public string defaultIconPath = "UI/Commands/Default"; - // === 新增:全局Hediff奖励(所有配置共享)=== + // === 新增:分层奖励Def引用(推荐使用)=== + public TieredHediffRewardDef rewardDef; + + // === 旧版:全局Hediff奖励(保留向后兼容)=== public List globalExtraHediffs = new List(); public List globalHediffRewards = new List(); @@ -336,6 +339,9 @@ namespace ArachnaeSwarm // 公开获取孵化配置列表的方法 public List IncubationConfigs => Props?.incubationConfigs ?? new List(); + // 获取奖励 Def(新系统) + public TieredHediffRewardDef RewardDef => Props?.rewardDef; + // 获取当前选择的配置 public IncubationConfig SelectedConfig { @@ -493,5 +499,73 @@ namespace ArachnaeSwarm return builder.ToString().TrimEndNewlines(); } + + // === 新增:使用分层系统抽取奖励 === + + /// + /// 根据品质抽取 Hediff 奖励(优先使用新的分层系统) + /// + /// 品质值 (0-1.5,支持150%上限) + /// 抽取的 Hediff 列表 + public List DrawRewardsForQuality(float quality) + { + // 优先使用新的分层奖励系统 + if (RewardDef != null) + { + return RewardDef.DrawRewardsForQuality(quality); + } + + // 回退到旧系统 + var config = SelectedConfig; + if (config != null) + { + return config.GetRewardHediffs(quality); + } + + return new List(); + } + + /// + /// 获取品质对应的阶段信息(仅新系统可用) + /// + public QualityTier GetTierForQuality(float quality) + { + return RewardDef?.GetTierForQuality(quality); + } + + /// + /// 获取奖励系统的描述文本 + /// + public string GetRewardSystemDescription() + { + if (RewardDef == null) + return GetHediffRewardDescription(); // 回退到旧描述 + + var builder = new StringBuilder(); + builder.AppendLine("ARA_TieredReward_Title".Translate()); + builder.AppendLine(); + + // 显示各阶段信息 + if (RewardDef.qualityTiers != null) + { + foreach (var tier in RewardDef.qualityTiers) + { + string qualityRange = $"{tier.minQuality:P0} - {tier.maxQuality:P0}"; + builder.AppendLine($" {tier.tierLabel ?? $"阶段{tier.tier}"}: {qualityRange}"); + + if (tier.drawRules != null) + { + foreach (var rule in tier.drawRules) + { + var pool = RewardDef.GetPool(rule.poolId); + string poolLabel = pool?.label ?? rule.poolId; + builder.AppendLine($" - {poolLabel} x{rule.count}"); + } + } + } + } + + return builder.ToString().TrimEndNewlines(); + } } }