diff --git a/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/Assemblies/WulaFallenEmpire.dll
index 4b985b38..01a4d656 100644
Binary files a/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/Assemblies/WulaFallenEmpire.dll differ
diff --git a/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Spiritualist_Weapon.xml b/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Spiritualist_Weapon.xml
index a7f1ca5e..ef8f9d5f 100644
--- a/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Spiritualist_Weapon.xml
+++ b/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Spiritualist_Weapon.xml
@@ -80,6 +80,15 @@
2
60
+
+
+ WULA_DamagePsychicScaling
+
+
+ 1
+ 1
+
+
None
@@ -246,6 +255,15 @@
2
60
+
+
+ WULA_DamagePsychicScaling
+
+
+ 1
+ 1
+
+
None
@@ -409,6 +427,15 @@
20
60
+
+
+ WULA_DamagePsychicScaling
+
+
+ 1
+ 1
+
+
None
diff --git a/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Test_Weapon.xml b/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Test_Weapon.xml
deleted file mode 100644
index 889a18fd..00000000
--- a/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Test_Weapon.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
- WULA_TestWeapon_PsychicScaling
-
- 一个用于测试心灵敏感度伤害缩放的武器。
-
- Things/Item/Equipment/WeaponRanged/Autopistol
- Graphic_Single
-
- Interact_Autopistol
-
- 1
- 1
-
- None
- true
-
-
- Verb_Shoot
- true
- Bullet_TestWeapon_PsychicScaling
- 1.0
- 30
- Shot_Autopistol
- GunTail_Light
- 9
-
-
-
-
- 1.0
- 1.0
-
-
-
-
-
- Bullet_TestWeapon_PsychicScaling
-
-
- Things/Projectile/Bullet_Small
- Graphic_Single
-
-
- Bullet
- 10
- 50
-
-
-
\ No newline at end of file
diff --git a/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon.xml b/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon.xml
index 714e0e2e..102c2dad 100644
--- a/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon.xml
+++ b/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon.xml
@@ -1106,12 +1106,12 @@
- Verb_Shoot
+ WulaFallenEmpire.Verb_ShootShotgun
true
WULA_Bullet_StarDrift_Shotgun_Spear
0.2
15
- 6
+ 1
3
ChargeLance_Fire
GunTail_Heavy
@@ -1133,6 +1133,11 @@
0.65
55
+
+
+ 6
+
+
diff --git a/1.6/Defs/WeaponTraitDefs/WULA_WeaponCategoryDefs.xml b/1.6/Defs/WeaponTraitDefs/WULA_WeaponCategoryDefs.xml
new file mode 100644
index 00000000..5731dd18
--- /dev/null
+++ b/1.6/Defs/WeaponTraitDefs/WULA_WeaponCategoryDefs.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ WULA_Psychic
+
+ 与心灵能量相互作用的武器。
+
+
+
\ No newline at end of file
diff --git a/1.6/Defs/WeaponTraitDefs/WULA_WeaponTraitDefs.xml b/1.6/Defs/WeaponTraitDefs/WULA_WeaponTraitDefs.xml
new file mode 100644
index 00000000..2498b14a
--- /dev/null
+++ b/1.6/Defs/WeaponTraitDefs/WULA_WeaponTraitDefs.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ WULA_DamagePsychicScaling
+
+ 这把武器的伤害会随着使用者的心灵敏感度而变化。
+ 1
+ WULA_Psychic
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/CompCustomUniqueWeapon.cs b/Source/WulaFallenEmpire/CompCustomUniqueWeapon.cs
new file mode 100644
index 00000000..62f94841
--- /dev/null
+++ b/Source/WulaFallenEmpire/CompCustomUniqueWeapon.cs
@@ -0,0 +1,154 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using UnityEngine;
+using Verse;
+using RimWorld;
+
+namespace WulaFallenEmpire
+{
+ public class CompCustomUniqueWeapon : CompUniqueWeapon
+ {
+ // 使用 'new' 关键字来明确隐藏基类成员,解决 CS0108 警告
+ public new CompProperties_CustomUniqueWeapon Props => (CompProperties_CustomUniqueWeapon)props;
+
+ private List customTraits = new List();
+
+ // 使用 'new' 关键字隐藏基类属性,解决 CS0506 错误
+ public new List TraitsListForReading => customTraits;
+
+ // PostExposeData 是 virtual 的,保留 override
+ public override void PostExposeData()
+ {
+ base.PostExposeData();
+ Scribe_Collections.Look(ref customTraits, "customTraits", LookMode.Def);
+ if (Scribe.mode == LoadSaveMode.PostLoadInit)
+ {
+ if (customTraits == null) customTraits = new List();
+ SetupCustomTraits(fromSave: true);
+ }
+ }
+
+ // PostPostMake 是 virtual 的,保留 override
+ public override void PostPostMake()
+ {
+ InitializeCustomTraits();
+ if (parent.TryGetComp(out var comp))
+ {
+ comp.SetQuality(QualityUtility.GenerateQuality(QualityGenerator.Super), ArtGenerationContext.Outsider);
+ }
+ }
+
+ private void InitializeCustomTraits()
+ {
+ if (customTraits == null) customTraits = new List();
+ customTraits.Clear();
+
+ if (Props.forcedTraits != null)
+ {
+ foreach (var traitToForce in Props.forcedTraits)
+ {
+ if (customTraits.All(t => !t.Overlaps(traitToForce)))
+ {
+ customTraits.Add(traitToForce);
+ }
+ }
+ }
+
+ IntRange traitRange = Props.numTraitsRange ?? new IntRange(1, 3);
+ int totalTraitsTarget = Mathf.Max(customTraits.Count, traitRange.RandomInRange);
+ int missingTraits = totalTraitsTarget - customTraits.Count;
+
+ if (missingTraits > 0)
+ {
+ // CanAddTrait 现在是我们自己的 'new' 方法
+ IEnumerable possibleTraits = DefDatabase.AllDefs.Where(CanAddTrait);
+ for (int i = 0; i < missingTraits; i++)
+ {
+ if (!possibleTraits.Any()) break;
+
+ var chosenTrait = possibleTraits.RandomElementByWeight(t => t.commonality);
+ customTraits.Add(chosenTrait);
+
+ possibleTraits = possibleTraits.Where(t => t != chosenTrait && !t.Overlaps(chosenTrait));
+ }
+ }
+
+ SetupCustomTraits(fromSave: false);
+ }
+
+ private void SetupCustomTraits(bool fromSave)
+ {
+ foreach (WeaponTraitDef trait in customTraits)
+ {
+ if (trait.abilityProps != null && parent.GetComp() is CompEquippableAbilityReloadable comp)
+ {
+ comp.props = trait.abilityProps;
+ if (!fromSave)
+ {
+ comp.Notify_PropsChanged();
+ }
+ }
+ }
+ }
+
+ // 使用 'new' 关键字隐藏基类方法,解决 CS0506 错误
+ public new bool CanAddTrait(WeaponTraitDef trait)
+ {
+ if (customTraits.Any(t => t == trait || t.Overlaps(t)))
+ return false;
+
+ if (Props.weaponCategories != null && Props.weaponCategories.Any() && !Props.weaponCategories.Contains(trait.weaponCategory))
+ return false;
+
+ if (customTraits.Count == 0 && !trait.canGenerateAlone)
+ return false;
+
+ return true;
+ }
+
+ // --- 下面的方法都是 virtual 的,保留 override ---
+
+ public override string TransformLabel(string label) => label;
+ public override Color? ForceColor() => null;
+
+ public override float GetStatOffset(StatDef stat) => customTraits.Sum(t => t.statOffsets.GetStatOffsetFromList(stat));
+ public override float GetStatFactor(StatDef stat) => customTraits.Aggregate(1f, (current, t) => current * t.statFactors.GetStatFactorFromList(stat));
+
+ public override string CompInspectStringExtra()
+ {
+ if (customTraits.NullOrEmpty()) return null;
+ return "WeaponTraits".Translate() + ": " + customTraits.Select(t => t.label).ToCommaList().CapitalizeFirst();
+ }
+
+ public override string CompTipStringExtra()
+ {
+ if (customTraits.NullOrEmpty()) return base.CompTipStringExtra();
+ return "WeaponTraits".Translate() + ": " + customTraits.Select(t => t.label).ToCommaList().CapitalizeFirst();
+ }
+
+ public override IEnumerable SpecialDisplayStats()
+ {
+ if (customTraits.NullOrEmpty()) yield break;
+
+ var builder = new StringBuilder();
+ builder.AppendLine("Stat_ThingUniqueWeaponTrait_Desc".Translate());
+ builder.AppendLine();
+
+ for (int i = 0; i < customTraits.Count; i++)
+ {
+ WeaponTraitDef trait = customTraits[i];
+ builder.AppendLine(trait.LabelCap.Colorize(ColorLibrary.Yellow));
+ builder.AppendLine(trait.description);
+ if (i < customTraits.Count - 1) builder.AppendLine();
+ }
+
+ yield return new StatDrawEntry(
+ parent.def.IsMeleeWeapon ? StatCategoryDefOf.Weapon_Melee : StatCategoryDefOf.Weapon_Ranged,
+ "Stat_ThingUniqueWeaponTrait_Label".Translate(),
+ customTraits.Select(t => t.label).ToCommaList().CapitalizeFirst(),
+ builder.ToString(),
+ 1104);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/CompProperties_CustomUniqueWeapon.cs b/Source/WulaFallenEmpire/CompProperties_CustomUniqueWeapon.cs
new file mode 100644
index 00000000..514a2bf3
--- /dev/null
+++ b/Source/WulaFallenEmpire/CompProperties_CustomUniqueWeapon.cs
@@ -0,0 +1,21 @@
+using System.Collections.Generic;
+using Verse;
+using RimWorld;
+
+namespace WulaFallenEmpire
+{
+ public class CompProperties_CustomUniqueWeapon : CompProperties_UniqueWeapon
+ {
+ // A list of traits that will always be added to the weapon.
+ public List forcedTraits;
+
+ // The range of traits to randomly add. If not defined in XML, a default of 1-3 will be used.
+ public IntRange? numTraitsRange;
+
+ public CompProperties_CustomUniqueWeapon()
+ {
+ // Point to the implementation of our custom logic.
+ this.compClass = typeof(CompCustomUniqueWeapon);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
index f8269d67..8771b901 100644
--- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
+++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
@@ -69,6 +69,8 @@
+
+