diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 45 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.h | 1 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 4 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 1 | ||||
-rw-r--r-- | src/server/game/Grids/Notifiers/GridNotifiers.h | 21 |
5 files changed, 58 insertions, 14 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 0428fb142af..ef84c706c64 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -3333,7 +3333,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui if (!me || !me->IsEngaged()) return; - ObjectVector targets; + Unit* unitTarget = nullptr; switch (e.GetTargetType()) { case SMART_TARGET_CREATURE_RANGE: @@ -3343,24 +3343,29 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui case SMART_TARGET_CLOSEST_PLAYER: case SMART_TARGET_PLAYER_RANGE: case SMART_TARGET_PLAYER_DISTANCE: + { + ObjectVector targets; GetTargets(targets, e); - break; - default: - return; - } - Unit* unitTarget = nullptr; - for (WorldObject* target : targets) - { - if (IsUnit(target) && me->IsFriendlyTo(target->ToUnit()) && target->ToUnit()->IsAlive() && target->ToUnit()->IsInCombat()) - { - uint32 healthPct = uint32(target->ToUnit()->GetHealthPct()); - if (healthPct > e.event.friendlyHealthPct.maxHpPct || healthPct < e.event.friendlyHealthPct.minHpPct) - continue; + for (WorldObject* target : targets) + { + if (IsUnit(target) && me->IsFriendlyTo(target->ToUnit()) && target->ToUnit()->IsAlive() && target->ToUnit()->IsInCombat()) + { + uint32 healthPct = uint32(target->ToUnit()->GetHealthPct()); + if (healthPct > e.event.friendlyHealthPct.maxHpPct || healthPct < e.event.friendlyHealthPct.minHpPct) + continue; - unitTarget = target->ToUnit(); + unitTarget = target->ToUnit(); + break; + } + } break; } + case SMART_TARGET_ACTION_INVOKER: + unitTarget = DoSelectLowestHpPercentFriendly((float)e.event.friendlyHealthPct.radius, e.event.friendlyHealthPct.minHpPct, e.event.friendlyHealthPct.maxHpPct); + break; + default: + return; } if (!unitTarget) @@ -3875,6 +3880,18 @@ Unit* SmartScript::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff) const return unit; } +Unit* SmartScript::DoSelectLowestHpPercentFriendly(float range, uint32 minHpPct, uint32 maxHpPct) const +{ + if (!me) + return nullptr; + + Unit* unit = nullptr; + Trinity::MostHPPercentMissingInRange u_check(me, range, minHpPct, maxHpPct); + Trinity::UnitLastSearcher<Trinity::MostHPPercentMissingInRange> searcher(me, unit, u_check); + Cell::VisitGridObjects(me, searcher, range); + return unit; +} + void SmartScript::DoFindFriendlyCC(std::vector<Creature*>& creatures, float range) const { if (!me) diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index bd5d1756657..caa86f3ef0b 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -66,6 +66,7 @@ class TC_GAME_API SmartScript void OnMoveInLineOfSight(Unit* who); Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff) const; + Unit* DoSelectLowestHpPercentFriendly(float range, uint32 minHpPct, uint32 maxHpPct) const; void DoFindFriendlyCC(std::vector<Creature*>& creatures, float range) const; void DoFindFriendlyMissingBuff(std::vector<Creature*>& creatures, float range, uint32 spellid) const; Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly) const; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 4ac8c616a88..6ee459d2ad1 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -943,6 +943,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_TARGET_PLAYER_RANGE: case SMART_TARGET_PLAYER_DISTANCE: break; + case SMART_TARGET_ACTION_INVOKER: + if (!NotNULL(e, e.event.friendlyHealthPct.radius)) + return false; + break; default: TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid target_type %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType()); return false; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 733f83f8abb..1c8c5271e8e 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -416,6 +416,7 @@ struct SmartEvent uint32 maxHpPct; uint32 repeatMin; uint32 repeatMax; + uint32 radius; } friendlyHealthPct; struct diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 97ead7a2332..697112972f4 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -829,6 +829,27 @@ namespace Trinity uint32 i_hp; }; + class MostHPPercentMissingInRange + { + public: + MostHPPercentMissingInRange(Unit const* obj, float range, uint32 minHpPct, uint32 maxHpPct) : i_obj(obj), i_range(range), i_minHpPct(minHpPct), i_maxHpPct(maxHpPct), i_hpPct(101.f) { } + + bool operator()(Unit* u) + { + if (u->IsAlive() && u->IsInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && i_minHpPct <= u->GetHealthPct() && u->GetHealthPct() <= i_maxHpPct && u->GetHealthPct() < i_hpPct) + { + i_hpPct = u->GetHealthPct(); + return true; + } + return false; + } + + private: + Unit const* i_obj; + float i_range; + float i_minHpPct, i_maxHpPct, i_hpPct; + }; + class FriendlyBelowHpPctEntryInRange { public: |