aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGiacomo Pozzoni <giacomopoz@gmail.com>2020-08-25 14:14:06 +0200
committerGitHub <noreply@github.com>2020-08-25 14:14:06 +0200
commitcbed1039c47f0e3487cea555bb8552a4e6445f5a (patch)
treede5727424fdb67b14a095d8d3077418f5048fcbd /src
parent3f4bcfbbe1ee919d9de85825c9b7fb4a4944ace9 (diff)
Core/SAI: Implement SMART_TARGET_ACTION_INVOKER in SMART_EVENT_FRIENDLY_HEALTH_PCT (#25318)
* Core/SAI: Implement SMART_TARGET_ACTION_INVOKER in SMART_EVENT_FRIENDLY_HEALTH_PCT * Require radius (5th parameter) to be set
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 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: