diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll
index 689016d1..c572fd43 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/PawnKinds/PawnKinds_Wula.xml b/1.6/1.6/Defs/PawnKinds/PawnKinds_Wula.xml
index 6f5f3ee5..99da6873 100644
--- a/1.6/1.6/Defs/PawnKinds/PawnKinds_Wula.xml
+++ b/1.6/1.6/Defs/PawnKinds/PawnKinds_Wula.xml
@@ -194,7 +194,7 @@
Wula/Things/WULA_Cat/AllegianceOverlays/None
CutoutWithOverlay
Graphic_Multi
- 7
+ 9
(1.4, 1.8, 1.4)
@@ -231,7 +231,7 @@
Wula/Things/WULA_Cat/AllegianceOverlays/None
CutoutWithOverlay
Graphic_Multi
- 7
+ 9
(1.4, 1.8, 1.4)
@@ -261,7 +261,7 @@
Wula/Things/WULA_Cat/AllegianceOverlays/None
CutoutWithOverlay
Graphic_Multi
- 5
+ 9
(1.4, 1.8, 1.4)
@@ -270,7 +270,6 @@
0.7
-
Wula_Mech_Mobile_Factory
@@ -297,7 +296,7 @@
Wula/Things/WULA_Cat/AllegianceOverlays/None
CutoutWithOverlay
Graphic_Multi
- 9
+ 12
(1.4, 1.8, 1.4)
diff --git a/1.6/1.6/Defs/ThingDefs_Races/WULA_Mechunit_Race.xml b/1.6/1.6/Defs/ThingDefs_Races/WULA_Mechunit_Race.xml
index d6e303f3..72a6152a 100644
--- a/1.6/1.6/Defs/ThingDefs_Races/WULA_Mechunit_Race.xml
+++ b/1.6/1.6/Defs/ThingDefs_Races/WULA_Mechunit_Race.xml
@@ -116,13 +116,18 @@
0
Wula_AI_Heavy_Panzer_Turret_Weapon
+ 20
+ 0
+ 5
+ true
+ 180
PawnRenderNode_TurretGun
PawnRenderNodeWorker_TurretGun
Body
- (7, 7)
+ (8, 8)
20
Any
@@ -300,48 +305,48 @@
-->
-
+ 1.0
+ 2.0
15
3
- 碰撞区域
- 2
+
+ 3
- 目标过滤
+
true
true
- 阶段1效果
+
Blunt
- 8
+ 1
0.1
- Bruise
+
+
+ MeleeHit_BladelinkZeusHammer
- 阶段2效果
+
Blunt
15
4
true
- ExplosionFlash
- MeleeHit_Slash
+
+ MeleeHit_BladelinkZeusHammer
- 击飞配置
+
PawnFlyer
- FlyerTakeoff
+
PawnFlyerLand
- 调试
+
false
false
false
- -->
+
@@ -394,13 +399,19 @@
0
Wula_AI_Rocket_Panzer_Turret_Weapon
+ 20
+ 30
+ 8
+ true
+ 180
+
PawnRenderNode_TurretGun
PawnRenderNodeWorker_TurretGun
Body
- (7, 7)
+ (8, 8)
20
Any
@@ -1232,6 +1243,48 @@
-->
+
+
+ 0.5
+ 1
+ 15
+ 3
+
+
+ 5
+
+
+ true
+ true
+
+
+ Blunt
+ 5
+ 0.1
+
+
+ MeleeHit_BladelinkZeusHammer
+
+
+ Blunt
+ 50
+ 8
+ true
+
+ MeleeHit_BladelinkZeusHammer
+
+
+ PawnFlyer
+
+ PawnFlyerLand
+
+
+ false
+ false
+ false
+
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/Pawn_Comps/MultiTurretGun/CompMultiTurretGun.cs b/Source/WulaFallenEmpire/Pawn_Comps/MultiTurretGun/CompMultiTurretGun.cs
index 8237f609..2bf7f58e 100644
--- a/Source/WulaFallenEmpire/Pawn_Comps/MultiTurretGun/CompMultiTurretGun.cs
+++ b/Source/WulaFallenEmpire/Pawn_Comps/MultiTurretGun/CompMultiTurretGun.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using Verse;
using Verse.AI;
@@ -10,29 +10,480 @@ namespace WulaFallenEmpire
public class CompProperties_MultiTurretGun : CompProperties_TurretGun
{
public int ID;
+ public float traverseSpeed = 30f; // 旋转速度(度/秒),默认30度/秒
+ public float aimTicks = 15; // 瞄准所需tick数
+ public float idleRotationSpeed = 5f; // 空闲时的旋转速度(度/秒)
+ public bool smoothRotation = true; // 是否启用平滑旋转
+ public float minAimAngle = 10f; // 开始预热所需的最小瞄准角度差(度)
+ public int resetCooldownTicks = 120; // 开火后的复位冷却时间(默认2秒)
+
public CompProperties_MultiTurretGun()
{
compClass = typeof(Comp_MultiTurretGun);
}
}
+
public class Comp_MultiTurretGun : CompTurretGun
{
private bool fireAtWill = true;
+ private float currentRotationAngle; // 当前实际旋转角度
+ private float targetRotationAngle; // 目标旋转角度
+ private float rotationVelocity; // 旋转速度(用于平滑插值)
+ private int ticksWithoutTarget = 0; // 没有目标的tick计数
+ private bool isIdleRotating = false; // 是否处于空闲旋转状态
+ private float idleRotationDirection = 1f; // 空闲旋转方向
+ private bool isAiming = false; // 是否正在瞄准
+ private float lastBaseRotationAngle; // 上一次记录的基座角度
+ private float lastTargetAngle; // 最后一次目标角度
+
+ // 添加缺失的字段
+ private LocalTargetInfo lastAttackedTarget = LocalTargetInfo.Invalid;
+ private int lastAttackTargetTick;
+
+ // Gizmo相关静态字段
+ private static readonly CachedTexture ToggleTurretIcon = new CachedTexture("UI/Gizmos/ToggleTurret");
+ private static bool gizmoAdded = false; // 防止重复添加Gizmo
+
+ // 复位冷却相关
+ private int resetCooldownTicksLeft = 0;
+ private bool isInResetCooldown = false;
+
public new CompProperties_MultiTurretGun Props => (CompProperties_MultiTurretGun)props;
- public override void CompTick()
+
+ // 添加属性
+ private bool WarmingUp => burstWarmupTicksLeft > 0;
+
+ public override void Initialize(CompProperties props)
{
- base.CompTick();
- if (!currentTarget.IsValid && burstCooldownTicksLeft <= 0)
+ base.Initialize(props);
+ // 初始化旋转角度为建筑方向
+ currentRotationAngle = parent.Rotation.AsAngle + Props.angleOffset;
+ targetRotationAngle = currentRotationAngle;
+ lastBaseRotationAngle = parent.Rotation.AsAngle;
+ lastTargetAngle = currentRotationAngle;
+ }
+
+ public override void PostSpawnSetup(bool respawningAfterLoad)
+ {
+ base.PostSpawnSetup(respawningAfterLoad);
+ if (!respawningAfterLoad)
{
- // 在其他情况下没有目标且冷却结束时也回正
- curRotation = parent.Rotation.AsAngle + Props.angleOffset;
+ currentRotationAngle = parent.Rotation.AsAngle + Props.angleOffset;
+ targetRotationAngle = currentRotationAngle;
+ lastBaseRotationAngle = parent.Rotation.AsAngle;
+ lastTargetAngle = currentRotationAngle;
+ }
+ gizmoAdded = false; // 重置Gizmo状态
+ }
+
+ private bool CanShoot
+ {
+ get
+ {
+ if (parent is Pawn pawn)
+ {
+ if (!pawn.Spawned || pawn.Downed || pawn.Dead || !pawn.Awake())
+ {
+ return false;
+ }
+ if (pawn.stances.stunner.Stunned)
+ {
+ return false;
+ }
+ if (TurretDestroyed)
+ {
+ return false;
+ }
+ if (pawn.IsColonyMechPlayerControlled && !fireAtWill)
+ {
+ return false;
+ }
+ }
+ CompCanBeDormant compCanBeDormant = parent.TryGetComp();
+ if (compCanBeDormant != null && !compCanBeDormant.Awake)
+ {
+ return false;
+ }
+ return true;
}
}
+
+ public override void CompTick()
+ {
+ if (!CanShoot)
+ {
+ ResetCurrentTarget();
+ return;
+ }
+
+ // 检查Pawn是否转向
+ CheckPawnRotationChange();
+
+ // 更新炮塔旋转(必须在目标检查之前)
+ UpdateTurretRotation();
+
+ // 处理VerbTick
+ AttackVerb.VerbTick();
+ if (AttackVerb.state == VerbState.Bursting)
+ {
+ return;
+ }
+
+ // 更新复位冷却
+ UpdateResetCooldown();
+
+ // 如果正在预热
+ if (WarmingUp)
+ {
+ // 检查是否仍然瞄准目标
+ if (currentTarget.IsValid && IsAimingAtTarget())
+ {
+ burstWarmupTicksLeft--;
+ if (burstWarmupTicksLeft == 0)
+ {
+ // 确保炮塔已经瞄准目标
+ if (IsAimedAtTarget())
+ {
+ AttackVerb.TryStartCastOn(currentTarget, surpriseAttack: false, canHitNonTargetPawns: true, preventFriendlyFire: false, nonInterruptingSelfCast: true);
+ lastAttackTargetTick = Find.TickManager.TicksGame;
+ lastAttackedTarget = currentTarget;
+
+ // 开火后重置目标,并启动复位冷却
+ ResetCurrentTarget();
+ StartResetCooldown();
+ }
+ else
+ {
+ // 如果没有瞄准,重置预热
+ burstWarmupTicksLeft = 1;
+ }
+ }
+ }
+ else
+ {
+ // 失去目标或失去瞄准,重置预热
+ ResetCurrentTarget();
+ }
+ return;
+ }
+
+ // 冷却中
+ if (burstCooldownTicksLeft > 0)
+ {
+ burstCooldownTicksLeft--;
+ }
+
+ // 冷却结束且复位冷却结束,尝试寻找目标
+ if (burstCooldownTicksLeft <= 0 && !isInResetCooldown && parent.IsHashIntervalTick(10))
+ {
+ TryAcquireTarget();
+ }
+
+ // 更新空闲旋转
+ UpdateIdleRotation();
+ }
+
+ private void UpdateResetCooldown()
+ {
+ if (isInResetCooldown && resetCooldownTicksLeft > 0)
+ {
+ resetCooldownTicksLeft--;
+ if (resetCooldownTicksLeft <= 0)
+ {
+ isInResetCooldown = false;
+ resetCooldownTicksLeft = 0;
+ }
+ }
+ }
+
+ private void StartResetCooldown()
+ {
+ resetCooldownTicksLeft = Props.resetCooldownTicks;
+ isInResetCooldown = true;
+ ticksWithoutTarget = 0; // 重置无目标计数
+ }
+
+ private void CheckPawnRotationChange()
+ {
+ // 如果父物体是Pawn,检查其朝向是否改变
+ if (parent is Pawn pawn)
+ {
+ float currentBaseRotation = pawn.Rotation.AsAngle;
+
+ // 如果朝向改变超过5度,立即更新基座方向
+ if (Mathf.Abs(Mathf.DeltaAngle(currentBaseRotation, lastBaseRotationAngle)) > 5f)
+ {
+ // 立即调整炮塔角度,跟上Pawn的转向
+ currentRotationAngle += Mathf.DeltaAngle(lastBaseRotationAngle, currentBaseRotation);
+ targetRotationAngle = currentRotationAngle;
+ lastBaseRotationAngle = currentBaseRotation;
+
+ // 如果有目标,重新计算目标角度
+ if (currentTarget.IsValid)
+ {
+ Vector3 targetPos = currentTarget.CenterVector3;
+ Vector3 turretPos = parent.DrawPos;
+ targetRotationAngle = (targetPos - turretPos).AngleFlat();
+ }
+ }
+ }
+ }
+
+ private void TryAcquireTarget()
+ {
+ // 如果正在复位冷却中,不寻找目标
+ if (isInResetCooldown)
+ return;
+
+ // 尝试寻找新目标
+ LocalTargetInfo newTarget = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(
+ this,
+ TargetScanFlags.NeedThreat | TargetScanFlags.NeedAutoTargetable
+ );
+
+ if (newTarget.IsValid)
+ {
+ // 如果已经有目标并且是同一个目标,保持当前状态
+ if (currentTarget.IsValid && currentTarget.Thing == newTarget.Thing)
+ {
+ // 检查是否已经瞄准目标
+ if (IsAimedAtTarget())
+ {
+ // 如果已经瞄准,开始预热
+ if (burstWarmupTicksLeft <= 0)
+ {
+ burstWarmupTicksLeft = Mathf.Max(1, Mathf.RoundToInt(Props.aimTicks));
+ }
+ }
+ else if (IsAimingAtTarget())
+ {
+ // 如果正在瞄准但未完成,保持当前状态
+ // 什么也不做,继续旋转
+ }
+ else
+ {
+ // 需要重新瞄准
+ burstWarmupTicksLeft = 0;
+ }
+ }
+ else
+ {
+ // 新目标,重置状态
+ currentTarget = newTarget;
+ burstWarmupTicksLeft = 0;
+ isAiming = true;
+
+ // 计算目标角度
+ Vector3 targetPos = currentTarget.CenterVector3;
+ Vector3 turretPos = parent.DrawPos;
+ targetRotationAngle = (targetPos - turretPos).AngleFlat();
+ lastTargetAngle = targetRotationAngle;
+ }
+ }
+ else
+ {
+ // 没有目标
+ ResetCurrentTarget();
+ }
+ }
+
+ private bool IsAimingAtTarget()
+ {
+ if (!currentTarget.IsValid)
+ return false;
+
+ // 计算当前角度与目标角度的差值
+ float angleDiff = Mathf.Abs(Mathf.DeltaAngle(currentRotationAngle, targetRotationAngle));
+
+ // 如果角度差小于最小瞄准角度,认为正在瞄准
+ return angleDiff <= Props.minAimAngle;
+ }
+
+ private bool IsAimedAtTarget()
+ {
+ if (!currentTarget.IsValid)
+ return false;
+
+ // 计算当前角度与目标角度的差值
+ float angleDiff = Mathf.Abs(Mathf.DeltaAngle(currentRotationAngle, targetRotationAngle));
+
+ // 如果角度差小于2度,认为已经瞄准
+ return angleDiff <= 2f;
+ }
+
+ private void UpdateTurretRotation()
+ {
+ if (!Props.smoothRotation)
+ {
+ // 非平滑旋转:直接设置角度
+ if (currentTarget.IsValid)
+ {
+ Vector3 targetPos = currentTarget.CenterVector3;
+ Vector3 turretPos = parent.DrawPos;
+ curRotation = (targetPos - turretPos).AngleFlat() + Props.angleOffset;
+ }
+ else
+ {
+ curRotation = parent.Rotation.AsAngle + Props.angleOffset;
+ }
+ return;
+ }
+
+ // 平滑旋转逻辑
+ if (currentTarget.IsValid)
+ {
+ // 有目标时,计算朝向目标的角度
+ Vector3 targetPos = currentTarget.CenterVector3;
+ Vector3 turretPos = parent.DrawPos;
+ targetRotationAngle = (targetPos - turretPos).AngleFlat();
+ ticksWithoutTarget = 0;
+ isIdleRotating = false;
+ lastTargetAngle = targetRotationAngle;
+ }
+ else
+ {
+ // 没有目标时,朝向初始角度
+ targetRotationAngle = parent.Rotation.AsAngle + Props.angleOffset;
+ ticksWithoutTarget++;
+ lastTargetAngle = targetRotationAngle;
+ }
+
+ // 确保角度在0-360范围内
+ targetRotationAngle = targetRotationAngle % 360f;
+ if (targetRotationAngle < 0f)
+ targetRotationAngle += 360f;
+
+ // 计算角度差(使用DeltaAngle处理360度循环)
+ float angleDiff = Mathf.DeltaAngle(currentRotationAngle, targetRotationAngle);
+
+ // 如果角度差很小,直接设置到目标角度
+ if (Mathf.Abs(angleDiff) < 0.1f)
+ {
+ currentRotationAngle = targetRotationAngle;
+ curRotation = currentRotationAngle;
+ return;
+ }
+
+ // 计算最大旋转速度(度/秒)
+ float maxRotationSpeed = Props.traverseSpeed;
+
+ // 如果有目标且在预热,根据预热进度调整旋转速度
+ if (currentTarget.IsValid && burstWarmupTicksLeft > 0)
+ {
+ float warmupProgress = 1f - (float)burstWarmupTicksLeft / (float)Math.Max(Props.aimTicks, 1f);
+
+ // 预热初期快速旋转,接近完成时减速
+ if (warmupProgress < 0.3f)
+ {
+ maxRotationSpeed *= 1.8f; // 初期更快
+ }
+ else if (warmupProgress > 0.7f)
+ {
+ maxRotationSpeed *= 0.5f; // 后期更慢,精确瞄准
+ }
+ }
+
+ // 转换为每tick的旋转速度
+ float maxRotationPerTick = maxRotationSpeed / 60f;
+
+ // 根据角度差调整旋转速度
+ float rotationSpeedMultiplier = Mathf.Clamp(Mathf.Abs(angleDiff) / 45f, 0.5f, 1.5f);
+ maxRotationPerTick *= rotationSpeedMultiplier;
+
+ // 计算这一帧应该旋转的角度
+ float rotationThisTick = Mathf.Clamp(angleDiff, -maxRotationPerTick, maxRotationPerTick);
+
+ // 应用旋转
+ currentRotationAngle += rotationThisTick;
+
+ // 确保角度在0-360范围内
+ currentRotationAngle = currentRotationAngle % 360f;
+ if (currentRotationAngle < 0f)
+ currentRotationAngle += 360f;
+
+ // 更新基类的curRotation
+ curRotation = currentRotationAngle;
+ }
+
+ private void UpdateIdleRotation()
+ {
+ // 只在没有目标、冷却结束且复位冷却结束时执行空闲旋转
+ if (!currentTarget.IsValid && burstCooldownTicksLeft <= 0 && !isInResetCooldown && ticksWithoutTarget > 120)
+ {
+ if (!isIdleRotating)
+ {
+ isIdleRotating = true;
+ idleRotationDirection = Rand.Value > 0.5f ? 1f : -1f;
+ }
+
+ // 缓慢旋转
+ float idleRotationPerTick = Props.idleRotationSpeed / 60f * idleRotationDirection;
+ currentRotationAngle += idleRotationPerTick;
+
+ // 确保角度在0-360范围内
+ currentRotationAngle = currentRotationAngle % 360f;
+ if (currentRotationAngle < 0f)
+ currentRotationAngle += 360f;
+
+ // 更新基类的curRotation
+ curRotation = currentRotationAngle;
+
+ // 每30tick随机可能改变方向
+ if (Find.TickManager.TicksGame % 30 == 0 && Rand.Value < 0.1f)
+ {
+ idleRotationDirection *= -1f;
+ }
+ }
+ else
+ {
+ isIdleRotating = false;
+ }
+ }
+
+ private void ResetCurrentTarget()
+ {
+ currentTarget = LocalTargetInfo.Invalid;
+ burstWarmupTicksLeft = 0;
+ isAiming = false;
+ }
+
+ public override void PostDraw()
+ {
+ base.PostDraw();
+
+ // 如果有目标且正在预热,绘制瞄准线
+ if (currentTarget.IsValid && burstWarmupTicksLeft > 0)
+ {
+ DrawTargetingLine();
+ }
+ }
+
+ private void DrawTargetingLine()
+ {
+ Vector3 lineStart = parent.DrawPos;
+ lineStart.y = AltitudeLayer.MetaOverlays.AltitudeFor();
+
+ Vector3 lineEnd = currentTarget.CenterVector3;
+ lineEnd.y = AltitudeLayer.MetaOverlays.AltitudeFor();
+
+ // 计算瞄准精度
+ float aimAccuracy = 1f - Mathf.Abs(Mathf.DeltaAngle(currentRotationAngle, targetRotationAngle)) / 45f;
+ aimAccuracy = Mathf.Clamp01(aimAccuracy);
+
+ // 根据瞄准精度改变线条颜色
+ Color lineColor = Color.Lerp(Color.yellow, Color.red, aimAccuracy);
+ lineColor.a = 0.7f;
+
+ GenDraw.DrawLineBetween(lineStart, lineEnd);
+ }
+
+
private void MakeGun()
{
gun = ThingMaker.MakeThing(Props.turretDef);
UpdateGunVerbs();
}
+
private void UpdateGunVerbs()
{
List allVerbs = gun.TryGetComp().AllVerbs;
@@ -46,13 +497,106 @@ namespace WulaFallenEmpire
};
}
}
+
+ // 添加Gizmo方法
+ public override IEnumerable CompGetGizmosExtra()
+ {
+ foreach (Gizmo gizmo in base.CompGetGizmosExtra())
+ {
+ yield return gizmo;
+ }
+
+ // 只让第一个Comp_MultiTurretGun组件生成Gizmo
+ if (parent is Pawn pawn && pawn.IsColonyMechPlayerControlled)
+ {
+ // 获取所有Comp_MultiTurretGun组件
+ var allTurretComps = parent.GetComps();
+
+ // 检查当前组件是否是第一个
+ if (!gizmoAdded)
+ {
+ gizmoAdded = true;
+
+ // 检查所有炮塔是否都有相同的fireAtWill状态
+ bool allTurretsEnabled = true;
+ bool allTurretsDisabled = true;
+
+ foreach (var turretComp in allTurretComps)
+ {
+ if (turretComp.fireAtWill)
+ allTurretsDisabled = false;
+ else
+ allTurretsEnabled = false;
+ }
+
+ // 确定Gizmo的初始状态
+ bool mixedState = !(allTurretsEnabled || allTurretsDisabled);
+
+ Command_Toggle command = new Command_Toggle();
+ command.defaultLabel = "CommandToggleTurret".Translate();
+ command.defaultDesc = "CommandToggleTurretDesc".Translate();
+ command.icon = ToggleTurretIcon.Texture;
+ command.isActive = () =>
+ {
+ // 如果有混合状态,显示为false但使用特殊图标
+ if (mixedState)
+ return false;
+ return allTurretsEnabled;
+ };
+ command.toggleAction = () =>
+ {
+ // 切换所有炮塔的状态
+ bool newState = !allTurretsEnabled;
+
+ foreach (var turretComp in allTurretComps)
+ {
+ turretComp.fireAtWill = newState;
+
+ // 如果关闭炮塔,重置当前目标
+ if (!newState)
+ {
+ turretComp.ResetCurrentTarget();
+ }
+ }
+ };
+
+ // 如果有混合状态,显示特殊图标
+ if (mixedState)
+ {
+ command.icon = ContentFinder.Get("UI/Commands/MixedState");
+ }
+
+ yield return command;
+ }
+ }
+ }
+
public override void PostExposeData()
{
+ base.PostExposeData();
Scribe_Values.Look(ref burstCooldownTicksLeft, "burstCooldownTicksLeft", 0);
Scribe_Values.Look(ref burstWarmupTicksLeft, "burstWarmupTicksLeft", 0);
Scribe_TargetInfo.Look(ref currentTarget, "currentTarget_" + Props.ID);
Scribe_Deep.Look(ref gun, "gun_" + Props.ID);
Scribe_Values.Look(ref fireAtWill, "fireAtWill", defaultValue: true);
+ Scribe_Values.Look(ref currentRotationAngle, "currentRotationAngle", 0f);
+ Scribe_Values.Look(ref targetRotationAngle, "targetRotationAngle", 0f);
+ Scribe_Values.Look(ref rotationVelocity, "rotationVelocity", 0f);
+ Scribe_Values.Look(ref ticksWithoutTarget, "ticksWithoutTarget", 0);
+ Scribe_Values.Look(ref isIdleRotating, "isIdleRotating", false);
+ Scribe_Values.Look(ref idleRotationDirection, "idleRotationDirection", 1f);
+ Scribe_Values.Look(ref isAiming, "isAiming", false);
+ Scribe_Values.Look(ref lastBaseRotationAngle, "lastBaseRotationAngle", 0f);
+ Scribe_Values.Look(ref lastTargetAngle, "lastTargetAngle", 0f);
+
+ // 保存缺失的字段
+ Scribe_TargetInfo.Look(ref lastAttackedTarget, "lastAttackedTarget_" + Props.ID);
+ Scribe_Values.Look(ref lastAttackTargetTick, "lastAttackTargetTick_" + Props.ID, 0);
+
+ // 保存复位冷却相关字段
+ Scribe_Values.Look(ref resetCooldownTicksLeft, "resetCooldownTicksLeft", 0);
+ Scribe_Values.Look(ref isInResetCooldown, "isInResetCooldown", false);
+
if (Scribe.mode == LoadSaveMode.PostLoadInit)
{
if (gun == null)
@@ -63,8 +607,23 @@ namespace WulaFallenEmpire
{
UpdateGunVerbs();
}
+
+ // 确保旋转角度有效
+ if (currentRotationAngle == 0f)
+ {
+ currentRotationAngle = parent.Rotation.AsAngle + Props.angleOffset;
+ targetRotationAngle = currentRotationAngle;
+ lastBaseRotationAngle = parent.Rotation.AsAngle;
+ lastTargetAngle = currentRotationAngle;
+ }
}
}
+
+ // 如果需要实现 IAttackTargetSearcher 接口
+ public new Thing Thing => parent;
+
+ public new LocalTargetInfo LastAttackedTarget => lastAttackedTarget;
+
+ public new int LastAttackTargetTick => lastAttackTargetTick;
}
-
}