This repository has been archived on 2026-04-05. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
ArachnaeSwarm/Source/ArachnaeSwarm/Hediff_NecroticVirus_Configurable.cs
2025-09-10 17:41:53 +08:00

147 lines
4.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using RimWorld;
using Verse;
using UnityEngine;
using System.Linq;
namespace ArachnaeSwarm
{
public class Hediff_NecroticVirus : HediffWithComps
{
private const int EffectInterval = 600;
// 用于存储攻击者派系的字段
private Faction casterFaction;
// 属性来获取我们的自定义Comp
private HediffComp_NecroticTransformation PropsComp => this.TryGetComp<HediffComp_NecroticTransformation>();
public override void PostAdd(DamageInfo? dinfo)
{
base.PostAdd(dinfo);
if (dinfo.HasValue && dinfo.Value.Instigator != null)
{
this.casterFaction = dinfo.Value.Instigator.Faction;
}
}
public override void Notify_PawnDied(DamageInfo? dinfo, Hediff culprit = null)
{
base.Notify_PawnDied(dinfo, culprit);
TransformToMutant();
}
public override void PostTick()
{
base.PostTick();
if (pawn.IsHashIntervalTick(EffectInterval) && pawn.Spawned)
{
ShowVirusEffects();
}
}
private void TransformToMutant()
{
var comp = PropsComp;
if (comp == null || comp.Props.mutantDef == null)
{
Log.Error($"[NecroticVirus] HediffComp_NecroticTransformation or its mutantDef is not configured in XML for {this.def.defName}.");
return;
}
// 检查严重性是否达到XML中配置的阈值
if (this.Severity < comp.Props.triggerSeverity)
{
return;
}
try
{
if (pawn.Corpse == null || pawn.Corpse.Destroyed)
{
return;
}
Map map = pawn.Corpse.Map;
IntVec3 position = pawn.Corpse.Position;
// 使用我们自己的、更安全的检查方法
if (!NecroticTransformationUtility.CanResurrect(pawn.Corpse))
{
Log.Warning($"[NecroticVirus] Pawn {pawn.LabelShort} does not meet conditions for resurrection.");
return;
}
// **优先使用攻击者的派系,如果没有,则执行备用逻辑**
Faction faction = this.casterFaction ?? GetHostileFaction();
// **调用我们自己的工具方法传入从XML获取的mutantDef**
NecroticTransformationUtility.ResurrectAsCustomMutant(pawn, comp.Props.mutantDef, faction);
// **关键修复在成功转化后立即移除导致转化的Hediff本身防止其残留**
pawn.health.RemoveHediff(this);
// 添加转化特效
FleckMaker.ThrowSmoke(position.ToVector3Shifted(), map, 1.5f);
FleckMaker.ThrowDustPuff(position.ToVector3Shifted(), map, 1.2f);
// 发送转化消息
if (PawnUtility.ShouldSendNotificationAbout(pawn))
{
Messages.Message(
"NecroticVirus_TransformationMessage".Translate(pawn.LabelShortCap, pawn.LabelShortCap),
new LookTargets(position, map),
MessageTypeDefOf.NegativeEvent
);
}
}
catch (System.Exception ex)
{
Log.Error($"[NecroticVirus] Error during transformation: {ex}");
}
}
private Faction GetHostileFaction()
{
if (pawn.Faction != null && pawn.Faction.HostileTo(Faction.OfPlayer))
{
return pawn.Faction;
}
Faction entitiesFaction = Find.FactionManager.AllFactions.FirstOrDefault(f => f.def.defName == "Entities");
if (entitiesFaction != null && !entitiesFaction.defeated)
{
return entitiesFaction;
}
return Find.FactionManager.RandomEnemyFaction(allowNonHumanlike: true, allowHidden: false, allowDefeated: false);
}
private void ShowVirusEffects()
{
if (pawn == null || !pawn.Spawned) return;
Vector3 pos = pawn.DrawPos;
Map map = pawn.Map;
float sizeMultiplier = 1f;
if (CurStageIndex == 1) sizeMultiplier = 1.2f;
if (CurStageIndex == 2) sizeMultiplier = 1.5f;
FleckMaker.ThrowMicroSparks(pos, map);
FleckMaker.ThrowDustPuff(pos, map, 0.8f * sizeMultiplier);
}
public override string TipStringExtra
{
get
{
return base.TipStringExtra + "\n" + "NecroticVirus_EffectTip".Translate();
}
}
public override void ExposeData()
{
base.ExposeData();
Scribe_References.Look(ref this.casterFaction, "casterFaction");
}
}
}