107 lines
3.5 KiB
C#
107 lines
3.5 KiB
C#
using RimWorld;
|
|
using UnityEngine;
|
|
using Verse;
|
|
|
|
namespace WulaFallenEmpire
|
|
{
|
|
public class CompProperties_DelayedDamageIfNotPlayer : CompProperties
|
|
{
|
|
public DamageDef damageDef;
|
|
public int damageAmount = 10;
|
|
public float armorPenetration = 0f;
|
|
public BodyPartDef hitPart;
|
|
public bool destroyIfKilled = true;
|
|
|
|
public CompProperties_DelayedDamageIfNotPlayer()
|
|
{
|
|
compClass = typeof(CompDelayedDamageIfNotPlayer);
|
|
}
|
|
}
|
|
|
|
public class CompDelayedDamageIfNotPlayer : ThingComp
|
|
{
|
|
private bool damageApplied = false;
|
|
private bool scheduledForNextFrame = false;
|
|
|
|
public CompProperties_DelayedDamageIfNotPlayer Props => (CompProperties_DelayedDamageIfNotPlayer)props;
|
|
|
|
public override void PostSpawnSetup(bool respawningAfterLoad)
|
|
{
|
|
base.PostSpawnSetup(respawningAfterLoad);
|
|
|
|
// 只在初次生成时检查,重新加载时不重复
|
|
if (!respawningAfterLoad)
|
|
{
|
|
CheckAndScheduleDamage();
|
|
}
|
|
}
|
|
|
|
private void CheckAndScheduleDamage()
|
|
{
|
|
// 检查派系,如果不是玩家派系则安排伤害
|
|
if (parent.Faction != Faction.OfPlayer && !damageApplied && !scheduledForNextFrame)
|
|
{
|
|
scheduledForNextFrame = true;
|
|
|
|
// 使用LongEventHandler来在下一帧执行
|
|
LongEventHandler.ExecuteWhenFinished(ApplyDelayedDamage);
|
|
}
|
|
}
|
|
|
|
private void ApplyDelayedDamage()
|
|
{
|
|
if (scheduledForNextFrame && !damageApplied)
|
|
{
|
|
// 再次确认对象仍然存在且未被销毁
|
|
if (parent != null && parent.Spawned && !parent.Destroyed)
|
|
{
|
|
ApplyDamage();
|
|
}
|
|
scheduledForNextFrame = false;
|
|
}
|
|
}
|
|
|
|
private void ApplyDamage()
|
|
{
|
|
try
|
|
{
|
|
if (parent == null || parent.Destroyed || damageApplied)
|
|
return;
|
|
|
|
// 创建伤害信息
|
|
DamageInfo damageInfo = new DamageInfo(
|
|
Props.damageDef,
|
|
Props.damageAmount,
|
|
armorPenetration: Props.armorPenetration,
|
|
instigator: parent
|
|
);
|
|
|
|
// 施加伤害
|
|
parent.TakeDamage(damageInfo);
|
|
|
|
damageApplied = true;
|
|
|
|
// 记录日志以便调试
|
|
Log.Message($"[CompDelayedDamage] Applied {Props.damageAmount} {Props.damageDef.defName} damage to {parent.Label} (Faction: {parent.Faction?.Name ?? "None"})");
|
|
|
|
// 检查是否被杀死
|
|
if (Props.destroyIfKilled && (parent.Destroyed || (parent is Pawn pawn && pawn.Dead)))
|
|
{
|
|
Log.Message($"[CompDelayedDamage] {parent.Label} was destroyed by delayed damage");
|
|
}
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
Log.Error($"[CompDelayedDamage] Error applying delayed damage: {ex}");
|
|
}
|
|
}
|
|
|
|
public override void PostExposeData()
|
|
{
|
|
base.PostExposeData();
|
|
Scribe_Values.Look(ref damageApplied, "damageApplied", false);
|
|
Scribe_Values.Look(ref scheduledForNextFrame, "scheduledForNextFrame", false);
|
|
}
|
|
}
|
|
}
|