diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index 42a2b3f8..7e3379b1 100644 Binary files a/1.6/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/1.6/Assemblies/WulaFallenEmpire.dll differ diff --git a/1.6/1.6/Defs/BackstoryDefs/Solid/Solid_Adult_WULA.xml b/1.6/1.6/Defs/BackstoryDefs/Solid/Solid_Adult_WULA.xml index 3d6b47ec..5e9da4c8 100644 --- a/1.6/1.6/Defs/BackstoryDefs/Solid/Solid_Adult_WULA.xml +++ b/1.6/1.6/Defs/BackstoryDefs/Solid/Solid_Adult_WULA.xml @@ -1092,4 +1092,4 @@ - + \ No newline at end of file diff --git a/1.6/1.6/Defs/BackstoryDefs/Solid/Solid_Child_WULA.xml b/1.6/1.6/Defs/BackstoryDefs/Solid/Solid_Child_WULA.xml index e27ffb9f..60ee8429 100644 --- a/1.6/1.6/Defs/BackstoryDefs/Solid/Solid_Child_WULA.xml +++ b/1.6/1.6/Defs/BackstoryDefs/Solid/Solid_Child_WULA.xml @@ -4,9 +4,9 @@ WULA_Child_Backstory01 False Childhood - 产地: - - [PAWN_nameDef] 是诞生于乌拉帝国的合成人。 + 产地:科鲁普 + 科鲁普 + [PAWN_nameDef] 是产自科鲁普星区的合成人。这片星区是一个四战之地——由于其地处边缘且地缘政治复杂,乌拉帝国从未真正掌控这片星区,但是此处优秀的稀有水晶和异星天然气使得帝国不愿放弃此星区的掌控。\n\n在此处生产的合成人使用的战略物资远高于其他星区,这使得其拥有更高的机体耐久和更低的能量消耗。 3 3 @@ -16,15 +16,28 @@ None -
  • Wula_Synth
  • -
  • WULA_Addons_Antenna_Hediff_Base
  • - +
  • WULA_Child_Backstory01_Hediff
  • -
  • - WULA_BrokenPersonalityTrait - 100 -
  • - + + WULA_Child_Backstory01_Hediff + + [PAWN_nameDef] 是产自科鲁普星区的合成人。这片星区是一个四战之地——由于其地处边缘且地缘政治复杂,乌拉帝国从未真正掌控这片星区,但是此处优秀的稀有水晶和异星天然气使得帝国不愿放弃此星区的掌控。\n\n在此处生产的合成人使用的战略物资远高于其他星区,这使得其拥有更高的机体耐久和更低的能量消耗。 + HediffWithComps + false + false + True + false + +
  • +
  • +
    + +
  • + 0.0025 +
  • +
    +
    + \ No newline at end of file diff --git a/1.6/1.6/Defs/StatDefs/WULA_Stats.xml b/1.6/1.6/Defs/StatDefs/WULA_Stats.xml index c61ff1bb..0097c01d 100644 --- a/1.6/1.6/Defs/StatDefs/WULA_Stats.xml +++ b/1.6/1.6/Defs/StatDefs/WULA_Stats.xml @@ -1,23 +1,126 @@ + + WULA_Synth + + 160 + + + WulaEnergyMaxLevelOffset 影响机械乌拉能量上限的偏移量。 - PawnMisc + WULA_Synth -1 1 PercentZero - WulaEnergyFallRateFactor 影响机械乌拉能量消耗速度的乘数因子。 - PawnMisc + WULA_Synth 1 0 PercentZero - + + + + WULA_NanoRepairCostPerHP + + 纳米修复系统修复每点生命值所消耗的能量。 + WULA_Synth + 0.1 + PercentZero + true + true + WulaFallenEmpire.StatWorker_NanoRepair + + + WULA_NanoRepairCooldownAfterDamage + + 受到伤害后纳米修复系统进入冷却的时间(秒)。 + WULA_Synth + 300 + Integer + true + true + WulaFallenEmpire.StatWorker_NanoRepair + + + + + WULA_MaintenanceDegradationFactor + + 乌拉帝国合成人维护需求退化速率的乘数。数值越高,机械乌拉越容易陷入低维护状态。 + WULA_Synth + 1.0 + FloatTwo + true + true + WulaFallenEmpire.StatWorker_Maintenance + + + WULA_MaintenanceStatusThresholdFactor + + 影响乌拉帝国合成人维护状态阈值的乘数。数值越高,越容易陷入低维护带来的减益状态。 + WULA_Synth + 1.0 + FloatTwo + true + true + WulaFallenEmpire.StatWorker_Maintenance + + + + WULA_MaintenanceDamageToMaintenanceFactor + + 乌拉帝国合成人因为伤害导致维护度损失的程度。数值越高,受到伤害时损失越多维护度。 + WULA_Synth + 0.01 + PercentZero + true + true + WulaFallenEmpire.StatWorker_Maintenance + + + + + WULA_MaintenanceMinorBreakdownThresholdFactor + + 影响乌拉帝国合成人进入轻微故障阈值的乘数。数值越高,越容易进入轻微故障状态。 + WULA_Synth + 1.0 + FloatTwo + true + true + WulaFallenEmpire.StatWorker_Maintenance + + + + WULA_MaintenanceMajorBreakdownThresholdFactor + + 影响乌拉帝国合成人进入严重故障阈值的乘数。数值越高,越容易进入严重故障状态。 + WULA_Synth + 1.0 + FloatTwo + true + true + WulaFallenEmpire.StatWorker_Maintenance + + + + WULA_MaintenanceCriticalFailureThresholdFactor + + 影响乌拉帝国合成人进入完全故障阈值的乘数。数值越高,越容易进入完全故障状态。 + WULA_Synth + 1.0 + FloatTwo + true + true + WulaFallenEmpire.StatWorker_Maintenance + + \ No newline at end of file diff --git a/1.6/1.6/Defs/ThingDefs_Misc/Apperals/WULA_Apparel.xml b/1.6/1.6/Defs/ThingDefs_Misc/Apperals/WULA_Apparel.xml index 5c36cee5..02d9afe8 100644 --- a/1.6/1.6/Defs/ThingDefs_Misc/Apperals/WULA_Apparel.xml +++ b/1.6/1.6/Defs/ThingDefs_Misc/Apperals/WULA_Apparel.xml @@ -1,61 +1,8 @@  - - - - Graphic_Single - CutoutComplex - - - UnfinishedApparel - false - WULA_Synth_Clothes_3_Technology - -
  • WULA_Cube_Productor_Energy
  • -
    - 225 -
    - 125 - -
  • Fabric
  • -
  • Leathery
  • -
    - -
  • ApparelNoble
  • -
    - - 15000 - 1 - 0.35 - 1 - 1 - 1.5 - - - -
  • Royal
  • -
  • Wula_Apparel
  • -
    - true - - - - false - - false - - false -
    - - -
  • - 10 - (1,1,1,1) -
  • -
    -
    -
    - + + 0 +
  • ApparelMisc
  • @@ -63,9 +10,67 @@ Graphic_Single CutoutComplex + + +
  • Wula_Apparel
  • +
    + +
  • Torso
  • +
    + +
  • Middle
  • +
    + false + false + false + true +
    + + +
  • + 10 + (1,1,1,1) +
  • +
    +
    + 1 + + UnfinishedApparel + false + + + 1 + 7000 + 0.35 + 1 + 1 + +
    + + +
  • ApparelNoble
  • +
  • Royal
  • +
    + true + false + false + false +
    + 50 +
    + + +
  • ApparelMisc
  • +
    + + Graphic_Single + CutoutComplex + + +
  • Wula_Apparel
  • @@ -88,20 +93,52 @@ UnfinishedApparel false - WULA_Synth_Clothes_3_Technology - -
  • WULA_Cube_Productor_Energy
  • -
    - 225
    - - 0.2 - 3000 - 0.35 - 1 - 1 -
    + + +
  • ApparelNoble
  • +
    + + +
  • Royal
  • +
    +
    + 50 +
    + + + Graphic_Single + CutoutComplex + + +
  • ApparelMisc
  • +
    + 0 + + + +
  • Wula_Apparel
  • +
  • Wula_Inner
  • +
    + +
  • Torso
  • +
    + +
  • OnSkin
  • +
    + false + false + false + true +
    + + UnfinishedApparel + GeneralLaborSpeed + false + +
    + WULA_Official_Uniform @@ -150,535 +187,6 @@ 1 - - - -
  • ApparelMisc
  • -
    - - Graphic_Single - CutoutComplex - - - -
  • Wula_Apparel_Init
  • -
  • Wula_Apparel
  • -
  • Wula_Clothes
  • -
    - false - false - false - true -
    - - -
  • - 10 - (1,1,1,1) -
  • -
    -
    - 1 - - UnfinishedApparel - false - - - 1 - 7000 - 0.35 - 1 - 1 - -
    - - -
  • ApparelMisc
  • -
    - - Graphic_Single - CutoutComplex - - - -
  • Wula_Apparel
  • -
  • Wula_Clothes
  • -
    - -
  • None
  • -
    - false - false - false - true -
    - - -
  • - 10 - (1,1,1,1) -
  • -
    -
    - 1 - - UnfinishedApparel - false - - - 0.2 - 3000 - 0.35 - 1 - 1 - -
    - - WULA_Sailor_Dress - - 这是乌拉帝国的一款连衣裙,上到贵族下到平民都可以穿,在肃穆的帝国中传递出了一丝俏皮和活泼。 - - Wula/Apparel/WULA_Sailor_Dress - - - -
  • Torso
  • - -
  • Arms
  • -
  • Legs
  • -
    - - -
  • Middle
  • -
    - Wula/Apparel/WULA_Sailor_Dress -
    - 100 - -
  • Fabric
  • -
  • Leathery
  • -
    - - 0.1 - 0.15 - - - - WULA_Synth_Clothes_Technology - -
  • WULA_Cube_Productor_Energy
  • -
    - GeneralLaborSpeed - - 3 - -
    -
    - - WULA_Maid_Uniform - - 乌拉帝国平民所穿的女仆装。虽然她们更习惯让异族的奴隶服侍自己,不过还是有一些乌拉星人选择从事服务业。 - - Wula/Apparel/WULA_Maid_Uniform - - - -
  • Torso
  • -
  • Shoulders
  • -
  • Arms
  • -
  • Legs
  • -
    - - -
  • Middle
  • -
    - Wula/Apparel/WULA_Maid_Uniform -
    - - 0.15 - 0.1 - 0.2 - 0.2 - - - 100 - -
  • Fabric
  • -
  • Leathery
  • -
    - - WULA_Synth_Clothes_Technology - -
  • WULA_Cube_Productor_Energy
  • -
    - GeneralLaborSpeed - - 3 - -
    -
    - - WULA_Maid_Uniform_Headband - - 乌拉帝国女仆装的配套发饰。 - - WULA_Synth_Clothes_Technology - -
  • WULA_Cube_Productor_Energy
  • -
    - 105 -
    - - Wula/Apparel/WULA_Maid_Uniform_Headband - - - 0.1 - - - - 20 - -
  • Fabric
  • -
  • Leathery
  • -
    - - false - -
  • FullHead
  • -
    - -
  • Overhead
  • -
    - ApparelHead - Wula/Apparel/WULA_Maid_Uniform_Headband -
    - -
  • RewardStandardHighFreq
  • -
    -
    - - WULA_Nurse_Uniform - - 乌拉帝国平民所穿的护士装。一反常态的深色护士服反倒让病人感到不安——不过比起救人,她们更多的是在执行一些在其他种族看来“非道德”的医学操作。 - - Wula/Apparel/WULA_Nurse_Uniform - - - -
  • Torso
  • -
  • Shoulders
  • -
  • Arms
  • -
  • Legs
  • -
    - - -
  • Middle
  • -
    - Wula/Apparel/WULA_Nurse_Uniform -
    - - 1 - - 100 - -
  • Fabric
  • -
  • Leathery
  • -
    - - WULA_Synth_Clothes_Technology - -
  • WULA_Cube_Productor_Energy
  • -
    - GeneralLaborSpeed - - 3 - -
    -
    - - WULA_Nurse_Uniform_Headband - - 乌拉帝国护士装的配套发饰。 - - WULA_Synth_Clothes_Technology - -
  • WULA_Cube_Productor_Energy
  • -
    - 105 -
    - - Wula/Apparel/WULA_Nurse_Uniform_Headband - - - 0.1 - - - - 20 - -
  • Fabric
  • -
  • Leathery
  • -
    - - false - -
  • FullHead
  • -
    - -
  • Overhead
  • -
    - ApparelHead - Wula/Apparel/WULA_Nurse_Uniform_Headband -
    - -
  • RewardStandardHighFreq
  • -
    -
    - - WULA_Qipao - - 乌拉帝国中较高等的公民所着服装,修身而不失典雅之姿。 - - Wula/Apparel/WULA_Qipao - - - -
  • Torso
  • -
  • Shoulders
  • -
  • Arms
  • -
  • Legs
  • -
    - - -
  • Middle
  • -
    - Wula/Apparel/WULA_Qipao -
    - - 0.1 - 0.1 - 0.1 - - 100 - -
  • Fabric
  • -
  • Leathery
  • -
    - - WULA_Synth_Clothes_Technology - -
  • WULA_Cube_Productor_Energy
  • -
    - GeneralLaborSpeed - - 3 - -
    -
    - - WULA_Nun_Uniform - - 乌拉帝国修女所着的衣服,虽然作为战斗服装来说几乎没有防护,但是它可以用乌拉帝国的技术抽出穿着者的灵能并形成一道灵能护盾——无论使用者是否愿意。 - Normal - - Wula/Apparel/WULA_Nun_Uniform - - - -
  • Wula_FE_Spiritualist_T1
  • -
    - -
  • Torso
  • -
  • Shoulders
  • -
  • Arms
  • -
  • Legs
  • -
    - - -
  • Middle
  • -
    - Wula/Apparel/WULA_Nun_Uniform -
    - - 2 - - - 10000 - 200 - 0.2 - 0.1 - 0.1 - 1.5 - - - 0.2 - -0.1 - - 200 - -
  • Fabric
  • -
  • Leathery
  • -
    - - WULA_Synth_Clothes_2_Technology - -
  • WULA_Cube_Productor_Energy
  • -
    - GeneralLaborSpeed - - 5 - -
    - -
  • - - - 1.5 - 250 - 2800 - - - true - false - true - - - (0.5, 0.3, 0.9, 0.5) - Interceptor_BlockedProjectile - Shield_Break - BulletShieldGenerator_Reactivate - - - true - 600 - - - 60 - -
  • -
    -
    - - WULA_Nun_veil - - 乌拉帝国修女装的配套发饰,能像服装那样支起一个较小的灵能护盾。 - Normal - - WULA_Synth_Clothes_2_Technology - -
  • WULA_Cube_Productor_Energy
  • -
    - 105 -
    - - Wula/Apparel/WULA_Nun_veil - - - 0.25 - 0.1 - - - - 50 - - 1 - - -
  • Fabric
  • -
  • Leathery
  • -
    - - -
  • Wula_FE_Spiritualist_T1
  • -
    - false - -
  • FullHead
  • -
    - -
  • Overhead
  • -
    - ApparelHead - Wula/Apparel/WULA_Nun_veil -
    - -
  • RewardStandardHighFreq
  • -
    - -
  • - - - 1.46 - 100 - 2800 - - - true - false - false - - - (0.5, 0.3, 0.9, 0.5) - Interceptor_BlockedProjectile - Shield_Break - BulletShieldGenerator_Reactivate - - - true - 600 - - - 60 - -
  • -
    -
    - - - - - Graphic_Single - CutoutComplex - - -
  • ApparelMisc
  • -
    - 30 - -
  • Fabric
  • -
  • Leathery
  • -
    - - -
  • Wula_Apparel
  • -
  • Wula_Inner
  • -
    - -
  • Torso
  • -
    - -
  • OnSkin
  • -
    - false - false - false - true -
    - - UnfinishedApparel - GeneralLaborSpeed - false - - 1 - - 0.2 - 0.1 - 0.5 - 0.5 - -
    WULA_Bodystocking @@ -769,7 +277,6 @@ - Spacer Normal @@ -1290,7 +797,6 @@ - Spacer Normal @@ -1512,7 +1018,6 @@ - Apparel_WULA_Manpack_Loitering_Munition @@ -1635,7 +1140,6 @@ - Shield diff --git a/1.6/1.6/Defs/ThingDefs_Misc/Apperals/WULA_FE_Materialist_Apparel.xml b/1.6/1.6/Defs/ThingDefs_Misc/Apperals/WULA_FE_Materialist_Apparel.xml deleted file mode 100644 index ba647e78..00000000 --- a/1.6/1.6/Defs/ThingDefs_Misc/Apperals/WULA_FE_Materialist_Apparel.xml +++ /dev/null @@ -1,286 +0,0 @@ - - - - WULA_Witch_Uniform - - 乌拉帝国图书馆的外勤人员所着制服,时尚轻便,内部埋藏了大量的纳米级管线,用于和战场上的机械部队建立链接,并极大强化附近的乌拉帝国机械部队——话说回来,操纵机械族作战也算是召唤师吧? - Normal - - WULA_Witch_Uniform_Hediff - WULA_Witch_Uniform_Mech_Hediff - - - Wula/Apparel/WULA_Witch_Uniform - - - -
  • RoyalTier6
  • -
  • Wula_FE_Materialist_T3
  • -
    - -
  • Torso
  • -
  • Shoulders
  • -
  • Arms
  • -
  • Legs
  • -
    - - -
  • Middle
  • -
    - Wula/Apparel/WULA_Witch_Uniform -
    - - 100 - - 300 - - 50000 - 3000 - 0.5 - 0.2 - 0.2 - 0.5 - - - 32 - 2 - 2 - 2 - - None - 200 - -
  • Fabric
  • -
  • Leathery
  • -
    - - -
  • - WULA_Witch_Uniform_Hediff - Brain -
  • -
    -
    - - WULA_Witch_Hat - - 乌拉帝国学院魔女装的配套帽子,和其衣服一样可以强化乌拉星人操纵机械集群的能力,此外还允许附近的机械族不需要能量补给——话说回来,操纵机械族作战也算是召唤师吧? - Normal - - - WULA_Witch_Hat_Hediff - WULA_Witch_Hat_Mech_Hediff - - - Wula/Apparel/WULA_Witch_Hat - - - 0.1 - - - 24 - 1 - 1 - 1 - - None - 150 - - 50 - - -
  • Fabric
  • -
  • Leathery
  • -
    - - -
  • RoyalTier6
  • -
  • Wula_FE_Spiritualist_T3
  • -
    - false - -
  • FullHead
  • -
    - -
  • Overhead
  • -
    - ApparelHead - Wula/Apparel/WULA_Witch_Hat - -
    - -
  • RewardStandardHighFreq
  • -
    - -
  • - WULA_Witch_Hat_Hediff - Brain -
  • -
    -
    - - - WULA_Witch_Uniform_Hediff - - 由乌拉帝国学院魔女装所提供的特殊立场,可以强化大范围内所有乌拉帝国机械体的战斗能力——灵能机械体和乌拉猫猫类机械体除外。 - - WULA_Witch_Uniform_Mech_Hediff - - HediffWithComps - false - - -
  • - 40 - WULA_Witch_Uniform_Mech_Hediff - - - -
  • Wula_AI_Heavy_Panzer
  • -
  • Wula_AI_Heavy_Panzer_Gunnery
  • -
  • WULA_Alpha_Wolf
  • -
  • WULA_Alpha_Mantodea
  • -
  • WULA_Mech_Flyer
  • -
  • WULA_Mech_Flyer_Melta
  • -
  • Wula_Mech_Mobile_Factory
  • -
  • Wula_Mech_Mobile_Factory_CR
  • -
  • Wula_Mech_Mobile_Factory_LR
  • -
  • Wula_AI_Engineer_Mother
  • -
  • Wula_AI_Engineer_Mother_Attack
  • - - - - - false - true - false - false - false - true - - true - true - -
    -
    - - WULA_Witch_Uniform_Mech_Hediff - - (0.52, 1, 0.95) - HediffWithComps - - WULA_Witch_Uniform_Hediff - - false - 一位身着乌拉帝国学院魔女装的乌拉星人在该机械体附近,为机械提供了强大的战斗能力加成。 - other - WULA_Addons_Antenna_Bodypart - 1 - 1 - -
  • - - 0.5 - 5 - 1.5 - 0.5 - 2 - 0.75 - -
  • -
    - -
  • - false -
  • -
  • -
  • -
    -
    - - WULA_Witch_Hat_Hediff - - 由乌拉帝国学院魔女装所提供的特殊立场,可以使大范围的乌拉帝国机械体自行汲取能量而无需充电——灵能机械体和乌拉猫猫类机械体除外。 - - WULA_Witch_Hat_Mech_Hediff - - HediffWithComps - false - - -
  • - 40 - WULA_Witch_Hat_Mech_Hediff - - - -
  • Wula_AI_Heavy_Panzer
  • -
  • Wula_AI_Heavy_Panzer_Gunnery
  • -
  • WULA_Alpha_Wolf
  • -
  • WULA_Alpha_Mantodea
  • -
  • WULA_Mech_Flyer
  • -
  • WULA_Mech_Flyer_Melta
  • -
  • Wula_Mech_Mobile_Factory
  • -
  • Wula_Mech_Mobile_Factory_CR
  • -
  • Wula_Mech_Mobile_Factory_LR
  • -
  • Wula_AI_Engineer_Mother
  • -
  • Wula_AI_Engineer_Mother_Attack
  • - - - - - false - true - false - false - false - true - - true - true - -
    -
    - - WULA_Witch_Hat_Mech_Hediff - - (0.52, 1, 0.95) - HediffWithComps - - WULA_Witch_Hat_Hediff - - false - - 一位身着乌拉帝国学院魔女帽的乌拉星人在该机械体附近,发出的自持协议信号使该机械族自行汲取能量而无需充电。 - other - WULA_Addons_Antenna_Bodypart - 1 - 1 - -
  • - -
  • MechEnergy
  • - - -
    - -
  • - false -
  • -
  • -
  • -
    -
    -
    \ No newline at end of file diff --git a/1.6/1.6/Defs/ThingDefs_Races/Races_Wulaspecies.xml b/1.6/1.6/Defs/ThingDefs_Races/Races_Wulaspecies.xml index 7387f520..4a34365b 100644 --- a/1.6/1.6/Defs/ThingDefs_Races/Races_Wulaspecies.xml +++ b/1.6/1.6/Defs/ThingDefs_Races/Races_Wulaspecies.xml @@ -779,6 +779,8 @@
  • +
  • Wula_Synth
  • +
  • WULA_Addons_Antenna_Hediff_Base
  • WULA_NanoRepairHediff
  • 1.0 diff --git a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/Misc_Gameplay.xml b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/Misc_Gameplay.xml index 6f6a79d1..0b3de553 100644 --- a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/Misc_Gameplay.xml +++ b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/Misc_Gameplay.xml @@ -210,4 +210,45 @@ {0}件物资被舰队退回(随着下一次成品空投一起退回) 输入存储: {0} 输出存储: {0} + + 材质 + 为此武器选择材质 + 当前材质:{0} + 没有可用的材质 + 已选择 {0} 作为材质 + 已自动选择 {0} 作为材质 + 自动选择(最充足) + 清除选择 + 材质选择已清除 + 生产开始后无法更改材质 + 此武器不支持材质选择 + 未选择材质 + + 固定原料 + 材质 + + 普遍性 + 前缀 + + + 纳米修复能量消耗 + 纳米修复系统修复每点生命值所消耗的能量。数值越低,修复消耗越低。 + 纳米修复冷却时间 + 受到伤害后纳米修复系统进入冷却的时间。数值越低,系统响应越快。 + + 纳米修复系统属性: + • 每点生命值修复消耗: {0} + • 最低启动能量阈值: {0} + • 伤害后冷却时间: {1} 秒 + • 系统状态: {0} + 已启用 + 已禁用 + + 维护系统属性: + • 阈值前退化速率: {0}/天\n• 阈值后退化速率: {1}/天\n• 阈值天数: {2}天 + • 轻微故障阈值: {0}\n• 严重故障阈值: {1}\n• 完全故障阈值: {2} + • 伤害转换因子: {0}/点伤害 + • 轻微故障阈值: {0} + • 严重故障阈值: {0} + • 完全故障阈值: {0} \ No newline at end of file diff --git a/Source/WulaFallenEmpire/GlobalWorkTable/GlobalProductionOrder.cs b/Source/WulaFallenEmpire/GlobalWorkTable/GlobalProductionOrder.cs index 6667a169..708d1f48 100644 --- a/Source/WulaFallenEmpire/GlobalWorkTable/GlobalProductionOrder.cs +++ b/Source/WulaFallenEmpire/GlobalWorkTable/GlobalProductionOrder.cs @@ -1,6 +1,7 @@ -// GlobalProductionOrder.cs (修复版) +// GlobalProductionOrder.cs (修正材质属性读取) using RimWorld; using System.Collections.Generic; +using System.Linq; using System.Text; using UnityEngine; using Verse; @@ -12,7 +13,10 @@ namespace WulaFallenEmpire public RecipeDef recipe; public int targetCount = 1; public int currentCount = 0; - public bool paused = true; // 初始状态为暂停 + public bool paused = true; + + // 材质选择:存储配方选择的材质(只有支持材质的配方才有) + public ThingDef chosenStuff = null; // 生产状态 public ProductionState state = ProductionState.Waiting; @@ -25,16 +29,15 @@ namespace WulaFallenEmpire } public string Label => recipe.LabelCap; - public string Description => $"{currentCount}/{targetCount} {recipe.products[0].thingDef.label}"; private float _progress = 0f; + public string Description => $"{currentCount}/{targetCount} {recipe.products[0].thingDef.label}"; + + private float _progress = 0f; public float progress { get => _progress; set { - // 确保进度在有效范围内 _progress = Mathf.Clamp01(value); - - // 如果检测到异常值,记录警告 if (value < 0f || value > 1f) { Log.Warning($"Progress clamped from {value} to {_progress} for {recipe?.defName ?? "unknown"}"); @@ -42,27 +45,252 @@ namespace WulaFallenEmpire } } + // 新增:检查订单是否已经开始生产(一旦开始就不能修改材质) + public bool HasStartedProduction => state == ProductionState.Producing || currentCount > 0; + + // 修正:检查产物是否支持材质选择 + public bool SupportsStuffChoice + { + get + { + if (recipe?.products == null || recipe.products.Count == 0) + return false; + + var productDef = recipe.products[0].thingDef; + if (productDef == null) + return false; + + // 检查产物是否有stuffCategories且costStuffCount > 0 + return productDef.stuffCategories != null && + productDef.stuffCategories.Count > 0 && + productDef.costStuffCount > 0; + } + } + + // 修正:获取产物的ThingDef + public ThingDef ProductDef => recipe?.products?.Count > 0 ? recipe.products[0].thingDef : null; + public void ExposeData() { Scribe_Defs.Look(ref recipe, "recipe"); Scribe_Values.Look(ref targetCount, "targetCount", 1); Scribe_Values.Look(ref currentCount, "currentCount", 0); Scribe_Values.Look(ref paused, "paused", true); - Scribe_Values.Look(ref _progress, "progress", 0f); // 序列化私有字段 + Scribe_Values.Look(ref _progress, "progress", 0f); Scribe_Values.Look(ref state, "state", ProductionState.Waiting); + Scribe_Defs.Look(ref chosenStuff, "chosenStuff"); // 修复:加载后验证数据 if (Scribe.mode == LoadSaveMode.PostLoadInit) { - // 使用属性设置器来钳制值 progress = _progress; - - // 确保状态正确 UpdateState(); + + // 确保材质选择有效 + if (SupportsStuffChoice && chosenStuff == null) + { + InitializeStuffChoice(); + } } } - // 修复:改进状态更新逻辑 + // 修正:初始化材质选择 + public void InitializeStuffChoice() + { + if (!SupportsStuffChoice) return; + + var availableStuff = GetAvailableStuffForProduct(); + + if (availableStuff.Count > 0) + { + chosenStuff = availableStuff[0]; + } + } + + // 修正:获取产物的可用材质列表 + public List GetAvailableStuffForProduct() + { + var availableStuff = new List(); + + if (ProductDef?.stuffCategories != null) + { + foreach (var stuffCategory in ProductDef.stuffCategories) + { + var stuffInCategory = DefDatabase.AllDefs + .Where(def => def.IsStuff && def.stuffProps?.categories != null && def.stuffProps.categories.Contains(stuffCategory)) + .ToList(); + + availableStuff.AddRange(stuffInCategory); + } + } + + return availableStuff.Distinct().ToList(); + } + + // 修正:HasEnoughResources 方法,考虑选择的材质 + public bool HasEnoughResources() + { + var globalStorage = Find.World.GetComponent(); + if (globalStorage == null) return false; + + // 检查固定消耗(costList) + foreach (var ingredient in recipe.ingredients) + { + bool hasEnoughForThisIngredient = false; + + foreach (var thingDef in ingredient.filter.AllowedThingDefs) + { + int requiredCount = ingredient.CountRequiredOfFor(thingDef, recipe); + int availableCount = globalStorage.GetInputStorageCount(thingDef); + + if (availableCount >= requiredCount) + { + hasEnoughForThisIngredient = true; + break; + } + } + + if (!hasEnoughForThisIngredient) + return false; + } + + // 检查材质消耗(如果支持材质选择) + if (SupportsStuffChoice && chosenStuff != null) + { + int requiredStuffCount = ProductDef.costStuffCount; + int availableStuffCount = globalStorage.GetInputStorageCount(chosenStuff); + + if (availableStuffCount < requiredStuffCount) + return false; + } + + return true; + } + + // 修正:ConsumeResources 方法,考虑选择的材质 + public bool ConsumeResources() + { + var globalStorage = Find.World.GetComponent(); + if (globalStorage == null) return false; + + // 消耗固定资源(costList) + foreach (var ingredient in recipe.ingredients) + { + bool consumedThisIngredient = false; + + foreach (var thingDef in ingredient.filter.AllowedThingDefs) + { + int requiredCount = ingredient.CountRequiredOfFor(thingDef, recipe); + int availableCount = globalStorage.GetInputStorageCount(thingDef); + + if (availableCount >= requiredCount) + { + if (globalStorage.RemoveFromInputStorage(thingDef, requiredCount)) + { + consumedThisIngredient = true; + break; + } + } + } + + if (!consumedThisIngredient) + return false; + } + + // 消耗材质(如果支持材质选择) + if (SupportsStuffChoice && chosenStuff != null) + { + int requiredStuffCount = ProductDef.costStuffCount; + + if (!globalStorage.RemoveFromInputStorage(chosenStuff, requiredStuffCount)) + return false; + } + + return true; + } + + // 修正:GetIngredientsTooltip 方法,显示固定消耗和可选材质 + public string GetIngredientsTooltip() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine(recipe.LabelCap); + sb.AppendLine(); + + // 固定消耗(costList) + sb.AppendLine("WULA_FixedIngredients".Translate() + ":"); + var globalStorage = Find.World.GetComponent(); + + foreach (var ingredient in recipe.ingredients) + { + foreach (var thingDef in ingredient.filter.AllowedThingDefs) + { + int requiredCount = ingredient.CountRequiredOfFor(thingDef, recipe); + int availableCount = globalStorage?.GetInputStorageCount(thingDef) ?? 0; + + string itemDisplay = $"{requiredCount} {thingDef.LabelCap}"; + + if (availableCount >= requiredCount) + { + sb.AppendLine($" {itemDisplay}"); + } + else + { + sb.AppendLine($" {itemDisplay}"); + } + } + } + + // 材质消耗(如果支持材质选择) + if (SupportsStuffChoice) + { + sb.AppendLine(); + sb.AppendLine("WULA_StuffMaterial".Translate() + ":"); + + if (chosenStuff != null) + { + int requiredStuffCount = ProductDef.costStuffCount; + int availableStuffCount = globalStorage?.GetInputStorageCount(chosenStuff) ?? 0; + + string stuffDisplay = $"{requiredStuffCount} {chosenStuff.LabelCap}"; + + if (availableStuffCount >= requiredStuffCount) + { + sb.AppendLine($" {stuffDisplay} (Selected)"); + } + else + { + sb.AppendLine($" {stuffDisplay} (Selected)"); + } + } + else + { + sb.AppendLine($" {"WULA_NoStuffSelected".Translate()}"); + } + } + + // 产品 + sb.AppendLine(); + sb.AppendLine("WULA_Products".Translate() + ":"); + foreach (var product in recipe.products) + { + sb.AppendLine($" {product.count} {product.thingDef.LabelCap}"); + } + + // 工作量信息 + sb.AppendLine(); + sb.AppendLine("WULA_WorkAmount".Translate() + ": " + GetWorkAmount().ToStringWorkAmount()); + + // 添加材质选择状态信息 + if (HasStartedProduction && SupportsStuffChoice) + { + sb.AppendLine(); + sb.AppendLine("Material choice is locked because production has started."); + } + + return sb.ToString(); + } + + // 其余方法保持不变... public void UpdateState() { if (state == ProductionState.Completed) @@ -80,7 +308,7 @@ namespace WulaFallenEmpire if (state == ProductionState.Waiting && !paused) { state = ProductionState.Producing; - progress = 0f; // 开始生产时重置进度 + progress = 0f; } } else @@ -88,230 +316,62 @@ namespace WulaFallenEmpire if (state == ProductionState.Producing) { state = ProductionState.Waiting; - progress = 0f; // 资源不足时重置进度 + progress = 0f; } } } - // 修复:改进生产完成逻辑 public void Produce() { var globalStorage = Find.World.GetComponent(); if (globalStorage == null) return; + foreach (var product in recipe.products) { - // 检查产物是否为Pawn if (product.thingDef.race != null) { - // 对于Pawn,我们存储的是Pawn的ThingDef,在释放时再随机生成PawnKind globalStorage.AddToOutputStorage(product.thingDef, product.count); } else { - // 对于普通物品,正常存储 globalStorage.AddToOutputStorage(product.thingDef, product.count); } } + currentCount++; - progress = 0f; // 生产完成后重置进度 + progress = 0f; + if (currentCount >= targetCount) { state = ProductionState.Completed; } } - // 检查是否有足够资源 - 修复逻辑 - public bool HasEnoughResources() - { - var globalStorage = Find.World.GetComponent(); - if (globalStorage == null) return false; - - // 遍历所有配料要求 - foreach (var ingredient in recipe.ingredients) - { - bool hasEnoughForThisIngredient = false; - - // 检查这个配料的所有允许物品类型 - foreach (var thingDef in ingredient.filter.AllowedThingDefs) - { - int requiredCount = ingredient.CountRequiredOfFor(thingDef, recipe); - int availableCount = globalStorage.GetInputStorageCount(thingDef); - - if (availableCount >= requiredCount) - { - hasEnoughForThisIngredient = true; - break; // 这个配料有足够的资源 - } - } - - // 如果任何一个配料没有足够资源,整个配方就无法生产 - if (!hasEnoughForThisIngredient) - return false; - } - - return true; - } - - // 消耗资源 - 修复逻辑 - public bool ConsumeResources() - { - var globalStorage = Find.World.GetComponent(); - if (globalStorage == null) return false; - - // 遍历所有配料要求 - foreach (var ingredient in recipe.ingredients) - { - bool consumedThisIngredient = false; - - // 尝试消耗这个配料的允许物品类型 - foreach (var thingDef in ingredient.filter.AllowedThingDefs) - { - int requiredCount = ingredient.CountRequiredOfFor(thingDef, recipe); - int availableCount = globalStorage.GetInputStorageCount(thingDef); - - if (availableCount >= requiredCount) - { - if (globalStorage.RemoveFromInputStorage(thingDef, requiredCount)) - { - consumedThisIngredient = true; - break; // 成功消耗这个配料 - } - } - } - - // 如果任何一个配料无法消耗,整个生产失败 - if (!consumedThisIngredient) - return false; - } - - return true; - } - // 修复:添加获取正确工作量的方法 public float GetWorkAmount() { if (recipe == null) return 1000f; - // 如果配方有明确的工作量且大于0,使用配方的工作量 if (recipe.workAmount > 0) return recipe.workAmount; - // 否则,使用第一个产品的WorkToMake属性 if (recipe.products != null && recipe.products.Count > 0) { ThingDef productDef = recipe.products[0].thingDef; if (productDef != null) { - // 获取产品的WorkToMake统计值 float workToMake = productDef.GetStatValueAbstract(StatDefOf.WorkToMake); if (workToMake > 0) return workToMake; - // 如果WorkToMake也是0或无效,使用产品的市场价值作为估算 float marketValue = productDef.GetStatValueAbstract(StatDefOf.MarketValue); if (marketValue > 0) - return marketValue * 10f; // 基于市场价值的估算 + return marketValue * 10f; } } - return 1000f; // 默认工作量 - } - - // 修复:在信息显示中使用正确的工作量 - public string GetIngredientsInfo() - { - StringBuilder sb = new StringBuilder(); - // 添加标题 - sb.AppendLine("WULA_RequiredIngredients".Translate() + ":"); - var globalStorage = Find.World.GetComponent(); - foreach (var ingredient in recipe.ingredients) - { - bool firstAllowedThing = true; - foreach (var thingDef in ingredient.filter.AllowedThingDefs) - { - int requiredCount = ingredient.CountRequiredOfFor(thingDef, recipe); - int availableCount = globalStorage?.GetInputStorageCount(thingDef) ?? 0; - if (firstAllowedThing) - { - sb.Append(" - "); - firstAllowedThing = false; - } - else - { - sb.Append(" / "); - } - sb.Append($"{requiredCount} {thingDef.label}"); - // 添加可用数量信息 - if (availableCount < requiredCount) - { - sb.Append($" ({availableCount}/{requiredCount})"); - } - else - { - sb.Append($" ({availableCount}/{requiredCount})"); - } - } - sb.AppendLine(); - } - // 添加产品信息 - sb.AppendLine(); - sb.AppendLine("WULA_Products".Translate() + ":"); - foreach (var product in recipe.products) - { - sb.AppendLine($" - {product.count} {product.thingDef.label}"); - } - // 修复:使用正确的工作量信息 - sb.AppendLine(); - sb.AppendLine("WULA_WorkAmount".Translate() + ": " + GetWorkAmount().ToStringWorkAmount()); - return sb.ToString(); - } - - // 修复:在Tooltip中也使用正确的工作量 - public string GetIngredientsTooltip() - { - StringBuilder sb = new StringBuilder(); - sb.AppendLine(recipe.LabelCap); - sb.AppendLine(); - // 材料需求 - sb.AppendLine("WULA_RequiredIngredients".Translate() + ":"); - var globalStorage = Find.World.GetComponent(); - foreach (var ingredient in recipe.ingredients) - { - bool ingredientSatisfied = false; - StringBuilder ingredientSB = new StringBuilder(); - foreach (var thingDef in ingredient.filter.AllowedThingDefs) - { - int requiredCount = ingredient.CountRequiredOfFor(thingDef, recipe); - int availableCount = globalStorage?.GetInputStorageCount(thingDef) ?? 0; - if (ingredientSB.Length > 0) - ingredientSB.Append(" / "); - ingredientSB.Append($"{requiredCount} {thingDef.label}"); - if (availableCount >= requiredCount) - { - ingredientSatisfied = true; - } - } - if (ingredientSatisfied) - { - sb.AppendLine($" {ingredientSB}"); - } - else - { - sb.AppendLine($" {ingredientSB}"); - } - } - // 产品 - sb.AppendLine(); - sb.AppendLine("WULA_Products".Translate() + ":"); - foreach (var product in recipe.products) - { - sb.AppendLine($" {product.count} {product.thingDef.label}"); - } - // 修复:使用正确的工作量 - sb.AppendLine(); - sb.AppendLine("WULA_WorkAmount".Translate() + ": " + GetWorkAmount().ToStringWorkAmount()); - return sb.ToString(); + return 1000f; } } } diff --git a/Source/WulaFallenEmpire/GlobalWorkTable/ITab_GlobalBills.cs b/Source/WulaFallenEmpire/GlobalWorkTable/ITab_GlobalBills.cs index 965ae4c4..9494d0bd 100644 --- a/Source/WulaFallenEmpire/GlobalWorkTable/ITab_GlobalBills.cs +++ b/Source/WulaFallenEmpire/GlobalWorkTable/ITab_GlobalBills.cs @@ -92,17 +92,17 @@ namespace WulaFallenEmpire return "WULA_NoGlobalStorage".Translate(); StringBuilder sb = new StringBuilder(); - + // 输入存储(原材料) sb.AppendLine("WULA_InputStorage".Translate() + ":"); sb.AppendLine(); - + var inputItems = globalStorage.inputStorage .Where(kvp => kvp.Value > 0) .OrderByDescending(kvp => kvp.Value) .ThenBy(kvp => kvp.Key.label) .ToList(); - + if (inputItems.Count == 0) { sb.AppendLine("WULA_NoItems".Translate()); @@ -111,22 +111,23 @@ namespace WulaFallenEmpire { foreach (var kvp in inputItems) { - sb.AppendLine($" {kvp.Value} {kvp.Key.label}"); + // 使用正确的图标格式并保留名称 + sb.AppendLine($" {kvp.Value} {kvp.Key.LabelCap}"); } } - + sb.AppendLine(); - + // 输出存储(产品) sb.AppendLine("WULA_OutputStorage".Translate() + ":"); sb.AppendLine(); - + var outputItems = globalStorage.outputStorage .Where(kvp => kvp.Value > 0) .OrderByDescending(kvp => kvp.Value) .ThenBy(kvp => kvp.Key.label) .ToList(); - + if (outputItems.Count == 0) { sb.AppendLine("WULA_NoItems".Translate()); @@ -135,19 +136,21 @@ namespace WulaFallenEmpire { foreach (var kvp in outputItems) { - sb.AppendLine($" {kvp.Value} {kvp.Key.label}"); + // 使用正确的图标格式并保留名称 + sb.AppendLine($" {kvp.Value} {kvp.Key.LabelCap}"); } } - + // 添加存储统计信息 sb.AppendLine(); sb.AppendLine("WULA_StorageStats".Translate()); sb.AppendLine($" {inputItems.Count} {("WULA_InputItems".Translate())}"); sb.AppendLine($" {outputItems.Count} {("WULA_OutputItems".Translate())}"); - + return sb.ToString(); } + // 修改:将开发者模式按钮改为上帝模式按钮 private void DoGodModeButtons(Rect rect) { @@ -268,20 +271,19 @@ namespace WulaFallenEmpire Widgets.EndScrollView(); return result; - } - + }// 在 ITab_GlobalBills.cs 中修正材质选择功能 private bool DoOrderRow(Rect rect, GlobalProductionOrder order) { Widgets.DrawHighlightIfMouseover(rect); - + // 增加内边距和行高 float padding = 8f; float lineHeight = 20f; - - // 图标区域 - 添加在左侧 + + // 图标区域 float iconSize = 32f; Rect iconRect = new Rect(rect.x + padding, rect.y + padding, iconSize, iconSize); - + // 绘制配方图标 if (order.recipe.UIIconThing != null) { @@ -291,26 +293,26 @@ namespace WulaFallenEmpire { GUI.DrawTexture(iconRect, order.recipe.UIIcon); } - - // 订单信息区域 - 向右偏移图标宽度 + + // 订单信息区域 float infoX = rect.x + padding + iconSize + 8f; - float infoWidth = rect.width - (padding * 2 + iconSize + 8f + 100f); // 减去控制按钮区域 - + float infoWidth = rect.width - (padding * 2 + iconSize + 8f + 100f); + Rect infoRect = new Rect(infoX, rect.y + padding, infoWidth, lineHeight); Widgets.Label(infoRect, order.Label); - + Rect descRect = new Rect(infoX, rect.y + padding + lineHeight + 2f, infoWidth, lineHeight); Widgets.Label(descRect, order.Description); - + // 状态显示区域 Rect statusRect = new Rect(infoX, rect.y + padding + (lineHeight + 2f) * 2, infoWidth, lineHeight); - + if (order.state == GlobalProductionOrder.ProductionState.Producing) { // 进度条 Rect progressRect = new Rect(infoX, rect.y + padding + (lineHeight + 2f) * 2, infoWidth, 18f); Widgets.FillableBar(progressRect, order.progress); - + // 进度文本 Text.Anchor = TextAnchor.MiddleCenter; Widgets.Label(progressRect, $"{order.progress:P0}"); @@ -324,53 +326,84 @@ namespace WulaFallenEmpire GlobalProductionOrder.ProductionState.Completed => "WULA_Completed".Translate(), _ => "WULA_Unknown".Translate() }; - - // 如果暂停,在状态前添加暂停标识 + if (order.paused && order.state != GlobalProductionOrder.ProductionState.Completed) { statusText = $"[||] {statusText}"; } - + Widgets.Label(statusRect, statusText); } - - // 控制按钮 + + // 控制按钮区域 float buttonY = rect.y + padding; float buttonWidth = 40f; float buttonSpacing = 5f; - + // 计算按钮位置(从右向左排列) float currentX = rect.xMax; - + // 删除按钮(最右边) Rect deleteButtonRect = new Rect(currentX - buttonWidth, buttonY, buttonWidth, 25f); currentX -= (buttonWidth + buttonSpacing); - + // 暂停/恢复按钮 Rect pauseButtonRect = new Rect(currentX - buttonWidth, buttonY, buttonWidth, 25f); currentX -= (buttonWidth + buttonSpacing); - - // 上帝模式:立刻完成按钮(在暂停按钮左边) + + // 材质选择按钮(如果支持材质选择且未开始生产) + Rect stuffButtonRect = new Rect(0f, 0f, 0f, 0f); + bool showStuffButton = false; + + if (order.SupportsStuffChoice && !order.HasStartedProduction) + { + showStuffButton = true; + stuffButtonRect = new Rect(currentX - buttonWidth, buttonY, buttonWidth, 25f); + currentX -= (buttonWidth + buttonSpacing); + } + + // 上帝模式:立刻完成按钮 Rect completeButtonRect = new Rect(currentX - buttonWidth, buttonY, buttonWidth, 25f); - + // 绘制删除按钮 if (Widgets.ButtonText(deleteButtonRect, "WULA_Delete".Translate())) { SelTable.globalOrderStack.Delete(order); SoundDefOf.Click.PlayOneShotOnCamera(); } - + // 绘制暂停/恢复按钮 string pauseButtonText = order.paused ? "WULA_Resume".Translate() : "WULA_Pause".Translate(); if (Widgets.ButtonText(pauseButtonRect, pauseButtonText)) { order.paused = !order.paused; - - // 暂停/恢复时更新状态 order.UpdateState(); SoundDefOf.Click.PlayOneShotOnCamera(); } - + + // 绘制材质选择按钮 + if (showStuffButton) + { + string stuffButtonText = order.chosenStuff != null ? + order.chosenStuff.LabelCap : + "WULA_ChooseStuff".Translate(); + + if (Widgets.ButtonText(stuffButtonRect, stuffButtonText)) + { + ShowStuffSelectionMenu(order); + SoundDefOf.Click.PlayOneShotOnCamera(); + } + + // 为材质选择按钮添加Tooltip + if (Mouse.IsOver(stuffButtonRect)) + { + string tooltip = order.chosenStuff != null ? + $"WULA_CurrentStuff".Translate(order.chosenStuff.LabelCap) : + "WULA_ChooseStuffTooltip".Translate(); + TooltipHandler.TipRegion(stuffButtonRect, tooltip); + } + } + // 绘制上帝模式按钮(仅上帝模式下可见) if (DebugSettings.godMode && order.state != GlobalProductionOrder.ProductionState.Completed) { @@ -379,17 +412,16 @@ namespace WulaFallenEmpire CompleteOrderImmediately(order); SoundDefOf.Click.PlayOneShotOnCamera(); } - - // 为上帝模式按钮添加Tooltip + if (Mouse.IsOver(completeButtonRect)) { TooltipHandler.TipRegion(completeButtonRect, "Instantly complete this order (God Mode Only)"); } } - - // 资源检查提示 - 只在等待资源且不暂停时显示红色边框 - if (!order.HasEnoughResources() && - order.state == GlobalProductionOrder.ProductionState.Waiting && + + // 资源检查提示 + if (!order.HasEnoughResources() && + order.state == GlobalProductionOrder.ProductionState.Waiting && !order.paused) { TooltipHandler.TipRegion(rect, "WULA_InsufficientResources".Translate()); @@ -397,15 +429,165 @@ namespace WulaFallenEmpire Widgets.DrawBox(rect, 2); GUI.color = Color.white; } - - // 添加材料信息的Tooltip - 这是核心功能 + + // 添加材料信息的Tooltip if (Mouse.IsOver(rect)) { TooltipHandler.TipRegion(rect, order.GetIngredientsTooltip()); } - + return Mouse.IsOver(rect); } + // 修正:显示材质选择菜单 + private void ShowStuffSelectionMenu(GlobalProductionOrder order) + { + if (order.HasStartedProduction) + { + Messages.Message("WULA_CannotChangeStuffAfterStart".Translate(), MessageTypeDefOf.RejectInput); + return; + } + if (!order.SupportsStuffChoice) + { + Messages.Message("WULA_RecipeDoesNotSupportStuff".Translate(), MessageTypeDefOf.RejectInput); + return; + } + var availableStuff = order.GetAvailableStuffForProduct(); + + if (availableStuff.Count == 0) + { + Messages.Message("WULA_NoStuffAvailable".Translate(), MessageTypeDefOf.RejectInput); + return; + } + List options = new List(); + var globalStorage = Find.World.GetComponent(); + + foreach (var stuffDef in availableStuff) + { + var stuffDefCopy = stuffDef; + + // 计算所需数量 + int requiredStuffCount = order.ProductDef.costStuffCount; + int availableCount = globalStorage?.GetInputStorageCount(stuffDefCopy) ?? 0; + + // 构建显示文本 + string label = $"{stuffDefCopy.LabelCap} ({requiredStuffCount} needed)"; + if (availableCount < requiredStuffCount) + { + label += $" (Only {availableCount} available)"; + } + else + { + label += $" ({availableCount} available)"; + } + + // 添加材质属性信息 + if (stuffDefCopy.stuffProps != null) + { + label += $"\n - {"WULA_Commonality".Translate()}: {stuffDefCopy.stuffProps.commonality}"; + if (stuffDefCopy.stuffProps.stuffAdjective != null) + { + label += $"\n - {"WULA_Adjective".Translate()}: {stuffDefCopy.stuffProps.stuffAdjective}"; + } + } + + options.Add(new FloatMenuOption( + label: label, + action: () => + { + order.chosenStuff = stuffDefCopy; + Messages.Message($"WULA_StuffSelected".Translate(stuffDefCopy.LabelCap), MessageTypeDefOf.TaskCompletion); + }, + shownItemForIcon: stuffDefCopy + )); + } + + // 添加"自动选择"选项 + options.Add(new FloatMenuOption( + label: "WULA_AutoSelectStuff".Translate(), + action: () => + { + // 选择库存最充足的材质 + var bestStuff = availableStuff + .OrderByDescending(stuff => globalStorage?.GetInputStorageCount(stuff) ?? 0) + .ThenBy(stuff => stuff.stuffProps?.commonality ?? 1f) + .FirstOrDefault(); + + if (bestStuff != null) + { + order.chosenStuff = bestStuff; + Messages.Message($"WULA_StuffAutoSelected".Translate(bestStuff.LabelCap), MessageTypeDefOf.TaskCompletion); + } + } + )); + + // 添加"清除选择"选项(如果当前有选择) + if (order.chosenStuff != null) + { + options.Add(new FloatMenuOption( + label: "WULA_ClearStuffSelection".Translate(), + action: () => + { + order.chosenStuff = null; + Messages.Message("WULA_StuffSelectionCleared".Translate(), MessageTypeDefOf.TaskCompletion); + } + )); + } + + Find.WindowStack.Add(new FloatMenu(options)); + } + // 修正:在添加订单时初始化材质选择 + private List GenerateRecipeOptions() + { + var options = new List(); + foreach (var recipe in SelTable.def.AllRecipes) + { + if (recipe.AvailableNow && recipe.AvailableOnNow(SelTable)) + { + string label = recipe.LabelCap; + options.Add(new FloatMenuOption( + label: label, + action: () => + { + var newOrder = new GlobalProductionOrder + { + recipe = recipe, + targetCount = 1, + paused = true + }; + + // 初始化材质选择(如果支持) + if (newOrder.SupportsStuffChoice) + { + newOrder.InitializeStuffChoice(); + } + + SelTable.globalOrderStack.AddOrder(newOrder); + SoundDefOf.Click.PlayOneShotOnCamera(); + Log.Message($"[DEBUG] Added order for {recipe.defName}"); + }, + shownItemForIcon: recipe.UIIconThing, + thingStyle: null, + forceBasicStyle: false, + priority: MenuOptionPriority.Default, + mouseoverGuiAction: null, + revalidateClickTarget: null, + extraPartWidth: 29f, + extraPartOnGUI: (Rect rect) => + { + return Widgets.InfoCardButton(rect.x + 5f, rect.y + (rect.height - 24f) / 2f, recipe); + }, + revalidateWorldClickTarget: null, + playSelectionSound: true, + orderInPriority: -recipe.displayPriority + )); + } + } + if (options.Count == 0) + { + options.Add(new FloatMenuOption("WULA_NoAvailableRecipes".Translate(), null)); + } + return options; + } // 新增:立刻完成订单的方法 private void CompleteOrderImmediately(GlobalProductionOrder order) @@ -480,60 +662,6 @@ namespace WulaFallenEmpire Log.Message($"[GOD MODE] Force completed order: {order.recipe.defName}, produced {remainingCount} units"); } - private List GenerateRecipeOptions() - { - var options = new List(); - - foreach (var recipe in SelTable.def.AllRecipes) - { - // 移除对Pawn配方的过滤,允许所有配方 - if (recipe.AvailableNow && recipe.AvailableOnNow(SelTable)) - { - string label = recipe.LabelCap; - - // 使用原版风格的FloatMenuOption构造函数,包含图标 - options.Add(new FloatMenuOption( - label: label, - action: () => - { - var newOrder = new GlobalProductionOrder - { - recipe = recipe, - targetCount = 1, - paused = true // 初始暂停 - }; - - SelTable.globalOrderStack.AddOrder(newOrder); - SoundDefOf.Click.PlayOneShotOnCamera(); - Log.Message($"[DEBUG] Added order for {recipe.defName}"); - }, - shownItemForIcon: recipe.UIIconThing, // 使用配方的图标ThingDef - thingStyle: null, - forceBasicStyle: false, - priority: MenuOptionPriority.Default, - mouseoverGuiAction: null, - revalidateClickTarget: null, - extraPartWidth: 29f, // 为信息卡按钮留出空间 - extraPartOnGUI: (Rect rect) => - { - // 绘制信息卡按钮,像原版一样 - return Widgets.InfoCardButton(rect.x + 5f, rect.y + (rect.height - 24f) / 2f, recipe); - }, - revalidateWorldClickTarget: null, - playSelectionSound: true, - orderInPriority: -recipe.displayPriority // 使用配方的显示优先级 - )); - } - } - - if (options.Count == 0) - { - options.Add(new FloatMenuOption("WULA_NoAvailableRecipes".Translate(), null)); - } - - return options; - } - public override void TabUpdate() { base.TabUpdate(); diff --git a/Source/WulaFallenEmpire/HediffComp/HediffCompProperties_NanoRepair.cs b/Source/WulaFallenEmpire/HediffComp/HediffCompProperties_NanoRepair.cs index eb4374d2..2643fd92 100644 --- a/Source/WulaFallenEmpire/HediffComp/HediffCompProperties_NanoRepair.cs +++ b/Source/WulaFallenEmpire/HediffComp/HediffCompProperties_NanoRepair.cs @@ -13,10 +13,16 @@ namespace WulaFallenEmpire public float minEnergyThreshold = 0.1f; // 最低能量阈值 public float repairCostPerHP = 0.1f; // 每点生命值修复的能量消耗 public int repairCooldownAfterDamage = 300; // 受到伤害后的修复冷却时间 - + // 新增:与 StatDef 的关联 + public StatDef repairCostStatDef; + public StatDef cooldownStatDef; public HediffCompProperties_NanoRepair() { compClass = typeof(HediffComp_NanoRepair); + + // 设置默认的 StatDef 引用 + repairCostStatDef = DefDatabase.GetNamedSilentFail("WULA_NanoRepairCostPerHP"); + cooldownStatDef = DefDatabase.GetNamedSilentFail("WULA_NanoRepairCooldownAfterDamage"); } } @@ -27,7 +33,7 @@ namespace WulaFallenEmpire private int lastDamageTick = -9999; private const int CheckInterval = 60; private int debugCounter = 0; - private bool repairSystemEnabled = true; // 默认开启修复系统 + public bool repairSystemEnabled = true; // 默认开启修复系统 // 获取可用的能量源 private Need GetEnergyNeed() @@ -161,7 +167,7 @@ namespace WulaFallenEmpire } // 检查是否在冷却期内 - int cooldownRemaining = Props.repairCooldownAfterDamage - (Find.TickManager.TicksGame - lastDamageTick); + int cooldownRemaining = ActualRepairCooldownAfterDamage - (Find.TickManager.TicksGame - lastDamageTick); if (cooldownRemaining > 0) { if (debugCounter % 10 == 0) @@ -404,10 +410,10 @@ namespace WulaFallenEmpire float maxHealth = partToRepair.def.GetMaxHealth(Pawn); float currentHealth = Pawn.health.hediffSet.GetPartHealth(partToRepair); float healthToRepair = maxHealth - currentHealth; - + // 计算修复成本 - float repairCost = healthToRepair * Props.repairCostPerHP; - + float repairCost = healthToRepair * ActualRepairCostPerHP; + // 根据机械族的能量消耗属性调整成本 var mechEnergyLoss = Pawn.GetStatValue(StatDefOf.MechEnergyLossPerHP); if (mechEnergyLoss > 0) @@ -625,6 +631,30 @@ namespace WulaFallenEmpire Log.Message($"[NanoRepair] 受到伤害,开始修复冷却: {lastDamageTick}"); } + // 新增:动态获取属性值的方法 + public float ActualRepairCostPerHP + { + get + { + if (Props.repairCostStatDef != null && Pawn != null) + { + return Pawn.GetStatValue(Props.repairCostStatDef); + } + return Props.repairCostPerHP; + } + } + public int ActualRepairCooldownAfterDamage + { + get + { + if (Props.cooldownStatDef != null && Pawn != null) + { + return (int)Pawn.GetStatValue(Props.cooldownStatDef); + } + return Props.repairCooldownAfterDamage; + } + } + // 添加Gizmo(小工具)用于切换修复系统 public override IEnumerable CompGetGizmos() { @@ -671,13 +701,14 @@ namespace WulaFallenEmpire "WULA_NoDamage".Translate(); string cooldownInfo = ""; - int cooldownRemaining = Props.repairCooldownAfterDamage - (Find.TickManager.TicksGame - lastDamageTick); + int cooldownRemaining = ActualRepairCooldownAfterDamage - (Find.TickManager.TicksGame - lastDamageTick); if (cooldownRemaining > 0) { cooldownInfo = "\n" + "WULA_RepairCooldown".Translate((cooldownRemaining / 60f).ToString("F1")); } - - return status + "\n" + damageInfo + cooldownInfo; + // 添加修复成本信息 + string costInfo = "\n" + "WULA_RepairCostPerHP".Translate(ActualRepairCostPerHP.ToStringPercent()); + return status + "\n" + damageInfo + cooldownInfo + costInfo; } } diff --git a/Source/WulaFallenEmpire/Pawn/WULA_Energy/WulaStatDefOf.cs b/Source/WulaFallenEmpire/Pawn/WULA_Energy/WulaStatDefOf.cs deleted file mode 100644 index 9c8a69d2..00000000 --- a/Source/WulaFallenEmpire/Pawn/WULA_Energy/WulaStatDefOf.cs +++ /dev/null @@ -1,17 +0,0 @@ -using RimWorld; -using Verse; - -namespace WulaFallenEmpire -{ - [DefOf] - public static class WulaStatDefOf - { - public static StatDef WulaEnergyMaxLevelOffset; - public static StatDef WulaEnergyFallRateFactor; - - static WulaStatDefOf() - { - DefOfHelper.EnsureInitializedInCtor(typeof(WulaStatDefOf)); - } - } -} diff --git a/Source/WulaFallenEmpire/Pawn/WULA_Maintenance/HediffCompProperties_MaintenanceDamage.cs b/Source/WulaFallenEmpire/Pawn/WULA_Maintenance/HediffCompProperties_MaintenanceDamage.cs index 61eb71ce..9a2ee22c 100644 --- a/Source/WulaFallenEmpire/Pawn/WULA_Maintenance/HediffCompProperties_MaintenanceDamage.cs +++ b/Source/WulaFallenEmpire/Pawn/WULA_Maintenance/HediffCompProperties_MaintenanceDamage.cs @@ -13,24 +13,29 @@ namespace WulaFallenEmpire compClass = typeof(HediffComp_MaintenanceDamage); } } - + // 在 HediffComp_MaintenanceDamage 类中添加 StatDef 支持 public class HediffComp_MaintenanceDamage : HediffComp { private HediffCompProperties_MaintenanceDamage Props => (HediffCompProperties_MaintenanceDamage)props; - public override void Notify_PawnPostApplyDamage(DamageInfo dinfo, float totalDamageDealt) { base.Notify_PawnPostApplyDamage(dinfo, totalDamageDealt); - - // 获取维护需求 var maintenanceNeed = Pawn.needs?.TryGetNeed(); if (maintenanceNeed == null) return; - - // 直接应用伤害惩罚 + // 使用 StatDef 值而不是硬编码值 maintenanceNeed.ApplyDamagePenalty(totalDamageDealt); } + public override string CompTipStringExtra + { + get + { + // 获取 StatDef 值 + var statDef = DefDatabase.GetNamedSilentFail("WULA_MaintenanceDamageToMaintenanceFactor"); + float damageFactor = statDef != null ? Pawn.GetStatValue(statDef) : Props.damageToMaintenanceFactor; - public override string CompTipStringExtra => "WULA_DamageAffectsMaintenance".Translate(Props.damageToMaintenanceFactor.ToStringPercent()); + return "WULA_DamageAffectsMaintenance".Translate(damageFactor.ToStringPercent()); + } + } } } diff --git a/Source/WulaFallenEmpire/Pawn/WULA_Maintenance/MaintenanceNeedExtension.cs b/Source/WulaFallenEmpire/Pawn/WULA_Maintenance/MaintenanceNeedExtension.cs index 4162105c..21d763df 100644 --- a/Source/WulaFallenEmpire/Pawn/WULA_Maintenance/MaintenanceNeedExtension.cs +++ b/Source/WulaFallenEmpire/Pawn/WULA_Maintenance/MaintenanceNeedExtension.cs @@ -9,18 +9,19 @@ namespace WulaFallenEmpire public float severityPerDayBeforeThreshold = 0.05f; public float severityPerDayAfterThreshold = 0.1f; public float thresholdDays = 5f; - + // 状态阈值 public float minorBreakdownThreshold = 0.3f; public float majorBreakdownThreshold = 0.1f; public float criticalFailureThreshold = 0.01f; - - // 伤害相关设置 - 简化 - public float damageToMaintenanceFactor = 0.01f; // 每点伤害扣除的维护度 - + + // 伤害相关设置 + public float damageToMaintenanceFactor = 0.01f; + // 维护效果相关的 HediffDefs public HediffDef minorBreakdownHediff = null; public HediffDef majorBreakdownHediff = null; public HediffDef criticalFailureHediff = null; } + } diff --git a/Source/WulaFallenEmpire/Pawn/WULA_Maintenance/Need_Maintenance.cs b/Source/WulaFallenEmpire/Pawn/WULA_Maintenance/Need_Maintenance.cs index 685effe4..176f2ec4 100644 --- a/Source/WulaFallenEmpire/Pawn/WULA_Maintenance/Need_Maintenance.cs +++ b/Source/WulaFallenEmpire/Pawn/WULA_Maintenance/Need_Maintenance.cs @@ -22,15 +22,34 @@ namespace WulaFallenEmpire { get { - if (CurLevel <= Extension?.criticalFailureThreshold) return MaintenanceStatus.CriticalFailure; - if (CurLevel <= Extension?.majorBreakdownThreshold) return MaintenanceStatus.MajorBreakdown; - if (CurLevel <= Extension?.minorBreakdownThreshold) return MaintenanceStatus.MinorBreakdown; + if (Extension == null) return MaintenanceStatus.Operational; + // 获取阈值乘数 + float minorFactor = GetStatValue("WULA_MaintenanceMinorBreakdownThresholdFactor"); + float majorFactor = GetStatValue("WULA_MaintenanceMajorBreakdownThresholdFactor"); + float criticalFactor = GetStatValue("WULA_MaintenanceCriticalFailureThresholdFactor"); + float minorThreshold = Extension.minorBreakdownThreshold * minorFactor; + float majorThreshold = Extension.majorBreakdownThreshold * majorFactor; + float criticalThreshold = Extension.criticalFailureThreshold * criticalFactor; + if (CurLevel <= criticalThreshold) return MaintenanceStatus.CriticalFailure; + if (CurLevel <= majorThreshold) return MaintenanceStatus.MajorBreakdown; + if (CurLevel <= minorThreshold) return MaintenanceStatus.MinorBreakdown; return MaintenanceStatus.Operational; } } public float DaysSinceLastMaintenance => daysSinceLastMaintenance; + // 新增:获取 StatDef 值的方法 + private float GetStatValue(string statDefName) + { + var statDef = DefDatabase.GetNamedSilentFail(statDefName); + if (statDef != null) + { + return pawn.GetStatValue(statDef); + } + return 1.0f; // 默认值 + } + public Need_Maintenance(Pawn pawn) : base(pawn) { } @@ -68,19 +87,17 @@ namespace WulaFallenEmpire CheckStatusChanges(); } + // 修改 CalculateDegradationRate 方法以使用 StatDef private float CalculateDegradationRate() { if (Extension == null) return 0f; - - if (daysSinceLastMaintenance < Extension.thresholdDays) - { - return Extension.severityPerDayBeforeThreshold; - } - else - { - return Extension.severityPerDayAfterThreshold; - } + float baseRate = daysSinceLastMaintenance < Extension.thresholdDays ? + Extension.severityPerDayBeforeThreshold : + Extension.severityPerDayAfterThreshold; + // 应用退化乘数 + float degradationFactor = GetStatValue("WULA_MaintenanceDegradationFactor"); + return baseRate * degradationFactor; } private void CheckStatusChanges() @@ -173,15 +190,17 @@ namespace WulaFallenEmpire OnMaintenancePerformed(maintenanceAmount); } - // 应用伤害惩罚 - 简单的线性减少 + // 修改 ApplyDamagePenalty 方法以使用 StatDef public void ApplyDamagePenalty(float damageAmount) { if (Extension == null) return; - - // 直接线性减少维护度 - float reduction = damageAmount * Extension.damageToMaintenanceFactor; + + // 获取伤害转换因子 + float damageFactor = GetStatValue("WULA_MaintenanceDamageToMaintenanceFactor"); + float reduction = damageAmount * damageFactor; + CurLevel = Math.Max(0f, CurLevel - reduction); - + // 检查状态变化 var newStatus = Status; if (newStatus != currentAppliedStatus) diff --git a/Source/WulaFallenEmpire/Stat/StatWorker_Maintenance.cs b/Source/WulaFallenEmpire/Stat/StatWorker_Maintenance.cs new file mode 100644 index 00000000..8f7dfd30 --- /dev/null +++ b/Source/WulaFallenEmpire/Stat/StatWorker_Maintenance.cs @@ -0,0 +1,234 @@ +// StatWorker_Maintenance.cs +using RimWorld; +using Verse; +using System.Collections.Generic; + +namespace WulaFallenEmpire +{ + public class StatWorker_Maintenance : StatWorker + { + public override bool ShouldShowFor(StatRequest req) + { + // 只在有维护需求的机械体上显示 + if (!base.ShouldShowFor(req)) + return false; + + if (req.Thing is Pawn pawn) + { + return HasMaintenanceNeed(pawn); + } + + return false; + } + + public override float GetValueUnfinalized(StatRequest req, bool applyPostProcess = true) + { + if (req.Thing is Pawn pawn) + { + var maintenanceNeed = GetMaintenanceNeed(pawn); + var extension = GetMaintenanceExtension(pawn); + + if (maintenanceNeed != null && extension != null) + { + return GetStatValueForMaintenance(stat.defName, maintenanceNeed, extension); + } + } + + return stat.defaultBaseValue; + } + + public override string GetExplanationUnfinalized(StatRequest req, ToStringNumberSense numberSense) + { + var explanation = base.GetExplanationUnfinalized(req, numberSense); + + if (req.Thing is Pawn pawn) + { + var maintenanceNeed = GetMaintenanceNeed(pawn); + var extension = GetMaintenanceExtension(pawn); + + if (maintenanceNeed != null && extension != null) + { + explanation += "\n\n" + GetMaintenanceExplanation(stat.defName, maintenanceNeed, extension); + } + } + + return explanation; + } + + private bool HasMaintenanceNeed(Pawn pawn) + { + return pawn?.needs?.TryGetNeed() != null; + } + + private Need_Maintenance GetMaintenanceNeed(Pawn pawn) + { + return pawn?.needs?.TryGetNeed(); + } + + private MaintenanceNeedExtension GetMaintenanceExtension(Pawn pawn) + { + var maintenanceNeed = GetMaintenanceNeed(pawn); + return maintenanceNeed?.Extension; + } + + private float GetStatValueForMaintenance(string statDefName, Need_Maintenance need, MaintenanceNeedExtension extension) + { + switch (statDefName) + { + case "WULA_MaintenanceDegradationFactor": + return CalculateDegradationFactor(need, extension); + + case "WULA_MaintenanceStatusThresholdFactor": + return CalculateStatusThresholdFactor(need, extension); + + case "WULA_MaintenanceDamageToMaintenanceFactor": + return CalculateDamageToMaintenanceFactor(need, extension); + + case "WULA_MaintenanceMinorBreakdownThresholdFactor": + return CalculateMinorBreakdownThresholdFactor(need, extension); + + case "WULA_MaintenanceMajorBreakdownThresholdFactor": + return CalculateMajorBreakdownThresholdFactor(need, extension); + + case "WULA_MaintenanceCriticalFailureThresholdFactor": + return CalculateCriticalFailureThresholdFactor(need, extension); + + default: + return stat.defaultBaseValue; + } + } + + private string GetMaintenanceExplanation(string statDefName, Need_Maintenance need, MaintenanceNeedExtension extension) + { + var explanation = "WULA_Maintenance_Properties".Translate(); + + switch (statDefName) + { + case "WULA_MaintenanceDegradationFactor": + explanation += GetDegradationFactorExplanation(need, extension); + break; + + case "WULA_MaintenanceStatusThresholdFactor": + explanation += GetStatusThresholdFactorExplanation(need, extension); + break; + + case "WULA_MaintenanceDamageToMaintenanceFactor": + explanation += GetDamageToMaintenanceFactorExplanation(need, extension); + break; + + case "WULA_MaintenanceMinorBreakdownThresholdFactor": + explanation += GetMinorBreakdownThresholdExplanation(need, extension); + break; + + case "WULA_MaintenanceMajorBreakdownThresholdFactor": + explanation += GetMajorBreakdownThresholdExplanation(need, extension); + break; + + case "WULA_MaintenanceCriticalFailureThresholdFactor": + explanation += GetCriticalFailureThresholdExplanation(need, extension); + break; + } + + return explanation; + } + + // 计算各种统计值的方法 + private float CalculateDegradationFactor(Need_Maintenance need, MaintenanceNeedExtension extension) + { + // 基础退化速率乘数 + return 1.0f; // 默认值,可以根据需要调整 + } + + private float CalculateStatusThresholdFactor(Need_Maintenance need, MaintenanceNeedExtension extension) + { + // 状态阈值乘数 + return 1.0f; // 默认值,可以根据需要调整 + } + + private float CalculateDamageToMaintenanceFactor(Need_Maintenance need, MaintenanceNeedExtension extension) + { + // 伤害到维护度的转换因子 + return extension?.damageToMaintenanceFactor ?? 0.01f; + } + + private float CalculateMinorBreakdownThresholdFactor(Need_Maintenance need, MaintenanceNeedExtension extension) + { + // 轻微故障阈值乘数 + return 1.0f; // 默认值 + } + + private float CalculateMajorBreakdownThresholdFactor(Need_Maintenance need, MaintenanceNeedExtension extension) + { + // 严重故障阈值乘数 + return 1.0f; // 默认值 + } + + private float CalculateCriticalFailureThresholdFactor(Need_Maintenance need, MaintenanceNeedExtension extension) + { + // 完全故障阈值乘数 + return 1.0f; // 默认值 + } + + // 解释文本生成方法 + private string GetDegradationFactorExplanation(Need_Maintenance need, MaintenanceNeedExtension extension) + { + return "WULA_Maintenance_DegradationFactor_Explanation".Translate( + extension?.severityPerDayBeforeThreshold.ToString("F3"), + extension?.severityPerDayAfterThreshold.ToString("F3"), + extension?.thresholdDays.ToString("F1") + ); + } + + private string GetStatusThresholdFactorExplanation(Need_Maintenance need, MaintenanceNeedExtension extension) + { + return "WULA_Maintenance_StatusThresholdFactor_Explanation".Translate( + extension?.minorBreakdownThreshold.ToStringPercent(), + extension?.majorBreakdownThreshold.ToStringPercent(), + extension?.criticalFailureThreshold.ToStringPercent() + ); + } + + private string GetDamageToMaintenanceFactorExplanation(Need_Maintenance need, MaintenanceNeedExtension extension) + { + return "WULA_Maintenance_DamageToMaintenanceFactor_Explanation".Translate( + (extension?.damageToMaintenanceFactor ?? 0.01f).ToStringPercent() + ); + } + + private string GetMinorBreakdownThresholdExplanation(Need_Maintenance need, MaintenanceNeedExtension extension) + { + return "WULA_Maintenance_MinorBreakdownThreshold_Explanation".Translate( + extension?.minorBreakdownThreshold.ToStringPercent() + ); + } + + private string GetMajorBreakdownThresholdExplanation(Need_Maintenance need, MaintenanceNeedExtension extension) + { + return "WULA_Maintenance_MajorBreakdownThreshold_Explanation".Translate( + extension?.majorBreakdownThreshold.ToStringPercent() + ); + } + + private string GetCriticalFailureThresholdExplanation(Need_Maintenance need, MaintenanceNeedExtension extension) + { + return "WULA_Maintenance_CriticalFailureThreshold_Explanation".Translate( + extension?.criticalFailureThreshold.ToStringPercent() + ); + } + + public override IEnumerable GetInfoCardHyperlinks(StatRequest req) + { + foreach (var hyperlink in base.GetInfoCardHyperlinks(req)) + { + yield return hyperlink; + } + + // 添加维护系统的超链接 + var maintenanceNeedDef = DefDatabase.GetNamedSilentFail("WULA_Maintenance"); + if (maintenanceNeedDef != null) + { + yield return new Dialog_InfoCard.Hyperlink(maintenanceNeedDef); + } + } + } +} diff --git a/Source/WulaFallenEmpire/Stat/StatWorker_NanoRepair.cs b/Source/WulaFallenEmpire/Stat/StatWorker_NanoRepair.cs new file mode 100644 index 00000000..c90c1157 --- /dev/null +++ b/Source/WulaFallenEmpire/Stat/StatWorker_NanoRepair.cs @@ -0,0 +1,131 @@ +// StatWorker_NanoRepair.cs +using RimWorld; +using Verse; +using System.Collections.Generic; + +namespace WulaFallenEmpire +{ + public class StatWorker_NanoRepair : StatWorker + { + public override bool ShouldShowFor(StatRequest req) + { + // 只在有 HediffCompProperties_NanoRepair 的 hediff 时显示 + if (!base.ShouldShowFor(req)) + return false; + + // 检查是否为 Pawn + if (req.Thing is Pawn pawn) + { + return HasNanoRepairHediff(pawn); + } + + return false; + } + + public override float GetValueUnfinalized(StatRequest req, bool applyPostProcess = true) + { + if (req.Thing is Pawn pawn) + { + var nanoComp = GetNanoRepairComp(pawn); + if (nanoComp != null) + { + // 根据请求的 StatDef 返回相应的值 + if (stat.defName == "WULA_NanoRepairCostPerHP") + { + return nanoComp.Props.repairCostPerHP; + } + else if (stat.defName == "WULA_NanoRepairCooldownAfterDamage") + { + return nanoComp.Props.repairCooldownAfterDamage; + } + } + } + + return stat.defaultBaseValue; + } + + public override string GetExplanationUnfinalized(StatRequest req, ToStringNumberSense numberSense) + { + var explanation = base.GetExplanationUnfinalized(req, numberSense); + + if (req.Thing is Pawn pawn) + { + var nanoComp = GetNanoRepairComp(pawn); + if (nanoComp != null) + { + explanation += "\n\n" + GetNanoRepairExplanation(nanoComp); + } + } + + return explanation; + } + + private bool HasNanoRepairHediff(Pawn pawn) + { + if (pawn?.health?.hediffSet?.hediffs == null) + return false; + + foreach (var hediff in pawn.health.hediffSet.hediffs) + { + var comp = hediff.TryGetComp(); + if (comp != null) + return true; + } + + return false; + } + + private HediffComp_NanoRepair GetNanoRepairComp(Pawn pawn) + { + if (pawn?.health?.hediffSet?.hediffs == null) + return null; + + foreach (var hediff in pawn.health.hediffSet.hediffs) + { + var comp = hediff.TryGetComp(); + if (comp != null) + return comp; + } + + return null; + } + + private string GetNanoRepairExplanation(HediffComp_NanoRepair nanoComp) + { + var props = nanoComp.Props; + var explanation = "WULA_NanoRepair_Properties".Translate(); + + if (stat.defName == "WULA_NanoRepairCostPerHP") + { + explanation += "WULA_NanoRepair_CostPerHP_Line".Translate(props.repairCostPerHP.ToStringPercent()); + explanation += "WULA_NanoRepair_MinEnergyThreshold_Line".Translate(props.minEnergyThreshold.ToStringPercent()); + } + else if (stat.defName == "WULA_NanoRepairCooldownAfterDamage") + { + explanation += "WULA_NanoRepair_CooldownAfterDamage_Line".Translate(props.repairCooldownAfterDamage, (props.repairCooldownAfterDamage / 60f).ToString("F1")); + + string systemStatus = nanoComp.repairSystemEnabled ? + "WULA_NanoRepair_SystemStatus_Enabled".Translate() : + "WULA_NanoRepair_SystemStatus_Disabled".Translate(); + explanation += "WULA_NanoRepair_SystemStatus_Line".Translate(systemStatus); + } + + return explanation; + } + + public override IEnumerable GetInfoCardHyperlinks(StatRequest req) + { + foreach (var hyperlink in base.GetInfoCardHyperlinks(req)) + { + yield return hyperlink; + } + + // 添加纳米修复系统的超链接 + var nanoHediffDef = DefDatabase.GetNamedSilentFail("WULA_NanoRepairHediff"); + if (nanoHediffDef != null) + { + yield return new Dialog_InfoCard.Hyperlink(nanoHediffDef); + } + } + } +} diff --git a/Source/WulaFallenEmpire/WulaDefOf.cs b/Source/WulaFallenEmpire/WulaDefOf.cs index 762c95aa..0848cdd4 100644 --- a/Source/WulaFallenEmpire/WulaDefOf.cs +++ b/Source/WulaFallenEmpire/WulaDefOf.cs @@ -27,4 +27,15 @@ namespace WulaFallenEmpire DefOfHelper.EnsureInitializedInCtor(typeof(JobDefOf_WULA)); } } + [DefOf] + public static class WulaStatDefOf + { + public static StatDef WulaEnergyMaxLevelOffset; + public static StatDef WulaEnergyFallRateFactor; + + static WulaStatDefOf() + { + DefOfHelper.EnsureInitializedInCtor(typeof(WulaStatDefOf)); + } + } } \ No newline at end of file diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj index 438b303e..5dd15174 100644 --- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj +++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj @@ -148,7 +148,6 @@ - @@ -157,6 +156,7 @@ +