From a9819852700eae318d107abf9eb8f18943521bf1 Mon Sep 17 00:00:00 2001 From: Patrick Hausmann Date: Fri, 24 Jul 2026 00:41:15 +0200 Subject: [PATCH 1/2] Fix ATR_REGENERATE* semantics: value is an interval, not a rate The engine treated ATR_REGENERATEHP/ATR_REGENERATEMANA as points per second, but in the original engine the value means 1 point every N seconds. Mods like L'Hiver use this attribute for monster regeneration: a value of e.g. 20 healed 20 HP per second instead of 1 HP every 20 seconds, so enemies regenerated faster than the player could damage them. --- game/world/objects/npc.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/game/world/objects/npc.cpp b/game/world/objects/npc.cpp index add7c6a32..fe89a0455 100644 --- a/game/world/objects/npc.cpp +++ b/game/world/objects/npc.cpp @@ -2299,13 +2299,16 @@ void Npc::tickRegen(int32_t& v, const int32_t max, const int32_t chg, const uint uint64_t tick = owner.tickCount(); if(tick
0 ? 1 : -1; + const int32_t n = int32_t((tick%period+dt)/period); + if(n==0) + return; - int32_t nextV = std::max(0,std::min(v+val1-val0,max)); + int32_t nextV = std::max(0,std::min(v+n*step,max)); if(v!=nextV) { v = nextV; // check health, in case of negative chg From 8eb4a55889e45a62ad949965c315e0209becc8cf Mon Sep 17 00:00:00 2001 From: Patrick Hausmann Date: Fri, 24 Jul 2026 00:41:43 +0200 Subject: [PATCH 2/2] Npc_CanSeeNpc: measure view cone from npc position instead of head bone In melee the head bone of an attacking monster dives into the target; with only a few centimeters between head and target the direction of that vector is numerically meaningless and the +-100 deg view-angle check fails at random. L'Hiver's anti-exploit healing reads this as "player ran away" and restores the monster's HP mid-fight, while the monster itself drops out of its attack state. The line-of-sight ray still starts at the head bone; only the view cone is measured from the npc position, matching the original engine. --- game/world/objects/npc.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/game/world/objects/npc.cpp b/game/world/objects/npc.cpp index fe89a0455..6cd16d300 100644 --- a/game/world/objects/npc.cpp +++ b/game/world/objects/npc.cpp @@ -4672,7 +4672,10 @@ bool Npc::canRayHitPoint(const Tempest::Vec3 self, const Tempest::Vec3 pos, floa return !w->ray(self, pos).hasCol; } - float dx = self.x-pos.x, dz=self.z-pos.z; + // measure view cone from npc position, not from head bone: in melee the head of an + // attacking monster dives into the target and the direction becomes numerical noise. + // L'Hiver anti-exploit scripts read this as "player ran away" and heal the monster + float dx = x-pos.x, dz = z-pos.z; float dir = angleDir(dx,dz); float da = float(M_PI)*(visual.viewDirection()-dir)/180.f; auto ca = angOverride > 0 ? std::cos(angOverride*M_PI/180.0) : ref;