diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index 2512b8b9..69266928 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/BodyAndPartDefs/Bodyparts_WULA.xml b/1.6/1.6/Defs/BodyAndPartDefs/Bodyparts_WULA.xml index 1c7a406d..c310a650 100644 --- a/1.6/1.6/Defs/BodyAndPartDefs/Bodyparts_WULA.xml +++ b/1.6/1.6/Defs/BodyAndPartDefs/Bodyparts_WULA.xml @@ -725,7 +725,7 @@ WULA_AI_Core_Bodypart - + 50 0 false 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 f7578532..90954fd9 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 @@ -1,7 +1,101 @@ + + WULA_ExperienceDataPack_Shooting + + 包含了射击经验的自律核心数据包,可以被乌拉帝国拥有自律核心的武器吸收以提升其品质。 + + Wula/Item/WULA_Dark_Matter_Item + Graphic_Single + + Never + false + false + true + false + + 1000 + 0.01 + 50 + + +
  • ResourcesRaw
  • +
    + false + Medium + 80 + 1 + 1 + +
  • + + + + WULA_ExperienceDataPack_Melee + + 包含了近战经验的自律核心数据包,可以被乌拉帝国拥有自律核心的武器吸收以提升其品质。 + + Wula/Item/WULA_Dark_Matter_Item + Graphic_Single + + Never + false + false + true + false + + 1000 + 0.01 + 50 + + +
  • ResourcesRaw
  • + + false + Medium + 80 + 1 + 1 + +
  • + + + - + + + +
  • + Melee + 1.5 + true + WULA_ExperienceDataPack_Melee + +
  • + 1000 + Good + WULA_WeaponEvolving +
  • +
  • + 3000 + Excellent + WULA_WeaponEvolving +
  • +
  • + 6000 + Masterwork + WULA_WeaponEvolving +
  • +
  • + 10000 + Legendary + WULA_WeaponMastering +
  • + + +
    +
    + WULA_MW_Charge_Mace 这种乌拉帝国战士使用的近战武器由多层复合的高密度钨合金或贫铀合金核心构成,可以利用无与伦比的冲击质量击晕对手。 @@ -76,9 +170,38 @@ 8 8 + +
  • + Melee + 1.5 + true + WULA_ExperienceDataPack_Melee + +
  • + 1000 + Good + WULA_WeaponEvolving +
  • +
  • + 3000 + Excellent + WULA_WeaponEvolving +
  • +
  • + 6000 + Masterwork + WULA_WeaponEvolving +
  • +
  • + 10000 + Legendary + WULA_WeaponMastering +
  • + +
    - + WULA_MW_ChainSword 这种嗡嗡作响的乌拉帝国链锯类武器有多条环绕剑脊高速旋转的多层复合锯齿链条,之间嵌有能量传导节点或微型冷却剂喷口,是力量与纯粹疯狂的象征——它在一次的攻击中会造成大量的伤口,足以从头到脚撕裂敌人的身体。 @@ -162,7 +285,7 @@ Maneuver_Slash_MeleeMiss Maneuver_Slash_MeleeDodge - + WULA_MW_Breaker_Bar 一种沉重的破墙设备,通常由装备外骨骼的乌拉帝国士兵携带,可以通过加压挥出势大力沉的一击,连续击倒多名敌人。 @@ -305,7 +428,40 @@ - + + + +
  • + Shooting + 1.5 + true + WULA_ExperienceDataPack_Shooting + +
  • + 1000 + Good + WULA_WeaponEvolving +
  • +
  • + 3000 + Excellent + WULA_WeaponEvolving +
  • +
  • + 6000 + Masterwork + WULA_WeaponEvolving +
  • +
  • + 10000 + Legendary + WULA_WeaponMastering +
  • + + +
    +
    + WULA_RW_Base_AR 乌拉帝国的基础突击步枪,仍然使用可靠的导气式结构驱动自动射击构件,是一种便宜但好用的武器,通常派发给殖民地作自卫武器之用。它下挂了一个眩光弹发射器,可以发射一枚眩光弹击晕区域内的敌人。 @@ -360,32 +516,6 @@ WULA_RW_Base_AR_Ability 眩光弹 - -
  • - Shooting - 1.5 - true - -
  • - 1000 - Good - WULA_WeaponEvolving -
  • -
  • - 3000 - Excellent -
  • -
  • - 6000 - Masterwork -
  • -
  • - 10000 - Legendary - WULA_WeaponMastering -
  • - -
    @@ -455,7 +585,7 @@ 30 - + WULA_RW_StarDrift_SG 乌拉帝国配发的近距离霰弹枪,以威力巨大的梭镖破甲弹为核心,专注于在短距离上的快速反应战斗和持续性压制能力 @@ -533,7 +663,7 @@ - + WULA_RW_Fractal_RF 乌拉帝国的磁轨狙击枪,通过引导强大的动能发射钢针,射速较慢,但是在击中目标后仍能继续飞行,对路径上的多个敌人造成伤害。 @@ -620,7 +750,7 @@ 5 - + WULA_RW_AutoCannon 一般由乌拉帝国跳帮组或骑士军团携带的自动炮,在拥有长射程的同时火力也非常凶猛,会造成区域性的爆炸效果以控制集群敌军。它同时下挂了一具长射程的EMP榴弹发射器,可以用于控制机械族的集群冲击。 @@ -778,7 +908,7 @@ - + WULA_RW_Beam_Base_AR 乌拉帝国殖民地的制式装备之一,在预热后通过高能电容能量的瞬间释放产生短光束,烧穿多个敌军。作为手持武器,其功率不算太高,因此虽然有强大的贯穿能力却没办法造成太大的伤害。 @@ -881,7 +1011,7 @@ 1 - + WULA_RW_Penetrating_Beam_Rifle 乌拉帝国的多用途穿透型光束武器,可以在散射和集束模式下切换以应对不同的情况。当分光棱镜打开时,其所发射的光束将分裂为多道,伤害和射程有所降低但是获得了更大的散射面积。 @@ -968,7 +1098,7 @@ 1 - + WULA_RW_Penetrating_Beam_Rifle_Ranged 乌拉帝国的多用途穿透型光束武器,可以在散射和集束模式下切换以应对不同的情况。当分光棱镜关闭时,其所发射的光束将集中在一个目标上,获得更大的对单目标的输出能力。 @@ -1098,7 +1228,7 @@ --> - + WULA_RW_Sphene_MG 乌拉帝国的通用机枪,负责在班组中提供如暴雨倾泻的高速连射光束流,产生的高温熔烧穿透效果极好,可以贯穿融化一条线上所有敌人。由于其光束武器的性质,在开始连射前有一段很长时间的预热,非常需要保护。 @@ -1202,7 +1332,7 @@ - + WULA_RW_Handle_Cannon 由乌拉帝国跳帮组或骑士军团携带的手持光束炮,需要很长的时间进行瞄准,但是可以射出在远距离上击穿单体强大光束流。 @@ -1459,7 +1589,7 @@ - + WULA_MW_Lance 乌拉帝国骑士所喜爱的远近合一的重型近战武器,采用高强度纳米碳纤维复合材料内芯,外层覆盖着带有散热格栅和能量导流槽的记忆合金装甲板,既可以在近战中刺穿对手,也可以从远距离上发射光束融化敌军装甲。 @@ -1702,7 +1832,7 @@ - + WULA_RW_Base_Loitering_Munition 乌拉帝国使用的一种反装甲肩扛式巡飞弹,开火速度和飞弹飞行速度都较慢,但是可以在远距离上击穿装甲并造成伤害。 @@ -1865,7 +1995,7 @@ - + WULA_RW_Auto_GL 乌拉帝国所装备的自动榴弹炮,主要发射用于对抗低护甲集群的杀伤性榴弹,优秀的供弹结构使其射速较同类武器快得多。除此之外,它也能临时装填和发射EMP榴弹或烟雾榴弹,这使其成为了一款多功能的支援型武器。 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 d8b0f7f7..221854c6 100644 --- a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/Misc_Gameplay.xml +++ b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/Misc_Gameplay.xml @@ -279,18 +279,43 @@ 暂无描述 - - 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! + 当前经验: {0} + 当前经验 + 此武器积累的总经验值 + + 下一个品质: {0} ({1}) + 下一个品质 + 在 {0} 经验时解锁 + + 当前品质 + 此武器当前的品质等级 + + 已达到最高品质: {0} + 提升自律核心经验所需技能: {0} + + {0} 已升级为 {1} 品质! + + + {0} 的自律核心正在随着其使用者获得的经验而进化,这将提升武器的品质 + {0} 的自律核心经验已达到最高水平! + + + 弹出数据包 + 将自律核心包含的数据提取为可被其他武器的自律核心吸收的数据包,武器将重置为初始状态。 + 吸收数据包 + 自律核心将吸收附近数据包中的经验来提升此武器的品质。 + 存储经验: {0} (来自 {1}) + 经验核心已弹出,包含 {0} 经验 + 从数据包吸收了 {0} 经验 + 未配置数据包定义 + 没有数据可弹出 + 附近未找到兼容的数据包 + 数据包中不包含经验 + 数据包组件缺失 + 溢出经验: {0} + 溢出经验 + 超过最大品质阈值的存储经验 + 超出经验已存储 + 吸收了 {0} 经验,{1} 转换为溢出数据包 + 所有 {0} 经验转换为溢出数据包(已达到最大品质) \ No newline at end of file diff --git a/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompExperienceCore.cs b/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompExperienceCore.cs index d8265c29..3364d3f7 100644 --- a/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompExperienceCore.cs +++ b/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompExperienceCore.cs @@ -20,41 +20,48 @@ namespace WulaFallenEmpire // 上次检查时的技能经验 private float lastSkillExperience; - // 是否已初始化品质 - private bool qualityInitialized; + // 是否已初始化 + private bool initialized = false; + + // 当前阈值索引 + private int currentThresholdIndex = 0; + + // 溢出的经验(超过最大阈值的部分) + private float overflowExperience = 0f; public CompProperties_ExperienceCore Props => (CompProperties_ExperienceCore)props; public float CurrentExperience => currentExperience; public QualityCategory CurrentQuality => currentQuality; + public float OverflowExperience => overflowExperience; + + // 获取最大经验阈值(最后一个阈值) + public float MaxExperienceThreshold + { + get + { + if (Props.experienceThresholds == null || Props.experienceThresholds.Count == 0) + return float.MaxValue; + + return Props.experienceThresholds[Props.experienceThresholds.Count - 1].experienceRequired; + } + } + + // 获取总经验(当前经验 + 溢出经验) + public float TotalExperience => currentExperience + overflowExperience; + + // 检查是否已达到最大品质 + public bool HasReachedMaxQuality => currentThresholdIndex >= Props.experienceThresholds.Count; // 获取下一个品质阈值 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; + if (Props.experienceThresholds == null || currentThresholdIndex >= Props.experienceThresholds.Count) + return null; + + return Props.experienceThresholds[currentThresholdIndex]; } } @@ -62,15 +69,282 @@ namespace WulaFallenEmpire { base.Initialize(props); - // 如果武器已经有品质,使用现有品质 + // 初始化当前品质 var qualityComp = parent.TryGetComp(); - if (qualityComp != null && !qualityInitialized) + if (qualityComp != null && !initialized) { + // 如果武器已经有品质,使用现有品质,否则设置为Normal currentQuality = qualityComp.Quality; - qualityInitialized = true; + initialized = true; + + Log.Message($"[ExperienceCore] Initialized {parent.Label} with quality: {currentQuality}"); } } + // 新增:获取命令按钮 + public override IEnumerable CompGetGizmosExtra() + { + foreach (Gizmo gizmo in base.CompGetGizmosExtra()) + { + yield return gizmo; + } + + // 弹出数据包按钮 + if (Props.dataPackDef != null && TotalExperience > 0) + { + yield return new Command_Action + { + defaultLabel = "WULA_EjectDataPack".Translate(), + defaultDesc = "WULA_EjectDataPackDesc".Translate(), + icon = ContentFinder.Get("UI/Commands/EjectDataPack"), + action = EjectDataPack + }; + } + + // 吸收数据包按钮 + if (Props.dataPackDef != null) + { + yield return new Command_Action + { + defaultLabel = "WULA_AbsorbDataPack".Translate(), + defaultDesc = "WULA_AbsorbDataPackDesc".Translate(), + icon = ContentFinder.Get("UI/Commands/AbsorbDataPack"), + action = AbsorbDataPack + }; + } + } + + // 弹出数据包方法 + private void EjectDataPack() + { + if (Props.dataPackDef == null) + { + Messages.Message("WULA_NoDataPackDef".Translate(), parent, MessageTypeDefOf.RejectInput); + return; + } + + if (TotalExperience <= 0) + { + Messages.Message("WULA_NoExperienceToEject".Translate(), parent, MessageTypeDefOf.RejectInput); + return; + } + + // 创建数据包 + Thing dataPack = ThingMaker.MakeThing(Props.dataPackDef); + CompExperienceDataPack dataPackComp = dataPack.TryGetComp(); + + if (dataPackComp != null) + { + // 计算要存储的总经验(当前经验 + 溢出经验) + float experienceToStore = TotalExperience; + float retainedExperience = TotalExperience * Props.experienceRetentionOnEject; + + dataPackComp.storedExperience = experienceToStore; + dataPackComp.sourceWeaponLabel = parent.Label; + + // 生成数据包 + GenPlace.TryPlaceThing(dataPack, parent.Position, parent.Map, ThingPlaceMode.Near); + + // 重置武器状态,保留部分经验 + ResetWeaponState(retainedExperience); + + Messages.Message("WULA_DataPackEjected".Translate(experienceToStore.ToString("F0")), parent, MessageTypeDefOf.PositiveEvent); + + Log.Message($"[ExperienceCore] Ejected data pack with {experienceToStore} experience, retained {retainedExperience}"); + } + else + { + Messages.Message("WULA_DataPackCompMissing".Translate(), parent, MessageTypeDefOf.RejectInput); + } + } + + // 吸收数据包方法 - 现在会吸收所有附近的数据包并处理溢出 + private void AbsorbDataPack() + { + if (Props.dataPackDef == null) + { + Messages.Message("WULA_NoDataPackDef".Translate(), parent, MessageTypeDefOf.RejectInput); + return; + } + + // 查找附近的所有数据包 + List dataPacks = FindNearbyDataPacks(); + if (dataPacks.Count == 0) + { + Messages.Message("WULA_NoDataPackNearby".Translate(), parent, MessageTypeDefOf.RejectInput); + return; + } + + // 计算总可吸收经验 + float totalExperienceToAbsorb = 0f; + foreach (Thing dataPack in dataPacks) + { + CompExperienceDataPack dataPackComp = dataPack.TryGetComp(); + if (dataPackComp != null && dataPackComp.storedExperience > 0) + { + totalExperienceToAbsorb += dataPackComp.storedExperience; + } + } + + if (totalExperienceToAbsorb <= 0) + { + Messages.Message("WULA_DataPackEmpty".Translate(), parent, MessageTypeDefOf.RejectInput); + return; + } + + // 计算实际可吸收的经验(不超过最大阈值) + float actualExperienceToAbsorb; + float overflowFromAbsorption = 0f; + + if (HasReachedMaxQuality) + { + // 如果已经达到最大品质,所有吸收的经验都算作溢出 + actualExperienceToAbsorb = 0f; + overflowFromAbsorption = totalExperienceToAbsorb; + } + else + { + float remainingToMax = MaxExperienceThreshold - currentExperience; + if (totalExperienceToAbsorb <= remainingToMax) + { + // 可以完全吸收 + actualExperienceToAbsorb = totalExperienceToAbsorb; + overflowFromAbsorption = 0f; + } + else + { + // 只能吸收部分,其余溢出 + actualExperienceToAbsorb = remainingToMax; + overflowFromAbsorption = totalExperienceToAbsorb - remainingToMax; + } + } + + // 应用吸收 + currentExperience += actualExperienceToAbsorb; + overflowExperience += overflowFromAbsorption; + + // 销毁所有被吸收的数据包 + foreach (Thing dataPack in dataPacks) + { + dataPack.Destroy(); + } + + // 检查升级 + if (actualExperienceToAbsorb > 0) + { + CheckForQualityUpgrade(); + } + + // 处理溢出经验 - 如果吸收后有溢出,自动创建一个新的数据包 + if (overflowFromAbsorption > 0) + { + CreateOverflowDataPack(overflowFromAbsorption); + } + + // 发送消息 + string messageText; + if (actualExperienceToAbsorb > 0 && overflowFromAbsorption > 0) + { + messageText = "WULA_DataPackPartiallyAbsorbed".Translate( + actualExperienceToAbsorb.ToString("F0"), + overflowFromAbsorption.ToString("F0") + ); + } + else if (actualExperienceToAbsorb > 0) + { + messageText = "WULA_DataPackAbsorbed".Translate(actualExperienceToAbsorb.ToString("F0")); + } + else + { + messageText = "WULA_DataPackOverflowOnly".Translate(overflowFromAbsorption.ToString("F0")); + } + + Messages.Message(messageText, parent, MessageTypeDefOf.PositiveEvent); + + Log.Message($"[ExperienceCore] {parent.Label} absorbed {actualExperienceToAbsorb} experience, overflow: {overflowFromAbsorption}, total: {currentExperience}, overflow total: {overflowExperience}"); + } + + // 创建溢出数据包 + private void CreateOverflowDataPack(float overflowAmount) + { + if (Props.dataPackDef == null || overflowAmount <= 0) + return; + + Thing overflowDataPack = ThingMaker.MakeThing(Props.dataPackDef); + CompExperienceDataPack dataPackComp = overflowDataPack.TryGetComp(); + + if (dataPackComp != null) + { + dataPackComp.storedExperience = overflowAmount; + dataPackComp.sourceWeaponLabel = parent.Label + " (Overflow)"; + + GenPlace.TryPlaceThing(overflowDataPack, parent.Position, parent.Map, ThingPlaceMode.Near); + + Log.Message($"[ExperienceCore] Created overflow data pack with {overflowAmount} experience"); + } + } + + // 查找附近的所有数据包 + private List FindNearbyDataPacks() + { + List foundDataPacks = new List(); + + if (parent.Map == null) + return foundDataPacks; + + // 在指定半径范围内查找所有相同类型的数据包 + CellRect searchRect = CellRect.CenteredOn(parent.Position, Props.absorbRadius); + foreach (IntVec3 cell in searchRect) + { + if (cell.InBounds(parent.Map)) + { + List things = parent.Map.thingGrid.ThingsListAt(cell); + foreach (Thing thing in things) + { + if (thing.def == Props.dataPackDef && + thing.TryGetComp() != null && + !foundDataPacks.Contains(thing)) + { + foundDataPacks.Add(thing); + } + } + } + } + + Log.Message($"[ExperienceCore] Found {foundDataPacks.Count} data packs within {Props.absorbRadius} tiles"); + return foundDataPacks; + } + + // 重置武器状态 + private void ResetWeaponState(float retainedExperience = 0f) + { + var oldTotalExperience = TotalExperience; + + // 分配保留的经验 + if (retainedExperience <= MaxExperienceThreshold) + { + currentExperience = retainedExperience; + overflowExperience = 0f; + } + else + { + currentExperience = MaxExperienceThreshold; + overflowExperience = retainedExperience - MaxExperienceThreshold; + } + + currentQuality = QualityCategory.Normal; + currentThresholdIndex = 0; + + // 更新品质组件 + var qualityComp = parent.TryGetComp(); + if (qualityComp != null) + { + qualityComp.SetQuality(currentQuality, ArtGenerationContext.Outsider); + } + + Log.Message($"[ExperienceCore] {parent.Label} reset from {oldTotalExperience} total experience to {currentExperience} + {overflowExperience} overflow"); + } + public override void Notify_Equipped(Pawn pawn) { base.Notify_Equipped(pawn); @@ -84,10 +358,9 @@ namespace WulaFallenEmpire if (skill != null) { lastSkillExperience = skill.XpTotalEarned; + Log.Message($"[ExperienceCore] {parent.Label} equipped by {pawn.Name}, tracking {Props.trackedSkill.defName}, starting experience: {lastSkillExperience}"); } } - - Log.Message($"[ExperienceCore] {parent.Label} equipped by {pawn.Name}, tracking {Props.trackedSkill?.defName}"); } public override void Notify_Unequipped(Pawn pawn) @@ -128,9 +401,30 @@ namespace WulaFallenEmpire { // 应用倍率 float actualGained = gainedExperience * Props.experienceMultiplier; - currentExperience += actualGained; - Log.Message($"[ExperienceCore] {parent.Label} gained {actualGained:F1} experience (from {gainedExperience:F1} skill exp)"); + // 分配经验:优先填充当前经验,超出部分转为溢出经验 + if (HasReachedMaxQuality) + { + // 已经达到最大品质,所有新经验都算作溢出 + overflowExperience += actualGained; + } + else + { + float remainingToMax = MaxExperienceThreshold - currentExperience; + if (actualGained <= remainingToMax) + { + // 可以完全添加到当前经验 + currentExperience += actualGained; + } + else + { + // 部分添加到当前经验,其余转为溢出 + currentExperience = MaxExperienceThreshold; + overflowExperience += (actualGained - remainingToMax); + } + } + + Log.Message($"[ExperienceCore] {parent.Label} gained {actualGained:F1} experience (current: {currentExperience:F1}, overflow: {overflowExperience:F1})"); // 检查品质升级 CheckForQualityUpgrade(); @@ -143,9 +437,10 @@ namespace WulaFallenEmpire private void CheckForQualityUpgrade() { var nextThreshold = NextThreshold; - if (nextThreshold != null && currentExperience >= nextThreshold.experienceRequired) + while (nextThreshold != null && currentExperience >= nextThreshold.experienceRequired) { UpgradeQuality(nextThreshold); + nextThreshold = NextThreshold; // 获取下一个阈值 } } @@ -153,27 +448,35 @@ namespace WulaFallenEmpire { var oldQuality = currentQuality; currentQuality = threshold.quality; + currentThresholdIndex++; // 移动到下一个阈值 // 更新武器的品质组件 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); + Log.Message($"[ExperienceCore] SUCCESS: {parent.Label} quality updated to {threshold.quality}"); } else { - Messages.Message("WULA_WeaponUpgraded".Translate(parent.Label, threshold.quality.GetLabel()), - parent, MessageTypeDefOf.PositiveEvent); + Log.Error($"[ExperienceCore] ERROR: {parent.Label} has no CompQuality component!"); + return; } - Log.Message($"[ExperienceCore] {parent.Label} upgraded from {oldQuality} to {threshold.quality}"); + // 发送升级消息 + string messageText; + if (!threshold.messageKey.NullOrEmpty()) + { + messageText = threshold.messageKey.Translate(parent.Label, threshold.quality.GetLabel()); + } + else + { + messageText = "WULA_WeaponUpgraded".Translate(parent.Label, threshold.quality.GetLabel()); + } + + Messages.Message(messageText, parent, MessageTypeDefOf.PositiveEvent); + + Log.Message($"[ExperienceCore] {parent.Label} upgraded from {oldQuality} to {threshold.quality} at {currentExperience} experience"); } public override string CompInspectStringExtra() @@ -186,7 +489,13 @@ namespace WulaFallenEmpire // 当前经验 sb.AppendLine("WULA_CurrentExperience".Translate(currentExperience.ToString("F0"))); - // 下一个品质阈值 + // 溢出经验(如果有) + if (overflowExperience > 0) + { + sb.AppendLine("WULA_OverflowExperience".Translate(overflowExperience.ToString("F0"))); + } + + // 下一个品质阈值或最大品质信息 var nextThreshold = NextThreshold; if (nextThreshold != null) { @@ -199,6 +508,10 @@ namespace WulaFallenEmpire else { sb.AppendLine("WULA_MaxQuality".Translate(currentQuality.GetLabel())); + if (overflowExperience > 0) + { + sb.AppendLine("WULA_OverflowStored".Translate()); + } } // 追踪的技能 @@ -216,12 +529,24 @@ namespace WulaFallenEmpire { yield return new StatDrawEntry( StatCategoryDefOf.Basics, - "WULA_CurrentExperience".Translate(), + "WULA_CurrentExperienceStat".Translate(), currentExperience.ToString("F0"), "WULA_CurrentExperienceDesc".Translate(), 2100 ); + // 溢出经验统计 + if (overflowExperience > 0) + { + yield return new StatDrawEntry( + StatCategoryDefOf.Basics, + "WULA_OverflowExperienceStat".Translate(), + overflowExperience.ToString("F0"), + "WULA_OverflowExperienceDesc".Translate(), + 2095 + ); + } + var nextThreshold = NextThreshold; if (nextThreshold != null) { @@ -251,9 +576,22 @@ namespace WulaFallenEmpire 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 initialized, "initialized", false); Scribe_Values.Look(ref lastSkillExperience, "lastSkillExperience", 0f); + Scribe_Values.Look(ref currentThresholdIndex, "currentThresholdIndex", 0); + Scribe_Values.Look(ref overflowExperience, "overflowExperience", 0f); Scribe_References.Look(ref equippedPawn, "equippedPawn"); + + // 修复:加载后重新初始化品质 + if (Scribe.mode == LoadSaveMode.PostLoadInit) + { + var qualityComp = parent.TryGetComp(); + if (qualityComp != null && qualityComp.Quality != currentQuality) + { + qualityComp.SetQuality(currentQuality, ArtGenerationContext.Outsider); + Log.Message($"[ExperienceCore] PostLoad: Updated {parent.Label} quality to {currentQuality}"); + } + } } } } diff --git a/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompExperienceDataPack.cs b/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompExperienceDataPack.cs new file mode 100644 index 00000000..20c8a4d2 --- /dev/null +++ b/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompExperienceDataPack.cs @@ -0,0 +1,33 @@ +using RimWorld; +using Verse; + +namespace WulaFallenEmpire +{ + public class CompExperienceDataPack : ThingComp + { + public float storedExperience; + public string sourceWeaponLabel; + + public CompProperties_ExperienceDataPack Props => (CompProperties_ExperienceDataPack)props; + + public override void PostExposeData() + { + base.PostExposeData(); + Scribe_Values.Look(ref storedExperience, "storedExperience", 0f); + Scribe_Values.Look(ref sourceWeaponLabel, "sourceWeaponLabel"); + } + + public override string CompInspectStringExtra() + { + return "WULA_DataPackExperience".Translate(storedExperience.ToString("F0"), sourceWeaponLabel ?? "Unknown"); + } + } + + public class CompProperties_ExperienceDataPack : CompProperties + { + public CompProperties_ExperienceDataPack() + { + compClass = typeof(CompExperienceDataPack); + } + } +} diff --git a/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompProperties_ExperienceCore.cs b/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompProperties_ExperienceCore.cs index b53db451..9b4cb2b7 100644 --- a/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompProperties_ExperienceCore.cs +++ b/Source/WulaFallenEmpire/ThingComp/WULA_PersonaCore/CompProperties_ExperienceCore.cs @@ -18,6 +18,15 @@ namespace WulaFallenEmpire // 是否显示经验信息 public bool showExperienceInfo = true; + // 数据包定义 + public ThingDef dataPackDef; + + // 弹出数据包时保留的经验比例 (0-1) + public float experienceRetentionOnEject = 0f; + + // 吸收数据包时的搜索半径 + public int absorbRadius = 3; + public CompProperties_ExperienceCore() { compClass = typeof(CompExperienceCore); diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj index 4cee0b42..534442e0 100644 --- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj +++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj @@ -176,6 +176,7 @@ +