From 88e2302f75d9c9473658606d650002c9ee40bae4 Mon Sep 17 00:00:00 2001 From: WinterSolstice8 <60417494+wintersolstice8@users.noreply.github.com> Date: Sat, 31 Jan 2026 20:16:11 -0700 Subject: [PATCH] [core] [lua] Add mobmod to disable mob H2H penalty --- scripts/enum/mob_mod.lua | 2 +- scripts/globals/combat/physical_utilities.lua | 10 +++-- src/map/attack.cpp | 16 ++++--- src/map/entities/battleentity.cpp | 16 +++---- src/map/mob_modifier.h | 42 +++++++++---------- 5 files changed, 47 insertions(+), 39 deletions(-) diff --git a/scripts/enum/mob_mod.lua b/scripts/enum/mob_mod.lua index 385292c27cf..a200146d015 100644 --- a/scripts/enum/mob_mod.lua +++ b/scripts/enum/mob_mod.lua @@ -28,7 +28,7 @@ xi.mobMod = NO_DESPAWN = 17, -- do not despawn when too far from spawn. Gob Diggers have this. VAR = 18, -- temp var for whatever. Gets cleared on spawn CAN_SHIELD_BLOCK = 19, -- toggle shield use for mobs without physical shields (trusts) - -- Unused = 20, -- Free to repurpose + NO_H2H_PENALTY = 20, -- Disables H2H penalty in base damage calculation when set to non-zero PET_SPELL_LIST = 21, -- set pet spell list NA_CHANCE = 22, -- % chance to cast -na IMMUNITY = 23, -- immune to set status effects. This only works from the db, not scripts diff --git a/scripts/globals/combat/physical_utilities.lua b/scripts/globals/combat/physical_utilities.lua index 320874cf87f..a62b6e8f15a 100644 --- a/scripts/globals/combat/physical_utilities.lua +++ b/scripts/globals/combat/physical_utilities.lua @@ -119,10 +119,12 @@ xi.combat.physical.calculateAttackDamage = function(actor, target, slot, physica local regionID = actor:getCurrentRegion() local fSTR = xi.combat.physical.calculateMeleeStatFactor(actor, target) - if regionID <= xi.region.LIMBUS then - mobH2HPenalty = 0.425 -- Vanilla - COP - else - mobH2HPenalty = 0.65 + if actor:getMobMod(xi.mobMod.NO_H2H_PENALTY) == 0 then + if regionID <= xi.region.LIMBUS then + mobH2HPenalty = 0.425 -- Vanilla - COP + else + mobH2HPenalty = 0.65 + end end baseDamage = actor:getWeaponDmg() + bonusBasePhysicalDamage diff --git a/src/map/attack.cpp b/src/map/attack.cpp index 913d49dfde6..cc701619cd8 100644 --- a/src/map/attack.cpp +++ b/src/map/attack.cpp @@ -25,6 +25,7 @@ #include "entities/battleentity.h" #include "items/item_weapon.h" #include "job_points.h" +#include "mob_modifier.h" #include "status_effect_container.h" #include "utils/puppetutils.h" @@ -632,13 +633,16 @@ void CAttack::ProcessDamage() int32 fSTR = battleutils::GetFSTR(m_attacker, m_victim, slot); REGION_TYPE regionID = m_attacker->loc.zone->GetRegionID(); - if (regionID <= REGION_TYPE::LIMBUS) // Pre TOAU zones + if (static_cast(m_attacker)->getMobMod(MOBMOD_NO_H2H_PENALTY) == 0) { - mobH2HPenalty = 0.425f; // Vanilla - COP - } - else - { - mobH2HPenalty = 0.650f; // TOAU onward + if (regionID <= REGION_TYPE::LIMBUS) // Pre TOAU zones + { + mobH2HPenalty = 0.425f; // Vanilla - COP + } + else + { + mobH2HPenalty = 0.650f; // TOAU onward + } } m_damage = m_baseDamage + m_bonusBasePhysicalDamage; diff --git a/src/map/entities/battleentity.cpp b/src/map/entities/battleentity.cpp index fa6ee587936..a166a3a54fb 100644 --- a/src/map/entities/battleentity.cpp +++ b/src/map/entities/battleentity.cpp @@ -2924,14 +2924,16 @@ bool CBattleEntity::OnAttack(CAttackState& state, action_t& action) else if (PTarget->objtype == TYPE_MOB && targ_weapon && targ_weapon->getSkillType() == SKILLTYPE::SKILL_HAND_TO_HAND) // This is how Attack Round checks for h2h penalty { REGION_TYPE regionID = PTarget->loc.zone->GetRegionID(); - - if (regionID <= REGION_TYPE::LIMBUS) // Pre TOAU zones - { - mobH2HPenalty = 0.425f; // Vanilla - COP - } - else + if (static_cast(PTarget)->getMobMod(MOBMOD_NO_H2H_PENALTY) == 0) { - mobH2HPenalty = 0.650f; // TOAU onward + if (regionID <= REGION_TYPE::LIMBUS) // Pre TOAU zones + { + mobH2HPenalty = 0.425f; // Vanilla - COP + } + else + { + mobH2HPenalty = 0.650f; // TOAU onward + } } } diff --git a/src/map/mob_modifier.h b/src/map/mob_modifier.h index a41bc2e7259..39286d212a0 100644 --- a/src/map/mob_modifier.h +++ b/src/map/mob_modifier.h @@ -28,27 +28,27 @@ Gets mapped for convenience in scripts/enum/mobMod.lua -- always edit both enum MOBMODIFIER : int { - MOBMOD_NONE = 0, - MOBMOD_GIL_MIN = 1, // minimum gil drop -- spawn mod only - MOBMOD_GIL_MAX = 2, // maximum gil drop -- spawn mod only - MOBMOD_MP_BASE = 3, // Give mob mp. Used for mobs that are not mages, wyverns, avatars - MOBMOD_SIGHT_RANGE = 4, // sight range - MOBMOD_SOUND_RANGE = 5, // sound range - MOBMOD_BUFF_CHANCE = 6, // % chance to buff (combat only) - MOBMOD_GA_CHANCE = 7, // % chance to use -ga spell - MOBMOD_HEAL_CHANCE = 8, // % chance to use heal - MOBMOD_HP_HEAL_CHANCE = 9, // can cast cures below this HP % - MOBMOD_SUBLINK = 10, // Sub link group. Enables mobs from different families to link if they share a SUBLINK value. - MOBMOD_LINK_RADIUS = 11, // link radius - MOBMOD_SEES_THROUGH_ILLUSION = 12, // Mob can see through the Illusion effect that grants effects similar to Sneak & Invisible without this mod and allows aggro (see Viscious Liquid in mamook) - MOBMOD_SEVERE_SPELL_CHANCE = 13, // % chance to use a severe spell like death or impact - MOBMOD_SKILL_LIST = 14, // uses given mob skill list - MOBMOD_MUG_GIL = 15, // amount gil carried for mugging - MOBMOD_DETECTION = 16, // Overrides mob family's detection method. In order to set to override to none an unused bit must be set such as DETECT_NONE1. - MOBMOD_NO_DESPAWN = 17, // do not despawn when too far from spawn. Gob Diggers have this. - MOBMOD_VAR = 18, // temp var for whatever. Gets cleared on spawn - MOBMOD_CAN_SHIELD_BLOCK = 19, // toggle shield use for mobs without physical shields (trusts) - // UNUSED = 20, // Free to repurpose + MOBMOD_NONE = 0, + MOBMOD_GIL_MIN = 1, // minimum gil drop -- spawn mod only + MOBMOD_GIL_MAX = 2, // maximum gil drop -- spawn mod only + MOBMOD_MP_BASE = 3, // Give mob mp. Used for mobs that are not mages, wyverns, avatars + MOBMOD_SIGHT_RANGE = 4, // sight range + MOBMOD_SOUND_RANGE = 5, // sound range + MOBMOD_BUFF_CHANCE = 6, // % chance to buff (combat only) + MOBMOD_GA_CHANCE = 7, // % chance to use -ga spell + MOBMOD_HEAL_CHANCE = 8, // % chance to use heal + MOBMOD_HP_HEAL_CHANCE = 9, // can cast cures below this HP % + MOBMOD_SUBLINK = 10, // Sub link group. Enables mobs from different families to link if they share a SUBLINK value. + MOBMOD_LINK_RADIUS = 11, // link radius + MOBMOD_SEES_THROUGH_ILLUSION = 12, // Mob can see through the Illusion effect that grants effects similar to Sneak & Invisible without this mod and allows aggro (see Viscious Liquid in mamook) + MOBMOD_SEVERE_SPELL_CHANCE = 13, // % chance to use a severe spell like death or impact + MOBMOD_SKILL_LIST = 14, // uses given mob skill list + MOBMOD_MUG_GIL = 15, // amount gil carried for mugging + MOBMOD_DETECTION = 16, // Overrides mob family's detection method. In order to set to override to none an unused bit must be set such as DETECT_NONE1. + MOBMOD_NO_DESPAWN = 17, // do not despawn when too far from spawn. Gob Diggers have this. + MOBMOD_VAR = 18, // temp var for whatever. Gets cleared on spawn + MOBMOD_CAN_SHIELD_BLOCK = 19, // toggle shield use for mobs without physical shields (trusts) + MOBMOD_NO_H2H_PENALTY = 20, // Disables H2H penalty in base damage calculation when set to non-zero MOBMOD_PET_SPELL_LIST = 21, // set pet spell list MOBMOD_NA_CHANCE = 22, // % chance to cast -na MOBMOD_IMMUNITY = 23, // immune to set status effects. This only works from the db, not scripts