31 if (victim &&
me->
Attack(victim,
true))
57 if (victim &&
me->
Attack(victim,
false))
91 Unit* target =
nullptr;
94 aiTargetType = info->target;
110 auto targetSelector = [&](
Unit const* candidate) ->
bool
112 if (!candidate->IsPlayer())
123 return targetSelectorInner(candidate);
139 float range = spellInfo->GetMaxRange(
false);
142 auto targetSelector = [&](
Unit const* candidate) ->
bool
144 if (!candidate->IsPlayer())
155 return targetSelectorInner(candidate);
183 return DoCast(victim, spellId, args);
188#define UPDATE_TARGET(a) {if (AIInfo->target<a) AIInfo->target=a;}
208 for (SpellEffectInfo const& effect : spellInfo->GetEffects())
210 uint32 targetType = effect.TargetA.GetTarget();
212 if (targetType == TARGET_UNIT_TARGET_ENEMY
213 || targetType == TARGET_DEST_TARGET_ENEMY)
214 UPDATE_TARGET(AITARGET_VICTIM)
215 else if (targetType == TARGET_UNIT_DEST_AREA_ENEMY)
216 UPDATE_TARGET(AITARGET_ENEMY)
218 if (effect.Effect == SPELL_EFFECT_APPLY_AURA)
220 if (targetType == TARGET_UNIT_TARGET_ENEMY)
221 UPDATE_TARGET(AITARGET_DEBUFF)
222 else if (spellInfo->IsPositive())
223 UPDATE_TARGET(AITARGET_BUFF)
228 AIInfo->maxRange = spellInfo->
GetMaxRange(
false) * 3 / 4;
305 if (targetList.empty())
314 return targetList.front();
336 if (ref->IsOffline())
339 targetList.push_back(ref->GetVictim());
346 targetList.push_back(currentVictim);
350 if (ref->IsOffline())
354 if (thisTarget != currentVictim)
355 targetList.push_back(thisTarget);
360 if (targetList.size() <= offset)
372 targetList.reverse();
377 targetList.pop_front();
386 if (targetList.size() <= num)
392 targetList.resize(num);
397 std::stringstream sstr;
398 sstr << std::boolalpha
@ SELECT_TARGET_ANY_FRIEND
@ SELECT_TARGET_AOE_FRIEND
@ SELECT_TARGET_ANY_ENEMY
@ SELECT_TARGET_SINGLE_FRIEND
@ SELECT_TARGET_SINGLE_ENEMY
@ SELECT_TARGET_AOE_ENEMY
AISpellInfoType * GetAISpellInfo(uint32 spellId, Difficulty difficulty)
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
if(posix_memalign(&__mallocedMemory, __align, __size)) return NULL
@ SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC
@ SPELL_ATTR5_NOT_ON_PLAYER
@ TARGET_UNIT_TARGET_PARTY
@ TARGET_DEST_DYNOBJ_ENEMY
@ TARGET_UNIT_CASTER_AREA_PARTY
@ TARGET_UNIT_DEST_AREA_ENEMY
@ TARGET_UNIT_TARGET_ALLY
@ TARGET_UNIT_SRC_AREA_ENEMY
@ TARGET_DEST_TARGET_ENEMY
@ TARGET_UNIT_TARGET_ENEMY
@ TARGET_UNIT_LASTTARGET_AREA_PARTY
@ SPELL_ATTR3_ONLY_ON_PLAYER
@ SPELL_EFFECT_HEALTH_LEECH
@ SPELL_EFFECT_HEAL_MAX_HEALTH
@ SPELL_EFFECT_HEAL_MECHANICAL
@ SPELL_EFFECT_ENVIRONMENTAL_DAMAGE
@ SPELL_EFFECT_SCHOOL_DAMAGE
@ SPELL_EFFECT_APPLY_AURA
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
@ SPELL_FAILED_BAD_TARGETS
@ SPELL_FAILED_SPELL_IN_PROGRESS
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will not check if a current cast is in progress.
Difficulty GetDifficultyID() const
void MoveChase(Unit *target, Optional< ChaseRange > dist={}, Optional< ChaseAngle > angle={})
float GetMaxRange(bool positive=false, WorldObject *caster=nullptr, Spell *spell=nullptr) const
::Difficulty const Difficulty
bool HasAttribute(SpellAttr0 attribute) const
int32 GetDuration() const
std::vector< SpellEffectInfo > const & GetEffects() const
Unit * GetCurrentVictim()
Trinity::IteratorPair< ThreatListIterator, std::nullptr_t > GetUnsortedThreatList() const
Trinity::IteratorPair< ThreatListIterator, std::nullptr_t > GetSortedThreatList() const
size_t GetThreatListSize() const
bool DoSpellAttackIfReady(uint32 spellId)
void AttackStartCaster(Unit *victim, float dist)
static void FillAISpellInfo()
bool PrepareTargetListSelection(std::list< Unit * > &targetList, SelectTargetMethod targetType, uint32 offset)
virtual void AttackStart(Unit *victim)
virtual void InitializeAI()
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
static std::unordered_map< std::pair< uint32, Difficulty >, AISpellInfoType > AISpellInfo
void SelectTargetList(std::list< Unit * > &targetList, uint32 num, SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
virtual void OnCharmed(bool isNew)
virtual std::string GetDebugInfo() const
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Unit * FinalizeTargetSelection(std::list< Unit * > &targetList, SelectTargetMethod targetType)
void FinalizeTargetListSelection(std::list< Unit * > &targetList, uint32 num, SelectTargetMethod targetType)
SpellCastResult DoCast(uint32 spellId)
void ClearUnitState(uint32 f)
ThreatManager & GetThreatManager()
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
MotionMaster * GetMotionMaster()
std::string GetDebugInfo() const override
bool Attack(Unit *victim, bool meleeAttack)
bool HasUnitState(const uint32 f) const
bool isAttackReady(WeaponAttackType type=BASE_ATTACK) const
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
void RandomResize(C &container, std::size_t requestedSize)