mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-26 20:02:25 +01:00
Core/SAI: refactored SMART_EVENT_FRIENDLY_HEALTH_PCT to reflect the behavior of SMART_EVENT_FRIENDLY_HEALTH
* added radius event parameter to limit the search range of the executing creature * moved the pct check to a macro and corrected the selection logic to support all target types
This commit is contained in:
3
sql/updates/world/4.3.4/2021_02_25_01_world.sql
Normal file
3
sql/updates/world/4.3.4/2021_02_25_01_world.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
UPDATE `smart_scripts` SET `event_param5`= `event_param4` WHERE `event_type`= 74;
|
||||
UPDATE `smart_scripts` SET `event_param4`= `event_param3` WHERE `event_type`= 74;
|
||||
UPDATE `smart_scripts` SET `event_param3`= 100 WHERE `event_type`= 74; -- normalizing all existing uses of this smart event to 100 yards
|
||||
@@ -374,8 +374,8 @@ void ScriptedAI::DoTeleportAll(float x, float y, float z, float o)
|
||||
Unit* ScriptedAI::DoSelectLowestHpFriendly(float range, uint32 minHPDiff)
|
||||
{
|
||||
Unit* unit = nullptr;
|
||||
Trinity::MostHPMissingInRange u_check(me, range, minHPDiff);
|
||||
Trinity::UnitLastSearcher<Trinity::MostHPMissingInRange> searcher(me, unit, u_check);
|
||||
Trinity::FriendlyMostHPMissingInRange u_check(me, range, minHPDiff);
|
||||
Trinity::UnitLastSearcher<Trinity::FriendlyMostHPMissingInRange> searcher(me, unit, u_check);
|
||||
Cell::VisitAllObjects(me, searcher, range);
|
||||
|
||||
return unit;
|
||||
|
||||
@@ -3381,40 +3381,15 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
||||
if (!me || !me->IsEngaged())
|
||||
return;
|
||||
|
||||
ObjectVector targets;
|
||||
switch (e.GetTargetType())
|
||||
Unit* target = DoSelectLowestHpPctFriendly((float)e.event.friendlyHealthPct.radius, e.event.friendlyHealthPct.minHpPct, e.event.friendlyHealthPct.maxHpPct);
|
||||
if (!target || !target->IsEngaged())
|
||||
{
|
||||
case SMART_TARGET_CREATURE_RANGE:
|
||||
case SMART_TARGET_CREATURE_GUID:
|
||||
case SMART_TARGET_CREATURE_DISTANCE:
|
||||
case SMART_TARGET_CLOSEST_CREATURE:
|
||||
case SMART_TARGET_CLOSEST_PLAYER:
|
||||
case SMART_TARGET_PLAYER_RANGE:
|
||||
case SMART_TARGET_PLAYER_DISTANCE:
|
||||
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;
|
||||
|
||||
unitTarget = target->ToUnit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!unitTarget)
|
||||
// if there are at least two same npcs, they will perform the same action immediately even if this is useless...
|
||||
RecalcTimer(e, 1000, 3000);
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessTimedAction(e, e.event.friendlyHealthPct.repeatMin, e.event.friendlyHealthPct.repeatMax, unitTarget);
|
||||
ProcessTimedAction(e, e.event.friendlyHealthPct.repeatMin, e.event.friendlyHealthPct.repeatMax, target);
|
||||
break;
|
||||
}
|
||||
case SMART_EVENT_DISTANCE_CREATURE:
|
||||
@@ -3845,8 +3820,21 @@ Unit* SmartScript::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
|
||||
|
||||
Unit* unit = nullptr;
|
||||
|
||||
Trinity::MostHPMissingInRange u_check(me, range, MinHPDiff);
|
||||
Trinity::UnitLastSearcher<Trinity::MostHPMissingInRange> searcher(me, unit, u_check);
|
||||
Trinity::FriendlyMostHPMissingInRange u_check(me, range, MinHPDiff);
|
||||
Trinity::UnitLastSearcher<Trinity::FriendlyMostHPMissingInRange> searcher(me, unit, u_check);
|
||||
Cell::VisitGridObjects(me, searcher, range);
|
||||
return unit;
|
||||
}
|
||||
|
||||
Unit* SmartScript::DoSelectLowestHpPctFriendly(float range, uint8 hpPctMin, uint8 hpPctMax)
|
||||
{
|
||||
if (!me)
|
||||
return nullptr;
|
||||
|
||||
Unit* unit = nullptr;
|
||||
|
||||
Trinity::FriendlyMostHPPctMissingInRange u_check(me, range, hpPctMin, hpPctMax);
|
||||
Trinity::UnitLastSearcher<Trinity::FriendlyMostHPPctMissingInRange> searcher(me, unit, u_check);
|
||||
Cell::VisitGridObjects(me, searcher, range);
|
||||
return unit;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ class TC_GAME_API SmartScript
|
||||
void OnMoveInLineOfSight(Unit* who);
|
||||
|
||||
Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff);
|
||||
Unit* DoSelectLowestHpPctFriendly(float range, uint8 hpPctMin, uint8 hpPctMax);
|
||||
void DoFindFriendlyCC(std::list<Creature*>& _list, float range);
|
||||
void DoFindFriendlyMissingBuff(std::list<Creature*>& list, float range, uint32 spellid);
|
||||
Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly);
|
||||
|
||||
@@ -938,6 +938,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
break;
|
||||
}
|
||||
case SMART_EVENT_FRIENDLY_HEALTH_PCT:
|
||||
{
|
||||
if (!NotNULL(e, e.event.friendlyHealth.radius))
|
||||
return false;
|
||||
|
||||
if (!IsMinMaxValid(e, e.event.friendlyHealthPct.repeatMin, e.event.friendlyHealthPct.repeatMax))
|
||||
return false;
|
||||
|
||||
@@ -946,22 +950,8 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has pct value above 100, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (e.GetTargetType())
|
||||
{
|
||||
case SMART_TARGET_CREATURE_RANGE:
|
||||
case SMART_TARGET_CREATURE_GUID:
|
||||
case SMART_TARGET_CREATURE_DISTANCE:
|
||||
case SMART_TARGET_CLOSEST_CREATURE:
|
||||
case SMART_TARGET_CLOSEST_PLAYER:
|
||||
case SMART_TARGET_PLAYER_RANGE:
|
||||
case SMART_TARGET_PLAYER_DISTANCE:
|
||||
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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SMART_EVENT_DISTANCE_CREATURE:
|
||||
if (e.event.distance.guid == 0 && e.event.distance.entry == 0)
|
||||
{
|
||||
|
||||
@@ -409,6 +409,7 @@ struct SmartEvent
|
||||
{
|
||||
uint32 minHpPct;
|
||||
uint32 maxHpPct;
|
||||
uint32 radius;
|
||||
uint32 repeatMin;
|
||||
uint32 repeatMax;
|
||||
} friendlyHealthPct;
|
||||
|
||||
@@ -794,10 +794,11 @@ namespace Trinity
|
||||
|
||||
// Unit checks
|
||||
|
||||
class MostHPMissingInRange
|
||||
class FriendlyMostHPMissingInRange
|
||||
{
|
||||
public:
|
||||
MostHPMissingInRange(Unit const* obj, float range, uint32 hp) : i_obj(obj), i_range(range), i_hp(hp) { }
|
||||
FriendlyMostHPMissingInRange(Unit const* obj, float range, uint32 hp) : i_obj(obj), i_range(range), i_hp(hp) { }
|
||||
|
||||
bool operator()(Unit* u)
|
||||
{
|
||||
if (u->IsAlive() && u->IsInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && u->GetMaxHealth() - u->GetHealth() > i_hp)
|
||||
@@ -813,6 +814,27 @@ namespace Trinity
|
||||
uint32 i_hp;
|
||||
};
|
||||
|
||||
class FriendlyMostHPPctMissingInRange
|
||||
{
|
||||
public:
|
||||
FriendlyMostHPPctMissingInRange(Unit const* obj, float range, uint8 hpPctMin, uint8 hpPctMax) : i_obj(obj), i_range(range), i_hpPctMin(hpPctMin), i_hpPctMax(hpPctMax) { }
|
||||
|
||||
bool operator()(Unit* u)
|
||||
{
|
||||
if (u->IsAlive() && u->IsInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && u->GetHealthPct() > i_hpPctMin && u->GetHealthPct() < i_hpPctMax)
|
||||
{
|
||||
i_hpPctMax = u->GetHealthPct();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
Unit const* i_obj;
|
||||
float i_range;
|
||||
uint8 i_hpPctMin;
|
||||
uint8 i_hpPctMax;
|
||||
};
|
||||
|
||||
class FriendlyBelowHpPctEntryInRange
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -1331,8 +1331,8 @@ class npc_captain_arnath : public CreatureScript
|
||||
Creature* FindFriendlyCreature() const
|
||||
{
|
||||
Creature* target = nullptr;
|
||||
Trinity::MostHPMissingInRange u_check(me, 60.0f, 0);
|
||||
Trinity::CreatureLastSearcher<Trinity::MostHPMissingInRange> searcher(me, target, u_check);
|
||||
Trinity::FriendlyMostHPMissingInRange u_check(me, 60.0f, 0);
|
||||
Trinity::CreatureLastSearcher<Trinity::FriendlyMostHPMissingInRange> searcher(me, target, u_check);
|
||||
Cell::VisitGridObjects(me, searcher, 60.0f);
|
||||
return target;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user