This commit is contained in:
2025-12-09 12:02:39 +08:00
parent 720487805f
commit 142df124dd
22 changed files with 991 additions and 539 deletions

View File

@@ -201,15 +201,22 @@ namespace WulaFallenEmpire
{
if (MechPawn == null || !CanBeAutonomous)
yield break;
// 工作模式切换按钮
if (CanWorkAutonomously)
{
yield return new DroneGizmo(this);
DroneGizmo droneGizmo = new DroneGizmo(this);
if (droneGizmo != null)
{
yield return droneGizmo;
}
}
// 更换武器按钮 - 确保不返回null
Gizmo weaponSwitchGizmo = CreateWeaponSwitchGizmo();
if (weaponSwitchGizmo != null)
{
yield return weaponSwitchGizmo;
}
// 更换武器按钮
yield return CreateWeaponSwitchGizmo();
}
/// <summary>
@@ -217,20 +224,43 @@ namespace WulaFallenEmpire
/// </summary>
private Gizmo CreateWeaponSwitchGizmo()
{
// 检查Pawn是否属于玩家派系
if (MechPawn?.Faction != Faction.OfPlayer)
try
{
return null; // 非玩家派系时不显示
// 检查Pawn是否属于玩家派系
if (MechPawn?.Faction != Faction.OfPlayer)
{
return null; // 非玩家派系时不显示
}
// 检查Pawn是否有效
if (MechPawn == null || MechPawn.Dead || MechPawn.Destroyed)
{
return null;
}
// 检查equipment是否有效
if (MechPawn.equipment == null)
{
return null;
}
Command_Action switchWeaponCommand = new Command_Action
{
defaultLabel = "WULA_SwitchWeapon".Translate(),
defaultDesc = "WULA_SwitchWeapon_Desc".Translate(),
icon = ContentFinder<Texture2D>.Get("Wula/UI/Abilities/WULA_WeaponSwitchAbility", false) ?? BaseContent.BadTex,
action = SwitchWeapon,
};
// 确保Command不为null
if (switchWeaponCommand == null)
{
Log.Error($"Failed to create weapon switch gizmo for {MechPawn?.LabelCap}");
return null;
}
return switchWeaponCommand;
}
Command_Action switchWeaponCommand = new Command_Action
catch (System.Exception ex)
{
defaultLabel = "WULA_SwitchWeapon".Translate(),
defaultDesc = "WULA_SwitchWeapon_Desc".Translate(),
icon = ContentFinder<Texture2D>.Get("Wula/UI/Abilities/WULA_WeaponSwitchAbility", false) ?? BaseContent.BadTex,
action = SwitchWeapon
};
return switchWeaponCommand;
Log.Error($"Error creating weapon switch gizmo: {ex}");
return null;
}
}
/// <summary>

View File

