This commit is contained in:
2025-10-15 14:03:08 +08:00
parent 4d743c74e0
commit 601d20b6a1
8 changed files with 12 additions and 325 deletions

View File

@@ -6,9 +6,6 @@ namespace ArachnaeSwarm
[DefOf]
public static class ARA_HediffDefOf
{
public static HediffDef ARA_Hediff_Frozen;
public static HediffDef ARA_Hediff_FrostCoverd_after;
public static HediffDef ARA_CryoShock;
public static HediffDef ARA_HiveMindMaster;
public static HediffDef ARA_HiveMindDrone;
public static HediffDef ARA_HiveMindWorker; // 如果存在这个Def

View File

@@ -193,8 +193,6 @@
<Compile Include="Hediffs\MoharHediffs\Tools.cs" />
<Compile Include="Hediffs\ProphecyGearEffect.cs" />
<Compile Include="HediffComp_TimedExplosion.cs" />
<Compile Include="Hediff_Frozen.cs" />
<Compile Include="HediffComp_GlobalFreeze.cs" />
<Compile Include="Hediffs\WULA_HediffDamgeShield\DRMDamageShield.cs" />
<Compile Include="Hediffs\WULA_HediffDamgeShield\Hediff_DamageShield.cs" />
<Compile Include="Thing_Comps\ARA_ThingComp_GuardianPsyField\Hediff_DynamicInterceptor.cs" />
@@ -275,7 +273,6 @@
<Compile Include="Buildings\Building_CatastropheMissileSilo\Building_CatastropheMissileSilo.cs" />
<Compile Include="Buildings\Building_CatastropheMissileSilo\WorldObject_CatastropheMissile.cs" />
<Compile Include="HarmonyPatches\Patch_ForceTargetable.cs" />
<Compile Include="HarmonyPatch_Pawn_HealthTracker_PreApplyDamage.cs" />
<Compile Include="Building_Comps\CompForceTargetable.cs" />
<Compile Include="PowerArmor\ARA_PowerArmor.cs" />
<Compile Include="PowerArmor\CompPowerArmorStation.cs" />

View File

@@ -1,73 +0,0 @@
using HarmonyLib;
using RimWorld;
using Verse;
using System.Linq;
using UnityEngine; // For FleckMaker
namespace ArachnaeSwarm
{
// Harmony 入口点,将在 Mod 加载时自动初始化
[StaticConstructorOnStartup]
public static class HarmonyPatches
{
static HarmonyPatches()
{
var harmony = new Harmony("ArachnaeSwarm.FreezeMod");
harmony.PatchAll();
}
}
// 补丁目标Pawn_HealthTracker 类的 PreApplyDamage 方法
[HarmonyPatch(typeof(Pawn_HealthTracker), "PreApplyDamage")]
public static class HarmonyPatch_Pawn_HealthTracker_PreApplyDamage
{
// Postfix 补丁:在原方法执行后运行
// __instance 是 Pawn_HealthTracker 的实例
// dinfo 是 DamageInfo 的引用
// absorbed 是 out bool 参数的引用
public static void Postfix(Pawn_HealthTracker __instance, ref DamageInfo dinfo, ref bool absorbed)
{
// 如果伤害已经被吸收,或者没有击中任何部位,则不处理
if (absorbed || dinfo.HitPart == null)
{
return;
}
Pawn pawn = (Pawn)AccessTools.Field(typeof(Pawn_HealthTracker), "pawn").GetValue(__instance);
if (pawn == null)
{
return;
}
// 复制一份 dinfo避免 ref 参数在 lambda 中使用的问题
DamageInfo currentDinfo = dinfo;
// 获取被击中部位上的 Hediff_Frozen
Hediff_Frozen frozenHediff = pawn.health.hediffSet.hediffs.OfType<Hediff_Frozen>()
.FirstOrDefault(h => h.Part == currentDinfo.HitPart);
// 如果该部位存在 Hediff_Frozen 并且已经完全冷冻
if (frozenHediff != null && frozenHediff.Severity >= currentDinfo.HitPart.def.GetMaxHealth(pawn))
{
// 检查伤害是否是我们的冷冻伤害(防止循环触发)
if (currentDinfo.Def.hediff == ARA_HediffDefOf.ARA_Hediff_Frozen)
{
return; // 忽略我们自己的冷冻伤害
}
// 检查伤害是否是会造成生命值损伤的普通伤害
if (currentDinfo.Def.harmsHealth && currentDinfo.Amount > 0.01f)
{
// 施加一个巨大的、足以摧毁该部位的伤害
DamageInfo fatalDamage = new DamageInfo(DamageDefOf.Crush, 99999f, 999f, -1f, currentDinfo.Instigator, currentDinfo.HitPart);
pawn.TakeDamage(fatalDamage);
// 播放一个破碎的特效
FleckMaker.Static(pawn.Position, pawn.Map, FleckDefOf.ExplosionFlash, 2f);
absorbed = true; // 标记原伤害已被处理,阻止其继续执行
}
}
}
}
}

View File

@@ -1,72 +0,0 @@
using RimWorld;
using Verse;
using System.Linq;
namespace ArachnaeSwarm
{
public class HediffComp_GlobalFreeze : HediffComp
{
private const int CheckInterval = 60; // 每60 ticks检查一次 (1秒)
private bool isStunnedByFreeze = false; // 用于追踪是否是由我们这个组件造成的眩晕
public HediffCompProperties_GlobalFreeze Props => (HediffCompProperties_GlobalFreeze)props;
public override void CompPostTick(ref float severityAdjustment)
{
base.CompPostTick(ref severityAdjustment);
// 每隔一段时间才执行一次,避免性能问题
if (Pawn.IsHashIntervalTick(CheckInterval))
{
// 计算全身所有Hediff_Frozen的总严重性
float totalFreezeSeverity = Pawn.health.hediffSet.hediffs
.OfType<Hediff_Frozen>()
.Sum(h => h.Severity);
// 获取Pawn的总生命值作为参考
float totalBodyHealth = Pawn.health.summaryHealth.SummaryHealthPercent * Pawn.MaxHitPoints;
// 计算冷冻阈值
float stunThreshold = totalBodyHealth * Props.stunThreshold;
// 如果总冷冻值超过阈值
if (totalFreezeSeverity >= stunThreshold)
{
// 如果Pawn当前没有被眩晕则施加一个“永久”的眩晕
// StunFor会取最大值所以我们给一个足够长的时间5秒它会在下一轮检查时被刷新
if (!Pawn.stances.stunner.Stunned)
{
Pawn.stances.stunner.StunFor(300, Pawn, false, true);
isStunnedByFreeze = true;
}
}
// 如果总冷冻值低于阈值,并且之前是由我们造成的眩晕
else if (isStunnedByFreeze)
{
// 立即停止眩晕
// 我们通过将stunTicksLeft设置为0来直接唤醒它
Pawn.stances.stunner.StunFor(0, Pawn, false, false);
isStunnedByFreeze = false;
}
}
}
// 保存和加载我们的状态,确保读档后逻辑正确
public override void CompExposeData()
{
base.CompExposeData();
Scribe_Values.Look(ref isStunnedByFreeze, "isStunnedByFreeze", false);
}
}
public class HediffCompProperties_GlobalFreeze : HediffCompProperties
{
// XML中可配置的阈值默认为全身健康的30%
public float stunThreshold = 0.3f;
public HediffCompProperties_GlobalFreeze()
{
compClass = typeof(HediffComp_GlobalFreeze);
}
}
}

View File

@@ -1,46 +0,0 @@
using RimWorld;
using Verse;
using UnityEngine;
namespace ArachnaeSwarm
{
public class Hediff_Frozen : Hediff_Injury
{
// 我们需要覆盖这个方法来改变在健康面板上显示的标签
public override string LabelInBrackets
{
get
{
// 如果严重性达到了部位的满生命值,就显示“完全冷冻”
if (Severity >= Part.def.GetMaxHealth(pawn))
{
return "Fully Frozen";
}
return base.LabelInBrackets;
}
}
// 当部位的疼痛感,可以根据严重性调整
public override float PainOffset
{
get
{
// 冷冻不造成额外疼痛
return 0f;
}
}
// 当一个部位的伤害被治疗(在这里就是冷冻值减少)时调用
public override void Heal(float amount)
{
// 减少严重性但不让它低于0
Severity -= amount;
if (Severity < 0)
{
Severity = 0;
}
}
// 伤害拦截逻辑将通过 Harmony 补丁实现,不在 Hediff 内部处理
}
}