This commit is contained in:
2025-11-18 17:30:12 +08:00
parent 1934f02ca8
commit 6b94929803
11 changed files with 771 additions and 249 deletions

View File

@@ -0,0 +1,279 @@
using RimWorld;
using Verse;
using Verse.Sound;
namespace WulaFallenEmpire
{
// HediffCompProperties 定义
public class HediffCompProperties_DisappearWithEffect : HediffCompProperties_Disappears
{
public FleckDef fleckDef; // 要播放的特效
public float fleckScale = 1f; // 特效缩放
public bool dropEquipment = false; // 是否掉落装备false = 直接销毁)
public bool destroyCorpse = true; // 是否销毁尸体
public bool playSound = true; // 是否播放音效
public SoundDef soundDef; // 自定义音效
public HediffCompProperties_DisappearWithEffect()
{
compClass = typeof(HediffComp_DisappearWithEffect);
}
}
// HediffComp 实现
public class HediffComp_DisappearWithEffect : HediffComp
{
public HediffCompProperties_DisappearWithEffect Props =>
(HediffCompProperties_DisappearWithEffect)props;
private int ticksUntilDisappear = -1;
private bool triggered = false;
public override void CompPostMake()
{
base.CompPostMake();
if (Props.disappearsAfterTicks != null)
{
ticksUntilDisappear = Props.disappearsAfterTicks.RandomInRange;
}
}
// 重写 CompPostTick 方法,在到达指定 tick 时触发效果
public override void CompPostTick(ref float severityAdjustment)
{
base.CompPostTick(ref severityAdjustment);
if (triggered || Pawn == null || Pawn.Destroyed) return;
// 检查是否到达消失时间
if (ticksUntilDisappear > 0)
{
ticksUntilDisappear--;
if (ticksUntilDisappear <= 0)
{
TriggerDisappearEffect();
}
}
// 如果 pawn 已经死亡,立即触发效果
else if (Pawn.Dead)
{
TriggerDisappearEffect();
}
}
// 处理 pawn 死亡事件 - 修复参数问题
public override void Notify_PawnDied(DamageInfo? dinfo, Hediff culprit = null)
{
base.Notify_PawnDied(dinfo, culprit);
if (!triggered)
{
TriggerDisappearEffect();
}
}
// 触发消失效果的核心方法
private void TriggerDisappearEffect()
{
if (triggered || Pawn == null || Pawn.Map == null || Pawn.Destroyed)
return;
triggered = true;
try
{
// 记录位置
IntVec3 position = Pawn.Position;
Map map = Pawn.Map;
// 1. 清除所有装备
ClearAllEquipment(map);
// 2. 播放特效
PlayFleckEffect(position, map);
// 3. 播放音效
PlaySoundEffect(position, map);
// 4. 发送消失消息(如果配置了)
SendDisappearMessage();
// 5. 删除 pawn
DestroyPawn();
Log.Message($"[DisappearWithEffect] Pawn {Pawn.LabelCap} disappeared at {position}");
}
catch (System.Exception ex)
{
Log.Error($"[DisappearWithEffect] Error in TriggerDisappearEffect: {ex}");
}
}
// 清除所有装备 - 修复参数问题
private void ClearAllEquipment(Map map)
{
if (Pawn.equipment == null && Pawn.apparel == null && Pawn.inventory == null)
return;
// 清除装备(武器)
if (Pawn.equipment != null)
{
var allEquipment = Pawn.equipment.AllEquipmentListForReading.ListFullCopy();
foreach (var thing in allEquipment)
{
if (Props.dropEquipment)
{
// 掉落装备 - 修复类型转换问题
ThingWithComps droppedWeapon;
Pawn.equipment.TryDropEquipment(thing, out droppedWeapon, Pawn.Position, true);
}
else
{
// 直接销毁装备
thing.Destroy(DestroyMode.Vanish);
}
}
}
// 清除 apparel服装
if (Pawn.apparel != null)
{
var wornApparel = Pawn.apparel.WornApparel.ListFullCopy();
foreach (var apparel in wornApparel)
{
if (Props.dropEquipment)
{
// 掉落服装
Apparel droppedApparel;
Pawn.apparel.TryDrop(apparel, out droppedApparel, Pawn.Position, true);
}
else
{
// 直接销毁服装
apparel.Destroy(DestroyMode.Vanish);
}
}
}
// 清除 inventory物品栏
if (Pawn.inventory != null)
{
var innerContainer = Pawn.inventory.innerContainer.InnerListForReading.ListFullCopy();
foreach (var thing in innerContainer)
{
if (Props.dropEquipment)
{
// 掉落物品
Thing droppedThing;
Pawn.inventory.innerContainer.TryDrop(thing, Pawn.Position, map, ThingPlaceMode.Near, out droppedThing);
}
else
{
// 直接销毁物品
thing.Destroy(DestroyMode.Vanish);
}
}
}
}
// 播放特效
private void PlayFleckEffect(IntVec3 position, Map map)
{
FleckDef fleckToUse = Props.fleckDef ?? FleckDefOf.PsycastAreaEffect;
// 在 pawn 位置播放特效
FleckMaker.Static(position, map, fleckToUse, Props.fleckScale);
// 额外在周围格子上播放特效,增强视觉效果
for (int i = 0; i < 8; i++)
{
IntVec3 nearbyCell = position + GenAdj.AdjacentCells[i];
if (nearbyCell.InBounds(map))
{
FleckMaker.Static(nearbyCell, map, fleckToUse, Props.fleckScale * 0.7f);
}
}
}
// 播放音效 - 修复音效播放问题
private void PlaySoundEffect(IntVec3 position, Map map)
{
if (!Props.playSound) return;
SoundDef soundToUse = Props.soundDef ?? SoundDefOf.PsycastPsychicPulse;
// 使用 SoundStarter 播放音效
SoundInfo soundInfo = SoundInfo.InMap(new TargetInfo(position, map));
soundToUse.PlayOneShot(soundInfo);
}
// 发送消失消息
private void SendDisappearMessage()
{
var disappearProps = props as HediffCompProperties_Disappears;
if (disappearProps?.messageOnDisappear != null)
{
Messages.Message(disappearProps.messageOnDisappear.Translate(Pawn.LabelShort),
Pawn, MessageTypeDefOf.NeutralEvent);
}
if (disappearProps?.letterLabelOnDisappear != null &&
disappearProps?.letterTextOnDisappear != null &&
Pawn.Faction == Faction.OfPlayer)
{
Find.LetterStack.ReceiveLetter(
disappearProps.letterLabelOnDisappear.Translate(Pawn.LabelShort),
disappearProps.letterTextOnDisappear.Translate(Pawn.LabelShort),
LetterDefOf.NeutralEvent,
new LookTargets(Pawn)
);
}
}
// 删除 pawn
private void DestroyPawn()
{
if (Pawn.Dead && Props.destroyCorpse)
{
// 如果是尸体,直接销毁
Pawn.Destroy();
}
else if (!Pawn.Dead)
{
// 如果是活着的 pawn先杀死再销毁
Pawn.Kill(null, this.parent);
if (Props.destroyCorpse)
{
Pawn.Destroy();
}
}
}
// 重写 CompTipStringExtra 显示额外信息
public override string CompTipStringExtra
{
get
{
if (ticksUntilDisappear > 0 && Props.showRemainingTime)
{
return "DisappearWithEffect_TimeRemaining".Translate(
ticksUntilDisappear.ToStringTicksToPeriod(Props.canUseDecimalsShortForm));
}
return null;
}
}
// 重写 CompDebugString 用于调试
public override string CompDebugString()
{
return $"Will disappear in: {ticksUntilDisappear} ticks (Triggered: {triggered})";
}
// 序列化数据
public override void CompExposeData()
{
base.CompExposeData();
Scribe_Values.Look(ref ticksUntilDisappear, "ticksUntilDisappear", -1);
Scribe_Values.Look(ref triggered, "triggered", false);
}
}
}

View File

@@ -160,6 +160,7 @@
<Compile Include="HarmonyPatches\WULA_AutonomousMech\Patch_CaravanFormingUtility_AllSendablePawns.cs" />
<Compile Include="HarmonyPatches\WULA_AutonomousMech\Patch_Pawn_ThreatDisabled.cs" />
<Compile Include="HarmonyPatches\WULA_AutonomousMech\Patch_UncontrolledMechDrawPulse.cs" />
<Compile Include="HediffComp\HediffCompProperties_DisappearWithEffect .cs" />
<Compile Include="HediffComp\HediffCompProperties_NanoRepair.cs" />
<Compile Include="HediffComp\HediffCompProperties_SwitchableHediff.cs" />
<Compile Include="HediffComp\WULA_HediffDamgeShield\DRMDamageShield.cs" />