fix(Scripts/Naxxramas): Patchwerk's Hateful Strike target selection (#25429)
This commit is contained in:
@@ -2310,6 +2310,32 @@ namespace Acore
|
|||||||
private:
|
private:
|
||||||
bool const _ascending;
|
bool const _ascending;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Binary predicate for sorting Units based on current value of health
|
||||||
|
class HealthOrderPred
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HealthOrderPred(bool ascending = true) : _ascending(ascending) { }
|
||||||
|
|
||||||
|
bool operator()(WorldObject const* objA, WorldObject const* objB) const
|
||||||
|
{
|
||||||
|
Unit const* a = objA->ToUnit();
|
||||||
|
Unit const* b = objB->ToUnit();
|
||||||
|
uint32 rA = a ? a->GetHealth() : 0;
|
||||||
|
uint32 rB = b ? b->GetHealth() : 0;
|
||||||
|
return _ascending ? rA < rB : rA > rB;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator() (Unit const* a, Unit const* b) const
|
||||||
|
{
|
||||||
|
uint32 rA = a ? a->GetHealth() : 0;
|
||||||
|
uint32 rB = b ? b->GetHealth() : 0;
|
||||||
|
return _ascending ? rA < rB : rA > rB;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool const _ascending;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class RedirectSpellEvent : public BasicEvent
|
class RedirectSpellEvent : public BasicEvent
|
||||||
|
|||||||
@@ -113,49 +113,37 @@ public:
|
|||||||
{
|
{
|
||||||
case EVENT_HATEFUL_STRIKE:
|
case EVENT_HATEFUL_STRIKE:
|
||||||
{
|
{
|
||||||
// Cast Hateful strike on the player with the highest amount of HP within melee distance, and second threat amount
|
// Scan melee targets (melee range), choose target according to mechanics:
|
||||||
std::list<Unit*> meleeRangeTargets;
|
// - If only 1 melee target exists, hit the tank (current victim).
|
||||||
Unit* finalTarget = nullptr;
|
// - Otherwise select the top RAID_MODE(1,2) threat targets (excluding current victim)
|
||||||
uint8 counter = 0;
|
// among melee targets and hit the one with the highest HP.
|
||||||
auto threatList = me->GetThreatMgr().GetSortedThreatList();
|
// - The target hit gains 500 flat threat.
|
||||||
for (auto i = threatList.begin(); i != threatList.end(); ++i, ++counter)
|
|
||||||
|
Unit* victim = me->GetVictim();
|
||||||
|
if (!victim)
|
||||||
{
|
{
|
||||||
// Gather all units with melee range
|
events.RescheduleEvent(EVENT_HATEFUL_STRIKE, 1s);
|
||||||
Unit* target = (*i)->GetVictim();
|
break;
|
||||||
if (me->IsWithinMeleeRange(target))
|
|
||||||
{
|
|
||||||
meleeRangeTargets.push_back(target);
|
|
||||||
}
|
|
||||||
// and add threat to most hated
|
|
||||||
if (counter < RAID_MODE(2, 3))
|
|
||||||
{
|
|
||||||
me->AddThreat(target, 500.0f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
counter = 0;
|
|
||||||
std::list<Unit*, std::allocator<Unit*>>::iterator itr;
|
Unit* hatefulTarget = victim; // default to current victim if no other target is available
|
||||||
for (itr = meleeRangeTargets.begin(); itr != meleeRangeTargets.end(); ++itr, ++counter)
|
|
||||||
|
std::list<Unit*> meleeTargets;
|
||||||
|
constexpr float HATEFUL_STRIKE_RANGE = 5.0f;
|
||||||
|
SelectTargetList(meleeTargets, RAID_MODE(1, 2), SelectTargetMethod::MaxThreat, 0, [&](Unit const* target)
|
||||||
{
|
{
|
||||||
// if there is only one target available
|
return target && target->IsPlayer() && target != victim && me->IsWithinCombatRange(target, HATEFUL_STRIKE_RANGE);
|
||||||
if (meleeRangeTargets.size() == 1)
|
});
|
||||||
{
|
|
||||||
finalTarget = (*itr);
|
if (!meleeTargets.empty())
|
||||||
}
|
|
||||||
else if (counter > 0) // skip first target
|
|
||||||
{
|
|
||||||
if (!finalTarget || (*itr)->GetHealth() > finalTarget->GetHealth())
|
|
||||||
{
|
|
||||||
finalTarget = (*itr);
|
|
||||||
}
|
|
||||||
// third loop
|
|
||||||
if (counter >= 2)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (finalTarget)
|
|
||||||
{
|
{
|
||||||
me->CastSpell(finalTarget, SPELL_HATEFUL_STRIKE, false);
|
meleeTargets.sort(Acore::HealthOrderPred(false));
|
||||||
|
hatefulTarget = meleeTargets.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
me->CastSpell(hatefulTarget, SPELL_HATEFUL_STRIKE, false);
|
||||||
|
me->AddThreat(hatefulTarget, 500.0f);
|
||||||
|
|
||||||
events.Repeat(1s);
|
events.Repeat(1s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user