@@ -20,6 +20,9 @@ namespace WulaFallenEmpire
// 新增:记录最后一次检查敌人的时间
private int lastEnemyCheckTick = -99999;
// 新增:记录最后一次发信的时间
private int lastLetterTick = -99999;
public HediffDef GetTargetInvisibilityDef()
{
return Props.InvisibilityDef;
@@ -49,6 +52,7 @@ namespace WulaFallenEmpire
Scribe_Values.Look(ref lastDetectedTick, "lastDetectedTick", 0);
Scribe_Values.Look(ref lastRevealedTick, "lastRevealedTick", 0);
Scribe_Values.Look(ref lastEnemyCheckTick, "lastEnemyCheckTick", 0);
Scribe_Values.Look(ref lastLetterTick, "lastLetterTick", 0);
}
public override void CompTick()
@@ -78,6 +82,9 @@ namespace WulaFallenEmpire
Invisibility.BecomeVisible();
lastDetectedTick = Find.TickManager.TicksGame;
// 触发显现事件
TrySendLetter("attack");
}
/// <summary>
@@ -85,7 +92,6 @@ namespace WulaFallenEmpire
/// </summary>
private void CheckForEnemiesInSight()
{
// 检查频率每30 tick检查一次约0.5秒)
if (!Sightstealer.IsHashIntervalTick(30) ||
Find.TickManager.TicksGame <= lastEnemyCheckTick + 30)
@@ -95,12 +101,6 @@ namespace WulaFallenEmpire
lastEnemyCheckTick = Find.TickManager.TicksGame;
// 如果配置为只在战斗状态时检查,且当前不在战斗状态,则跳过
if (Props.onlyCheckInCombat && !IsInCombatState())
{
return;
}
// 检查视线内是否有敌人
bool enemyInSight = false;
List<Pawn> enemiesInSight = new List<Pawn>();
@@ -156,108 +156,110 @@ namespace WulaFallenEmpire
lastDetectedTick = Find.TickManager.TicksGame;
lastRevealedTick = Find.TickManager.TicksGame;
// 可选:添加视觉或声音效果
if (Props.showRevealEffect)
// 触发显现事件
TrySendLetter("detected", enemiesInSight);
}
}
/// <summary>
/// 尝试发送信件
/// </summary>
private void TrySendLetter(string cause, List<Pawn> enemies = null)
{
// 检查是否应该发送信件
if (!ShouldSendLetter())
return;
// 发送信件
SendLetter(cause, enemies);
}
/// <summary>
/// 检查是否应该发送信件
/// </summary>
private bool ShouldSendLetter()
{
// 如果配置为不发信直接返回false
if (!Props.sendLetterOnReveal)
return false;
// 检查发送间隔
int currentTick = Find.TickManager.TicksGame;
if (currentTick < lastLetterTick + Props.letterIntervalTicks)
{
// 还没到发送间隔
return false;
}
// 检查Pawn是否非玩家控制
if (Sightstealer.Faction == Faction.OfPlayer)
{
// 玩家控制的Pawn不发送信件
return false;
}
return true;
}
/// <summary>
/// 发送信件
/// </summary>
private void SendLetter(string cause, List<Pawn> enemies = null)
{
try
{
int currentTick = Find.TickManager.TicksGame;
// 获取信件标题和内容
string title = Props.letterTitle;
string text = Props.letterText;
// 如果标题或内容为空,使用默认值
if (string.IsNullOrEmpty(title))
title = "隐身单位现身";
if (string.IsNullOrEmpty(text))
{
ShowRevealEffect(enemiesInSight);
string enemyInfo = "";
if (enemies != null && enemies.Count > 0)
{
if (enemies.Count == 1)
{
enemyInfo = $"被 {enemies[0].LabelCap} 发现";
}
else
{
enemyInfo = $"被 {enemies.Count} 个敌人发现";
}
}
else if (cause == "attack")
{
enemyInfo = "发动了攻击";
}
text = $"{Sightstealer.LabelCap}{Sightstealer.Faction?.Name ?? ""})在 {Sightstealer.Map?.Parent?.LabelCap ?? ""} 现身了。\n\n{enemyInfo}\n位置{Sightstealer.Position}";
}
// 可选:发送消息
if (Props.sendRevealMessage && Sightstealer.Faction == Faction.OfPlayer)
{
SendRevealMessage(enemiesInSight);
}
}
}
/// <summary>
/// 检查是否处于战斗状态
/// </summary>
private bool IsInCombatState()
{
// 如果有当前工作且是战斗相关工作
if (Sightstealer.CurJob != null)
{
JobDef jobDef = Sightstealer.CurJob.def;
if (jobDef == JobDefOf.AttackMelee ||
jobDef == JobDefOf.AttackStatic ||
jobDef == JobDefOf.Wait_Combat ||
jobDef == JobDefOf.Flee ||
jobDef == JobDefOf.FleeAndCower)
{
return true;
}
}
// 如果有敌人目标
if (Sightstealer.mindState.enemyTarget != null)
{
return true;
}
// 如果最近受到过伤害
if (Find.TickManager.TicksGame - Sightstealer.mindState.lastHarmTick < 300) // 最近5秒内受到伤害
{
return true;
}
// 如果最近攻击过目标
if (Find.TickManager.TicksGame - Sightstealer.mindState.lastAttackTargetTick < 300)
{
return true;
}
return false;
}
/// <summary>
/// 显示解除隐身的效果
/// </summary>
private void ShowRevealEffect(List<Pawn> enemies)
{
if (Sightstealer.Map == null) return;
// 创建一个闪光效果
FleckMaker.ThrowLightningGlow(Sightstealer.Position.ToVector3Shifted(),
Sightstealer.Map, 2f);
// 可选:播放声音
if (Props.revealSound != null)
{
Props.revealSound.PlayOneShot(new TargetInfo(Sightstealer.Position, Sightstealer.Map));
}
}
/// <summary>
/// 发送解除隐身消息
/// </summary>
private void SendRevealMessage(List<Pawn> enemies)
{
if (enemies.Count == 0) return;
string message;
if (enemies.Count == 1)
{
message = "WFE.RevealedBySingleEnemy".Translate(
Sightstealer.LabelShort,
enemies[0].LabelShort
// 发送信件
Letter letter = LetterMaker.MakeLetter(
title,
text,
LetterDefOf.NeutralEvent,
new LookTargets(Sightstealer)
);
Find.LetterStack.ReceiveLetter(letter);
// 更新最后发信时间
lastLetterTick = currentTick;
}
else
catch (System.Exception ex)
{
message = "WFE.RevealedByMultipleEnemies".Translate(
Sightstealer.LabelShort,
enemies.Count
);
Log.Error($"CompFighterInvisible: Error sending letter for {Sightstealer?.LabelCap}: {ex}");
}
Messages.Message(message, Sightstealer, MessageTypeDefOf.NeutralEvent);
}
/// <summary>
/// 获取下次可以隐身的时间
/// </summary>
public int NextInvisibilityTick => lastDetectedTick + Props.stealthCooldownTicks;
// ... 其他方法保持不变 ...
/// <summary>
/// 手动触发解除隐身(供外部调用)
@@ -269,6 +271,11 @@ namespace WulaFallenEmpire
Invisibility.BecomeVisible();
lastDetectedTick = Find.TickManager.TicksGame;
lastRevealedTick = Find.TickManager.TicksGame;
// 尝试发送信件
TrySendLetter("manual");
}
// ... 其他方法保持不变 ...
}
}

View File

@@ -46,24 +46,31 @@ namespace WulaFallenEmpire
// 新增:是否忽略某些状态的敌人(如倒地、死亡等)
public bool ignoreDownedEnemies = true;
public bool ignoreSleepingEnemies = false;
// 新增:简化发信配置
public bool sendLetterOnReveal = false;
public string letterTitle = "";
public string letterText = "";
public int letterIntervalTicks = 1200;
public CompProperties_FighterInvisible()
{
compClass = typeof(CompFighterInvisible);
}
public override IEnumerable<string> ConfigErrors(ThingDef parentDef)
{
foreach (string error in base.ConfigErrors(parentDef))
{
yield return error;
}
if (InvisibilityDef == null)
{
yield return "InvisibilityDef is not defined for CompProperties_FighterInvisible";
}
if (revealDetectionRadius <= 0)
{
revealDetectionRadius = FirstDetectedRadius;