diff --git a/.gitignore b/.gitignore
index 2d2bf7ca..5601d9e2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -53,8 +53,14 @@
*.tmp
# Build outputs and debug files
-**/obj/Debug/
-**/obj/Release/
-**/bin/Debug/
-**/bin/Release/
+**/obj/
+**/bin/
*.csproj.CoreCompileInputs.cache
+*.csproj.FileListAbsolute.txt
+*.pdb
+*.dll.config
+*.cache
+*.suo
+*.user
+_ReSharper.*
+*.dotCover
diff --git a/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/Assemblies/WulaFallenEmpire.dll
index d0d59f33..99ba3dbf 100644
Binary files a/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/Assemblies/WulaFallenEmpire.dll differ
diff --git a/1.6/Assemblies/WulaFallenEmpire.pdb b/1.6/Assemblies/WulaFallenEmpire.pdb
deleted file mode 100644
index a565f103..00000000
Binary files a/1.6/Assemblies/WulaFallenEmpire.pdb and /dev/null differ
diff --git a/1.6/Defs/AbilityDefs/Abilities_WULA_Emergency.xml b/1.6/Defs/AbilityDefs/Abilities_WULA_Emergency.xml
index e2bc7ec2..25e4b4a1 100644
--- a/1.6/Defs/AbilityDefs/Abilities_WULA_Emergency.xml
+++ b/1.6/Defs/AbilityDefs/Abilities_WULA_Emergency.xml
@@ -10,7 +10,6 @@
true
true
false
- CastAbilityOnThing
false
false
@@ -33,4 +32,4 @@
-
\ No newline at end of file
+
diff --git a/1.6/Defs/HediffDefs/Hediffs_BodyParts_WULA.xml b/1.6/Defs/HediffDefs/Hediffs_BodyParts_WULA.xml
index edbe0fac..d23961be 100644
--- a/1.6/Defs/HediffDefs/Hediffs_BodyParts_WULA.xml
+++ b/1.6/Defs/HediffDefs/Hediffs_BodyParts_WULA.xml
@@ -146,6 +146,7 @@
true
true
false
+ CastAbilityOnThing
15
@@ -245,8 +246,6 @@
0
-
-
0.5
diff --git a/1.6/Defs/ThingDefs_Misc/Apparel/WULA_ShieldBelt.xml b/1.6/Defs/ThingDefs_Misc/Apparel/WULA_ShieldBelt.xml
index e69de29b..03f61d51 100644
--- a/1.6/Defs/ThingDefs_Misc/Apparel/WULA_ShieldBelt.xml
+++ b/1.6/Defs/ThingDefs_Misc/Apparel/WULA_ShieldBelt.xml
@@ -0,0 +1,247 @@
+
+
+
+
+ WULA_ShieldBelt
+
+ 乌拉帝国的个人护盾装置,可以产生动量排斥场来阻挡来袭的投射物。护盾可以通过能力按钮开关,并且具有可配置的护盾值和范围。
+ Ultra
+
+ WULA_Synth_Weapon_2_Stun_Technology
+ UnfinishedBelt
+
+ WULA_Cube_Productor_Energy
+
+
+ 8
+
+
+
+ Things/Item/Equipment/WeaponMelee/Knife
+ Graphic_Single
+
+
+ 50
+ 25
+ 3
+ 1
+
+
+ 12000
+ 1.2
+ 0.4
+
+
+ Apparel
+
+
+
+ Waist
+
+ Things/Pawn/Humanlike/Apparel/ShieldBelt/ShieldBelt
+
+ Belt
+
+
+ BeltDefensePop
+
+
+ Soldier
+
+
+
+
+
+ 200
+
+ 3.0
+
+ true
+
+ false
+
+ false
+
+ false
+
+ (0.2, 0.6, 1.0)
+
+ 5.0
+
+ 300
+
+ BulletShield_Ambience
+
+ BulletShieldGenerator_Reactivate
+
+ false
+
+ true
+
+
+
+
+
+
+ WULA_ShieldBelt_Advanced
+
+ 乌拉帝国的高级个人护盾装置,具有更强的护盾值、更大的范围,并且可以抵抗近战攻击和EMP伤害。
+ Ultra
+
+ WULA_Synth_Weapon_2_Stun_Technology
+ UnfinishedBelt
+
+ WULA_Cube_Productor_Energy
+
+
+ 10
+
+
+
+ Things/Item/Equipment/WeaponMelee/Knife
+ Graphic_Single
+
+
+ 100
+ 50
+ 6
+ 2
+ 10
+
+
+ 20000
+ 2.0
+ 0.2
+
+
+ Apparel
+
+
+
+ Waist
+
+ Things/Pawn/Humanlike/Apparel/ShieldBelt/ShieldBelt
+
+ Belt
+
+
+ BeltDefensePop
+
+
+ Soldier
+
+
+
+
+
+ 400
+
+ 4.5
+
+ true
+
+ true
+
+ true
+
+ true
+
+ (1.0, 0.6, 0.2)
+
+ 8.0
+
+ 180
+
+ BulletShield_Ambience
+
+ BulletShieldGenerator_Reactivate
+
+ false
+
+ true
+
+
+
+
+
+
+ WULA_ShieldBelt_Deflector
+
+ 乌拉帝国的偏转型个人护盾装置,采用低角护盾技术,不会被破坏但只能偏转投射物。这种护盾永远不会过载,但也无法完全阻挡攻击。
+ Ultra
+
+ WULA_Synth_Weapon_2_Stun_Technology
+ UnfinishedBelt
+
+ WULA_Cube_Productor_Energy
+
+
+ 6
+
+
+
+ Things/Item/Equipment/WeaponMelee/Knife
+ Graphic_Single
+
+
+ 30
+ 15
+ 2
+ 1
+
+
+ 8000
+ 0.8
+ 0.4
+
+
+ Apparel
+
+
+
+ Waist
+
+ Things/Pawn/Humanlike/Apparel/ShieldBelt/ShieldBelt
+
+ Belt
+
+
+ BeltDefensePop
+
+
+ Soldier
+
+
+
+
+
+ 100
+
+ 2.5
+
+ true
+
+ false
+
+ false
+
+ false
+
+ (0.6, 1.0, 0.6)
+
+ 0
+
+ 0
+
+ BulletShield_Ambience
+
+ BulletShieldGenerator_Reactivate
+
+ true
+
+ false
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/CompAbilityEffect_EmergencyEnergyRestore.cs b/Source/WulaFallenEmpire/CompAbilityEffect_EmergencyEnergyRestore.cs
index 0832f9dc..c9ceb91c 100644
--- a/Source/WulaFallenEmpire/CompAbilityEffect_EmergencyEnergyRestore.cs
+++ b/Source/WulaFallenEmpire/CompAbilityEffect_EmergencyEnergyRestore.cs
@@ -9,6 +9,7 @@ namespace WulaFallenEmpire
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
{
+ Log.Message($"[EmergencyEnergyRestore] Apply method called for {parent.pawn?.LabelShort}");
base.Apply(target, dest);
Pawn caster = parent.pawn;
@@ -45,14 +46,9 @@ namespace WulaFallenEmpire
public override bool CanApplyOn(LocalTargetInfo target, LocalTargetInfo dest)
{
- bool canApply = base.CanApplyOn(target, dest) && IsWulaRace(parent.pawn);
-
- if (Props.requireDowned)
- {
- canApply = canApply && parent.pawn.Downed;
- }
-
- return canApply;
+ Log.Message($"[EmergencyEnergyRestore] CanApplyOn called. Pawn: {parent.pawn?.LabelShort}");
+ // 暂时强制返回true,以排除CanApplyOn的限制
+ return true;
}
private bool IsWulaRace(Pawn pawn)
@@ -61,4 +57,4 @@ namespace WulaFallenEmpire
return pawn.def.defName == "WulaSpecies";
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/WulaFallenEmpire/CompProperties_WulaShieldBelt.cs b/Source/WulaFallenEmpire/CompProperties_WulaShieldBelt.cs
new file mode 100644
index 00000000..6b926f1b
--- /dev/null
+++ b/Source/WulaFallenEmpire/CompProperties_WulaShieldBelt.cs
@@ -0,0 +1,31 @@
+using RimWorld;
+using UnityEngine;
+using Verse;
+using Verse.Sound;
+
+namespace WulaFallenEmpire
+{
+ public class CompProperties_WulaShieldBelt : CompProperties
+ {
+ public int maxShieldHitPoints = 200;
+ public float shieldRadius = 3.0f;
+ public bool interceptGroundProjectiles = true;
+ public bool interceptAirProjectiles = false;
+ public bool interceptMeleeAttacks = false;
+ public bool empImmune = false;
+ public Color shieldColor = new Color(0.2f, 0.6f, 1.0f);
+ public float rechargeRate = 5.0f;
+ public int rechargeCooldownTicks = 300;
+ public SoundDef activeSound;
+ public EffecterDef reactivateEffect;
+ public bool startEnabled = false;
+
+ // 护盾模式:true = 有生命值模式(可被破坏),false = 无生命值模式(类似低角护盾,只是偏转)
+ public bool useHitPointsMode = true;
+
+ public CompProperties_WulaShieldBelt()
+ {
+ compClass = typeof(CompWulaShieldBelt);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/CompWulaShieldBelt.cs b/Source/WulaFallenEmpire/CompWulaShieldBelt.cs
new file mode 100644
index 00000000..46ff596c
--- /dev/null
+++ b/Source/WulaFallenEmpire/CompWulaShieldBelt.cs
@@ -0,0 +1,365 @@
+using RimWorld;
+using System.Collections.Generic;
+using UnityEngine;
+using Verse;
+using Verse.Sound;
+
+namespace WulaFallenEmpire
+{
+ [StaticConstructorOnStartup]
+ public class CompWulaShieldBelt : ThingComp
+ {
+ private float shieldHitPoints;
+ private int ticksToReset = -1;
+ private int lastKeepDisplayTick = -9999;
+ private Vector3 impactAngleVect;
+ private int lastAbsorbDamageTick = -9999;
+ private bool shieldEnabled = false;
+ private Sustainer sustainer;
+ // 静态构造函数加载材质
+ private static readonly Material BubbleMat = MaterialPool.MatFrom("Other/ShieldBubble", ShaderDatabase.Transparent, Color.white);
+
+ public CompProperties_WulaShieldBelt Props => (CompProperties_WulaShieldBelt)props;
+
+ public float ShieldHitPoints => shieldHitPoints;
+ public float ShieldMaxHitPoints => Props.maxShieldHitPoints;
+ public bool ShieldEnabled => shieldEnabled;
+
+ private bool ShouldDisplay
+ {
+ get
+ {
+ Pawn wearer = GetWearer();
+ return wearer != null && wearer.Spawned && (wearer.Drafted || (wearer.Faction != null && wearer.Faction.IsPlayer) || Find.TickManager.TicksGame < lastKeepDisplayTick + 50);
+ }
+ }
+
+ public override void PostExposeData()
+ {
+ base.PostExposeData();
+ Scribe_Values.Look(ref shieldHitPoints, "shieldHitPoints", 0f);
+ Scribe_Values.Look(ref ticksToReset, "ticksToReset", -1);
+ Scribe_Values.Look(ref shieldEnabled, "shieldEnabled", Props.startEnabled);
+ }
+
+ public override void PostSpawnSetup(bool respawningAfterLoad)
+ {
+ base.PostSpawnSetup(respawningAfterLoad);
+ if (!respawningAfterLoad)
+ {
+ shieldHitPoints = Props.maxShieldHitPoints;
+ shieldEnabled = Props.startEnabled;
+ }
+ }
+
+ public override void CompTick()
+ {
+ base.CompTick();
+
+ Pawn wearer = GetWearer();
+ if (wearer == null) return;
+
+ if (shieldEnabled)
+ {
+ if (sustainer == null && Props.activeSound != null)
+ {
+ sustainer = Props.activeSound.TrySpawnSustainer(SoundInfo.InMap(wearer, MaintenanceType.PerTick));
+ }
+ sustainer?.Maintain();
+ }
+ else
+ {
+ sustainer?.End();
+ sustainer = null;
+ }
+
+ if (ticksToReset > 0)
+ {
+ ticksToReset--;
+ if (ticksToReset <= 0)
+ {
+ Reset();
+ }
+ }
+ else if (shieldEnabled && Props.useHitPointsMode && shieldHitPoints < Props.maxShieldHitPoints)
+ {
+ shieldHitPoints += Props.rechargeRate / 60f; // 每秒恢复
+ if (shieldHitPoints > Props.maxShieldHitPoints)
+ {
+ shieldHitPoints = Props.maxShieldHitPoints;
+ }
+ }
+ }
+
+ public override void PostDraw()
+ {
+ base.PostDraw();
+ if (shieldEnabled && ShouldDisplay)
+ {
+ float num = Mathf.Lerp(1.2f, 1.55f, shieldHitPoints / Props.maxShieldHitPoints);
+ Vector3 drawPos = GetWearer().Drawer.DrawPos;
+ drawPos.y = AltitudeLayer.MoteOverhead.AltitudeFor();
+ int num2 = Find.TickManager.TicksGame - lastAbsorbDamageTick;
+ if (num2 < 8)
+ {
+ float num3 = (8 - num2) / 8f * 0.05f;
+ drawPos += impactAngleVect * num3;
+ num -= num3;
+ }
+
+ float alpha;
+ if (Props.useHitPointsMode)
+ {
+ // 生命值模式:透明度根据护盾生命值变化
+ alpha = Mathf.Lerp(0.2f, 0.7f, shieldHitPoints / Props.maxShieldHitPoints);
+ }
+ else
+ {
+ // 偏转模式:固定透明度,稍微闪烁效果
+ alpha = 0.4f + Mathf.Sin(Time.time * 2f) * 0.1f;
+ }
+ Color color = Props.shieldColor;
+ color.a = alpha;
+
+ Matrix4x4 matrix = default(Matrix4x4);
+ matrix.SetTRS(drawPos, Quaternion.identity, Vector3.one * num * Props.shieldRadius);
+ Graphics.DrawMesh(MeshPool.plane10, matrix, BubbleMat, 0, null, 0, MaterialPropertyBlock);
+ }
+ }
+
+ private MaterialPropertyBlock materialPropertyBlock;
+ private MaterialPropertyBlock MaterialPropertyBlock
+ {
+ get
+ {
+ if (materialPropertyBlock == null)
+ {
+ materialPropertyBlock = new MaterialPropertyBlock();
+ }
+ materialPropertyBlock.SetColor(ShaderPropertyIDs.Color, Props.shieldColor);
+ return materialPropertyBlock;
+ }
+ }
+
+ public bool CheckIntercept(Projectile projectile, Vector3 lastExactPos, Vector3 newExactPos)
+ {
+ if (!shieldEnabled)
+ return false;
+
+ // 如果使用生命值模式且护盾已破坏,则不拦截
+ if (Props.useHitPointsMode && shieldHitPoints <= 0f)
+ return false;
+
+ Pawn wearer = GetWearer();
+ if (wearer == null || !wearer.Spawned)
+ return false;
+
+ if (!Props.interceptGroundProjectiles && !projectile.def.projectile.flyOverhead)
+ return false;
+
+ if (!Props.interceptAirProjectiles && projectile.def.projectile.flyOverhead)
+ return false;
+
+ Vector3 center = wearer.TrueCenter();
+ float radius = Props.shieldRadius;
+
+ // 简单检查:如果射线起点和终点都在圆外,且连线不穿过圆,则不相交
+ float distanceFromLastPos = Vector3.Distance(lastExactPos, center);
+ float distanceFromNewPos = Vector3.Distance(newExactPos, center);
+
+ if (distanceFromLastPos > radius && distanceFromNewPos > radius)
+ {
+ // 计算点到线段的最短距离
+ Vector3 line = newExactPos - lastExactPos;
+ float lineLength = line.magnitude;
+ Vector3 lineDirection = line / lineLength;
+ float projection = Mathf.Clamp(Vector3.Dot(center - lastExactPos, lineDirection), 0f, lineLength);
+ Vector3 closestPoint = lastExactPos + lineDirection * projection;
+ float distanceToLine = Vector3.Distance(center, closestPoint);
+
+ if (distanceToLine > radius)
+ return false;
+ }
+
+ lastKeepDisplayTick = Find.TickManager.TicksGame + 40;
+
+ // 根据模式处理伤害
+ if (Props.useHitPointsMode)
+ {
+ // 生命值模式:吸收伤害并可能破坏护盾
+ AbsorbDamage(projectile.DamageAmount, projectile.ExactPosition);
+ }
+ else
+ {
+ // 偏转模式:只是偏转,不消耗护盾生命值
+ DeflectProjectile(projectile.ExactPosition);
+ }
+
+ return true;
+ }
+
+ public bool CheckMeleeIntercept(DamageInfo dinfo, Pawn attacker)
+ {
+ if (!shieldEnabled || !Props.interceptMeleeAttacks || shieldHitPoints <= 0f)
+ return false;
+
+ Pawn wearer = GetWearer();
+ if (wearer == null || !wearer.Spawned)
+ return false;
+
+ lastKeepDisplayTick = Find.TickManager.TicksGame + 40;
+ AbsorbDamage(dinfo.Amount, attacker.Position.ToVector3());
+ return true;
+ }
+
+ private void AbsorbDamage(float damage, Vector3 impactPos)
+ {
+ if (Props.empImmune && damage > 0f)
+ {
+ // EMP免疫时减少EMP伤害
+ damage *= 0.1f;
+ }
+
+ // 只有在生命值模式下才扣除护盾生命值
+ if (Props.useHitPointsMode)
+ {
+ shieldHitPoints -= damage;
+ }
+
+ lastAbsorbDamageTick = Find.TickManager.TicksGame;
+
+ Pawn wearer = GetWearer();
+ if (wearer != null)
+ {
+ impactAngleVect = Vector3Utility.HorizontalVectorFromAngle((impactPos - wearer.TrueCenter()).AngleFlat() + 180f);
+ }
+
+ // 只有在生命值模式下才会破坏护盾
+ if (Props.useHitPointsMode && shieldHitPoints <= 0f)
+ {
+ Break();
+ }
+ }
+
+ private void DeflectProjectile(Vector3 impactPos)
+ {
+ // 偏转模式:只显示视觉效果,不消耗护盾生命值
+ lastAbsorbDamageTick = Find.TickManager.TicksGame;
+
+ Pawn wearer = GetWearer();
+ if (wearer != null)
+ {
+ impactAngleVect = Vector3Utility.HorizontalVectorFromAngle((impactPos - wearer.TrueCenter()).AngleFlat() + 180f);
+
+ // 播放偏转特效
+ FleckMaker.ThrowLightningGlow(impactPos, wearer.Map, 0.5f);
+ }
+ }
+
+ private void Break()
+ {
+ shieldHitPoints = 0f;
+ ticksToReset = Props.rechargeCooldownTicks;
+ sustainer?.End();
+ sustainer = null;
+
+ Pawn wearer = GetWearer();
+ if (wearer != null && wearer.Map != null)
+ {
+ FleckMaker.Static(wearer.TrueCenter(), wearer.Map, FleckDefOf.ExplosionFlash, 12f);
+ for (int i = 0; i < 6; i++)
+ {
+ FleckMaker.ThrowDustPuff(wearer.TrueCenter() + Vector3Utility.HorizontalVectorFromAngle(Rand.Range(0, 360)) * Rand.Range(0.3f, 0.6f), wearer.Map, Rand.Range(0.8f, 1.2f));
+ }
+ }
+ }
+
+ private void Reset()
+ {
+ if (parent.Spawned)
+ {
+ SoundDefOf.EnergyShield_Reset.PlayOneShot(new TargetInfo(parent.Position, parent.Map));
+ FleckMaker.ThrowLightningGlow(GetWearer().TrueCenter(), parent.Map, 3f);
+
+ if (Props.reactivateEffect != null)
+ {
+ Effecter effecter = Props.reactivateEffect.Spawn(parent.Position, parent.Map);
+ effecter.Trigger(new TargetInfo(parent.Position, parent.Map), TargetInfo.Invalid);
+ effecter.Cleanup();
+ }
+ }
+ shieldHitPoints = Props.maxShieldHitPoints;
+ }
+
+ public void ToggleShield()
+ {
+ shieldEnabled = !shieldEnabled;
+
+ Pawn wearer = GetWearer();
+ if (wearer != null)
+ {
+ string message = shieldEnabled ? $"{wearer.LabelShort}激活了护盾" : $"{wearer.LabelShort}关闭了护盾";
+ Messages.Message(message, MessageTypeDefOf.NeutralEvent, false);
+ }
+
+ if (!shieldEnabled)
+ {
+ sustainer?.End();
+ sustainer = null;
+ }
+ }
+
+ private Pawn GetWearer()
+ {
+ if (parent is Apparel apparel)
+ {
+ return apparel.Wearer;
+ }
+ return null;
+ }
+
+ // 添加初始化方法,确保护盾值正确设置
+ public override void Initialize(CompProperties props)
+ {
+ base.Initialize(props);
+ shieldHitPoints = ((CompProperties_WulaShieldBelt)props).maxShieldHitPoints;
+ shieldEnabled = ((CompProperties_WulaShieldBelt)props).startEnabled;
+ }
+
+ public override IEnumerable CompGetWornGizmosExtra()
+ {
+ // 确保穿戴者存在
+ Pawn wearer = GetWearer();
+ if (wearer == null) yield break;
+
+ // 不限制只有选中时才显示
+ yield return new Command_Toggle
+ {
+ defaultLabel = "护盾开关",
+ defaultDesc = shieldEnabled ? "关闭护盾" : "激活护盾",
+ icon = ContentFinder.Get("UI/Commands/DesirePower"),
+ isActive = () => shieldEnabled,
+ toggleAction = ToggleShield
+ };
+ }
+
+ public override string CompInspectStringExtra()
+ {
+ if (shieldEnabled)
+ {
+ if (Props.useHitPointsMode)
+ {
+ return $"护盾: {shieldHitPoints:F0} / {Props.maxShieldHitPoints} (生命值模式)";
+ }
+ else
+ {
+ return "护盾: 激活 (偏转模式)";
+ }
+ }
+ else
+ {
+ return "护盾: 已关闭";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/EmergencyAbilityPatches.cs b/Source/WulaFallenEmpire/EmergencyAbilityPatches.cs
new file mode 100644
index 00000000..845cc8e6
--- /dev/null
+++ b/Source/WulaFallenEmpire/EmergencyAbilityPatches.cs
@@ -0,0 +1,136 @@
+using HarmonyLib;
+using RimWorld;
+using System; // Added for Type
+using System.Collections.Generic;
+using System.Reflection;
+using System.Reflection.Emit;
+using Verse;
+
+namespace WulaFallenEmpire
+{
+ [HarmonyPatch]
+ public static class EmergencyAbilityPatches
+ {
+ // 修复倒地时无法使用能力的问题
+ [HarmonyPatch(typeof(Ability), "get_CanCast")]
+ [HarmonyPostfix]
+ public static void CanCast_Postfix(Ability __instance, ref AcceptanceReport __result)
+ {
+ if (__instance.def.defName == "WULA_EmergencyEnergyRestore")
+ {
+ Log.Message($"[EmergencyAbilityPatches] CanCast_Postfix for {__instance.pawn?.LabelShort}, initial result: {__result.Accepted}, reason: {__result.Reason}");
+ if (!__result.Accepted)
+ {
+ // 检查是否是因为pawn失去知觉而无法使用能力
+ if (__instance.pawn.Downed)
+ {
+ // 对于紧急能量恢复能力,我们允许在倒地时使用
+ __result = true;
+ Log.Message($"[EmergencyAbilityPatches] CanCast_Postfix: Pawn is downed, overriding to true. New result: {__result.Accepted}");
+ }
+ }
+ }
+ }
+
+ // 修复倒地时无法显示能力按钮的问题
+ [HarmonyPatch(typeof(Pawn_AbilityTracker), "get_AllAbilitiesForReading")]
+ [HarmonyPostfix]
+ public static void GetAbilitiesForDisplay_Postfix(Pawn_AbilityTracker __instance, ref List __result)
+ {
+ // 检查pawn是否倒地
+ if (__instance.pawn.Downed)
+ {
+ // 添加紧急能量恢复能力,即使pawn倒地
+ foreach (Ability ability in __instance.abilities)
+ {
+ if (ability.def.defName == "WULA_EmergencyEnergyRestore" && !__result.Contains(ability))
+ {
+ __result.Add(ability);
+ }
+ }
+ }
+ }
+
+ // 修复倒地时无法使用能力的UI限制 - 直接修补Ability.GizmoDisabled方法
+ [HarmonyPatch(typeof(Ability), "GizmoDisabled")]
+ [HarmonyPostfix]
+ public static void Ability_GizmoDisabled_Postfix(Ability __instance, ref bool __result, ref string reason)
+ {
+ if (__instance.def.defName == "WULA_EmergencyEnergyRestore")
+ {
+ Log.Message($"[EmergencyAbilityPatches] GizmoDisabled_Postfix for {__instance.pawn?.LabelShort}, initial result: {__result}, reason: {reason}");
+ if (__result)
+ {
+ // 检查是否是因为倒地而被禁用
+ if (__instance.pawn.Downed && reason != null &&
+ (reason.Contains("失去知觉") || reason.Contains("unconscious") || reason.Contains("CommandDisabledUnconscious")))
+ {
+ // 对于紧急能量恢复能力,我们允许在倒地时使用
+ __result = false;
+ reason = null;
+ Log.Message($"[EmergencyAbilityPatches] GizmoDisabled_Postfix: Pawn is downed, overriding to false. New result: {__result}");
+ }
+ }
+ }
+ }
+
+ // 额外的安全措施:修复Command_Ability的禁用检查
+ [HarmonyPatch(typeof(Command_Ability), "get_Disabled")]
+ [HarmonyPostfix]
+ public static void Command_Ability_GizmoDisabled_Postfix(Command_Ability __instance, ref bool __result)
+ {
+ // 使用反射获取ability字段
+ var abilityField = typeof(Command_Ability).GetField("ability", BindingFlags.Instance | BindingFlags.NonPublic);
+ if (abilityField == null) return;
+
+ Ability ability = (Ability)abilityField.GetValue(__instance);
+ if (ability == null) return;
+
+ if (ability.def.defName == "WULA_EmergencyEnergyRestore")
+ {
+ Log.Message($"[EmergencyAbilityPatches] Command_Ability_GizmoDisabled_Postfix for {ability.pawn?.LabelShort}, initial result: {__result}");
+ if (__result && ability.pawn.Downed)
+ {
+ // 对于紧急能量恢复能力,我们允许在倒地时使用
+ __result = false;
+ Log.Message($"[EmergencyAbilityPatches] Command_Ability_GizmoDisabled_Postfix: Pawn is downed, overriding to false. New result: {__result}");
+ }
+ }
+ }
+
+ // 新增补丁:检查ApparelPreventsShooting是否阻止了施法
+ [HarmonyPatch(typeof(Verb), "ApparelPreventsShooting")]
+ [HarmonyPostfix]
+ public static void ApparelPreventsShooting_Postfix(Verb __instance, ref bool __result)
+ {
+ Log.Message($"[EmergencyAbilityPatches] ApparelPreventsShooting_Postfix called. Verb type: {__instance.GetType().Name}, Caster: {__instance.CasterPawn?.LabelShort}, initial result: {__result}");
+ if (__instance is Verb_CastAbility castAbilityVerb && castAbilityVerb.ability?.def.defName == "WULA_EmergencyEnergyRestore")
+ {
+ Log.Message($"[EmergencyAbilityPatches] ApparelPreventsShooting_Postfix for EmergencyEnergyRestore. Pawn: {__instance.CasterPawn?.LabelShort}, result: {__result}");
+ }
+ }
+
+ // 最终诊断补丁:检查Verb.TryStartCastOn是否被调用
+ [HarmonyPatch(typeof(Verb), "TryStartCastOn", new Type[] { typeof(LocalTargetInfo), typeof(LocalTargetInfo), typeof(bool), typeof(bool), typeof(bool), typeof(bool) })]
+ [HarmonyPrefix]
+ public static void TryStartCastOn_DiagnosticPrefix(Verb __instance, LocalTargetInfo castTarg, LocalTargetInfo destTarg, ref bool __result)
+ {
+ Log.Message($"[EmergencyAbilityPatches] TryStartCastOn_DiagnosticPrefix called for Verb type: {__instance.GetType().Name}. Caster: {__instance.CasterPawn?.LabelShort}. CastTarg: {castTarg}, DestTarg: {destTarg}");
+ if (__instance is Verb_CastAbility castAbilityVerb && castAbilityVerb.ability?.def.defName == "WULA_EmergencyEnergyRestore")
+ {
+ Log.Message($"[EmergencyAbilityPatches] TryStartCastOn_DiagnosticPrefix: This is EmergencyEnergyRestore ability. Caster: {__instance.CasterPawn?.LabelShort}");
+ }
+ }
+
+ // 诊断补丁:检查Verb_CastAbility.TryCastShot是否被调用
+ [HarmonyPatch(typeof(Verb_CastAbility), "TryCastShot")]
+ [HarmonyPrefix]
+ public static void TryCastShot_DiagnosticPrefix(Verb_CastAbility __instance, ref bool __result)
+ {
+ if (__instance.ability?.def.defName == "WULA_EmergencyEnergyRestore")
+ {
+ Log.Message($"[EmergencyAbilityPatches] TryCastShot_DiagnosticPrefix called for EmergencyEnergyRestore. Pawn: {__instance.CasterPawn?.LabelShort}");
+ }
+ }
+ }
+}
diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
index 6de951e6..df0101bf 100644
--- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
+++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
@@ -14,13 +14,15 @@
true
- true
- full
+ false
+ none
false
..\..\1.6\Assemblies\
DEBUG;TRACE
prompt
4
+ Off
+ .allowedextension
pdbonly
@@ -80,6 +82,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/WulaFallenEmpire/WulaFallenEmpireMod.cs b/Source/WulaFallenEmpire/WulaFallenEmpireMod.cs
index cb6a4608..41cb256b 100644
--- a/Source/WulaFallenEmpire/WulaFallenEmpireMod.cs
+++ b/Source/WulaFallenEmpire/WulaFallenEmpireMod.cs
@@ -13,6 +13,9 @@ namespace WulaFallenEmpire
// 初始化Harmony
var harmony = new Harmony("tourswen.wulafallenempire"); // 替换为您的唯一Mod ID
harmony.PatchAll(Assembly.GetExecutingAssembly());
+
+ // 手动应用护盾腰带的近战拦截补丁
+ WulaShieldBeltPatches.ApplyMeleePatch(harmony);
Log.Message("[WulaFallenEmpire] Harmony patches applied.");
}
diff --git a/Source/WulaFallenEmpire/WulaShieldBeltPatches.cs b/Source/WulaFallenEmpire/WulaShieldBeltPatches.cs
new file mode 100644
index 00000000..3b706712
--- /dev/null
+++ b/Source/WulaFallenEmpire/WulaShieldBeltPatches.cs
@@ -0,0 +1,97 @@
+using HarmonyLib;
+using RimWorld;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using Verse;
+
+namespace WulaFallenEmpire
+{
+ public static class WulaShieldBeltPatches
+ {
+ // 拦截投射物
+ [HarmonyPatch(typeof(Projectile), "CheckForFreeInterceptBetween")]
+ [HarmonyPrefix]
+ public static bool CheckForFreeInterceptBetween_Prefix(Projectile __instance, Vector3 lastExactPos, Vector3 newExactPos, ref bool __result)
+ {
+ var map = __instance.Map;
+ if (map == null) return true;
+
+ // 检查所有穿戴护盾腰带的pawn
+ var pawns = map.mapPawns.AllPawnsSpawned;
+ foreach (var pawn in pawns)
+ {
+ if (pawn.apparel?.WornApparel == null) continue;
+
+ foreach (var apparel in pawn.apparel.WornApparel)
+ {
+ var shieldComp = apparel.GetComp();
+ if (shieldComp != null && shieldComp.CheckIntercept(__instance, lastExactPos, newExactPos))
+ {
+ // 使用反射调用protected方法
+ typeof(Projectile).GetMethod("Impact", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
+ .Invoke(__instance, new object[] { null, true });
+ __result = true;
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ // 拦截近战攻击 - 使用Harmony的手动补丁方式
+ public static void ApplyMeleePatch(Harmony harmony)
+ {
+ // 获取Thing.TakeDamage方法
+ var originalMethod = typeof(Thing).GetMethod("TakeDamage",
+ System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
+
+ if (originalMethod != null)
+ {
+ // 获取我们的前缀方法
+ var prefixMethod = typeof(WulaShieldBeltPatches).GetMethod("TakeDamage_Manual_Prefix",
+ System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
+
+ // 应用补丁
+ harmony.Patch(originalMethod, new HarmonyMethod(prefixMethod));
+ }
+ }
+
+ // 手动补丁方法
+ public static bool TakeDamage_Manual_Prefix(Thing __instance, DamageInfo dinfo, ref DamageWorker.DamageResult __result)
+ {
+ // 只有当实例是Pawn时才执行护盾腰带的逻辑
+ if (__instance is Pawn pawn)
+ {
+ if (pawn.apparel?.WornApparel == null) return true;
+
+ // 检查是否有护盾腰带可以拦截这次攻击
+ foreach (var apparel in pawn.apparel.WornApparel)
+ {
+ var shieldComp = apparel.GetComp();
+ if (shieldComp != null && dinfo.Instigator is Pawn attacker)
+ {
+ if (shieldComp.CheckMeleeIntercept(dinfo, attacker))
+ {
+ __result = new DamageWorker.DamageResult();
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ // 为护盾腰带添加投射物拦截器接口支持
+ [HarmonyPatch(typeof(CompProjectileInterceptor), "CheckIntercept")]
+ [HarmonyPostfix]
+ public static void CheckIntercept_Postfix(CompProjectileInterceptor __instance, Projectile projectile, Vector3 lastExactPos, Vector3 newExactPos, ref bool __result)
+ {
+ if (__result) return; // 如果已经被拦截了就不需要再检查
+
+ // 这个补丁确保我们的护盾系统与原版的投射物拦截系统兼容
+ }
+ }
+}
diff --git a/Source/WulaFallenEmpire/clean.bat b/Source/WulaFallenEmpire/clean.bat
new file mode 100644
index 00000000..a657fac4
--- /dev/null
+++ b/Source/WulaFallenEmpire/clean.bat
@@ -0,0 +1,5 @@
+@echo off
+echo 清理临时文件...
+if exist "obj" rmdir /s /q obj
+if exist "bin" rmdir /s /q bin
+echo 清理完成!
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs b/Source/WulaFallenEmpire/obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs
deleted file mode 100644
index 3871b184..00000000
--- a/Source/WulaFallenEmpire/obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-//
-using System;
-using System.Reflection;
-[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
diff --git a/Source/WulaFallenEmpire/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/Source/WulaFallenEmpire/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
deleted file mode 100644
index 455cf6fa..00000000
Binary files a/Source/WulaFallenEmpire/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache and /dev/null differ
diff --git a/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.csproj.AssemblyReference.cache b/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.csproj.AssemblyReference.cache
deleted file mode 100644
index 4665d311..00000000
Binary files a/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.csproj.AssemblyReference.cache and /dev/null differ
diff --git a/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.csproj.CoreCompileInputs.cache b/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.csproj.CoreCompileInputs.cache
deleted file mode 100644
index 078ed891..00000000
--- a/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.csproj.CoreCompileInputs.cache
+++ /dev/null
@@ -1 +0,0 @@
-981fae8ea86dc7ccc506adb49b6855ce4c202ff9e230c7a6c385d9789ef4b0aa
diff --git a/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.csproj.FileListAbsolute.txt b/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.csproj.FileListAbsolute.txt
deleted file mode 100644
index fe056ac7..00000000
--- a/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.csproj.FileListAbsolute.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\WulaFallenEmpire.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\WulaFallenEmpire.pdb
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\Assembly-CSharp.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.CoreModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.IMGUIModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.TextRenderingModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\NAudio.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\NVorbis.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.AudioModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\Unity.Collections.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\Unity.Burst.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\Unity.Mathematics.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\com.rlabrecque.steamworks.net.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\Assembly-CSharp-firstpass.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.AssetBundleModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.PhysicsModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\Unity.TextMeshPro.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\ISharpZipLib.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.InputLegacyModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.PerformanceReportingModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.ImageConversionModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.ScreenCaptureModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.UI.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\netstandard.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.SharedInternalsModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.TextCoreTextEngineModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.PropertiesModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\Unity.Collections.LowLevel.ILSupport.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\Unity.Burst.Unsafe.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.TextCoreFontEngineModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.UIModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.Physics2DModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.AnimationModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\bin\Debug\UnityEngine.SpriteShapeModule.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\obj\Debug\WulaFallenEmpire.csproj.AssemblyReference.cache
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\obj\Debug\WulaFallenEmpire.csproj.CoreCompileInputs.cache
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\obj\Debug\WulaFall.44DB8A10.Up2Date
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\obj\Debug\WulaFallenEmpire.dll
-E:\SteamLibrary\steamapps\common\RimWorld\Mods\WulaFallenEmpire\Source\WulaFallenEmpire\obj\Debug\WulaFallenEmpire.pdb
-C:\Steam\steamapps\workshop\content\294100\3516260226\1.6\Assemblies\WulaFallenEmpire.dll
-C:\Steam\steamapps\workshop\content\294100\3516260226\1.6\Assemblies\WulaFallenEmpire.pdb
-C:\Steam\steamapps\workshop\content\294100\3516260226\Source\WulaFallenEmpire\obj\Debug\WulaFallenEmpire.csproj.AssemblyReference.cache
-C:\Steam\steamapps\workshop\content\294100\3516260226\Source\WulaFallenEmpire\obj\Debug\WulaFallenEmpire.csproj.CoreCompileInputs.cache
-C:\Steam\steamapps\workshop\content\294100\3516260226\Source\WulaFallenEmpire\obj\Debug\WulaFallenEmpire.dll
-C:\Steam\steamapps\workshop\content\294100\3516260226\Source\WulaFallenEmpire\obj\Debug\WulaFallenEmpire.pdb
-C:\Steam\steamapps\common\RimWorld\Mods\3516260226\1.6\Assemblies\WulaFallenEmpire.dll
-C:\Steam\steamapps\common\RimWorld\Mods\3516260226\1.6\Assemblies\WulaFallenEmpire.pdb
-C:\Steam\steamapps\common\RimWorld\Mods\3516260226\Source\WulaFallenEmpire\obj\Debug\WulaFallenEmpire.csproj.AssemblyReference.cache
-C:\Steam\steamapps\common\RimWorld\Mods\3516260226\Source\WulaFallenEmpire\obj\Debug\WulaFallenEmpire.csproj.CoreCompileInputs.cache
-C:\Steam\steamapps\common\RimWorld\Mods\3516260226\Source\WulaFallenEmpire\obj\Debug\WulaFallenEmpire.dll
-C:\Steam\steamapps\common\RimWorld\Mods\3516260226\Source\WulaFallenEmpire\obj\Debug\WulaFallenEmpire.pdb
diff --git a/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.dll b/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.dll
deleted file mode 100644
index 89ffb7ff..00000000
Binary files a/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.dll and /dev/null differ
diff --git a/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.pdb b/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.pdb
deleted file mode 100644
index 1142b654..00000000
Binary files a/Source/WulaFallenEmpire/obj/Debug/WulaFallenEmpire.pdb and /dev/null differ