diff --git a/common/ruletypes.h b/common/ruletypes.h index 4e9d61c7f..16e85805d 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -389,6 +389,7 @@ RULE_INT(Spells, AI_PursueDetrimentalChance, 90) // Chance while chasing target RULE_INT(Spells, AI_IdleNoSpellMinRecast, 6000) // AI spell recast time(MS) check when no spell is cast while idle. (min time in random) RULE_INT(Spells, AI_IdleNoSpellMaxRecast, 60000) // AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random) RULE_INT(Spells, AI_IdleBeneficialChance, 100) // Chance while idle to do a beneficial spell on self or others. +RULE_INT(Spells, AI_HealHPPct, 50) // HP Pct NPCs will start heals at (in and out of combat) if spell's max_hp is not set RULE_BOOL(Spells, SHDProcIDOffByOne, true) // pre June 2009 SHD spell procs were off by 1, they stopped doing this in June 2009 (so UF+ spell files need this false) RULE_BOOL(Spells, Jun182014HundredHandsRevamp, false) // this should be true for if you import a spell file newer than June 18, 2014 RULE_BOOL(Spells, SwarmPetTargetLock, false) // Use old method of swarm pets target locking till target dies then despawning. diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 5dca4e01e..e4066e2cc 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -97,10 +97,11 @@ bool NPC::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes, bool bInnates continue; } - if (AIspells[i].min_hp != 0 && GetIntHPRatio() < AIspells[i].min_hp) + // we reuse these fields for heal overrides + if (AIspells[i].type != SpellType_Heal && AIspells[i].min_hp != 0 && GetIntHPRatio() < AIspells[i].min_hp) continue; - if (AIspells[i].max_hp != 0 && GetIntHPRatio() > AIspells[i].max_hp) + if (AIspells[i].type != SpellType_Heal && AIspells[i].max_hp != 0 && GetIntHPRatio() > AIspells[i].max_hp) continue; if (iSpellTypes & AIspells[i].type) { @@ -137,9 +138,13 @@ bool NPC::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes, bool bInnates && tar->DontHealMeBefore() < Timer::GetCurrentTime() && !(tar->IsPet() && tar->GetOwner()->IsClient()) //no buffing PC's pets ) { - uint8 hpr = (uint8)tar->GetHPRatio(); - if(hpr <= 35 || (!IsEngaged() && hpr <= 50) || (tar->IsClient() && hpr <= 99)) { + auto hp_ratio = tar->GetIntHPRatio(); + + int min_hp = AIspells[i].min_hp; // well 0 is default, so no special case here + int max_hp = AIspells[i].max_hp ? AIspells[i].max_hp : RuleI(Spells, AI_HealHPPct); + + if (EQEmu::ValueWithin(hp_ratio, min_hp, max_hp) || (tar->IsClient() && hp_ratio <= 99)) { // not sure about client bit, leaving it uint32 tempTime = 0; AIDoSpellCast(i, tar, mana_cost, &tempTime); tar->SetDontHealMeBefore(tempTime);