diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index e55182b2..d4689ffe 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/AbilityDefs/WULA_Misc_Ability.xml b/1.6/1.6/Defs/AbilityDefs/WULA_Misc_Ability.xml index 3fdadd2b..7756a16a 100644 --- a/1.6/1.6/Defs/AbilityDefs/WULA_Misc_Ability.xml +++ b/1.6/1.6/Defs/AbilityDefs/WULA_Misc_Ability.xml @@ -51,7 +51,7 @@ WULA_PsiCrusher 以灵能能量发出非人尖啸,直接解构面前扇形区域内的所有目标,无论是建筑物还是活物都难逃毁灭。这种术式需要的灵能难以估量,只有搭载大量封闭灵能回路的灵能泰坦可以连续使用。 - UI/Abilities/FireSpew + Wula/UI/Abilities/WULA_PsiCrusher True False true @@ -247,7 +247,7 @@ WULA_Psi_Skip 使用灵能撕开一个连接自身、虚境和目的地的单向通道,随后以极短的时间穿过整个通道,以瞬间移动到目标地点。 - UI/Abilities/Skip + Wula/UI/Abilities/WULA_TeleportSelf True False false @@ -396,7 +396,7 @@ WULA_Psi_Black_Hole 撕开虚境的裂口,在目标地点召唤一道虚境阴影,它泄露的庞大灵能会持续伤害范围内的敌方单位和建筑,并让物品快速损坏,即使是心灵失聪的目标也不能完全免疫这种超现实伤害——对于高心灵敏感度的单位这种伤害则更加致命。 - UI/Abilities/FireSpew + Wula/UI/Abilities/WULA_Psi_Black_Hole True False true diff --git a/1.6/1.6/Defs/EventDefs/EventDef_Wula/Wula_MainEvent.xml b/1.6/1.6/Defs/EventDefs/EventDef_Wula/Wula_MainEvent.xml index 8599faa3..f4bfefc0 100644 --- a/1.6/1.6/Defs/EventDefs/EventDef_Wula/Wula_MainEvent.xml +++ b/1.6/1.6/Defs/EventDefs/EventDef_Wula/Wula_MainEvent.xml @@ -675,6 +675,84 @@
  • 这是一个测试选项,你可以吃到各种打
  • +
  • + + +
  • + +
  • + 4000 + Wula_PIA_Legion_Faction + ImmediateAttackFriendly + EdgeDropGroups + Combat + +
  • + Combat + 100 + + 1 + +
  • + + +
  • + +
  • + + +
  • + + +
  • + +
  • + 4000 + Wula_PIA_Legion_Faction + ImmediateAttackFriendly + EdgeDropGroups + Combat + +
  • + Combat + 100 + + 1 + +
  • + + +
  • + +
  • + + +
  • + + +
  • + +
  • + 1000 + Wula_PIA_Legion_Faction + ImmediateAttackFriendly + EdgeDropGroups + Combat + +
  • + Combat + 100 + + 1 + +
  • + + +
  • + +
  • + +
  • diff --git a/1.6/1.6/Defs/FactionDefs/Factions_Player_WULA.xml b/1.6/1.6/Defs/FactionDefs/Factions_Player_WULA.xml index f51e9e94..f777fe73 100644 --- a/1.6/1.6/Defs/FactionDefs/Factions_Player_WULA.xml +++ b/1.6/1.6/Defs/FactionDefs/Factions_Player_WULA.xml @@ -36,7 +36,7 @@ Wula_PIA_Legion_Faction - 隶属于乌拉帝国开发署的暴力机关,主要职责是对那些已经有人占领但是军事实力较弱的星球进行封锁和原住民驱离。虽然她们不是真正的军队,但是所保有的舰队和武装力量足以支撑其发起一场横跨星域的战争。\n\n她们之中大部分人居住在自己的庞大舰队中,地表只有零星前哨殖民地。她们也不会派出商队之类的交易者,只会在自己的派系范围内活动,并使用舰队支援这些地面据点的生产和战斗。你可以通过任务接洽和 + 隶属于乌拉帝国开发署的暴力机关,主要职责是对那些已经有人占领但是军事实力较弱的星球进行封锁和原住民驱离。虽然她们不是真正的军队,但是所保有的舰队和武装力量足以支撑其发起一场横跨星域的战争。\n\n她们之中大部分人居住在自己的庞大舰队中,地表只有零星前哨殖民地。她们也不会派出商队之类的交易者,只会在自己的派系范围内活动,并使用舰队支援这些地面据点的生产和战斗。 Wula_PawnKind 乌拉帝国合成人 乌拉帝国合成人 diff --git a/1.6/1.6/Defs/PawnKinds/PawnKinds_Wula.xml b/1.6/1.6/Defs/PawnKinds/PawnKinds_Wula.xml index 12024838..5b09e0d0 100644 --- a/1.6/1.6/Defs/PawnKinds/PawnKinds_Wula.xml +++ b/1.6/1.6/Defs/PawnKinds/PawnKinds_Wula.xml @@ -1,5 +1,6 @@  + Wula_PawnKind @@ -55,7 +56,7 @@ Wula/Things/WULA_Cat/AllegianceOverlays/None CutoutWithOverlay Graphic_Multi - 1 + 1.2
  • @@ -68,7 +69,7 @@ Wula/Things/WULA_Attack_Cat/AllegianceOverlays/None CutoutWithOverlay Graphic_Multi - 1 + 1.2 @@ -95,7 +96,7 @@ Wula/Things/WULA_Constructor_Cat/AllegianceOverlays/None CutoutWithOverlay Graphic_Multi - 1 + 1.2 @@ -112,7 +113,7 @@ Wula/Things/WULA_Assault_Cat/AllegianceOverlays/None CutoutWithOverlay Graphic_Multi - 1 + 1.2 @@ -212,7 +213,7 @@ Wula/Things/WULA_Cat/AllegianceOverlays/None CutoutWithOverlay Graphic_Multi - 3.8 + 3.4 (1.4, 1.8, 1.4) @@ -345,6 +346,7 @@ Wula_PIA_Light_Unit WulaSpecies + Wula_PIA_Legion_Faction
  • @@ -370,6 +372,7 @@ true
  • Wula_Armor_Light
  • +
  • Wula_Inner
  • Wula_Melee_Weapon_T1
  • @@ -402,6 +405,7 @@ Wula_PIA_Heavy_Unit WulaSpecies + Wula_PIA_Legion_Faction
  • @@ -427,6 +431,7 @@ true
  • Wula_Armor_Super_Heavy
  • +
  • Wula_Inner
  • Wula_Melee_Weapon_T1
  • @@ -460,6 +465,7 @@ Wula_PIA_Heavy_Unit_Melee WulaSpecies + Wula_PIA_Legion_Faction
  • @@ -477,8 +483,8 @@ 18 20 500 - 10~20 - 10~20 + 99~99 + 99~99 Legendary Legendary Legendary @@ -488,13 +494,14 @@ Plasteel
  • Wula_Armor_Super_Heavy
  • +
  • Wula_Inner
  • Wula_Melee_Weapon_T3
  • WULA_Heavy_Infantry_PowerArmor
  • -
  • WULA_Heavy_Infantry_Helmet
  • +
  • WULA_Heavy_Infantry_Helmet_Nomask
  • 999999~999999 1 @@ -523,6 +530,7 @@ Wula_PIA_Heavy_Unit_Range WulaSpecies + Wula_PIA_Legion_Faction
  • @@ -540,8 +548,8 @@ 18 20 500 - 10~20 - 10~20 + 99~99 + 99~99 Legendary Legendary Legendary @@ -549,6 +557,7 @@
  • Wula_Armor_Super_Heavy
  • Wula_Armor_Shield
  • +
  • Wula_Inner
  • Wula_Ranged_Weapon_T3
  • @@ -586,6 +595,7 @@ WULA_Legion_PawnKind WulaSpecies + Wula_PIA_Legion_Faction
  • @@ -600,6 +610,7 @@
  • + true 0 true @@ -625,6 +636,7 @@ Wula_PIA_Legion_Escort_Unit WulaSpecies + Wula_PIA_Legion_Faction
  • @@ -639,11 +651,15 @@
  • + + true + 1 + 18 20 500 - 10~20 - 10~20 + 99~99 + 99~99 Legendary Legendary Legendary @@ -652,14 +668,14 @@ true Plasteel -
  • Wula_Armor_Super_Heavy
  • +
  • Wula_Legion_Apparel
  • WULA_MW_Twohanded_ChainBroadsword
  • -
  • WULA_Heavy_Infantry_PowerArmor
  • -
  • WULA_Heavy_Infantry_Helmet
  • +
  • WULA_Heavy_Infantry_Helmet_Nomask
  • +
  • WULA_Champion_Warrior_Armor
  • 999999~999999 1 @@ -682,5 +698,9 @@
  • WULA_Adult_Backstory_Legion_Escort
  • + + +
  • WULA_Trait_Broken_Personality
  • +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/QuestScriptDefs/WULA_Colony_Promotion.xml b/1.6/1.6/Defs/QuestScriptDefs/WULA_Colony_Promotion.xml index ef97f2ea..3fd0d3f9 100644 --- a/1.6/1.6/Defs/QuestScriptDefs/WULA_Colony_Promotion.xml +++ b/1.6/1.6/Defs/QuestScriptDefs/WULA_Colony_Promotion.xml @@ -331,9 +331,9 @@ Raids 1.0 - 1.5 + 0.25 0.04 - 1~1 + 1~2 1.1 500 diff --git a/1.6/1.6/Defs/Scenarios/Scenarios_WULA.xml b/1.6/1.6/Defs/Scenarios/Scenarios_WULA.xml index 7a23157e..1aa3defc 100644 --- a/1.6/1.6/Defs/Scenarios/Scenarios_WULA.xml +++ b/1.6/1.6/Defs/Scenarios/Scenarios_WULA.xml @@ -81,11 +81,6 @@ Apparel_WULA_Manpack_Loitering_Munition 2 -
  • - StartingThing_Defined - WULA_Charge_Cube - 10 -
  • StartingThing_Defined WULA_Fake_Mothership_Beacon_Building diff --git a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Drop_Buildings.xml b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Drop_Buildings.xml index 4e6e1280..1efa9094 100644 --- a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Drop_Buildings.xml +++ b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Drop_Buildings.xml @@ -1618,7 +1618,7 @@ Wula/Building/Wula_Fusion_Generators_Incoming Graphic_Single CutoutFlying - (3,3) + (3.5,3.5) Accelerate @@ -1654,7 +1654,8 @@ Wula/Building/Wula_Fusion_Generators Graphic_Single - (3,3) + (3.5,3.5) + (0, 0, 0.3) (1.93,1,1.69) (-0.03,0,-0.1) 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 54b0b177..998851e3 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 @@ -751,6 +751,8 @@ -0.1 + 1 + 1 @@ -766,6 +768,134 @@ 20 + + WULA_Heavy_Infantry_Helmet_Nomask + + 与乌拉帝国重装装甲配套的头盔,防御力强大。这个版本不配发面罩,因为军需处终于想起来了机械乌拉是不会中毒的。 + +
  • HeadgearNoble
  • + + + + 10 + + WULA_Synth_Armor_2_Technology + + + Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask + + + 20000 + 1000 + 5 + 0 + 1.5 + 1.5 + 2.0 + 5 + + + -0.1 + + + +
  • WULA_Heavy_Infantry_Helmet_Nomask
  • +
  • RoyalTier5
  • +
  • Royal
  • +
    + Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask +
    + 0 + + 2 + 15 + + + + WULA_Champion_Warrior_Armor + + 为乌拉帝国的野心冠军勇士提供的护甲,它比起那些重型护甲要轻便不少。此外,它装备了稀有的双层全反射盾,外部射弹根本无法穿透其护盾,这使得对手只能进入护盾范围内与其近身搏斗。 + +
  • ApparelNoble
  • +
    + + false + + Wula/Apparel/WULA_Champion_Warrior_Armor + + + 50000 + 5 + 0 + 1.3 + 1.3 + 1.5 + 1 + -1 + 0 + 0 + + 3 + + + -0.8 + -2 + 250 + 1 + -2 + + 0 + + 300 + 25 + 25 + 200 + + + +
  • WULA_Champion_Warrior_Armor
  • +
  • RoyalTier5
  • +
  • Royal
  • +
    + Wula/Apparel/WULA_Champion_Warrior_Armor +
    + +
  • + 1000 + 2.5 + 2.8 + 0.01 + 4.0 + false +
  • +
  • + 6 + 1 + 1 + 30 + + + Interceptor_BlockedProjectile + Interceptor_BlockedProjectile + Shield_Break + BulletShieldGenerator_Reactivate + + (0.9, 0.2, 0.2, 0.5) + + + true + false + true + + + true + 1 + 30 + 0 + Interceptor_BlockedProjectile +
  • +
    +
    WULA_Shield_Base diff --git a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Manpack_Weapon.xml b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Manpack_Weapon.xml index 363d20cf..2bf4c041 100644 --- a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Manpack_Weapon.xml +++ b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Manpack_Weapon.xml @@ -324,7 +324,7 @@
  • WULA_MW_ChainSword_MultiStrike
  • 1.75 - 35 + 30 2 WULA_MW_ChainSword_Hit WULA_MW_ChainSword_Hit @@ -351,17 +351,19 @@ 8~12 0.2 -
  • - WULA_MW_Twohanded_ChainBroadsword_Ability - 传送核心 +
  • + +
  • WULA_MW_Twohanded_ChainBroadsword_Second_Ability
  • +
  • WULA_MW_Twohanded_ChainBroadsword_Ability
  • +
    WULA_MW_Twohanded_ChainBroadsword_Ability - 使用CBs-25"地狱牙"刀头的相位引擎立刻折跃至一个新的位置——这种折跃引擎只能折跃小型目标,如果持刀者体型大于1则无法发起传送。 - UI/Abilities/Skip + 使用CBs-25"地狱牙"刀头的相位引擎立刻折跃至一个新的位置——这种折跃引擎只能折跃小型目标,如果持刀者体型大于3则无法发起传送。 + Wula/UI/Abilities/WULA_TeleportSelf True False false @@ -385,7 +387,7 @@ 0 0 - 1 + 3 Impact 3 false @@ -399,6 +401,45 @@ + + WULA_MW_Twohanded_ChainBroadsword_Second_Ability + + 使用CBs-25"地狱牙"刀头的相位引擎将目标拉近到施法者身边——这种折跃引擎只能折跃小型目标,如果持刀者体型大于3则无法发起传送。 + Wula/UI/Abilities/WULA_PullTarget + True + False + false + 200 + HoraxianSpellLight_Warmup + true + + Verb_CastAbility + 1 + 30 + WULA_Psi_Skip_Sound + false + + true + + + +
  • + 30 + 3 + 1.75 + + 15 + 15 + + 3 + Impact + 3 + true + true + true +
  • +
    +
    WULA_MW_Breaker_Bar @@ -508,7 +549,7 @@ WULA_MW_Breaker_Bar_Ability 将PMb-97"破墙槌"的锤头加到最大压强,随后挥出必中的一击,以突破严密的人墙——即使敌人侥幸存活,也会头晕目眩并被砸飞出一段距离。 - UI/Abilities/UnnaturalHealing + Wula/UI/Abilities/WULA_MW_Breaker_Bar_Ability 300 false true @@ -1030,7 +1071,7 @@ WULA_RW_EMP_RF_EMP_Ability 使用FLm-78"萤石"下挂的榴弹发射器发射一枚EMP榴弹以击破护盾和控制机械族,这种重型榴弹发射器发射距离较远,但是需要一点时间架设开火。 - Wula/UI/Abilities/WULA_RW_Auto_GL_Smoke_Ability + Wula/UI/Abilities/WULA_RW_EMP_RF_EMP_Ability True False Misc11 diff --git a/1.6/1.6/Defs/TraitDefs/Traits_WULA.xml b/1.6/1.6/Defs/TraitDefs/Traits_WULA.xml index 8162d78d..1fbe6a39 100644 --- a/1.6/1.6/Defs/TraitDefs/Traits_WULA.xml +++ b/1.6/1.6/Defs/TraitDefs/Traits_WULA.xml @@ -166,7 +166,7 @@
  • - 这个乌拉帝国合成人没有完整的人格,这使得她更像是一台真正的机械——除了饮食外,所有的需求都已经被禁用。 + 这个乌拉帝国合成人没有完整的人格,这使得她更像是一台真正的机械。
  • Mood
  • Joy
  • 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 a993352f..389f13bf 100644 --- a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/Misc_Gameplay.xml +++ b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/Misc_Gameplay.xml @@ -57,24 +57,6 @@ {0}的纳米修复系统已禁用 纳米修复: 已禁用 - - 附近没有可回收的乌拉猫猫。 - 地堡已满。 - 已调用 {0} 个乌拉猫猫回到地堡。 - 已回收 {0}。 - 没有可转换的乌拉猫猫。 - 地堡内的的乌拉猫猫不足。 - 正在将地堡内的{0}个乌拉猫猫转换为{1}。 - - 呼叫乌拉猫猫进驻 - 呼叫{0}格内的乌拉猫猫前来报到,以便转换为其他类型的猫猫,或是使用地堡内武器抵御敌军。 - 地堡存储已满。 - 释放乌拉猫猫 - 将地堡内的乌拉猫猫释放出来,它们可以在离开前重新选择装备以转变类型。\n容量:{0}/{1} - 地堡内没有乌拉猫猫待命。 - - 容量:{0}/{1} - 召唤空投建筑 从乌拉帝国的舰队呼叫对应的建筑空投到此处 空投建筑将在 {0} 后到达 @@ -311,4 +293,54 @@ 显示区域反射盾 隐藏该单位的区域反射盾,这不会影响其实际功能,仅影响视觉效果 显示该单位的区域反射盾,这不会影响其实际功能,仅影响视觉效果 + + + 地堡已满。 + 已回收 {0}。 (当前: {1}/{2}) + 没有可转换的乌拉猫猫。 + 地堡内的的乌拉猫猫不足。 + 正在将地堡内的{0}个乌拉猫猫转换为{1}。 + 呼叫乌拉猫猫进驻 + 呼叫{0}格内的乌拉猫猫前来报到,以便转换为其他类型的猫猫,或是使用地堡内武器抵御敌军。 + 地堡存储已满。 + 释放乌拉猫猫 + 将地堡内的乌拉猫猫释放出来,它们可以在离开前重新选择装备以转变类型。\n容量:{0}/{1} + 地堡内没有乌拉猫猫待命。 + 附近没有可回收的乌拉猫猫。 + 已调用 {0} 个乌拉猫猫回到地堡。 + 容量: {0}/{1} + 转换冷却: {0} 小时 + + + 建筑刚部署,需要等待 {0} 小时后才能转换 + 需要进驻 {0} 个乌拉猫猫,当前: {1}/{2} + 冷却时间剩余: {0} 小时 + 目标单位: {0} + 需要乌拉猫猫: {0} 个 + {0} 已转换为 {1} + + + 单位未生成或已销毁 + 无法确定目标建筑类型 + 周围没有找到合适的放置位置 + 将在附近位置 {0} 部署建筑 + 无法部署建筑: {0} + {0} 已部署为 {1} + 将恢复为: {0} + 最大存储容量: {0} 个乌拉猫猫 + ✓ 当前位置可以放置建筑 + ✗ {0} + + 传送后无有效落脚位置,已取消传送。 + 无效传送位置 + + + 无法拉取该目标 + {0} 体型过大,无法拉取(最大体型:{1}) + 拉取失败:找不到合适的落地位置 + 必须选择一个生物作为目标 + 目标超出范围(最大范围:{0}) + 目标距离过近(最小距离:{0}格) + 没有视线到目标 + 无法拉取该目标 \ No newline at end of file diff --git a/Content/Textures/Wula/Apparel/WULA_Champion_Warrior_Armor.png b/Content/Textures/Wula/Apparel/WULA_Champion_Warrior_Armor.png new file mode 100644 index 00000000..b25ebbab Binary files /dev/null and b/Content/Textures/Wula/Apparel/WULA_Champion_Warrior_Armor.png differ diff --git a/Content/Textures/Wula/Apparel/WULA_Champion_Warrior_Armor_Thin_east.png b/Content/Textures/Wula/Apparel/WULA_Champion_Warrior_Armor_Thin_east.png new file mode 100644 index 00000000..808da4f7 Binary files /dev/null and b/Content/Textures/Wula/Apparel/WULA_Champion_Warrior_Armor_Thin_east.png differ diff --git a/Content/Textures/Wula/Apparel/WULA_Champion_Warrior_Armor_Thin_north.png b/Content/Textures/Wula/Apparel/WULA_Champion_Warrior_Armor_Thin_north.png new file mode 100644 index 00000000..d3c21b65 Binary files /dev/null and b/Content/Textures/Wula/Apparel/WULA_Champion_Warrior_Armor_Thin_north.png differ diff --git a/Content/Textures/Wula/Apparel/WULA_Champion_Warrior_Armor_Thin_south.png b/Content/Textures/Wula/Apparel/WULA_Champion_Warrior_Armor_Thin_south.png new file mode 100644 index 00000000..e7eedd12 Binary files /dev/null and b/Content/Textures/Wula/Apparel/WULA_Champion_Warrior_Armor_Thin_south.png differ diff --git a/Content/Textures/Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask.png b/Content/Textures/Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask.png new file mode 100644 index 00000000..0f9e090b Binary files /dev/null and b/Content/Textures/Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask.png differ diff --git a/Content/Textures/Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask_east.png b/Content/Textures/Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask_east.png new file mode 100644 index 00000000..771a3193 Binary files /dev/null and b/Content/Textures/Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask_east.png differ diff --git a/Content/Textures/Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask_north.png b/Content/Textures/Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask_north.png new file mode 100644 index 00000000..d8cb33b2 Binary files /dev/null and b/Content/Textures/Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask_north.png differ diff --git a/Content/Textures/Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask_south.png b/Content/Textures/Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask_south.png new file mode 100644 index 00000000..e0a6f721 Binary files /dev/null and b/Content/Textures/Wula/Apparel/WULA_Heavy_Infantry_Helmet_Nomask_south.png differ diff --git a/Content/Textures/Wula/UI/Abilities/WULA_MW_Breaker_Bar_Ability.png b/Content/Textures/Wula/UI/Abilities/WULA_MW_Breaker_Bar_Ability.png new file mode 100644 index 00000000..7c905178 Binary files /dev/null and b/Content/Textures/Wula/UI/Abilities/WULA_MW_Breaker_Bar_Ability.png differ diff --git a/Content/Textures/Wula/UI/Abilities/WULA_PsiCrusher.png b/Content/Textures/Wula/UI/Abilities/WULA_PsiCrusher.png new file mode 100644 index 00000000..ed213194 Binary files /dev/null and b/Content/Textures/Wula/UI/Abilities/WULA_PsiCrusher.png differ diff --git a/Content/Textures/Wula/UI/Abilities/WULA_Psi_Black_Hole.png b/Content/Textures/Wula/UI/Abilities/WULA_Psi_Black_Hole.png new file mode 100644 index 00000000..e6671264 Binary files /dev/null and b/Content/Textures/Wula/UI/Abilities/WULA_Psi_Black_Hole.png differ diff --git a/Content/Textures/Wula/UI/Abilities/WULA_PullTarget.png b/Content/Textures/Wula/UI/Abilities/WULA_PullTarget.png new file mode 100644 index 00000000..4a6f4fdb Binary files /dev/null and b/Content/Textures/Wula/UI/Abilities/WULA_PullTarget.png differ diff --git a/Content/Textures/Wula/UI/Abilities/WULA_TeleportSelf.png b/Content/Textures/Wula/UI/Abilities/WULA_TeleportSelf.png new file mode 100644 index 00000000..fefe81c6 Binary files /dev/null and b/Content/Textures/Wula/UI/Abilities/WULA_TeleportSelf.png differ diff --git a/Source/WulaFallenEmpire/Ability/WULA_AbilityTeleportSelf/CompAbilityEffect_TeleportSelf.cs b/Source/WulaFallenEmpire/Ability/WULA_AbilityTeleportSelf/CompAbilityEffect_TeleportSelf.cs index 07705710..d1aa2d63 100644 --- a/Source/WulaFallenEmpire/Ability/WULA_AbilityTeleportSelf/CompAbilityEffect_TeleportSelf.cs +++ b/Source/WulaFallenEmpire/Ability/WULA_AbilityTeleportSelf/CompAbilityEffect_TeleportSelf.cs @@ -97,7 +97,7 @@ namespace WulaFallenEmpire // 如果无法找到有效位置,取消传送 if (!CanTeleportTo(finalTargetCell, map)) { - Messages.Message("TeleportFailedNoValidLocation".Translate(), caster, MessageTypeDefOf.RejectInput); + Messages.Message("WULA_TeleportFailedNoValidLocation".Translate(), caster, MessageTypeDefOf.RejectInput); return; } @@ -218,7 +218,7 @@ namespace WulaFallenEmpire { if (showMessages) { - Messages.Message("CannotTeleportToLocation".Translate(), + Messages.Message("WULA_CannotTeleportToLocation".Translate(), new LookTargets(target.Cell, parent.pawn.Map), MessageTypeDefOf.RejectInput); } @@ -294,7 +294,7 @@ namespace WulaFallenEmpire { if (!CanHitTarget(target)) { - return "CannotTeleportToLocation".Translate(); + return "WULA_CannotTeleportToLocation".Translate(); } return base.ExtraLabelMouseAttachment(target); } diff --git a/Source/WulaFallenEmpire/Ability/WULA_EquippableAbilities/CompEquippableAbilities.cs b/Source/WulaFallenEmpire/Ability/WULA_EquippableAbilities/CompEquippableAbilities.cs new file mode 100644 index 00000000..90dd5a13 --- /dev/null +++ b/Source/WulaFallenEmpire/Ability/WULA_EquippableAbilities/CompEquippableAbilities.cs @@ -0,0 +1,66 @@ +using RimWorld; +using System.Collections.Generic; +using System.Linq; +using Verse; + +namespace WulaFallenEmpire +{ + public class CompEquippableAbilities : ThingComp + { + public CompProperties_EquippableAbilities Props => (CompProperties_EquippableAbilities)props; + + private Pawn wearer; + private List grantedAbilities = new List(); + + public override void Notify_Equipped(Pawn pawn) + { + base.Notify_Equipped(pawn); + wearer = pawn; + GrantAbilities(pawn); + } + + public override void Notify_Unequipped(Pawn pawn) + { + base.Notify_Unequipped(pawn); + RemoveAbilities(pawn); + wearer = null; + } + + private void GrantAbilities(Pawn pawn) + { + if (pawn.abilities == null || Props.abilityDefs == null) + return; + + foreach (AbilityDef abilityDef in Props.abilityDefs) + { + if (!pawn.abilities.abilities.Any(a => a.def == abilityDef)) + { + Ability ability = new Ability(pawn, abilityDef); + pawn.abilities.GainAbility(abilityDef); + grantedAbilities.Add(ability); + } + } + } + + private void RemoveAbilities(Pawn pawn) + { + if (pawn.abilities == null) + return; + + foreach (Ability ability in grantedAbilities) + { + pawn.abilities.RemoveAbility(ability.def); + } + grantedAbilities.Clear(); + } + + public override string CompInspectStringExtra() + { + if (Props.abilityDefs != null && Props.abilityDefs.Count > 0) + { + return $"授予技能: {Props.abilityDefs.Count}"; + } + return base.CompInspectStringExtra(); + } + } +} diff --git a/Source/WulaFallenEmpire/Ability/WULA_EquippableAbilities/CompProperties_EquippableAbilities.cs b/Source/WulaFallenEmpire/Ability/WULA_EquippableAbilities/CompProperties_EquippableAbilities.cs new file mode 100644 index 00000000..c57533f0 --- /dev/null +++ b/Source/WulaFallenEmpire/Ability/WULA_EquippableAbilities/CompProperties_EquippableAbilities.cs @@ -0,0 +1,16 @@ +using RimWorld; +using System.Collections.Generic; +using Verse; + +namespace WulaFallenEmpire +{ + public class CompProperties_EquippableAbilities : CompProperties + { + public List abilityDefs; + + public CompProperties_EquippableAbilities() + { + compClass = typeof(CompEquippableAbilities); + } + } +} diff --git a/Source/WulaFallenEmpire/Ability/WULA_PullTarget/CompAbilityEffect_PullTarget.cs b/Source/WulaFallenEmpire/Ability/WULA_PullTarget/CompAbilityEffect_PullTarget.cs new file mode 100644 index 00000000..2b164c67 --- /dev/null +++ b/Source/WulaFallenEmpire/Ability/WULA_PullTarget/CompAbilityEffect_PullTarget.cs @@ -0,0 +1,439 @@ +using System.Collections.Generic; +using System.Linq; +using RimWorld; +using UnityEngine; +using Verse; +using Verse.Sound; + +namespace WulaFallenEmpire +{ + public class CompAbilityEffect_PullTarget : CompAbilityEffect + { + public static string PullUsedSignalTag = "CompAbilityEffect.PullUsed"; + + public new CompProperties_AbilityPullTarget Props => (CompProperties_AbilityPullTarget)props; + + public override IEnumerable GetPreCastActions() + { + yield return new PreCastAction + { + action = delegate(LocalTargetInfo target, LocalTargetInfo dest) + { + Pawn caster = parent.pawn; + Pawn targetPawn = target.Pawn; + Map map = caster.Map; + + if (targetPawn == null || !IsValidPullTarget(targetPawn)) + { + Messages.Message("WULA_InvalidPullTarget".Translate(), caster, MessageTypeDefOf.RejectInput); + return; + } + + // 在目标位置创建入口特效 + if (Props.customEntryFleck != null) + { + FleckMaker.Static(targetPawn.Position, map, Props.customEntryFleck); + } + else + { + FleckMaker.Static(targetPawn.Position, map, FleckDefOf.PsycastSkipFlashEntry); + } + + // 播放拉取音效 + SoundDefOf.Psycast_Skip_Entry.PlayOneShot(new TargetInfo(targetPawn.Position, map)); + + // 计算拉取目的地 + IntVec3 pullDestination = FindPullDestination(caster, targetPawn, map); + + // 存储拉取目的地 + this.pullDestination = pullDestination; + }, + ticksAwayFromCast = 5 + }; + } + + private IntVec3 pullDestination = IntVec3.Invalid; + + public override void Apply(LocalTargetInfo target, LocalTargetInfo dest) + { + base.Apply(target, dest); + + Pawn caster = parent.pawn; + Pawn targetPawn = target.Pawn; + Map map = caster.Map; + + if (targetPawn == null || !IsValidPullTarget(targetPawn)) + { + Messages.Message("WULA_InvalidPullTarget".Translate(), caster, MessageTypeDefOf.RejectInput); + return; + } + + // 使用存储的拉取目的地或重新计算 + IntVec3 finalDestination = this.pullDestination.IsValid ? this.pullDestination : FindPullDestination(caster, targetPawn, map); + this.pullDestination = IntVec3.Invalid; + + // 验证目的地 + finalDestination = ValidateAndAdjustDestination(finalDestination, targetPawn, map); + + if (!CanTeleportTo(finalDestination, map)) + { + Messages.Message("WULA_PullFailedNoValidLocation".Translate(), caster, MessageTypeDefOf.RejectInput); + return; + } + + // 目标位置入口效果器 + EffecterDef entryEffecter = Props.customEntryEffecter ?? EffecterDefOf.Skip_Entry; + Effecter entryEffect = entryEffecter.Spawn(targetPawn, map); + parent.AddEffecterToMaintain(entryEffect, targetPawn.Position, 60); + + // 目的地出口效果器 + EffecterDef exitEffecter = Props.customExitEffecter ?? EffecterDefOf.Skip_Exit; + Effecter exitEffect = exitEffecter.Spawn(finalDestination, map); + parent.AddEffecterToMaintain(exitEffect, finalDestination, 60); + + // 执行传送(拉取) + targetPawn.Position = finalDestination; + targetPawn.Notify_Teleported(); + + // 如果是玩家阵营,解除战争迷雾 + if ((targetPawn.Faction == Faction.OfPlayer || targetPawn.IsPlayerControlled) && targetPawn.Position.Fogged(map)) + { + FloodFillerFog.FloodUnfog(targetPawn.Position, map); + } + + // 拉取后眩晕目标 + targetPawn.stances.stunner.StunFor(Props.stunTicks.RandomInRange, caster, addBattleLog: true, showMote: true); + + // 发送拉取信号 + SendPullUsedSignal(targetPawn.Position, caster); + + // 播放到达时的喧嚣效果 + if (Props.destClamorType != null) + { + float adjustedRadius = Props.destClamorRadius * Props.effectScale; + GenClamor.DoClamor(caster, finalDestination, adjustedRadius, Props.destClamorType); + } + + // 播放拉取成功音效 + SoundDefOf.Psycast_Skip_Exit.PlayOneShot(new TargetInfo(finalDestination, map)); + + // 记录拉取信息 + if (Prefs.DevMode) + { + Log.Message($"[PullTarget] {caster.Label} 将 {targetPawn.Label} 拉取到 {finalDestination}"); + } + } + + /// + /// 检查目标是否可以被拉取 + /// + private bool IsValidPullTarget(Pawn target) + { + // 检查目标是否为Pawn + if (target == null) + return false; + + // 检查体型限制 + if (target.BodySize > Props.maxTargetBodySize) + { + Messages.Message("WULA_TargetTooLarge".Translate(target.LabelShort, Props.maxTargetBodySize), + parent.pawn, MessageTypeDefOf.RejectInput); + return false; + } + + // 检查目标是否死亡或倒下 + if (target.Dead || target.Downed) + return false; + + // 检查目标是否可被影响(根据派系关系) + if (!Props.canPullHostile && target.HostileTo(parent.pawn.Faction)) + return false; + + if (!Props.canPullNeutral && target.Faction != null && !target.HostileTo(parent.pawn.Faction) && target.Faction != parent.pawn.Faction) + return false; + + if (!Props.canPullFriendly && target.Faction == parent.pawn.Faction) + return false; + + // 检查特殊免疫状态 + if (target.GetComp() != null) + return false; + + return true; + } + + /// + /// 寻找拉取目的地(施法者附近的合适位置) + /// + private IntVec3 FindPullDestination(Pawn caster, Pawn target, Map map) + { + // 在施法者周围寻找合适的拉取位置 + IntVec3 center = caster.Position; + int searchRadius = Props.pullDestinationSearchRadius; + + // 优先选择施法者周围的空位 + for (int radius = 1; radius <= searchRadius; radius++) + { + foreach (IntVec3 cell in GenRadial.RadialCellsAround(center, radius, true)) + { + if (cell.InBounds(map) && + CanTeleportTo(cell, map) && + cell != caster.Position && // 避免和目标重叠 + cell != target.Position) + { + // 检查该位置是否在施法者视线内(可选) + if (!Props.requireLineOfSightToDestination || GenSight.LineOfSight(center, cell, map)) + { + return cell; + } + } + } + } + + // 如果找不到合适位置,返回施法者位置(作为备选) + return center; + } + + /// + /// 验证并调整拉取目的地 + /// + private IntVec3 ValidateAndAdjustDestination(IntVec3 destination, Pawn target, Map map) + { + // 如果目的地不可传送,寻找替代位置 + if (!CanTeleportTo(destination, map)) + { + IntVec3 adjustedCell = FindNearestValidTeleportPosition(destination, target, map, Props.maxPositionAdjustRadius); + if (adjustedCell.IsValid) + { + return adjustedCell; + } + } + + return destination; + } + + /// + /// 寻找最近的可行传送位置 + /// + private IntVec3 FindNearestValidTeleportPosition(IntVec3 center, Pawn pawn, Map map, int maxRadius = 15) + { + // 首先检查中心点本身 + if (CanTeleportTo(center, map)) + return center; + + // 在逐渐增大的半径内搜索 + for (int radius = 1; radius <= maxRadius; radius++) + { + int numCells = GenRadial.NumCellsInRadius(radius); + for (int i = 0; i < numCells; i++) + { + IntVec3 cell = center + GenRadial.RadialPattern[i]; + if (cell.InBounds(map) && CanTeleportTo(cell, map)) + { + return cell; + } + } + } + + return IntVec3.Invalid; + } + + public override bool Valid(LocalTargetInfo target, bool showMessages = true) + { + Pawn targetPawn = target.Pawn; + + if (targetPawn == null) + { + if (showMessages) + { + Messages.Message("WULA_MustTargetPawn".Translate(), + new LookTargets(parent.pawn), + MessageTypeDefOf.RejectInput); + } + return false; + } + + if (!IsValidPullTarget(targetPawn)) + { + if (showMessages) + { + // 错误消息已经在IsValidPullTarget中显示 + } + return false; + } + + // 检查最小距离 - 新增:不允许对身边一格的单位释放 + float distance = target.Cell.DistanceTo(parent.pawn.Position); + if (distance <= Props.minRange) + { + if (showMessages) + { + Messages.Message("WULA_TargetTooClose".Translate(Props.minRange), + new LookTargets(parent.pawn), + MessageTypeDefOf.RejectInput); + } + return false; + } + + // 检查最大距离 + if (distance > Props.range) + { + if (showMessages) + { + Messages.Message("WULA_TargetOutOfRange".Translate(Props.range), + new LookTargets(parent.pawn), + MessageTypeDefOf.RejectInput); + } + return false; + } + + // 检查视线(如果需要) + if (Props.requireLineOfSight && !GenSight.LineOfSight(parent.pawn.Position, target.Cell, parent.pawn.Map)) + { + if (showMessages) + { + Messages.Message("WULA_NoLineOfSight".Translate(), + new LookTargets(parent.pawn), + MessageTypeDefOf.RejectInput); + } + return false; + } + + return base.Valid(target, showMessages); + } + + /// + /// 检查是否可以命中目标 + /// + public bool CanHitTarget(LocalTargetInfo target) + { + Pawn targetPawn = target.Pawn; + + if (targetPawn == null) + return false; + + // 检查距离 + float distance = target.Cell.DistanceTo(parent.pawn.Position); + + // 新增:检查最小距离 + if (distance <= Props.minRange) + return false; + + if (Props.range > 0f && distance > Props.range) + return false; + + // 检查视线(如果需要) + if (Props.requireLineOfSight && !GenSight.LineOfSight(parent.pawn.Position, target.Cell, parent.pawn.Map)) + return false; + + // 检查目标有效性 + return IsValidPullTarget(targetPawn); + } + + /// + /// 检查是否可以传送到指定位置 + /// + private bool CanTeleportTo(IntVec3 cell, Map map) + { + if (!cell.InBounds(map)) + return false; + + // 检查战争迷雾 + if (!Props.canTeleportToFogged && cell.Fogged(map)) + return false; + + // 检查屋顶 + if (!Props.canTeleportToRoofed && map.roofGrid.Roofed(cell)) + return false; + + // 检查是否可站立 + if (!cell.Standable(map)) + return false; + + // 检查是否有障碍物 + Building edifice = cell.GetEdifice(map); + if (edifice != null && edifice.def.surfaceType != SurfaceType.Item && + edifice.def.surfaceType != SurfaceType.Eat && !(edifice is Building_Door { Open: not false })) + { + return false; + } + + // 检查是否有物品阻挡 + List thingList = cell.GetThingList(map); + for (int i = 0; i < thingList.Count; i++) + { + if (thingList[i].def.category == ThingCategory.Item) + { + return false; + } + } + + return true; + } + + public override string ExtraLabelMouseAttachment(LocalTargetInfo target) + { + if (!CanHitTarget(target)) + { + // 检查具体原因以提供更精确的错误信息 + Pawn targetPawn = target.Pawn; + float distance = target.Cell.DistanceTo(parent.pawn.Position); + + if (targetPawn == null) + return "WULA_MustTargetPawn".Translate(); + + if (distance <= Props.minRange) + return "WULA_TargetTooClose".Translate(Props.minRange); + + if (Props.range > 0f && distance > Props.range) + return "WULA_TargetOutOfRange".Translate(Props.range); + + if (Props.requireLineOfSight && !GenSight.LineOfSight(parent.pawn.Position, target.Cell, parent.pawn.Map)) + return "WULA_NoLineOfSight".Translate(); + + return "WULA_CannotPullTarget".Translate(); + } + return base.ExtraLabelMouseAttachment(target); + } + + public override void DrawEffectPreview(LocalTargetInfo target) + { + // 绘制目标高亮 + GenDraw.DrawTargetHighlight(target); + + // 绘制拉取范围 + if (Props.range > 0) + { + GenDraw.DrawRadiusRing(parent.pawn.Position, Props.range); + } + + // 绘制最小范围环 - 新增:显示不允许释放的区域 + if (Props.minRange > 0) + { + GenDraw.DrawRadiusRing(parent.pawn.Position, Props.minRange, Color.red); + } + + // 预览拉取目的地(如果可能) + Pawn targetPawn = target.Pawn; + if (targetPawn != null && IsValidPullTarget(targetPawn)) + { + IntVec3 destination = FindPullDestination(parent.pawn, targetPawn, parent.pawn.Map); + if (destination.IsValid) + { + GenDraw.DrawCircleOutline(destination.ToVector3Shifted(), 1f, SimpleColor.Green); + } + } + } + + public static void SendPullUsedSignal(LocalTargetInfo target, Thing initiator) + { + Find.SignalManager.SendSignal(new Signal(PullUsedSignalTag, target.Named("POSITION"), initiator.Named("SUBJECT"))); + } + } + + // 可选的免疫组件 + public class CompImmuneToPull : ThingComp + { + // 简单的标记组件,表示该单位免疫拉取效果 + } +} diff --git a/Source/WulaFallenEmpire/Ability/WULA_PullTarget/CompProperties_AbilityPullTarget.cs b/Source/WulaFallenEmpire/Ability/WULA_PullTarget/CompProperties_AbilityPullTarget.cs new file mode 100644 index 00000000..3cba4e9d --- /dev/null +++ b/Source/WulaFallenEmpire/Ability/WULA_PullTarget/CompProperties_AbilityPullTarget.cs @@ -0,0 +1,47 @@ +using RimWorld; +using Verse; + +namespace WulaFallenEmpire +{ + public class CompProperties_AbilityPullTarget : CompProperties_AbilityEffect + { + public float range = 12f; + public float minRange = 1f; // 新增:最小拉取距离,默认为1格 + public IntRange stunTicks = new IntRange(30, 60); + public float maxTargetBodySize = 2f; // 最大可拉取目标的体型 + + // 拉取目的地设置 + public int pullDestinationSearchRadius = 3; // 在施法者周围搜索拉取目的地的半径 + public bool requireLineOfSightToDestination = false; // 是否需要视线到拉取目的地 + + // 到达时的喧嚣效果 + public ClamorDef destClamorType; + public float destClamorRadius = 2f; + + // 拉取限制 + public bool requireLineOfSight = true; + public bool canTeleportToFogged = true; + public bool canTeleportToRoofed = true; + + // 派系关系限制 + public bool canPullHostile = true; + public bool canPullNeutral = true; + public bool canPullFriendly = false; // 默认不拉取友军 + + // 自定义效果器 + public EffecterDef customEntryEffecter; + public EffecterDef customExitEffecter; + public FleckDef customEntryFleck; + public FleckDef customExitFleck; + public float effectScale = 1.0f; // 效果缩放比例 + + // 位置调整设置 + public int maxPositionAdjustRadius = 15; // 最大位置调整半径 + public bool allowPositionAdjustment = true; // 是否允许自动调整位置 + + public CompProperties_AbilityPullTarget() + { + compClass = typeof(CompAbilityEffect_PullTarget); + } + } +} diff --git a/Source/WulaFallenEmpire/BuildingComp/WULA_MechanoidRecycler/Building_MechanoidRecycler.cs b/Source/WulaFallenEmpire/BuildingComp/WULA_MechanoidRecycler/Building_MechanoidRecycler.cs index 8471b4fe..31a5aeef 100644 --- a/Source/WulaFallenEmpire/BuildingComp/WULA_MechanoidRecycler/Building_MechanoidRecycler.cs +++ b/Source/WulaFallenEmpire/BuildingComp/WULA_MechanoidRecycler/Building_MechanoidRecycler.cs @@ -53,14 +53,14 @@ namespace WulaFallenEmpire { if (storedMechanoidCount >= Props.maxStorageCapacity) { - Messages.Message("回收器已满", MessageTypeDefOf.RejectInput); + Messages.Message("WULA_RecyclerFull".Translate(), MessageTypeDefOf.RejectInput); return; } storedMechanoidCount++; mech.Destroy(); // 直接销毁,不存储实例 - Messages.Message($"机械族 {mech.LabelCap} 已回收 (当前: {storedMechanoidCount}/{Props.maxStorageCapacity})", + Messages.Message("WULA_MechRecycled".Translate(mech.LabelCap, storedMechanoidCount, Props.maxStorageCapacity), MessageTypeDefOf.PositiveEvent); // 通知转换组件存储更新 @@ -100,7 +100,7 @@ namespace WulaFallenEmpire { if (storedMechanoidCount == 0) { - Messages.Message("没有可用的机械族进行转换", MessageTypeDefOf.RejectInput); + Messages.Message("WULA_NoMechsToConvert".Translate(), MessageTypeDefOf.RejectInput); return; } @@ -121,7 +121,7 @@ namespace WulaFallenEmpire { if (!ConsumeMechanoids(count)) { - Messages.Message("机械族数量不足", MessageTypeDefOf.RejectInput); + Messages.Message("WULA_NotEnoughMechs".Translate(), MessageTypeDefOf.RejectInput); return; } @@ -143,7 +143,7 @@ namespace WulaFallenEmpire } TrySpawnFromQueue(); - Messages.Message($"正在转换 {count} 个机械族为 {kindDef.LabelCap}", MessageTypeDefOf.PositiveEvent); + Messages.Message("WULA_ConvertingMechs".Translate(count, kindDef.LabelCap), MessageTypeDefOf.PositiveEvent); } private void TrySpawnFromQueue() @@ -194,15 +194,15 @@ namespace WulaFallenEmpire // 回收附近机械族按钮 Command_Action recycleCommand = new Command_Action { - defaultLabel = "回收附近机械族", - defaultDesc = $"命令附近 {Props.recycleRange} 格内的机械族前来回收", + defaultLabel = "WULA_RecycleNearbyMechs".Translate(), + defaultDesc = "WULA_RecycleNearbyMechsDesc".Translate(Props.recycleRange), icon = ContentFinder.Get("Wula/UI/Commands/WULA_RecycleNearbyMechanoids"), action = RecycleNearbyMechanoids }; if (storedMechanoidCount >= Props.maxStorageCapacity) { - recycleCommand.Disable("储存器已满"); + recycleCommand.Disable("WULA_StorageFull".Translate()); } yield return recycleCommand; @@ -210,15 +210,15 @@ namespace WulaFallenEmpire // 生成机械族按钮 Command_Action spawnCommand = new Command_Action { - defaultLabel = "转换机械族", - defaultDesc = $"将储存的机械族转换为其他单位 (当前: {storedMechanoidCount}/{Props.maxStorageCapacity})", + defaultLabel = "WULA_ConvertMechs".Translate(), + defaultDesc = "WULA_ConvertMechsDesc".Translate(storedMechanoidCount, Props.maxStorageCapacity), icon = ContentFinder.Get("Wula/UI/Commands/WULA_ConvertMechanoids"), action = OpenSpawnInterface }; if (storedMechanoidCount == 0) { - spawnCommand.Disable("没有可用的机械族"); + spawnCommand.Disable("WULA_NoAvailableMechs".Translate()); } yield return spawnCommand; @@ -229,7 +229,7 @@ namespace WulaFallenEmpire { if (storedMechanoidCount >= Props.maxStorageCapacity) { - Messages.Message("储存器已满", MessageTypeDefOf.RejectInput); + Messages.Message("WULA_StorageFull".Translate(), MessageTypeDefOf.RejectInput); return; } @@ -237,7 +237,7 @@ namespace WulaFallenEmpire if (nearbyMechs.Count == 0) { - Messages.Message("附近没有可回收的机械族", MessageTypeDefOf.RejectInput); + Messages.Message("WULA_NoNearbyRecyclableMechs".Translate(), MessageTypeDefOf.RejectInput); return; } @@ -250,7 +250,7 @@ namespace WulaFallenEmpire } } - Messages.Message($"已命令 {assignedCount} 个机械族前来回收", MessageTypeDefOf.PositiveEvent); + Messages.Message("WULA_MechsOrderedToRecycle".Translate(assignedCount), MessageTypeDefOf.PositiveEvent); } private List FindNearbyRecyclableMechanoids() @@ -312,7 +312,7 @@ namespace WulaFallenEmpire stringBuilder.Append(baseString); } - string storedInfo = $"储存机械族: {storedMechanoidCount}/{Props.maxStorageCapacity}"; + string storedInfo = "WULA_StoredMechs".Translate(storedMechanoidCount, Props.maxStorageCapacity); if (stringBuilder.Length > 0) stringBuilder.AppendLine(); @@ -322,7 +322,7 @@ namespace WulaFallenEmpire if (IsCooldownActive) { stringBuilder.AppendLine(); - stringBuilder.Append($"转换冷却: {GetRemainingCooldownHours():F1} 小时"); + stringBuilder.Append("WULA_TransformCooldown".Translate(GetRemainingCooldownHours().ToString("F1"))); } return stringBuilder.ToString(); diff --git a/Source/WulaFallenEmpire/BuildingComp/WULA_TransformAtFullCapacity/CompTransformAtFullCapacity.cs b/Source/WulaFallenEmpire/BuildingComp/WULA_TransformAtFullCapacity/CompTransformAtFullCapacity.cs index e25dae48..05f359b5 100644 --- a/Source/WulaFallenEmpire/BuildingComp/WULA_TransformAtFullCapacity/CompTransformAtFullCapacity.cs +++ b/Source/WulaFallenEmpire/BuildingComp/WULA_TransformAtFullCapacity/CompTransformAtFullCapacity.cs @@ -9,8 +9,7 @@ namespace WulaFallenEmpire { private CompProperties_TransformAtFullCapacity Props => (CompProperties_TransformAtFullCapacity)props; - // 存储转换前的计数,用于恢复 - private int storedCountAtTransform = 0; + // 移除存储计数的字段,不再进行数量传递 public Building_MechanoidRecycler Recycler => parent as Building_MechanoidRecycler; public bool IsCooldownActive => Recycler?.IsCooldownActive ?? false; @@ -24,7 +23,7 @@ namespace WulaFallenEmpire public override void PostExposeData() { base.PostExposeData(); - Scribe_Values.Look(ref storedCountAtTransform, "storedCountAtTransform", 0); + // 移除存储计数的保存 } public override IEnumerable CompGetGizmosExtra() @@ -33,7 +32,7 @@ namespace WulaFallenEmpire { Command_Action command = new Command_Action { - defaultLabel = Props.gizmoLabel, + defaultLabel = Props.gizmoLabel.Translate(), defaultDesc = GetGizmoDescription(), icon = GetGizmoIcon(), action = TransformToPawn @@ -42,11 +41,11 @@ namespace WulaFallenEmpire // 禁用条件 if (IsCooldownActive) { - command.Disable($"建筑刚部署,需要等待 {Recycler.GetRemainingCooldownHours():F1} 小时后才能转换"); + command.Disable("WULA_BuildingCooldown".Translate(Recycler.GetRemainingCooldownHours().ToString("F1"))); } else if (!IsAtFullCapacity) { - command.Disable($"需要储存 {Props.requiredCapacity} 个机械族,当前: {Recycler.StoredCount}/{Props.requiredCapacity}"); + command.Disable("WULA_NeedMoreMechs".Translate(Props.requiredCapacity, Recycler.StoredCount, Props.requiredCapacity)); } yield return command; @@ -55,12 +54,13 @@ namespace WulaFallenEmpire private string GetGizmoDescription() { - string desc = Props.gizmoDesc; + string desc = Props.gizmoDesc.Translate(); if (IsCooldownActive) { - desc += $"\n\n冷却时间剩余: {Recycler.GetRemainingCooldownHours():F1} 小时"; + desc += "\n\n" + "WULA_CooldownRemaining".Translate(Recycler.GetRemainingCooldownHours().ToString("F1")); } - desc += $"\n目标单位: {Props.targetPawnKind.LabelCap}"; + desc += "\n" + "WULA_TargetUnit".Translate(Props.targetPawnKind.LabelCap); + desc += "\n" + "WULA_MechsRequired".Translate(Props.requiredCapacity); return desc; } @@ -92,13 +92,10 @@ namespace WulaFallenEmpire IntVec3 position = parent.Position; Faction faction = parent.Faction; - // 存储当前的机械族计数(用于恢复) - storedCountAtTransform = Recycler.StoredCount; - // 消耗存储的机械族 if (!Recycler.ConsumeMechanoids(Props.requiredCapacity)) { - Messages.Message("机械族数量不足", MessageTypeDefOf.RejectInput); + Messages.Message("WULA_NotEnoughMechs".Translate(), MessageTypeDefOf.RejectInput); return; } @@ -117,11 +114,12 @@ namespace WulaFallenEmpire Pawn newPawn = PawnGenerator.GeneratePawn(request); - // 添加转换组件并设置恢复数据 + // 添加转换组件,只传递建筑定义,不传递数量 var transformComp = newPawn.GetComp(); if (transformComp != null) { - transformComp.SetRestoreData(parent.def, storedCountAtTransform); + // 只设置建筑定义,不设置恢复数量 + transformComp.SetRestoreData(parent.def); } else { @@ -135,7 +133,8 @@ namespace WulaFallenEmpire transformComp.props = compProps; newPawn.AllComps.Add(transformComp); transformComp.Initialize(compProps); - transformComp.SetRestoreData(parent.def, storedCountAtTransform); + // 只设置建筑定义,不设置恢复数量 + transformComp.SetRestoreData(parent.def); } // 移除建筑 @@ -150,7 +149,7 @@ namespace WulaFallenEmpire Find.Selector.Select(newPawn); } - Messages.Message($"{parent.Label} 已转换为 {newPawn.LabelCap}", MessageTypeDefOf.PositiveEvent); + Messages.Message("WULA_BuildingTransformedToPawn".Translate(parent.Label, newPawn.LabelCap), MessageTypeDefOf.PositiveEvent); // 播放转换效果 PlayTransformEffects(position, map); diff --git a/Source/WulaFallenEmpire/BuildingComp/WULA_TransformAtFullCapacity/CompTransformIntoBuilding.cs b/Source/WulaFallenEmpire/BuildingComp/WULA_TransformAtFullCapacity/CompTransformIntoBuilding.cs index bd448d76..aa084b14 100644 --- a/Source/WulaFallenEmpire/BuildingComp/WULA_TransformAtFullCapacity/CompTransformIntoBuilding.cs +++ b/Source/WulaFallenEmpire/BuildingComp/WULA_TransformAtFullCapacity/CompTransformIntoBuilding.cs @@ -11,9 +11,8 @@ namespace WulaFallenEmpire private CompProperties_TransformIntoBuilding Props => (CompProperties_TransformIntoBuilding)props; private Pawn Pawn => (Pawn)parent; - // 恢复数据 + // 恢复数据 - 只存储建筑定义,不存储数量 private ThingDef restoreBuildingDef; - private int restoreMechanoidCount; // 缓存校验结果 private bool? lastValidationResult = null; @@ -29,14 +28,13 @@ namespace WulaFallenEmpire { base.PostExposeData(); Scribe_Defs.Look(ref restoreBuildingDef, "restoreBuildingDef"); - Scribe_Values.Look(ref restoreMechanoidCount, "restoreMechanoidCount", 0); + // 移除存储数量的保存 } - // 设置恢复数据 - public void SetRestoreData(ThingDef buildingDef, int mechanoidCount) + // 设置恢复数据 - 只设置建筑定义 + public void SetRestoreData(ThingDef buildingDef) { restoreBuildingDef = buildingDef; - restoreMechanoidCount = mechanoidCount; } public override IEnumerable CompGetGizmosExtra() @@ -45,7 +43,7 @@ namespace WulaFallenEmpire { Command_Action command = new Command_Action { - defaultLabel = Props.gizmoLabel, + defaultLabel = Props.gizmoLabel.Translate(), defaultDesc = GetGizmoDescription(), icon = GetGizmoIcon(), action = TransformToBuilding @@ -67,18 +65,20 @@ namespace WulaFallenEmpire private string GetGizmoDescription() { StringBuilder sb = new StringBuilder(); - sb.Append(Props.gizmoDesc); + sb.Append(Props.gizmoDesc.Translate()); if (restoreBuildingDef != null) { sb.AppendLine(); sb.AppendLine(); - sb.Append($"将恢复为: {restoreBuildingDef.LabelCap}"); + sb.Append("WULA_WillRestoreTo".Translate(restoreBuildingDef.LabelCap)); - if (restoreMechanoidCount > 0) + // 显示目标建筑的最大存储容量 + var recyclerProps = restoreBuildingDef.GetCompProperties(); + if (recyclerProps != null) { sb.AppendLine(); - sb.Append($"恢复机械族储存: {restoreMechanoidCount}"); + sb.Append("WULA_MaxStorageCapacity".Translate(recyclerProps.maxStorageCapacity)); } } @@ -90,11 +90,11 @@ namespace WulaFallenEmpire sb.AppendLine(); if (isValid) { - sb.Append("✓ 当前位置可以放置建筑"); + sb.Append("WULA_PositionValid".Translate()); } else { - sb.Append($"✗ {failReason}"); + sb.Append("WULA_PositionInvalid".Translate(failReason)); } return sb.ToString(); @@ -118,7 +118,7 @@ namespace WulaFallenEmpire if (parent == null || !parent.Spawned) { - failReason = "单位未生成或已销毁"; + failReason = "WULA_UnitNotSpawned".Translate(); return false; } @@ -126,7 +126,7 @@ namespace WulaFallenEmpire ThingDef buildingDef = restoreBuildingDef ?? Props.targetBuildingDef; if (buildingDef == null) { - failReason = "无法确定目标建筑类型"; + failReason = "WULA_CannotDetermineBuildingType".Translate(); return false; } @@ -166,7 +166,7 @@ namespace WulaFallenEmpire ThingDef buildingDef = restoreBuildingDef ?? Props.targetBuildingDef; if (buildingDef == null) { - failReason = "无法确定目标建筑类型"; + failReason = "WULA_CannotDetermineBuildingType".Translate(); return false; } @@ -185,7 +185,7 @@ namespace WulaFallenEmpire } } - failReason = "周围没有找到合适的放置位置"; + failReason = "WULA_NoSuitablePositionFound".Translate(); return false; } @@ -202,7 +202,7 @@ namespace WulaFallenEmpire ThingDef buildingDef = restoreBuildingDef ?? Props.targetBuildingDef; if (buildingDef == null) { - Messages.Message("无法确定目标建筑类型", MessageTypeDefOf.RejectInput); + Messages.Message("WULA_CannotDetermineBuildingType".Translate(), MessageTypeDefOf.RejectInput); return; } @@ -215,11 +215,11 @@ namespace WulaFallenEmpire if (TryFindNearbyValidPosition(out alternativePosition, out failReason)) { desiredPosition = alternativePosition; - Messages.Message($"将在附近位置 {desiredPosition} 部署建筑", MessageTypeDefOf.NeutralEvent); + Messages.Message("WULA_DeployingAtNearbyPosition".Translate(desiredPosition), MessageTypeDefOf.NeutralEvent); } else { - Messages.Message($"无法部署建筑: {failReason}", MessageTypeDefOf.RejectInput); + Messages.Message("WULA_CannotDeployBuilding".Translate(failReason), MessageTypeDefOf.RejectInput); return; } } @@ -231,12 +231,8 @@ namespace WulaFallenEmpire Building newBuilding = (Building)GenSpawn.Spawn(buildingDef, desiredPosition, map, WipeMode.Vanish); newBuilding.SetFaction(faction); - // 恢复机械族计数 - var recycler = newBuilding as Building_MechanoidRecycler; - if (recycler != null && restoreMechanoidCount > 0) - { - recycler.SetMechanoidCount(restoreMechanoidCount); - } + // 不再恢复机械族计数,新建筑为空状态 + // 如果需要,可以在这里设置初始状态,但不再传递之前的数量 // 添加建筑转换组件 var transformComp = newBuilding.TryGetComp(); @@ -260,7 +256,7 @@ namespace WulaFallenEmpire Find.Selector.Select(newBuilding); } - Messages.Message($"{Pawn.LabelCap} 已部署为 {newBuilding.Label}", MessageTypeDefOf.PositiveEvent); + Messages.Message("WULA_PawnDeployedAsBuilding".Translate(Pawn.LabelCap, newBuilding.Label), MessageTypeDefOf.PositiveEvent); // 播放转换效果 PlayTransformEffects(desiredPosition, map); diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj index b9545d6c..c1494cb9 100644 --- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj +++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj @@ -94,6 +94,10 @@ + + + + diff --git a/美术与文本源文件/Wula/Apparel/WULA_Champion_Warrior_Armor_Thin_south.sai2 b/美术与文本源文件/Wula/Apparel/WULA_Champion_Warrior_Armor_Thin_south.sai2 new file mode 100644 index 00000000..4bfae4de Binary files /dev/null and b/美术与文本源文件/Wula/Apparel/WULA_Champion_Warrior_Armor_Thin_south.sai2 differ diff --git a/美术与文本源文件/Wula/Apparel/WULA_Knight_Helmet_south.sai2 b/美术与文本源文件/Wula/Apparel/WULA_Knight_Helmet_south.sai2 deleted file mode 100644 index b2fa1295..00000000 Binary files a/美术与文本源文件/Wula/Apparel/WULA_Knight_Helmet_south.sai2 and /dev/null differ diff --git a/美术与文本源文件/Wula/Apparel/WULA_Knight_PowerArmor_Thin_south.sai2 b/美术与文本源文件/Wula/Apparel/WULA_Knight_PowerArmor_Thin_south.sai2 deleted file mode 100644 index b473b956..00000000 Binary files a/美术与文本源文件/Wula/Apparel/WULA_Knight_PowerArmor_Thin_south.sai2 and /dev/null differ diff --git a/美术与文本源文件/Wula/Apparel/WULA_Priest_Hat_south.sai2 b/美术与文本源文件/Wula/Apparel/WULA_Priest_Hat_south.sai2 deleted file mode 100644 index 709444df..00000000 Binary files a/美术与文本源文件/Wula/Apparel/WULA_Priest_Hat_south.sai2 and /dev/null differ diff --git a/美术与文本源文件/Wula/Apparel/WULA_Priest_Uniform_Thin_south.sai2 b/美术与文本源文件/Wula/Apparel/WULA_Priest_Uniform_Thin_south.sai2 deleted file mode 100644 index d2fe04ab..00000000 Binary files a/美术与文本源文件/Wula/Apparel/WULA_Priest_Uniform_Thin_south.sai2 and /dev/null differ diff --git a/美术与文本源文件/Wula/Apparel/WULA_Sailor_Dress_Thin_east.sai2 b/美术与文本源文件/Wula/Apparel/WULA_Sailor_Dress_Thin_east.sai2 deleted file mode 100644 index 3b4eed9a..00000000 Binary files a/美术与文本源文件/Wula/Apparel/WULA_Sailor_Dress_Thin_east.sai2 and /dev/null differ diff --git a/美术与文本源文件/Wula/Apparel/WULA_Sailor_Dress_Thin_north.sai2 b/美术与文本源文件/Wula/Apparel/WULA_Sailor_Dress_Thin_north.sai2 deleted file mode 100644 index eb2e635f..00000000 Binary files a/美术与文本源文件/Wula/Apparel/WULA_Sailor_Dress_Thin_north.sai2 and /dev/null differ diff --git a/美术与文本源文件/Wula/Apparel/WULA_Sailor_Dress_Thin_south.sai2 b/美术与文本源文件/Wula/Apparel/WULA_Sailor_Dress_Thin_south.sai2 deleted file mode 100644 index 89534376..00000000 Binary files a/美术与文本源文件/Wula/Apparel/WULA_Sailor_Dress_Thin_south.sai2 and /dev/null differ diff --git a/美术与文本源文件/Wula/UI/Abilities/WULA_MW_Breaker_Bar_Ability.sai2 b/美术与文本源文件/Wula/UI/Abilities/WULA_MW_Breaker_Bar_Ability.sai2 new file mode 100644 index 00000000..d2026d7b Binary files /dev/null and b/美术与文本源文件/Wula/UI/Abilities/WULA_MW_Breaker_Bar_Ability.sai2 differ diff --git a/美术与文本源文件/Wula/UI/Abilities/WULA_PsiCrusher.sai2 b/美术与文本源文件/Wula/UI/Abilities/WULA_PsiCrusher.sai2 new file mode 100644 index 00000000..1fd3b410 Binary files /dev/null and b/美术与文本源文件/Wula/UI/Abilities/WULA_PsiCrusher.sai2 differ diff --git a/美术与文本源文件/Wula/UI/Abilities/WULA_TeleportSelf.sai2 b/美术与文本源文件/Wula/UI/Abilities/WULA_TeleportSelf.sai2 new file mode 100644 index 00000000..4c9ced3a Binary files /dev/null and b/美术与文本源文件/Wula/UI/Abilities/WULA_TeleportSelf.sai2 differ