diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll
index 00da6fd7..849f6821 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/ThingDefs_Misc/Apperals/WULA_Apparel.xml b/1.6/1.6/Defs/ThingDefs_Misc/Apperals/WULA_Apparel.xml
index b35b1e63..39abdd7b 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
@@ -503,16 +503,16 @@
-
- 1.25
- 150
+ 1
+ 50
2800
+ 3
true
- false
- false
+ true
+ true
(0.9, 0.2, 0.2, 0.5)
@@ -520,13 +520,14 @@
Shield_Break
BulletShieldGenerator_Reactivate
+ false
+
false
600
60
-
diff --git a/Source/WulaFallenEmpire/HarmonyPatches/Projectile_Launch_Patch.cs b/Source/WulaFallenEmpire/HarmonyPatches/Projectile_Launch_Patch.cs
index 8722f5f9..bad0bcd3 100644
--- a/Source/WulaFallenEmpire/HarmonyPatches/Projectile_Launch_Patch.cs
+++ b/Source/WulaFallenEmpire/HarmonyPatches/Projectile_Launch_Patch.cs
@@ -7,45 +7,42 @@ using Verse;
namespace WulaFallenEmpire.HarmonyPatches
{
- [HarmonyPatch(typeof(Projectile), "CheckForFreeInterceptBetween")]
- public static class Projectile_CheckForFreeInterceptBetween_Patch
+ [HarmonyPatch(typeof(Projectile), "Impact")]
+ public static class Projectile_Impact_Patch
{
- public static bool Prefix(Projectile __instance, Vector3 lastExactPos, Vector3 newExactPos)
+ private static Dictionary bounceCount = new Dictionary();
+
+ [HarmonyPrefix]
+ public static bool Prefix(Projectile __instance, Thing hitThing)
{
try
{
- if (__instance == null || __instance.Map == null || __instance.Destroyed || !__instance.Spawned)
+ if (__instance.Destroyed || !__instance.Spawned || hitThing == null)
return true;
- var map = __instance.Map;
- var pawns = map.mapPawns?.AllPawnsSpawned;
- if (pawns == null) return true;
-
- foreach (Pawn pawn in pawns)
+ // 检查抛射体是否击中了穿戴护盾的 pawn
+ if (hitThing is Pawn hitPawn)
{
- if (pawn == null || !pawn.Spawned || pawn.Dead || pawn.Downed || pawn.apparel == null)
- continue;
-
- foreach (Apparel apparel in pawn.apparel.WornApparel)
+ // 获取 pawn 身上的所有拦截护盾
+ var interceptors = GetInterceptorsOnPawn(hitPawn);
+
+ foreach (var interceptor in interceptors)
{
- if (apparel?.TryGetComp() is CompApparelInterceptor interceptor)
+ if (interceptor.TryInterceptProjectile(__instance, hitThing))
{
- try
+ // 记录反弹次数
+ int currentBounces = bounceCount.TryGetValue(__instance, 0) + 1;
+ bounceCount[__instance] = currentBounces;
+
+ // 检查最大反弹次数
+ if (currentBounces >= interceptor.Props.maxBounces)
{
- if (interceptor.TryIntercept(__instance, lastExactPos, newExactPos))
- {
- // 简单直接:立即销毁子弹
- if (!__instance.Destroyed && __instance.Spawned)
- {
- __instance.Destroy(DestroyMode.Vanish);
- }
- return false;
- }
- }
- catch (Exception ex)
- {
- Log.Warning($"[Interceptor] Error: {ex.Message}");
+ __instance.Destroy();
+ return false;
}
+
+ // 拦截成功,阻止原版 Impact 逻辑
+ return false;
}
}
}
@@ -54,27 +51,49 @@ namespace WulaFallenEmpire.HarmonyPatches
}
catch (Exception ex)
{
- Log.Error($"[Interceptor] Critical error: {ex}");
+ Log.Error($"Error in Projectile_Impact_Patch: {ex}");
return true;
}
}
- }
- [HarmonyPatch(typeof(Projectile), "Tick")]
- public static class Projectile_Tick_Patch
- {
- public static bool Prefix(Projectile __instance)
+ private static List GetInterceptorsOnPawn(Pawn pawn)
{
- return __instance != null && !__instance.Destroyed && __instance.Spawned;
+ var result = new List();
+
+ if (pawn == null || pawn.apparel == null)
+ return result;
+
+ try
+ {
+ foreach (var apparel in pawn.apparel.WornApparel)
+ {
+ var interceptor = apparel.GetComp();
+ if (interceptor != null && interceptor.Active)
+ {
+ result.Add(interceptor);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error($"Error in GetInterceptorsOnPawn: {ex}");
+ }
+
+ return result;
}
- }
- [HarmonyPatch(typeof(Projectile), "TickInterval")]
- public static class Projectile_TickInterval_Patch
- {
- public static bool Prefix(Projectile __instance, int delta)
+ // 清理反弹计数 - 修复:使用 Thing 的 Destroy 方法
+ [HarmonyPatch(typeof(Thing), "Destroy")]
+ public static class Thing_Destroy_Patch
{
- return __instance != null && !__instance.Destroyed && __instance.Spawned;
+ [HarmonyPostfix]
+ public static void Postfix(Thing __instance)
+ {
+ if (__instance is Projectile projectile)
+ {
+ bounceCount.Remove(projectile);
+ }
+ }
}
}
}
diff --git a/Source/WulaFallenEmpire/HediffComp/WULA_HediffComp_TopTurret/HediffComp_TopTurret.cs b/Source/WulaFallenEmpire/HediffComp/WULA_HediffComp_TopTurret/HediffComp_TopTurret.cs
index 37b2de23..d96cb358 100644
--- a/Source/WulaFallenEmpire/HediffComp/WULA_HediffComp_TopTurret/HediffComp_TopTurret.cs
+++ b/Source/WulaFallenEmpire/HediffComp/WULA_HediffComp_TopTurret/HediffComp_TopTurret.cs
@@ -15,10 +15,9 @@ namespace WulaFallenEmpire
}
public ThingDef turretDef;
-
public float angleOffset;
-
public bool autoAttack = true;
+ public bool defaultEnabled = true; // 新增:默认启用状态
}
[StaticConstructorOnStartup]
@@ -88,10 +87,200 @@ namespace WulaFallenEmpire
}
}
+ private bool ShouldAttackVolleyTarget
+ {
+ get
+ {
+ if (!VolleyTargetManager.IsVolleyEnabled(Pawn))
+ return false;
+
+ LocalTargetInfo volleyTarget = VolleyTargetManager.GetVolleyTarget(Pawn);
+ if (!volleyTarget.IsValid)
+ return false;
+
+ // 检查目标是否在射程内
+ float distance = Pawn.Position.DistanceTo(volleyTarget.Cell);
+ if (distance > AttackVerb.verbProps.range)
+ return false;
+
+ // 检查是否可以命中目标
+ return AttackVerb.CanHitTarget(volleyTarget);
+ }
+ }
+ public override void CompPostTick(ref float severityAdjustment)
+ {
+ base.CompPostTick(ref severityAdjustment);
+
+ if (!TurretEnabled)
+ {
+ ResetCurrentTarget();
+ return;
+ }
+ if (!this.CanShoot)
+ {
+ return;
+ }
+ // 新增:优先处理齐射目标
+ if (ShouldAttackVolleyTarget)
+ {
+ LocalTargetInfo volleyTarget = VolleyTargetManager.GetVolleyTarget(Pawn);
+ this.currentTarget = volleyTarget;
+ this.curRotation = (volleyTarget.Cell.ToVector3Shifted() - this.Pawn.DrawPos).AngleFlat() + this.Props.angleOffset;
+ }
+ else if (this.currentTarget.IsValid)
+ {
+ this.curRotation = (this.currentTarget.Cell.ToVector3Shifted() - this.Pawn.DrawPos).AngleFlat() + this.Props.angleOffset;
+ }
+
+ this.AttackVerb.VerbTick();
+ if (this.AttackVerb.state != VerbState.Bursting)
+ {
+ if (this.WarmingUp)
+ {
+ this.burstWarmupTicksLeft--;
+ if (this.burstWarmupTicksLeft == 0)
+ {
+ this.AttackVerb.TryStartCastOn(this.currentTarget, false, true, false, true);
+ this.lastAttackTargetTick = Find.TickManager.TicksGame;
+ this.lastAttackedTarget = this.currentTarget;
+ return;
+ }
+ }
+ else
+ {
+ if (this.burstCooldownTicksLeft > 0)
+ {
+ this.burstCooldownTicksLeft--;
+ }
+ if (this.burstCooldownTicksLeft <= 0 && this.Pawn.IsHashIntervalTick(10))
+ {
+ // 只有在没有齐射目标时才寻找新目标
+ if (!ShouldAttackVolleyTarget)
+ {
+ this.currentTarget = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(this, TargetScanFlags.NeedThreat | TargetScanFlags.NeedAutoTargetable, null, 0f, 9999f);
+ if (this.currentTarget.IsValid)
+ {
+ this.burstWarmupTicksLeft = 1;
+ return;
+ }
+ }
+ this.ResetCurrentTarget();
+ }
+ }
+ }
+ }
+ // 新增:齐射Gizmos
+ public override IEnumerable CompGetGizmos()
+ {
+ // 只有 pawn 被选中且是玩家派系时才显示按钮
+ if (this.Pawn.Faction == Faction.OfPlayer && Find.Selector.IsSelected(this.Pawn))
+ {
+ // 原有开关按钮
+ yield return new Command_Toggle
+ {
+ defaultLabel = "CommandToggleTurret".Translate(),
+ defaultDesc = "CommandToggleTurretDesc".Translate(),
+ icon = ContentFinder.Get("UI/Gizmos/ToggleTurret"),
+ isActive = () => TurretEnabled,
+ toggleAction = () => TurretEnabled = !TurretEnabled,
+ hotKey = KeyBindingDefOf.Misc1
+ };
+ // 新增:齐射开关按钮
+ yield return new Command_Toggle
+ {
+ defaultLabel = "CommandToggleVolley".Translate(),
+ defaultDesc = "CommandToggleVolleyDesc".Translate(),
+ icon = ContentFinder.Get("UI/Gizmos/VolleyFire"),
+ isActive = () => VolleyTargetManager.IsVolleyEnabled(Pawn),
+ toggleAction = () => VolleyTargetManager.ToggleVolley(Pawn),
+ hotKey = KeyBindingDefOf.Misc2
+ };
+ // 新增:设置齐射目标按钮(只在齐射启用时显示)
+ if (VolleyTargetManager.IsVolleyEnabled(Pawn))
+ {
+ yield return new Command_Action
+ {
+ defaultLabel = "CommandSetVolleyTarget".Translate(),
+ defaultDesc = "CommandSetVolleyTargetDesc".Translate(),
+ icon = ContentFinder.Get("UI/Gizmos/SetTarget"),
+ action = () => Find.Targeter.BeginTargeting(TargetingParameters.ForAttack(),
+ delegate (LocalTargetInfo target)
+ {
+ VolleyTargetManager.SetVolleyTarget(Pawn, target);
+ },
+ null,
+ null,
+ "SetVolleyTarget".Translate()),
+ hotKey = KeyBindingDefOf.Misc3
+ };
+ // 新增:清除齐射目标按钮
+ LocalTargetInfo currentVolleyTarget = VolleyTargetManager.GetVolleyTarget(Pawn);
+ if (currentVolleyTarget.IsValid)
+ {
+ yield return new Command_Action
+ {
+ defaultLabel = "CommandClearVolleyTarget".Translate(),
+ defaultDesc = "CommandClearVolleyTargetDesc".Translate(),
+ icon = ContentFinder.Get("UI/Gizmos/ClearTarget"),
+ action = () => VolleyTargetManager.ClearVolleyTarget(Pawn),
+ hotKey = KeyBindingDefOf.Misc4
+ };
+ }
+ }
+ }
+ }
+ // 新增:在提示中显示齐射状态
+ public override string CompTipStringExtra
+ {
+ get
+ {
+ string baseString = base.CompTipStringExtra;
+ string turretStatus = TurretEnabled ? "Turret: Active" : "Turret: Inactive";
+
+ string volleyStatus = "Volley: ";
+ if (VolleyTargetManager.IsVolleyEnabled(Pawn))
+ {
+ LocalTargetInfo volleyTarget = VolleyTargetManager.GetVolleyTarget(Pawn);
+ if (volleyTarget.IsValid)
+ {
+ volleyStatus += $"Targeting {volleyTarget.Thing?.LabelCap ?? volleyTarget.Cell.ToString()}";
+ }
+ else
+ {
+ volleyStatus += "Enabled (No Target)";
+ }
+ }
+ else
+ {
+ volleyStatus += "Disabled";
+ }
+ string result = turretStatus + "\n" + volleyStatus;
+ return string.IsNullOrEmpty(baseString) ? result : baseString + "\n" + result;
+ }
+ }
+
+ // 新增:炮塔启用状态
+ public bool TurretEnabled
+ {
+ get { return turretEnabled; }
+ set
+ {
+ turretEnabled = value;
+ if (!turretEnabled)
+ {
+ ResetCurrentTarget(); // 禁用时重置目标
+ }
+ }
+ }
+
private bool CanShoot
{
get
{
+ // 新增:检查炮塔是否启用
+ if (!TurretEnabled)
+ return false;
+
Pawn pawn;
if ((pawn = (this.Pawn)) != null)
{
@@ -150,6 +339,8 @@ namespace WulaFallenEmpire
{
base.CompPostMake();
this.MakeGun();
+ // 新增:设置默认启用状态
+ TurretEnabled = Props.defaultEnabled;
}
private void MakeGun()
@@ -171,9 +362,18 @@ namespace WulaFallenEmpire
};
}
}
+
public override void CompPostTick(ref float severityAdjustment)
{
base.CompPostTick(ref severityAdjustment);
+
+ // 新增:只在启用状态下执行攻击逻辑
+ if (!TurretEnabled)
+ {
+ ResetCurrentTarget();
+ return;
+ }
+
if (!this.CanShoot)
{
return;
@@ -230,6 +430,9 @@ namespace WulaFallenEmpire
Scribe_TargetInfo.Look(ref this.currentTarget, "currentTarget");
Scribe_Deep.Look(ref this.gun, "gun", Array.Empty