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