147 lines
4.9 KiB
C#
147 lines
4.9 KiB
C#
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");
|
||
}
|
||
}
|
||
} |