mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Spells: Added helper function to select random injured healing spell targets
This commit is contained in:
@@ -8613,6 +8613,75 @@ bool WorldObjectSpellLineTargetCheck::operator()(WorldObject* target) const
|
||||
return WorldObjectSpellTargetCheck::operator ()(target);
|
||||
}
|
||||
|
||||
void SelectRandomInjuredTargets(std::list<WorldObject*>& targets, size_t maxTargets, bool prioritizePlayers)
|
||||
{
|
||||
if (targets.size() <= maxTargets)
|
||||
return;
|
||||
|
||||
std::vector<WorldObject*> tempTargets(targets.begin(), targets.end());
|
||||
|
||||
auto begin = tempTargets.begin();
|
||||
auto end = tempTargets.end();
|
||||
|
||||
if (prioritizePlayers)
|
||||
{
|
||||
auto playersEnd = std::stable_partition(begin, end, [](WorldObject const* target)
|
||||
{
|
||||
return target->IsPlayer();
|
||||
});
|
||||
|
||||
size_t playerCount = std::distance(begin, playersEnd);
|
||||
if (playerCount < maxTargets)
|
||||
{
|
||||
// not enough players, add nonplayer targets
|
||||
// prioritize injured nonplayers over full health nonplayers
|
||||
auto injuredNonPlayersEnd = std::stable_partition(playersEnd, end, [](WorldObject const* target)
|
||||
{
|
||||
return target->IsUnit() && !target->ToUnit()->IsFullHealth();
|
||||
});
|
||||
|
||||
size_t injuredNonPlayersCount = std::distance(playersEnd, injuredNonPlayersEnd);
|
||||
if (playerCount + injuredNonPlayersCount < maxTargets)
|
||||
{
|
||||
// not enough players + injured nonplayers
|
||||
// fill remainder with random full health nonplayers
|
||||
Containers::RandomShuffle(injuredNonPlayersEnd, end);
|
||||
}
|
||||
else if (playerCount + injuredNonPlayersCount > maxTargets)
|
||||
{
|
||||
// randomize injured nonplayers order
|
||||
// final list will contain all players + random injured nonplayers
|
||||
Containers::RandomShuffle(playersEnd, injuredNonPlayersEnd);
|
||||
}
|
||||
|
||||
targets.assign(tempTargets.begin(), tempTargets.begin() + maxTargets);
|
||||
return;
|
||||
}
|
||||
|
||||
// We have more players than we requested, proceed checking injured targets
|
||||
end = playersEnd;
|
||||
}
|
||||
|
||||
auto injuredUnitsEnd = std::stable_partition(begin, end, [](WorldObject const* target)
|
||||
{
|
||||
return target->IsUnit() && !target->ToUnit()->IsFullHealth();
|
||||
});
|
||||
|
||||
size_t injuredUnitsCount = std::distance(begin, injuredUnitsEnd);
|
||||
if (injuredUnitsCount < maxTargets)
|
||||
{
|
||||
// not enough injured units
|
||||
// fill remainder with full health units
|
||||
Containers::RandomShuffle(injuredUnitsEnd, end);
|
||||
}
|
||||
else if (injuredUnitsCount > maxTargets)
|
||||
{
|
||||
// select random injured units
|
||||
Containers::RandomShuffle(begin, injuredUnitsEnd);
|
||||
}
|
||||
|
||||
targets.assign(tempTargets.begin(), tempTargets.begin() + maxTargets);
|
||||
}
|
||||
} //namespace Trinity
|
||||
|
||||
CastSpellTargetArg::CastSpellTargetArg(WorldObject* target)
|
||||
|
||||
@@ -933,6 +933,8 @@ namespace Trinity
|
||||
|
||||
bool operator()(WorldObject* target) const;
|
||||
};
|
||||
|
||||
TC_GAME_API void SelectRandomInjuredTargets(std::list<WorldObject*>& targets, size_t maxTargets, bool prioritizePlayers);
|
||||
}
|
||||
|
||||
using SpellEffectHandlerFn = void(Spell::*)();
|
||||
|
||||
@@ -324,12 +324,7 @@ class spell_sha_downpour : public SpellScript
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
uint32 const maxTargets = 6;
|
||||
if (targets.size() > maxTargets)
|
||||
{
|
||||
targets.sort(Trinity::HealthPctOrderPred());
|
||||
targets.resize(maxTargets);
|
||||
}
|
||||
Trinity::SelectRandomInjuredTargets(targets, 6, true);
|
||||
}
|
||||
|
||||
void CountEffectivelyHealedTarget()
|
||||
|
||||
Reference in New Issue
Block a user