diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 2432d37..55e30fe 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/BodyAndPartDefs/ARA_Bodyparts.xml b/1.6/1.6/Defs/BodyAndPartDefs/ARA_Bodyparts.xml index b92231a..68c5f04 100644 --- a/1.6/1.6/Defs/BodyAndPartDefs/ARA_Bodyparts.xml +++ b/1.6/1.6/Defs/BodyAndPartDefs/ARA_Bodyparts.xml @@ -587,6 +587,535 @@ + + ArachnaeQueen_Neurotyrant_Body + + + Torso + Middle + Outside + +
  • Torso
  • +
    + + +
  • + ARA_Dorsum + 0.14 + +
  • Torso
  • + + + +
  • + ARA_Chitin_Shell + 背部甲片 + 0.02 + Outside + +
  • Torso
  • + + + +
  • + ARA_Exoskeleton_Dorsum + 0.016 + Inside + +
  • Torso
  • + + +
    + + +
  • + ARA_Sternum + 0.15 + +
  • Torso
  • + + + +
  • + ARA_Exoskeleton_Sternum + 0.015 + Outside + +
  • Torso
  • + + + +
  • + Heart + 0.020 + Inside + +
  • Torso
  • + + + +
  • + Stomach + 0.025 + Inside + +
  • Torso
  • + + + +
  • + Lung + 左肺(其一) + 0.025 + Inside + +
  • Torso
  • + + +
  • + Lung + 左肺(其二) + 0.025 + Inside + +
  • Torso
  • + + +
  • + Lung + 右肺(其一) + 0.025 + Inside + +
  • Torso
  • + + +
  • + Lung + 右肺(其二) + 0.025 + Inside + +
  • Torso
  • + + + +
  • + Kidney + 左肾 + 0.017 + Inside + +
  • Torso
  • + + +
  • + Kidney + 右肾 + 0.017 + Inside + +
  • Torso
  • + + + +
  • + Liver + 0.025 + 肝脏(其一) + Inside + +
  • Torso
  • + + +
  • + Liver + 肝脏(其二) + 0.025 + Inside + +
  • Torso
  • + + +
    + + +
  • + ARA_Tail + Bottom + Inside + 0.15 + +
  • Torso
  • +
  • Legs
  • + + + +
  • + ARA_Chitin_Shell + 尾部甲片 + 0.01 + Outside + +
  • Torso
  • + + + +
  • + ARA_Gonad + 0.005 + Inside + +
  • ARA_Genitalias
  • + + + +
  • + ARA_Ovary + 0.01 + Inside + +
  • ARA_Genitalias
  • + + +
    + + +
  • + Neck + 0.075 + Top + +
  • Neck
  • + + +
  • + Head + 0.80 + +
  • UpperHead
  • +
  • FullHead
  • +
  • HeadAttackTool
  • + + + +
  • + ARA_Chitin_Shell + 头部甲片 + 0.02 + Outside + +
  • UpperHead
  • + + + +
  • + ARA_Psy_Nerve_Tract + 第一神经束 + 0.05 + Inside + +
  • ARA_Psy_Nerve_Tracts
  • + + +
  • + ARA_Psy_Nerve_Tract + 第二神经束 + 0.05 + Inside + +
  • ARA_Psy_Nerve_Tracts
  • + + +
  • + ARA_Psy_Nerve_Tract + 第三神经束 + 0.05 + Inside + +
  • ARA_Psy_Nerve_Tracts
  • + + +
  • + ARA_Psy_Nerve_Tract + 第四神经束 + 0.05 + Inside + +
  • ARA_Psy_Nerve_Tracts
  • + + +
  • + ARA_Psy_Nerve_Tract + 第四神经束 + 0.05 + Inside + +
  • ARA_Psy_Nerve_Tracts
  • + + +
  • + ARA_Psy_Nerve_Tract + 第五神经束 + 0.05 + Inside + +
  • ARA_Psy_Nerve_Tracts
  • + + +
  • + ARA_Psy_Nerve_Tract + 第六四神经束 + 0.05 + Inside + +
  • ARA_Psy_Nerve_Tracts
  • + + +
  • + ARA_Psy_Nerve_Tract + 第七神经束 + 0.05 + Inside + +
  • ARA_Psy_Nerve_Tracts
  • + + +
  • + ARA_Psy_Nerve_Tract + 第八神经束 + 0.05 + Inside + +
  • ARA_Psy_Nerve_Tracts
  • + + + +
  • + Skull + 0.18 + Inside + +
  • UpperHead
  • +
  • Eyes
  • +
  • FullHead
  • + + +
  • + Brain + 0.8 + +
  • UpperHead
  • +
  • Eyes
  • +
  • FullHead
  • + + +
    + +
  • + Eye + left eye + 0.07 + +
  • FullHead
  • +
  • Eyes
  • + + LeftEye + true + +
  • South
  • +
  • West
  • +
    + +
  • + Eye + right eye + 0.07 + +
  • FullHead
  • +
  • Eyes
  • + + RightEye + +
  • South
  • +
  • East
  • +
    + +
  • + Ear + left ear + 0.07 + true + +
  • UpperHead
  • +
  • FullHead
  • + + +
  • + Ear + right ear + 0.07 + +
  • UpperHead
  • +
  • FullHead
  • + + +
  • + Nose + 0.10 + +
  • FullHead
  • + + +
  • + Jaw + 0.15 + +
  • Teeth
  • +
  • FullHead
  • +
  • Mouth
  • + + +
  • + Tongue + 0.001 + Inside + +
  • FullHead
  • + + +
    + +
    + +
    + + +
  • + Shoulder + 左副肢关节 + 0.12 + LeftShoulder + true + +
  • Shoulders
  • + + +
  • + Clavicle + 左副肢外骨骼 + 0.09 + Top + Outside + true + +
  • Shoulders
  • + + +
  • + Arm + 左副肢 + 0.77 + true + +
  • Arms
  • + + +
  • + Hand + 左鳌钳 + 0.14 + Bottom + true + +
  • Hands
  • +
  • HeadClaw
  • + + +
  • + Finger + 右鳌钳口 + 0.14 + +
  • Hands
  • +
  • LeftHand
  • + + +
    + +
    + +
    + +
  • + Shoulder + 右副肢关节 + 0.12 + LeftShoulder + true + +
  • Shoulders
  • + + +
  • + Clavicle + 右副肢外骨骼 + 0.09 + Top + Outside + true + +
  • Shoulders
  • + + +
  • + Arm + 右副肢 + 0.77 + true + +
  • Arms
  • + + +
  • + Hand + 右鳌钳 + 0.14 + Bottom + true + +
  • Hands
  • +
  • HeadClaw
  • + + +
  • + Finger + 右鳌钳口 + 0.14 + +
  • Hands
  • +
  • RightHand
  • + + +
    + +
    + +
    + + +
  • + Waist + 体节分界 + 0 + Bottom + +
  • Waist
  • + + +
    +
    +
    ARA_Dorsum @@ -709,6 +1238,9 @@ true false 0 + +
  • ARA_Psy_Source
  • +
    ARA_Pouch diff --git a/1.6/1.6/Defs/PawnCapacityDefs/ARA_PawnCapacity.xml b/1.6/1.6/Defs/PawnCapacityDefs/ARA_PawnCapacity.xml new file mode 100644 index 0000000..1f5a299 --- /dev/null +++ b/1.6/1.6/Defs/PawnCapacityDefs/ARA_PawnCapacity.xml @@ -0,0 +1,9 @@ + + + + ARA_PsychicStange + + 60 + ArachnaeSwarm.PawnCapacityWorker_PsychicStange + + diff --git a/1.6/1.6/Defs/PawnKindDef/ARA_PawnKinds.xml b/1.6/1.6/Defs/PawnKindDef/ARA_PawnKinds.xml index b16c938..f312823 100644 --- a/1.6/1.6/Defs/PawnKindDef/ARA_PawnKinds.xml +++ b/1.6/1.6/Defs/PawnKindDef/ARA_PawnKinds.xml @@ -662,8 +662,8 @@
  • - ArachnaeSwarm/Things/ARA_Baneling/BodiesEmp/Naked_Thin - 1 + ArachnaeSwarm/Things/ARA_Acidcut/Bodies/Naked_Thin + 1.75 (0.4, 0.5, 0.37) (0,0,-0.15) diff --git a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceQueen.xml b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceQueen.xml index 08aff34..3ff3e99 100644 --- a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceQueen.xml +++ b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceQueen.xml @@ -877,7 +877,7 @@ - ArachnaeQueen_Body + ArachnaeQueen_Neurotyrant_Body 5 4 true diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo index ba92dd4..1f6eb90 100644 Binary files a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo and b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo differ diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json index 4b84934..da053b2 100644 --- a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json +++ b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json @@ -2,6 +2,10 @@ "Version": 1, "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\\pawncapacityworker\\pawncapacityworker_psychicstange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawncapacityworker\\pawncapacityworker_psychicstange.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\\pawn_comps\\ara_swarmspellholder\\gizmo_swarmspellstatus.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_swarmspellholder\\gizmo_swarmspellstatus.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" @@ -42,7 +46,7 @@ "DocumentGroups": [ { "DockedWidth": 200, - "SelectedChildIndex": 2, + "SelectedChildIndex": 1, "Children": [ { "$type": "Bookmark", @@ -50,7 +54,20 @@ }, { "$type": "Document", - "DocumentIndex": 4, + "DocumentIndex": 0, + "Title": "PawnCapacityWorker_PsychicStange.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PawnCapacityWorker\\PawnCapacityWorker_PsychicStange.cs", + "RelativeDocumentMoniker": "PawnCapacityWorker\\PawnCapacityWorker_PsychicStange.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PawnCapacityWorker\\PawnCapacityWorker_PsychicStange.cs", + "RelativeToolTip": "PawnCapacityWorker\\PawnCapacityWorker_PsychicStange.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABMAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-02-03T07:42:21.662Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 5, "Title": "CompProperties_AbilityPsychicLoadCost.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadCost\\CompProperties_AbilityPsychicLoadCost.cs", "RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadCost\\CompProperties_AbilityPsychicLoadCost.cs", @@ -62,20 +79,20 @@ }, { "$type": "Document", - "DocumentIndex": 0, + "DocumentIndex": 1, "Title": "Gizmo_SwarmSpellStatus.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_SwarmSpellHolder\\Gizmo_SwarmSpellStatus.cs", "RelativeDocumentMoniker": "Pawn_Comps\\ARA_SwarmSpellHolder\\Gizmo_SwarmSpellStatus.cs", "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_SwarmSpellHolder\\Gizmo_SwarmSpellStatus.cs", "RelativeToolTip": "Pawn_Comps\\ARA_SwarmSpellHolder\\Gizmo_SwarmSpellStatus.cs", - "ViewState": "AgIAAGcAAAAAAAAAAAAMwHMAAABAAAAAAAAAAA==", + "ViewState": "AgIAAGcAAAAAAAAAAAAMwHwAAAAgAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2026-01-30T08:20:07.463Z", "EditorCaption": "" }, { "$type": "Document", - "DocumentIndex": 2, + "DocumentIndex": 3, "Title": "CompAbilityEffect_PsychicLoadCost.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadCost\\CompAbilityEffect_PsychicLoadCost.cs", "RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadCost\\CompAbilityEffect_PsychicLoadCost.cs", @@ -87,7 +104,7 @@ }, { "$type": "Document", - "DocumentIndex": 5, + "DocumentIndex": 6, "Title": "CompAbilityEffect_PsychicBrainburn.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\PsychicBrainburn\\CompAbilityEffect_PsychicBrainburn.cs", "RelativeDocumentMoniker": "Abilities\\PsychicBrainburn\\CompAbilityEffect_PsychicBrainburn.cs", @@ -99,7 +116,7 @@ }, { "$type": "Document", - "DocumentIndex": 1, + "DocumentIndex": 2, "Title": "ARA_DefOf.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_DefOf.cs", "RelativeDocumentMoniker": "ARA_DefOf.cs", @@ -111,7 +128,7 @@ }, { "$type": "Document", - "DocumentIndex": 3, + "DocumentIndex": 4, "Title": "Comp_SwarmSpellHolder.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_SwarmSpellHolder\\Comp_SwarmSpellHolder.cs", "RelativeDocumentMoniker": "Pawn_Comps\\ARA_SwarmSpellHolder\\Comp_SwarmSpellHolder.cs", @@ -123,7 +140,7 @@ }, { "$type": "Document", - "DocumentIndex": 6, + "DocumentIndex": 7, "Title": "SwarmSpellUtility.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_SwarmSpellHolder\\SwarmSpellUtility.cs", "RelativeDocumentMoniker": "Pawn_Comps\\ARA_SwarmSpellHolder\\SwarmSpellUtility.cs", @@ -135,7 +152,7 @@ }, { "$type": "Document", - "DocumentIndex": 7, + "DocumentIndex": 8, "Title": "CompAutoMechCarrier.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs", "RelativeDocumentMoniker": "Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs", diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index de1044a..ef3330e 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -332,6 +332,7 @@ + diff --git a/Source/ArachnaeSwarm/PawnCapacityWorker/PawnCapacityWorker_PsychicStange.cs b/Source/ArachnaeSwarm/PawnCapacityWorker/PawnCapacityWorker_PsychicStange.cs new file mode 100644 index 0000000..54972d3 --- /dev/null +++ b/Source/ArachnaeSwarm/PawnCapacityWorker/PawnCapacityWorker_PsychicStange.cs @@ -0,0 +1,354 @@ +using RimWorld; +using System.Collections.Generic; +using Verse; + +namespace ArachnaeSwarm +{ + /// + /// 灵能稳定性(Psychic Stange)的能力计算器 + /// 基于ARA_Psy_Source标签的部件效率和意识水平 + /// + public class PawnCapacityWorker_PsychicStange : PawnCapacityWorker + { + #region 字段 + // 定义我们需要的BodyPartTagDef + private static BodyPartTagDef PsySourceTagDef = null; + + // 用于缓存的Consciousness容量Def + private static PawnCapacityDef ConsciousnessDef = null; + #endregion + + #region 初始化 + /// + /// 确保标签Def已初始化 + /// + private void EnsureTagDefsInitialized() + { + if (PsySourceTagDef == null) + { + // 尝试从DefDatabase获取标签定义 + PsySourceTagDef = DefDatabase.GetNamedSilentFail("ARA_Psy_Source"); + + if (PsySourceTagDef == null) + { + Log.Warning("[虫群术法] 未找到ARA_Psy_Source的BodyPartTagDef定义"); + // 创建一个临时的标签定义以避免空引用 + PsySourceTagDef = new BodyPartTagDef + { + defName = "ARA_Psy_Source", + label = "Psychic Source" + }; + } + } + + if (ConsciousnessDef == null) + { + ConsciousnessDef = DefDatabase.GetNamedSilentFail("Consciousness"); + if (ConsciousnessDef == null) + { + // 如果找不到Consciousness,使用默认的 + ConsciousnessDef = PawnCapacityDefOf.Consciousness; + } + } + } + #endregion + + #region 主要计算方法 + /// + /// 计算灵能稳定性容量水平 + /// + public override float CalculateCapacityLevel(HediffSet diffSet, List impactors = null) + { + // 确保标签Def已初始化 + EnsureTagDefsInitialized(); + + // 如果没有意识能力,直接返回0 + if (!diffSet.pawn.health.capacities.CapableOf(ConsciousnessDef)) + { + // 如果有传入impactors,记录影响因子 + if (impactors != null) + { + impactors.Add(new PawnCapacityUtility.CapacityImpactorCapacity + { + capacity = ConsciousnessDef + }); + } + return 0f; + } + + // 获取意识水平 + float consciousnessLevel = diffSet.pawn.health.capacities.GetLevel(ConsciousnessDef); + if (consciousnessLevel <= 0f) + { + if (impactors != null) + { + impactors.Add(new PawnCapacityUtility.CapacityImpactorCapacity + { + capacity = ConsciousnessDef + }); + } + return 0f; + } + + // 计算ARA_Psy_Source标签部件的平均效率 + float psySourceEfficiency = CalculatePsySourceEfficiency(diffSet, impactors); + + // 最终容量 = 灵能源效率 × 意识水平 + float finalCapacity = psySourceEfficiency * consciousnessLevel; + + // 如果有传入impactors,记录最终影响 + if (impactors != null && finalCapacity < 1f) + { + // 如果灵能源效率不是100%,记录它 + if (psySourceEfficiency < 1f) + { + // 注意:这里我们需要使用自定义的CapacityImpactor来记录灵能源的影响 + // 由于PawnCapacityUtility.CalculateTagEfficiency不直接返回影响器列表, + // 我们需要自己创建影响器 + RecordPsySourceImpactors(diffSet, impactors); + } + + // 如果意识水平不是100%,记录它 + if (consciousnessLevel < 1f) + { + impactors.Add(new PawnCapacityUtility.CapacityImpactorCapacity + { + capacity = ConsciousnessDef + }); + } + } + + return finalCapacity; + } + + /// + /// 计算灵能源标签部件的效率 + /// + private float CalculatePsySourceEfficiency(HediffSet diffSet, List impactors = null) + { + if (PsySourceTagDef == null) + return 0f; + + // 使用PawnCapacityUtility.CalculateTagEfficiency计算标签部件的平均效率 + // 这里我们使用默认的最大值和范围 + float efficiency = PawnCapacityUtility.CalculateTagEfficiency( + diffSet, + PsySourceTagDef, + maximum: float.MaxValue, + lerp: default(FloatRange), + impactors: impactors + ); + + return efficiency; + } + + /// + /// 记录灵能源部件的影响器 + /// + private void RecordPsySourceImpactors(HediffSet diffSet, List impactors) + { + if (diffSet == null || diffSet.pawn == null || diffSet.pawn.RaceProps?.body == null) + return; + + // 获取所有带有ARA_Psy_Source标签的部件 + var partsWithTag = diffSet.pawn.RaceProps.body.GetPartsWithTag(PsySourceTagDef); + + foreach (var part in partsWithTag) + { + // 检查部件是否缺失或受损 + if (diffSet.PartIsMissing(part)) + { + // 部件缺失 + impactors.Add(new PawnCapacityUtility.CapacityImpactorBodyPartHealth + { + bodyPart = part + }); + } + else + { + // 检查部件的健康百分比 + float partHealth = diffSet.GetPartHealth(part); + float partMaxHealth = part.def.GetMaxHealth(diffSet.pawn); + float healthPercent = partHealth / partMaxHealth; + + if (healthPercent < 1f) + { + // 部件受损 + impactors.Add(new PawnCapacityUtility.CapacityImpactorBodyPartHealth + { + bodyPart = part + }); + } + } + } + } + #endregion + + #region 容量可用性检查 + /// + /// 检查身体定义是否可以拥有此容量 + /// 只有当身体拥有ARA_Psy_Source标签的部件时才显示 + /// + public override bool CanHaveCapacity(BodyDef body) + { + // 确保标签Def已初始化 + EnsureTagDefsInitialized(); + + if (PsySourceTagDef == null || body == null) + return false; + + // 检查身体是否拥有带有ARA_Psy_Source标签的部件 + return body.HasPartWithTag(PsySourceTagDef); + } + #endregion + + #region 工具方法 + /// + /// 获取详细的能力影响描述 + /// + public string GetDetailedCapacityInfo(HediffSet diffSet) + { + EnsureTagDefsInitialized(); + + if (!CanHaveCapacity(diffSet.pawn.RaceProps.body)) + { + return "此单位没有灵能源部件,无法拥有灵能稳定性能力。"; + } + + float consciousnessLevel = diffSet.pawn.health.capacities.GetLevel(ConsciousnessDef); + float psySourceEfficiency = CalculatePsySourceEfficiency(diffSet, null); + float finalCapacity = psySourceEfficiency * consciousnessLevel; + + var partsWithTag = diffSet.pawn.RaceProps.body.GetPartsWithTag(PsySourceTagDef); + int totalParts = 0; + int functionalParts = 0; + int missingParts = 0; + int damagedParts = 0; + + foreach (var part in partsWithTag) + { + totalParts++; + + if (diffSet.PartIsMissing(part)) + { + missingParts++; + } + else + { + float partHealth = diffSet.GetPartHealth(part); + float partMaxHealth = part.def.GetMaxHealth(diffSet.pawn); + + if (partHealth < partMaxHealth) + { + damagedParts++; + } + else + { + functionalParts++; + } + } + } + + string result = $"灵能稳定性: {finalCapacity:P0}\n"; + result += $" 意识水平: {consciousnessLevel:P0}\n"; + result += $" 灵能源效率: {psySourceEfficiency:P0}\n"; + result += $" 灵能源部件: {totalParts}个 (正常: {functionalParts}, 受损: {damagedParts}, 缺失: {missingParts})"; + + return result; + } + + /// + /// 检查是否所有灵能源部件都完整 + /// + public bool AreAllPsySourcesIntact(HediffSet diffSet) + { + EnsureTagDefsInitialized(); + + if (PsySourceTagDef == null || diffSet.pawn.RaceProps?.body == null) + return false; + + var partsWithTag = diffSet.pawn.RaceProps.body.GetPartsWithTag(PsySourceTagDef); + + foreach (var part in partsWithTag) + { + if (diffSet.PartIsMissing(part)) + return false; + + float partHealth = diffSet.GetPartHealth(part); + float partMaxHealth = part.def.GetMaxHealth(diffSet.pawn); + + if (partHealth < partMaxHealth) + return false; + } + + return true; + } + + /// + /// 获取灵能源部件的总健康百分比 + /// + public float GetTotalPsySourceHealthPercent(HediffSet diffSet) + { + EnsureTagDefsInitialized(); + + if (PsySourceTagDef == null || diffSet.pawn.RaceProps?.body == null) + return 0f; + + var partsWithTag = diffSet.pawn.RaceProps.body.GetPartsWithTag(PsySourceTagDef); + + if (partsWithTag.Count == 0) + return 0f; + + float totalHealth = 0f; + float totalMaxHealth = 0f; + + foreach (var part in partsWithTag) + { + float partMaxHealth = part.def.GetMaxHealth(diffSet.pawn); + totalMaxHealth += partMaxHealth; + + if (!diffSet.PartIsMissing(part)) + { + float partHealth = diffSet.GetPartHealth(part); + totalHealth += partHealth; + } + } + + if (totalMaxHealth <= 0f) + return 0f; + + return totalHealth / totalMaxHealth; + } + + /// + /// 获取功能正常的灵能源部件数量 + /// + public int GetFunctionalPsySourceCount(HediffSet diffSet) + { + EnsureTagDefsInitialized(); + + if (PsySourceTagDef == null || diffSet.pawn.RaceProps?.body == null) + return 0; + + var partsWithTag = diffSet.pawn.RaceProps.body.GetPartsWithTag(PsySourceTagDef); + int functionalCount = 0; + + foreach (var part in partsWithTag) + { + if (!diffSet.PartIsMissing(part)) + { + float partHealth = diffSet.GetPartHealth(part); + float partMaxHealth = part.def.GetMaxHealth(diffSet.pawn); + + if (partHealth >= partMaxHealth) + { + functionalCount++; + } + } + } + + return functionalCount; + } + #endregion + } +}