diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll
index fc40d144..2512b8b9 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/HediffDefs/WULA_FM_Hediffs.xml b/1.6/1.6/Defs/HediffDefs/WULA_FM_Hediffs.xml
new file mode 100644
index 00000000..9972c004
--- /dev/null
+++ b/1.6/1.6/Defs/HediffDefs/WULA_FM_Hediffs.xml
@@ -0,0 +1,91 @@
+
+
+
+
+ WULA_Addons_Antenna_Hediff_Base
+ Hediff_Mechlink
+
+ 乌拉帝国合成人脑袋上有一对天线,她们可以使用这套通讯设备与乌拉帝国舰队通讯,除此之外,她们也可以用这套系统收发次级机械族信号——虽然她们大多数时候并没有供其指挥机械族的带宽可用。
+ 一对可以与舰队通讯的天线。
+ false
+ false
+ true
+ WULA_Addons_Antenna_Bodypart
+
+
+
+
+
+ 调频切换
+ 在舰队、火炮和战舰呼叫频率中进行切换,以呼叫不同的支援
+ 频道:{0}
+ 查看当前频率的详细信息
+
+ Wula_FM_Switc_Fleet
+ Wula_FM_Switc_Artillery
+ Wula_FM_Switc_Aircraft
+
+ 0
+ Wula/UI/Commands/WULA_NanoSwitch
+ false
+
+
+
+
+
+ Wula_FM_Switc_Fleet
+
+ 允许乌拉帝国的合成人呼叫舰队,舰队会为地面上的乌拉帝国殖民地提供支援,但是支援的具体类型需要调频到其他频道进行呼叫。
+ Hediff_High
+ false
+ false
+ True
+ false
+
+
+ false
+
+
+
+
+
+ WULA_CallBattleShip
+
+
+
+
+
+ Wula_FM_Switc_Artillery
+
+ 允许乌拉帝国的合成人呼叫轨道火力支援,包含一系列精准度较差但是覆盖范围广的轰炸能力,一般由拥有<color=#BD2F31><i>武器阵列</i></color>的战舰提供。
+ Hediff_High
+ false
+ false
+ True
+ false
+
+
+ false
+
+
+
+
+
+
+ Wula_FM_Switc_Aircraft
+
+ 允许乌拉帝国的合成人呼叫空中火力,包含一系列精准迅速的近地密接支援,一般由拥有<color=#BD952F><i>机库</i></color>的战舰提供。
+ Hediff_High
+ false
+ false
+ True
+ false
+
+
+ false
+
+
+
+
+
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/HediffDefs/WULA_Misc_Hediffs.xml b/1.6/1.6/Defs/HediffDefs/WULA_Misc_Hediffs.xml
index 24f9c666..cd64eb07 100644
--- a/1.6/1.6/Defs/HediffDefs/WULA_Misc_Hediffs.xml
+++ b/1.6/1.6/Defs/HediffDefs/WULA_Misc_Hediffs.xml
@@ -82,26 +82,6 @@
-
- WULA_Addons_Antenna_Hediff_Base
- Hediff_Mechlink
-
- 乌拉帝国合成人脑袋上有一对天线,她们可以使用这套通讯设备与乌拉帝国舰队通讯。
- 一对可以与舰队通讯的天线。
- false
- false
- true
- WULA_Addons_Antenna_Bodypart
-
-
-
-
-
- WULA_CallBattleShip
-
-
-
-
WULA_ChargingHediff
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 7d9c0c8c..f8a3bb77 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
@@ -861,6 +861,9 @@
false
false
+
+ WULA_WeaponArmor_Productor_Technology
+
1
1
@@ -971,9 +974,6 @@
50
false
Item
-
- WULA_Colony_License_LV1_Technology
-
WulaFallenEmpire.ITab_GlobalBills
@@ -1321,4 +1321,166 @@
+
+
+
+ WULA_Cube_Productor_Cleanzone
+
+ 清理出一块场地并准备好资源,使得乌拉帝国母舰可以向此处投放建筑。建造好的信标可以收起或移至他处,但是必须要有母舰或者后勤舰在上空才能投送建筑。\n\n乌拉帝国编织体是一台简易的塑性构造体,只能生产一些材料,以本地加工的方式降低舰队的加工压力。
+ Wula/Building/WULA_Cube_Productor_Energy_south
+ MinifiedThing
+ Normal
+
+ BuildingsMisc
+
+
+ Wula/Building/WULA_Dropping_Building_Cleanzone
+ Graphic_Multi
+ (1,1)
+
+ false
+
+
+ Building
+ PassThroughOnly
+ false
+ 0.5
+ false
+ 0
+ true
+ (0,0,-1)
+ false
+
+ WULA_WeaponArmor_Productor_Technology
+
+
+ 1
+ 1
+ 1
+ 0
+
+ (1,1)
+ 0
+ 1
+
+ 50
+ 1
+
+
+ BuildingDestroyed_Metal_Small
+
+
+ PlaceWorker_PreventInteractionSpotOverlap
+
+ WULA_Buildings
+
+
+ WULA_Cube_Productor_Incoming
+ true
+ 1
+ WULA_Flyover_BaseBuilder
+ true
+ false
+ 乌拉帝国母舰或后勤舰
+
+
+
+
+ WULA_Cube_Productor_Incoming
+
+ (1,1)
+
+ Wula/Building/WULA_Charging_Station_Synth_Incoming
+ Graphic_Single
+ CutoutFlying
+ (1,1)
+
+
+ Accelerate
+ Things/Skyfaller/SkyfallerShadowDropPod
+ (2, 2)
+ DropPod_Fall
+ 100
+ Explosion_Vaporize
+ 0.05
+ 1
+ 1
+
+
+ (0,0)
+ (1, 1)
+
+
+ WULA_Cube_Productor
+
+
+
+ Smoke_Joint
+
+
+
+
+ WULA_Cube_Productor
+
+ 一台简易的塑性构造体,只能生产一些材料,以本地加工的方式降低舰队的加工压力。
+ Building_WorkTable
+ MapMeshAndRealTime
+
+ Wula/Building/WULA_Cube_Productor_Energy
+ Graphic_Multi
+ (1,1)
+
+ false
+
+
+ (0.75, 0.75, 0.5)
+
+
+ ConstructMetal
+
+ 80
+ 3
+
+ Building
+ 0.5
+ True
+
+ 2000
+ 180
+ 1.0
+
+ (1,1)
+ 2120
+ PassThroughOnly
+ 50
+ True
+ (0,0,-1)
+ Item
+
+
+ Make_WULA_Charge_Cube
+ Make_WULA_Charge_Cube_Group
+ Recharge_WULA_Charge_Cube_Energy
+ Recharge_WULA_Charge_Cube_Energy_Group
+ Make_Component_By_WULA_Cube_Productor
+ Make_WULA_Dark_Matter_Item
+ Make_WULA_Neutronium
+
+
+ ITab_Bills
+
+
+
+ CompPowerTrader
+ 500
+
+
+
+ PlaceWorker_PreventInteractionSpotOverlap
+
+
+
+ BillsTab
+
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Local_Buildings.xml b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Local_Buildings.xml
index bd01984c..4fdbe286 100644
--- a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Local_Buildings.xml
+++ b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Local_Buildings.xml
@@ -54,81 +54,6 @@
0.65
-
-
- WULA_Cube_Productor_Energy
-
- 一台仿制乌拉帝国科技而建造的塑性构造体,可制造乌拉帝国所有的物品。
- Building_WorkTable
- MapMeshAndRealTime
-
- Wula/Building/WULA_Cube_Productor_Energy
- Graphic_Multi
- (1,1)
-
- false
-
-
- (0.75, 0.75, 0.5)
-
-
- ConstructMetal
-
- 80
- 3
-
- Building
- 0.5
- True
-
- WULA_Adv_WorkTable_Technology
-
-
- 2000
- 180
- 1.0
-
- (1,1)
- WULA_Buildings
- 2120
- PassThroughOnly
- 50
- True
- (0,0,-1)
- Item
-
-
- Make_WULA_Charge_Cube
- Make_WULA_Charge_Cube_Group
- Recharge_WULA_Charge_Cube_Energy
- Recharge_WULA_Charge_Cube_Energy_Group
- Make_Component_By_WULA_Cube_Productor
- Make_WULA_Dark_Matter_Item
- Make_WULA_Neutronium
-
-
- ITab_Bills
-
-
-
- CompPowerTrader
- 500
-
-
-
-
-
-
-
- PlaceWorker_PreventInteractionSpotOverlap
-
-
-
- BillsTab
-
-
-
-
Wula_AI_Heavy_Panzer_Gunnery_Turret
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 fc6e3a1a..b00aa4a5 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
@@ -2,7 +2,9 @@
0
-
+
+ Fabric
+
ApparelMisc
diff --git a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Remake_Weapon.xml b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Remake_Weapon.xml
index c5770965..f7578532 100644
--- a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Remake_Weapon.xml
+++ b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Remake_Weapon.xml
@@ -20,7 +20,9 @@
5
0
-
+
+ Metallic
+
80
2
@@ -89,7 +91,9 @@
Spacer
0
-
+
+ Metallic
+
90
25
@@ -175,7 +179,9 @@
0.8
Spacer
0
-
+
+ Metallic
+
20000
@@ -354,6 +360,32 @@
WULA_RW_Base_AR_Ability
眩光弹
+
+
+ Shooting
+ 1.5
+ true
+
+
+ 1000
+ Good
+ WULA_WeaponEvolving
+
+
+ 3000
+ Excellent
+
+
+ 6000
+ Masterwork
+
+
+ 10000
+ Legendary
+ WULA_WeaponMastering
+
+
+
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 424f1aa3..d8b0f7f7 100644
--- a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/Misc_Gameplay.xml
+++ b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/Misc_Gameplay.xml
@@ -259,4 +259,38 @@
种族能量属性:
机械乌拉能量上限偏移量:影响该种族的最大能量储备。
机械乌拉能量消耗速度:影响该种族的能量消耗速率。
+
+
+ 切换效果
+ 点击打开菜单选择不同的效果模式
+ 当前效果:{0}
+ 点击查看当前效果的详细信息
+
+
+ 当前:{0}
+ {0}
+ 已切换到:{0}
+ 选择效果模式
+ 当前效果:{0}\n\n{1}
+ 当前效果:{0}
+
+
+ 未知
+ 无
+ 暂无描述
+
+
+ Current Experience: {0}
+ The total experience accumulated by this weapon.
+ Next Quality: {0} ({1})
+ Next Quality
+ Unlocks at {0} experience.
+ Current Quality
+ The current quality level of this weapon.
+ Maximum Quality Reached: {0}
+ Tracked Skill: {0}
+ {0} has been upgraded to {1} quality!
+
+ Your {0} is evolving with experience!
+ The {0} has reached mastery level!
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/GlobalWorkTable/Building_GlobalWorkTable.cs b/Source/WulaFallenEmpire/GlobalWorkTable/Building_GlobalWorkTable.cs
index 10ed7dc1..a91d0dbf 100644
--- a/Source/WulaFallenEmpire/GlobalWorkTable/Building_GlobalWorkTable.cs
+++ b/Source/WulaFallenEmpire/GlobalWorkTable/Building_GlobalWorkTable.cs
@@ -1,4 +1,4 @@
-// 在 Building_GlobalWorkTable.cs 中移除材质相关代码
+// 在 Building_GlobalWorkTable.cs 中添加材质处理逻辑
using RimWorld;
using System.Collections.Generic;
using System.Linq;
@@ -17,6 +17,13 @@ namespace WulaFallenEmpire
private int lastProcessTick = -1;
private const int ProcessInterval = 1;
+ // 材质映射定义
+ private static readonly Dictionary StuffCategoryMapping = new Dictionary
+ {
+ { StuffCategoryDefOf.Metallic, ThingDefOf.Plasteel }, // 金属类 -> 玻璃钢
+ { StuffCategoryDefOf.Fabric, ThingDefOf_WULA.Hyperweave } // 布革类 -> 超织物
+ };
+
public Building_GlobalWorkTable()
{
globalOrderStack = new GlobalProductionOrderStack(this);
@@ -214,7 +221,7 @@ namespace WulaFallenEmpire
if (!validSpots.Contains(cell) && cell.Standable(map))
{
validSpots.Add(cell);
-
+
if (validSpots.Count >= maxSpots)
break;
}
@@ -224,7 +231,7 @@ namespace WulaFallenEmpire
return validSpots;
}
- // 简化:分配物品到空投舱,移除材质相关代码
+ // 新增:分配物品到空投舱,包含材质处理
private List> DistributeItemsToPods(GlobalStorageWorldComponent storage, int podCount)
{
List> podContents = new List>();
@@ -264,8 +271,7 @@ namespace WulaFallenEmpire
while (remainingCount > 0)
{
int stackSize = Mathf.Min(remainingCount, thingDef.stackLimit);
- Thing thing = ThingMaker.MakeThing(thingDef); // 不再传递材质参数
- thing.stackCount = stackSize;
+ Thing thing = CreateThingWithMaterial(thingDef, stackSize);
allItems.Add(thing);
remainingCount -= stackSize;
}
@@ -292,6 +298,57 @@ namespace WulaFallenEmpire
return podContents;
}
+ // 新增:创建物品并应用材质规则
+ private Thing CreateThingWithMaterial(ThingDef thingDef, int stackCount)
+ {
+ // 检查物品是否需要材质
+ if (thingDef.MadeFromStuff)
+ {
+ // 获取物品可用的材质类别
+ var stuffCategories = thingDef.stuffCategories;
+ if (stuffCategories != null && stuffCategories.Count > 0)
+ {
+ // 检查是否有金属类材质需求
+ var metallicCategory = stuffCategories.FirstOrDefault(sc =>
+ sc.defName == "Metallic" || sc.defName.Contains("Metallic"));
+
+ // 检查是否有布革类材质需求
+ var fabricCategory = stuffCategories.FirstOrDefault(sc =>
+ sc.defName == "Fabric" || sc.defName.Contains("Fabric") ||
+ sc.defName == "Leathery" || sc.defName.Contains("Leather"));
+
+ // 应用材质规则
+ ThingDef selectedStuff = null;
+
+ if (metallicCategory != null)
+ {
+ // 金属类 -> 玻璃钢
+ selectedStuff = ThingDefOf.Plasteel;
+ Log.Message($"[Material Rule] {thingDef.defName} requires metallic, using Plasteel");
+ }
+ else if (fabricCategory != null)
+ {
+ // 布革类 -> 超织物
+ selectedStuff = ThingDefOf_WULA.Hyperweave;
+ Log.Message($"[Material Rule] {thingDef.defName} requires fabric/leather, using Hyperweave");
+ }
+
+ // 创建带有指定材质的物品
+ if (selectedStuff != null)
+ {
+ Thing thing = ThingMaker.MakeThing(thingDef, selectedStuff);
+ thing.stackCount = stackCount;
+ return thing;
+ }
+ }
+ }
+
+ // 默认情况:创建无材质的物品
+ Thing defaultThing = ThingMaker.MakeThing(thingDef);
+ defaultThing.stackCount = stackCount;
+ return defaultThing;
+ }
+
// 在 Building_GlobalWorkTable.cs 中修改 GetRandomPawnKindForType 方法
private PawnKindDef GetRandomPawnKindForType(ThingDef pawnType)
{
diff --git a/Source/WulaFallenEmpire/GlobalWorkTable/GlobalProductionOrder.cs b/Source/WulaFallenEmpire/GlobalWorkTable/GlobalProductionOrder.cs
index 88861432..7571405a 100644
--- a/Source/WulaFallenEmpire/GlobalWorkTable/GlobalProductionOrder.cs
+++ b/Source/WulaFallenEmpire/GlobalWorkTable/GlobalProductionOrder.cs
@@ -1,4 +1,4 @@
-// GlobalProductionOrder.cs (移除所有材质相关代码)
+// GlobalProductionOrder.cs (修复成本计算,使用产物的costList)
using RimWorld;
using System.Collections.Generic;
using System.Linq;
@@ -62,13 +62,47 @@ namespace WulaFallenEmpire
}
}
- // 简化:HasEnoughResources 方法,移除材质检查
+ // 新增:获取产物的成本列表
+ private Dictionary GetProductCostList()
+ {
+ var costDict = new Dictionary();
+
+ if (ProductDef?.costList != null)
+ {
+ foreach (var cost in ProductDef.costList)
+ {
+ if (costDict.ContainsKey(cost.thingDef))
+ costDict[cost.thingDef] += cost.count;
+ else
+ costDict[cost.thingDef] = cost.count;
+ }
+ }
+
+ return costDict;
+ }
+
+ // 修复:HasEnoughResources 方法,使用产物的costList
public bool HasEnoughResources()
{
var globalStorage = Find.World.GetComponent();
if (globalStorage == null) return false;
- // 只检查固定消耗(costList)
+ // 首先检查产物的costList(对于武器等物品)
+ var productCostList = GetProductCostList();
+ if (productCostList.Count > 0)
+ {
+ foreach (var kvp in productCostList)
+ {
+ int requiredCount = kvp.Value;
+ int availableCount = globalStorage.GetInputStorageCount(kvp.Key);
+
+ if (availableCount < requiredCount)
+ return false;
+ }
+ return true;
+ }
+
+ // 如果没有costList,则回退到配方的ingredients(对于加工类配方)
foreach (var ingredient in recipe.ingredients)
{
bool hasEnoughForThisIngredient = false;
@@ -92,13 +126,25 @@ namespace WulaFallenEmpire
return true;
}
- // 简化:ConsumeResources 方法,移除材质消耗
+ // 修复:ConsumeResources 方法,使用产物的costList
public bool ConsumeResources()
{
var globalStorage = Find.World.GetComponent();
if (globalStorage == null) return false;
- // 只消耗固定资源(costList)
+ // 首先消耗产物的costList(对于武器等物品)
+ var productCostList = GetProductCostList();
+ if (productCostList.Count > 0)
+ {
+ foreach (var kvp in productCostList)
+ {
+ if (!globalStorage.RemoveFromInputStorage(kvp.Key, kvp.Value))
+ return false;
+ }
+ return true;
+ }
+
+ // 如果没有costList,则消耗配方的ingredients(对于加工类配方)
foreach (var ingredient in recipe.ingredients)
{
bool consumedThisIngredient = false;
@@ -125,22 +171,25 @@ namespace WulaFallenEmpire
return true;
}
- // 简化:GetIngredientsTooltip 方法,只显示固定消耗
+ // 修复: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)
+ // 首先显示产物的costList(对于武器等物品)
+ var productCostList = GetProductCostList();
+ if (productCostList.Count > 0)
{
- foreach (var thingDef in ingredient.filter.AllowedThingDefs)
+ sb.AppendLine("WULA_FixedIngredients".Translate() + ":");
+
+ foreach (var kvp in productCostList)
{
- int requiredCount = ingredient.CountRequiredOfFor(thingDef, recipe);
+ ThingDef thingDef = kvp.Key;
+ int requiredCount = kvp.Value;
int availableCount = globalStorage?.GetInputStorageCount(thingDef) ?? 0;
string itemDisplay = $"{requiredCount} {thingDef.LabelCap}";
@@ -155,6 +204,31 @@ namespace WulaFallenEmpire
}
}
}
+ else
+ {
+ // 如果没有costList,显示配方的ingredients(对于加工类配方)
+ sb.AppendLine("WULA_FixedIngredients".Translate() + ":");
+
+ 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}");
+ }
+ }
+ }
+ }
// 产品
sb.AppendLine();
diff --git a/Source/WulaFallenEmpire/HediffComp/HediffCompProperties_SwitchableHediff.cs b/Source/WulaFallenEmpire/HediffComp/HediffCompProperties_SwitchableHediff.cs
new file mode 100644
index 00000000..0e33ec2c
--- /dev/null
+++ b/Source/WulaFallenEmpire/HediffComp/HediffCompProperties_SwitchableHediff.cs
@@ -0,0 +1,296 @@
+// HediffCompProperties_SwitchableHediff.cs
+using RimWorld;
+using Verse;
+using System.Collections.Generic;
+using UnityEngine;
+using System.Text;
+
+namespace WulaFallenEmpire
+{
+ public class HediffCompProperties_SwitchableHediff : HediffCompProperties
+ {
+ // 可切换的hediff列表
+ public List availableHediffs = new List();
+
+ // 默认选择的hediff索引
+ public int defaultHediffIndex = 0;
+
+ // Gizmo图标路径
+ public string gizmoIconPath = "UI/Commands/Default";
+
+ // 是否显示当前状态的提示
+ public bool showStatusInGizmo = true;
+
+ // 可自定义的标签和描述
+ public string switchLabel = "WULA_SwitchableHediff_SwitchLabel"; // 默认翻译键
+ public string switchDesc = "WULA_SwitchableHediff_SwitchDesc"; // 默认翻译键
+ public string statusLabel = "WULA_SwitchableHediff_StatusLabel"; // 默认翻译键
+ public string statusDesc = "WULA_SwitchableHediff_StatusDesc"; // 默认翻译键
+
+ public HediffCompProperties_SwitchableHediff()
+ {
+ compClass = typeof(HediffComp_SwitchableHediff);
+ }
+ }
+
+ public class HediffComp_SwitchableHediff : HediffComp
+ {
+ public HediffCompProperties_SwitchableHediff Props => (HediffCompProperties_SwitchableHediff)props;
+
+ // 当前选择的hediff索引
+ private int currentHediffIndex = -1;
+
+ // 当前激活的hediff引用
+ private Hediff activeHediff;
+
+ public override void CompPostMake()
+ {
+ base.CompPostMake();
+
+ // 初始化当前选择
+ if (currentHediffIndex == -1 && Props.availableHediffs.Count > 0)
+ {
+ currentHediffIndex = Props.defaultHediffIndex;
+ if (currentHediffIndex >= Props.availableHediffs.Count)
+ currentHediffIndex = 0;
+
+ // 应用初始hediff
+ ApplySelectedHediff();
+ }
+ }
+
+ // 应用当前选择的hediff
+ private void ApplySelectedHediff()
+ {
+ // 移除之前激活的hediff
+ if (activeHediff != null && Pawn.health.hediffSet.hediffs.Contains(activeHediff))
+ {
+ Pawn.health.RemoveHediff(activeHediff);
+ }
+ activeHediff = null;
+
+ // 应用新的hediff
+ if (currentHediffIndex >= 0 && currentHediffIndex < Props.availableHediffs.Count)
+ {
+ var hediffDef = Props.availableHediffs[currentHediffIndex];
+ if (hediffDef != null)
+ {
+ activeHediff = HediffMaker.MakeHediff(hediffDef, Pawn);
+ activeHediff.Severity = 1f; // 默认严重性为1
+ Pawn.health.AddHediff(activeHediff);
+
+ Log.Message($"[SwitchableHediff] Applied {hediffDef.defName} to {Pawn.LabelShort}");
+ }
+ }
+ }
+
+ // 切换到特定索引的hediff
+ private void SwitchToHediff(int index)
+ {
+ if (index >= 0 && index < Props.availableHediffs.Count)
+ {
+ currentHediffIndex = index;
+ ApplySelectedHediff();
+
+ // 发送切换消息
+ var hediffDef = Props.availableHediffs[index];
+ if (hediffDef != null)
+ {
+ Messages.Message("WULA_SwitchableHediff_SwitchedTo".Translate(hediffDef.label),
+ Pawn, MessageTypeDefOf.SilentInput);
+ }
+ }
+ }
+
+ // 获取当前hediff名称
+ private string GetCurrentHediffName()
+ {
+ if (currentHediffIndex >= 0 && currentHediffIndex < Props.availableHediffs.Count)
+ {
+ var hediffDef = Props.availableHediffs[currentHediffIndex];
+ return hediffDef?.label ?? "WULA_Unknown".Translate();
+ }
+ return "WULA_None".Translate();
+ }
+
+ // 获取当前hediff描述
+ private string GetCurrentHediffDesc()
+ {
+ if (currentHediffIndex >= 0 && currentHediffIndex < Props.availableHediffs.Count)
+ {
+ var hediffDef = Props.availableHediffs[currentHediffIndex];
+ return hediffDef?.description ?? "WULA_NoDescription".Translate();
+ }
+ return string.Empty;
+ }
+
+ // 获取特定hediff的描述
+ private string GetHediffDescription(int index)
+ {
+ if (index >= 0 && index < Props.availableHediffs.Count)
+ {
+ var hediffDef = Props.availableHediffs[index];
+ return hediffDef?.description ?? "WULA_NoDescription".Translate();
+ }
+ return string.Empty;
+ }
+
+ // 获取特定hediff的详细工具提示(包含效果信息)
+ private string GetHediffDetailedTooltip(int index)
+ {
+ if (index >= 0 && index < Props.availableHediffs.Count)
+ {
+ var hediffDef = Props.availableHediffs[index];
+ if (hediffDef == null) return string.Empty;
+
+ StringBuilder sb = new StringBuilder();
+
+ // 添加描述
+ if (!hediffDef.description.NullOrEmpty())
+ {
+ sb.AppendLine(hediffDef.description);
+ }
+ return sb.ToString().TrimEndNewlines();
+ }
+ return string.Empty;
+ }
+ public override IEnumerable CompGetGizmos()
+ {
+ // 只有玩家派系的pawn才显示Gizmo
+ if (Pawn.Faction == Faction.OfPlayer && Props.availableHediffs.Count > 1)
+ {
+ // 主切换按钮 - 显示当前状态
+ Command_Action mainButton = new Command_Action
+ {
+ // 使用可自定义的标签,如果没有自定义则使用翻译键
+ defaultLabel = Props.switchLabel.Translate(),
+ defaultDesc = "WULA_SwitchableHediff_CurrentMode".Translate(GetCurrentHediffName()) + "\n" +
+ Props.switchDesc.Translate(),
+ icon = ContentFinder.Get(Props.gizmoIconPath, false) ?? BaseContent.BadTex,
+ action = () => {
+ // 显示选择菜单
+ ShowHediffSelectionMenu();
+ },
+ hotKey = KeyBindingDefOf.Misc2
+ };
+
+ yield return mainButton;
+
+ // 如果启用了状态显示,添加一个信息Gizmo
+ if (Props.showStatusInGizmo)
+ {
+ Command_Action statusButton = new Command_Action
+ {
+ defaultLabel = Props.statusLabel.Translate(GetCurrentHediffName()),
+ defaultDesc = Props.statusDesc.Translate() + "\n\n" +
+ "WULA_SwitchableHediff_CurrentDesc".Translate(GetCurrentHediffDesc()),
+ icon = ContentFinder.Get("UI/Commands/Info", false) ?? BaseContent.BadTex,
+ action = () => {
+ // 显示当前hediff的详细信息
+ ShowCurrentHediffInfo();
+ }
+ };
+
+ yield return statusButton;
+ }
+ }
+ }
+
+ // 显示hediff选择菜单
+ private void ShowHediffSelectionMenu()
+ {
+ List options = new List();
+
+ for (int i = 0; i < Props.availableHediffs.Count; i++)
+ {
+ int index = i; // 捕获当前索引
+ var hediffDef = Props.availableHediffs[i];
+ string label = hediffDef?.label ?? "WULA_Unknown".Translate();
+ string description = GetHediffDetailedTooltip(i); // 获取详细工具提示
+
+ // 标记当前选择的项目
+ string prefix = (i == currentHediffIndex) ? "✓ " : " ";
+
+ // 创建选项
+ var option = new FloatMenuOption(
+ prefix + label,
+ () => {
+ SwitchToHediff(index);
+ }
+ );
+
+ // 设置工具提示 - 使用详细的描述信息
+ option.tooltip = description;
+
+ options.Add(option);
+ }
+
+ // 显示浮动菜单
+ if (options.Count > 0)
+ {
+ Find.WindowStack.Add(new FloatMenu(options, "WULA_SwitchableHediff_SelectMode".Translate()));
+ }
+ }
+
+ // 显示当前hediff的详细信息
+ private void ShowCurrentHediffInfo()
+ {
+ if (currentHediffIndex >= 0 && currentHediffIndex < Props.availableHediffs.Count)
+ {
+ var hediffDef = Props.availableHediffs[currentHediffIndex];
+ string description = GetHediffDetailedTooltip(currentHediffIndex); // 使用详细工具提示
+
+ Messages.Message(
+ "WULA_SwitchableHediff_CurrentModeInfo".Translate(hediffDef?.label, description),
+ MessageTypeDefOf.SilentInput
+ );
+ }
+ }
+
+ public override string CompTipStringExtra
+ {
+ get
+ {
+ string baseTip = base.CompTipStringExtra ?? "";
+ string currentEffect = "WULA_SwitchableHediff_CurrentEffect".Translate(GetCurrentHediffName());
+
+ if (!string.IsNullOrEmpty(baseTip))
+ return baseTip + "\n" + currentEffect;
+ else
+ return currentEffect;
+ }
+ }
+
+ public override string CompLabelInBracketsExtra
+ {
+ get
+ {
+ return GetCurrentHediffName();
+ }
+ }
+
+ public override void CompExposeData()
+ {
+ base.CompExposeData();
+ Scribe_Values.Look(ref currentHediffIndex, "currentHediffIndex", -1);
+
+ // 加载后重新应用hediff
+ if (Scribe.mode == LoadSaveMode.PostLoadInit && currentHediffIndex != -1)
+ {
+ ApplySelectedHediff();
+ }
+ }
+
+ // 当父hediff被移除时,也要移除激活的hediff
+ public override void CompPostPostRemoved()
+ {
+ base.CompPostPostRemoved();
+
+ if (activeHediff != null && Pawn.health.hediffSet.hediffs.Contains(activeHediff))
+ {
+ Pawn.health.RemoveHediff(activeHediff);
+ }
+ activeHediff = null;
+ }
+ }
+}
diff --git a/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompExperienceCore.cs b/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompExperienceCore.cs
new file mode 100644
index 00000000..d8265c29
--- /dev/null
+++ b/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompExperienceCore.cs
@@ -0,0 +1,259 @@
+using RimWorld;
+using System.Collections.Generic;
+using System.Text;
+using UnityEngine;
+using Verse;
+
+namespace WulaFallenEmpire
+{
+ public class CompExperienceCore : ThingComp
+ {
+ // 当前经验值
+ private float currentExperience;
+
+ // 当前品质
+ private QualityCategory currentQuality = QualityCategory.Normal;
+
+ // 当前装备者
+ private Pawn equippedPawn;
+
+ // 上次检查时的技能经验
+ private float lastSkillExperience;
+
+ // 是否已初始化品质
+ private bool qualityInitialized;
+
+ public CompProperties_ExperienceCore Props => (CompProperties_ExperienceCore)props;
+
+ public float CurrentExperience => currentExperience;
+ public QualityCategory CurrentQuality => currentQuality;
+
+ // 获取下一个品质阈值
+ public ExperienceThreshold NextThreshold
+ {
+ get
+ {
+ var thresholds = Props.experienceThresholds;
+ for (int i = 0; i < thresholds.Count; i++)
+ {
+ if (currentExperience < thresholds[i].experienceRequired)
+ return thresholds[i];
+ }
+ return null;
+ }
+ }
+
+ // 获取当前品质对应的经验阈值
+ public ExperienceThreshold CurrentThreshold
+ {
+ get
+ {
+ var thresholds = Props.experienceThresholds;
+ for (int i = thresholds.Count - 1; i >= 0; i--)
+ {
+ if (currentExperience >= thresholds[i].experienceRequired)
+ return thresholds[i];
+ }
+ return null;
+ }
+ }
+
+ public override void Initialize(CompProperties props)
+ {
+ base.Initialize(props);
+
+ // 如果武器已经有品质,使用现有品质
+ var qualityComp = parent.TryGetComp();
+ if (qualityComp != null && !qualityInitialized)
+ {
+ currentQuality = qualityComp.Quality;
+ qualityInitialized = true;
+ }
+ }
+
+ public override void Notify_Equipped(Pawn pawn)
+ {
+ base.Notify_Equipped(pawn);
+
+ equippedPawn = pawn;
+
+ // 记录当前技能经验
+ if (pawn.skills != null && Props.trackedSkill != null)
+ {
+ var skill = pawn.skills.GetSkill(Props.trackedSkill);
+ if (skill != null)
+ {
+ lastSkillExperience = skill.XpTotalEarned;
+ }
+ }
+
+ Log.Message($"[ExperienceCore] {parent.Label} equipped by {pawn.Name}, tracking {Props.trackedSkill?.defName}");
+ }
+
+ public override void Notify_Unequipped(Pawn pawn)
+ {
+ base.Notify_Unequipped(pawn);
+
+ equippedPawn = null;
+ lastSkillExperience = 0f;
+
+ Log.Message($"[ExperienceCore] {parent.Label} unequipped from {pawn.Name}");
+ }
+
+ public override void CompTick()
+ {
+ base.CompTick();
+
+ // 每60tick检查一次经验变化(约1秒)
+ if (Find.TickManager.TicksGame % 60 == 0 && equippedPawn != null)
+ {
+ UpdateExperience();
+ }
+ }
+
+ private void UpdateExperience()
+ {
+ if (equippedPawn?.skills == null || Props.trackedSkill == null)
+ return;
+
+ var skill = equippedPawn.skills.GetSkill(Props.trackedSkill);
+ if (skill == null)
+ return;
+
+ // 计算获得的经验
+ float currentSkillExperience = skill.XpTotalEarned;
+ float gainedExperience = currentSkillExperience - lastSkillExperience;
+
+ if (gainedExperience > 0)
+ {
+ // 应用倍率
+ float actualGained = gainedExperience * Props.experienceMultiplier;
+ currentExperience += actualGained;
+
+ Log.Message($"[ExperienceCore] {parent.Label} gained {actualGained:F1} experience (from {gainedExperience:F1} skill exp)");
+
+ // 检查品质升级
+ CheckForQualityUpgrade();
+
+ // 更新记录的经验值
+ lastSkillExperience = currentSkillExperience;
+ }
+ }
+
+ private void CheckForQualityUpgrade()
+ {
+ var nextThreshold = NextThreshold;
+ if (nextThreshold != null && currentExperience >= nextThreshold.experienceRequired)
+ {
+ UpgradeQuality(nextThreshold);
+ }
+ }
+
+ private void UpgradeQuality(ExperienceThreshold threshold)
+ {
+ var oldQuality = currentQuality;
+ currentQuality = threshold.quality;
+
+ // 更新武器的品质组件
+ var qualityComp = parent.TryGetComp();
+ if (qualityComp != null)
+ {
+ qualityComp.SetQuality(threshold.quality, ArtGenerationContext.Outsider);
+ }
+
+ // 发送升级消息
+ if (!threshold.messageKey.NullOrEmpty())
+ {
+ Messages.Message(threshold.messageKey.Translate(parent.Label, threshold.quality.GetLabel()),
+ parent, MessageTypeDefOf.PositiveEvent);
+ }
+ else
+ {
+ Messages.Message("WULA_WeaponUpgraded".Translate(parent.Label, threshold.quality.GetLabel()),
+ parent, MessageTypeDefOf.PositiveEvent);
+ }
+
+ Log.Message($"[ExperienceCore] {parent.Label} upgraded from {oldQuality} to {threshold.quality}");
+ }
+
+ public override string CompInspectStringExtra()
+ {
+ if (!Props.showExperienceInfo)
+ return null;
+
+ StringBuilder sb = new StringBuilder();
+
+ // 当前经验
+ sb.AppendLine("WULA_CurrentExperience".Translate(currentExperience.ToString("F0")));
+
+ // 下一个品质阈值
+ var nextThreshold = NextThreshold;
+ if (nextThreshold != null)
+ {
+ float progress = currentExperience / nextThreshold.experienceRequired;
+ sb.AppendLine("WULA_NextQualityProgress".Translate(
+ nextThreshold.quality.GetLabel(),
+ progress.ToStringPercent()
+ ));
+ }
+ else
+ {
+ sb.AppendLine("WULA_MaxQuality".Translate(currentQuality.GetLabel()));
+ }
+
+ // 追踪的技能
+ if (Props.trackedSkill != null)
+ {
+ sb.Append("WULA_TrackedSkill".Translate(Props.trackedSkill.LabelCap));
+ }
+
+ return sb.ToString().TrimEndNewlines();
+ }
+
+ public override IEnumerable SpecialDisplayStats()
+ {
+ if (Props.showExperienceInfo)
+ {
+ yield return new StatDrawEntry(
+ StatCategoryDefOf.Basics,
+ "WULA_CurrentExperience".Translate(),
+ currentExperience.ToString("F0"),
+ "WULA_CurrentExperienceDesc".Translate(),
+ 2100
+ );
+
+ var nextThreshold = NextThreshold;
+ if (nextThreshold != null)
+ {
+ float progress = currentExperience / nextThreshold.experienceRequired;
+ yield return new StatDrawEntry(
+ StatCategoryDefOf.Basics,
+ "WULA_NextQuality".Translate(),
+ $"{nextThreshold.quality.GetLabel()} ({progress.ToStringPercent()})",
+ "WULA_NextQualityDesc".Translate(nextThreshold.experienceRequired),
+ 2099
+ );
+ }
+
+ yield return new StatDrawEntry(
+ StatCategoryDefOf.Basics,
+ "WULA_CurrentQuality".Translate(),
+ currentQuality.GetLabel(),
+ "WULA_CurrentQualityDesc".Translate(),
+ 2098
+ );
+ }
+ }
+
+ public override void PostExposeData()
+ {
+ base.PostExposeData();
+
+ Scribe_Values.Look(ref currentExperience, "currentExperience", 0f);
+ Scribe_Values.Look(ref currentQuality, "currentQuality", QualityCategory.Normal);
+ Scribe_Values.Look(ref qualityInitialized, "qualityInitialized", false);
+ Scribe_Values.Look(ref lastSkillExperience, "lastSkillExperience", 0f);
+ Scribe_References.Look(ref equippedPawn, "equippedPawn");
+ }
+ }
+}
diff --git a/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompProperties_ExperienceCore.cs b/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompProperties_ExperienceCore.cs
new file mode 100644
index 00000000..b53db451
--- /dev/null
+++ b/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompProperties_ExperienceCore.cs
@@ -0,0 +1,33 @@
+using RimWorld;
+using System.Collections.Generic;
+using Verse;
+
+namespace WulaFallenEmpire
+{
+ public class CompProperties_ExperienceCore : CompProperties
+ {
+ // 经验阈值配置
+ public List experienceThresholds;
+
+ // 技能类型:近战还是射击
+ public SkillDef trackedSkill;
+
+ // 经验获取倍率
+ public float experienceMultiplier = 1.0f;
+
+ // 是否显示经验信息
+ public bool showExperienceInfo = true;
+
+ public CompProperties_ExperienceCore()
+ {
+ compClass = typeof(CompExperienceCore);
+ }
+ }
+
+ public class ExperienceThreshold
+ {
+ public int experienceRequired;
+ public QualityCategory quality;
+ public string messageKey; // 升级消息的翻译键
+ }
+}
diff --git a/Source/WulaFallenEmpire/WulaDefOf.cs b/Source/WulaFallenEmpire/WulaDefOf.cs
index 9943a7ab..32c96501 100644
--- a/Source/WulaFallenEmpire/WulaDefOf.cs
+++ b/Source/WulaFallenEmpire/WulaDefOf.cs
@@ -9,7 +9,8 @@ namespace WulaFallenEmpire
public static ThingDef WULA_MaintenancePod;
public static ThingDef WULA_Charging_Station_Synth;
public static ThingDef WULA_PocketMapExit;
-
+ public static ThingDef Hyperweave;
+
static ThingDefOf_WULA()
{
DefOfHelper.EnsureInitializedInCtor(typeof(ThingDefOf_WULA));
diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
index 41f33833..4cee0b42 100644
--- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
+++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
@@ -120,6 +120,7 @@
+
@@ -174,6 +175,8 @@
+
+
diff --git a/美术与文本源文件/Wula/UI/EventUI/新建画布2.sai2 b/美术与文本源文件/Wula/UI/EventUI/新建画布2.sai2
index 7b0b7587..0f5624fa 100644
Binary files a/美术与文本源文件/Wula/UI/EventUI/新建画布2.sai2 and b/美术与文本源文件/Wula/UI/EventUI/新建画布2.sai2 differ