修改版灵能

This commit is contained in:
2025-08-03 14:55:46 +08:00
parent 236b52765d
commit 6bbd328e2f
11 changed files with 221 additions and 260 deletions

View File

@@ -0,0 +1,74 @@
using HarmonyLib;
using RimWorld;
using Verse;
using UnityEngine;
namespace WulaFallenEmpire.HarmonyPatches
{
// ==========================================================================================
// FINAL CORRECTED PATCH: Targets the DamageInfo constructor.
//
// REASONING: This is the universal "catch-all" solution. Almost all damage inflicted
// in the game must first create a DamageInfo instance. By patching the constructor
// with a Postfix, we can modify the damage value right at its source, immediately
// after it's created. This ensures our logic applies universally (to melee, all
// projectile types, abilities, etc.) and is not bypassed by specific implementations
// like the one found in `Bullet.Impact`.
// ==========================================================================================
[HarmonyPatch(typeof(DamageInfo), MethodType.Constructor)]
[HarmonyPatch(new[] {
typeof(DamageDef),
typeof(float),
typeof(float),
typeof(float),
typeof(Thing),
typeof(BodyPartRecord),
typeof(ThingDef),
typeof(DamageInfo.SourceCategory),
typeof(Thing),
typeof(bool),
typeof(bool),
typeof(QualityCategory),
typeof(bool),
typeof(bool)
})]
public static class DamageInfo_Constructor_Patch // Renamed class for ultimate clarity
{
public static void Postfix(ref DamageInfo __instance, Thing instigator, ThingDef weapon)
{
if (weapon == null)
{
return;
}
var psychicCompProps = weapon.GetCompProperties<CompProperties_PsychicScaling>();
if (psychicCompProps == null)
{
return;
}
if (!(instigator is Pawn instigatorPawn))
{
return;
}
float psychicSensitivity = instigatorPawn.GetStatValue(StatDefOf.PsychicSensitivity);
float damageMultiplier = 1f;
if (psychicSensitivity > 1f)
{
damageMultiplier = 1f + (psychicSensitivity - 1f) * psychicCompProps.damageMultiplierPerSensitivityPoint;
}
else if (psychicSensitivity < 1f)
{
damageMultiplier = 1f - (1f - psychicSensitivity) * psychicCompProps.damageReductionMultiplierPerSensitivityPoint;
}
float originalAmount = __instance.Amount;
float finalMultiplier = Mathf.Max(0f, damageMultiplier);
float newAmount = originalAmount * finalMultiplier;
__instance.SetAmount(newAmount);
}
}
}

View File

@@ -1,69 +0,0 @@
using HarmonyLib;
using RimWorld;
using Verse;
namespace WulaFallenEmpire.HarmonyPatches
{
[HarmonyPatch(typeof(Pawn_HealthTracker), "PreApplyDamage")]
public static class HealthTracker_PreApplyDamage_Patch
{
/// <summary>
/// 在伤害应用到Pawn之前执行的补丁。
/// </summary>
/// <param name="dinfo">伤害信息,可以被修改。</param>
/// <param name="absorbed">输出参数如果伤害被完全吸收则为true。</param>
public static void Prefix(ref DamageInfo dinfo, out bool absorbed)
{
// 必须为out参数赋默认值
absorbed = false;
// 检查伤害来源是否是一个Pawn
Pawn instigatorPawn = dinfo.Instigator as Pawn;
if (instigatorPawn == null)
{
return;
}
// 检查这个Pawn是否装备了武器
if (instigatorPawn.equipment?.Primary == null)
{
return;
}
// 检查武器上是否有我们的心灵增幅组件
var psychicComp = instigatorPawn.equipment.Primary.GetComp<CompPsychicScaling>();
if (psychicComp == null)
{
return;
}
// 获取心灵敏感度属性值
float psychicSensitivity = instigatorPawn.GetStatValue(StatDefOf.PsychicSensitivity);
// 根据心灵敏感度是否大于100%,使用不同的计算逻辑
float damageMultiplier;
if (psychicSensitivity > 1f)
{
// 增伤伤害会根据XML中的增伤系数获得额外加成
damageMultiplier = 1 + ((psychicSensitivity - 1) * psychicComp.Props.damageMultiplierPerSensitivityPoint);
}
else if (psychicSensitivity < 1f)
{
// 减伤伤害会根据XML中的减伤系数降低
damageMultiplier = 1 - ((1 - psychicSensitivity) * psychicComp.Props.damageReductionMultiplierPerSensitivityPoint);
}
else
{
// 敏感度正好为100%,伤害不变
damageMultiplier = 1f;
}
// 获取当前伤害值并应用乘数
float originalAmount = dinfo.Amount;
float newAmount = originalAmount * damageMultiplier;
// 更新伤害信息中的伤害值
dinfo.SetAmount(newAmount);
}
}
}