diff --git a/HarmonySrc/NecromancerBloodPatch.cs b/HarmonySrc/NecromancerBloodPatch.cs index af901eb..44d0dc9 100644 --- a/HarmonySrc/NecromancerBloodPatch.cs +++ b/HarmonySrc/NecromancerBloodPatch.cs @@ -25,9 +25,11 @@ namespace NecromancerTome /// something adjacent, but it takes exactly ONE item name, not "any item of a category", /// and its actual runtime enforcement point wasn't confirmed by decompilation either - /// not risking an untested mechanism for this). - /// 2. "При крафте нужно отнимать у персонажа 90% имеющегося ХП" - crafting this recipe - /// costs 90% of the player's CURRENT health. Recipes have no cost hook beyond their - /// ingredient list at all. + /// 2. "При крафте нужно отнимать у персонажа 90% имеющегося ХП" (2026-08-30), corrected + /// by the user on 2026-11-02: reading CURRENT health there was a bug. The cost is 90% + /// of the player's MAXIMUM health, and a necromancer whose current health is below + /// that dies from the ritual. Recipes have no cost hook beyond their ingredient list + /// at all. /// /// "любого ножа" (ANY knife) is detected via ItemClass.DisplayType == "meleeKnife" - decompiled /// Data/Config/items.xml directly: every real vanilla knife (meleeWpnBladeT0BoneKnife, @@ -200,12 +202,24 @@ namespace NecromancerTome { return; } - // Deliberately not clamped to leave the player at least 1 HP - the user asked for a - // straight 90% cost, and a blood ritual that can genuinely kill you if you're already - // badly hurt fits the theme. AddHealth is the same safe, non-combat HP-modification - // API vanilla itself uses (decompiled EntityAlive.AddHealth) - not DamageEntity/ + // 90% of MAXIMUM health, per the user's correction of 2026-11-02 ("Это баг. Должно + // быть 90% от максимального здоровья. Таким образом, некромант погибнет, если + // здоровья в момент изготовления меньше 90%"). The original 2026-08-30 code read + // the CURRENT health, so a queue of jars got geometrically cheaper (100% -> 10% -> + // 1% of the starting HP) and could only kill at 1-4 HP through rounding. + // + // HOW DEATH HAPPENS, from the 3.4 decompile (don't "fix" this into a direct Kill + // call): Stat.Value's setter clamps to [0, ModifiedMax] (Utils.FastClamp), so HP + // bottoms out at exactly 0, never negative - and EntityAlive.OnUpdateLiving's own + // check `Health <= 0 && !IsDead() && !isEntityRemote && !IsGodMode.Value` kills the + // entity with DamageEntity(DamageSource.disease, 1) on the next update. A player + // who could not pay the full cost thus dies by vanilla's hand one frame later, + // logged as disease (god mode skips that check, leaving them merely at 0 HP). + // Survival takes strictly MORE than the cost: paying exactly it ends at 0 HP, and + // 0 HP is death in vanilla (the check is <= 0, not < 0). AddHealth stays the safe, + // non-combat HP-modification API vanilla itself uses - not DamageEntity/ // DamageResponse, since this isn't damage from a source, it's a direct self-cost. - int amount = Mathf.RoundToInt(__state.Health * NecromancerBloodPatch.HealthCostFraction); + int amount = Mathf.RoundToInt(__state.GetMaxHealth() * NecromancerBloodPatch.HealthCostFraction); if (amount <= 0) { return; @@ -213,9 +227,9 @@ namespace NecromancerTome __state.AddHealth(-amount); // The grunt goes AFTER the HP is actually gone, so a craft that somehow bailed out - // above never makes a sound the player cannot account for. At the 90% cost this is the - // big pain clip in every normal case (amount > 15 unless the player is already down to - // about 17 HP), and drops to the small one exactly where vanilla would drop it too. + // above never makes a sound the player cannot account for. With the cost now a fixed + // 0.9 * MaxHealth this is the big pain clip in every normal case (amount > 15 whenever + // MaxHealth >= 18), and drops to the small one exactly where vanilla would drop it too. NecromancerBloodPatch.PlayPainSound(__state, amount); Debug.Log("[NecromancerTome] NecromancerBloodPatch: crafted blood, deducted " + amount + " HP from owner=" + __state.entityId); diff --git a/NecromancerHarmony.dll b/NecromancerHarmony.dll index 261c52a..7614448 100644 Binary files a/NecromancerHarmony.dll and b/NecromancerHarmony.dll differ diff --git a/NecromancerHarmony.pdb b/NecromancerHarmony.pdb index 0e2a885..694a44a 100644 Binary files a/NecromancerHarmony.pdb and b/NecromancerHarmony.pdb differ