aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp45
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h1
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp4
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h1
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h21
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 4dce17ab33a..37b5a737cd4 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -3598,7 +3598,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:
@@ -3608,24 +3608,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)
@@ -4231,6 +4236,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 5e88f2608fe..5376e251d6a 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -70,6 +70,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 fc8bfd7877d..0f7d64c2d54 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -1018,6 +1018,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 " SI64FMTD " 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 60f28387014..4a4c7b562f1 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -422,6 +422,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 08165b08934..2f75b5d7447 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -887,6 +887,27 @@ namespace Trinity
uint64 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: