396 _selfSpec(player->GetPrimarySpecialization()),
397 _isSelfHealer(
PlayerAI::IsPlayerHealer(player)),
398 _isSelfRangedAttacker(
PlayerAI::IsPlayerRangedAttacker(player))
435 uint32 knownRank, nextRank;
440 nextRank =
sSpellMgr->GetNextSpellInChain(spellId);
445 nextRank =
sSpellMgr->GetFirstSpellInChain(spellId);
450 knownRank = nextRank;
451 nextRank =
sSpellMgr->GetNextSpellInChain(knownRank);
466 return{ spell, target };
474 Unit* pTarget =
nullptr;
504 totalWeights += wSpell.second;
512 delete wSpell.first.first;
516 if (randNum < wSpell.second)
517 selected = wSpell.first;
520 randNum -= wSpell.second;
521 delete wSpell.first.first;
533 spell.first->prepare(targets);
548 uint32 rangedAttackSpell = 0;
553 switch (rangedTemplate->GetSubClass())
569 if (!rangedAttackSpell)
599 std::set<Aura*> removableShapeshifts;
602 Aura* aura = auraEff->GetBase();
612 removableShapeshifts.insert(aura);
615 for (
Aura* aura : removableShapeshifts)
639 if (!charmer->IsValidAttackTarget(who))
648 if (
UnitAI* charmerAI = charmer->GetAI())
1193 if (aura->GetCasterGUID() == charmer->
GetGUID() && aura->GetBase()->IsPermanent())
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
@ ITEM_SUBCLASS_WEAPON_GUN
@ ITEM_SUBCLASS_WEAPON_BOW
@ ITEM_SUBCLASS_WEAPON_WAND
@ ITEM_SUBCLASS_WEAPON_THROWN
@ SPELL_SEED_OF_CORRUPTION
@ SPELL_HAMMER_OF_JUSTICE
@ SPELL_DEMONIC_EMPOWERMENT
@ SPELL_DIVINE_ILLUMINATION
@ PASSIVE_ELEMENTAL_FOCUS
@ SPELL_DIVINE_PROTECTION
@ SPELL_UNSTABLE_AFFLICTION
@ SPELL_SHIELD_OF_RIGHTEOUS
@ SPELL_BLESSING_OF_MIGHT
@ SPELL_POWER_WORD_SHIELD
@ SPELL_HAND_OF_SACRIFICE
@ SPELL_SHADOW_PROTECTION
@ SPELL_SURVIVAL_INSTINCTS
@ SPELL_UNBREAKABLE_ARMOR
@ PASSIVE_SPIRIT_REDEMPTION
@ SPELL_HAMMER_OF_RIGHTEOUS
@ SPELL_EMPOWER_RUNE_WEAP
@ SPELL_ELEMENTAL_MASTERY
@ SPELL_ICEBORN_FORTITUDE
@ SPELL_INTIMIDATING_SHOUT
@ PASSIVE_MASTER_OF_GHOUL
@ SPELL_HAND_OF_PROTECTION
@ SPELL_SHADOW_WORD_DEATH
static const float CASTER_CHASE_DISTANCE
#define INVENTORY_SLOT_BAG_0
uint32 urand(uint32 min, uint32 max)
@ SPELL_ATTR0_NO_AURA_CANCEL
@ SPELL_AURA_MOD_SHAPESHIFT
@ TRIGGERED_CAST_DIRECTLY
In Spell::prepare, will be cast directly without setting containers for executed spell.
@ TRIGGERED_NONE
Not triggered.
SpellInfo const * GetSpellInfo() const
bool IsEngaged() const override
bool IsInEvadeMode() const
ItemTemplate const * GetTemplate() const
Difficulty GetDifficultyID() const
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={}, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
void MoveFollow(Unit *target, float dist, Optional< ChaseAngle > angle={}, Optional< Milliseconds > duration={}, bool ignoreTargetWalk=false, MovementSlot slot=MOTION_SLOT_ACTIVE, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
void Remove(MovementGenerator *movement, MovementSlot slot=MOTION_SLOT_ACTIVE)
static ObjectGuid GetGUID(Object const *o)
void DoRangedAttackIfReady()
static bool IsPlayerRangedAttacker(Player const *who)
virtual Unit * SelectAttackTarget() const
std::pair< TargetedSpell, uint32 > PossibleSpell
void DoCastAtTarget(TargetedSpell spell)
void DoAutoAttackIfReady()
TargetedSpell SelectSpellCast(PossibleSpellVector &spells)
static bool IsPlayerHealer(Player const *who)
TargetedSpell VerifySpellCast(uint32 spellId, Unit *target)
ChrSpecialization const _selfSpec
ChrSpecialization GetSpec(Player const *who=nullptr) const
bool IsRangedAttacker(Player const *who=nullptr) const
std::vector< PossibleSpell > PossibleSpellVector
void CancelAllShapeshifts()
Creature * GetCharmer() const
ChrSpecialization GetPrimarySpecialization() const
Item * GetItemByPos(uint16 pos) const
bool HasSpell(uint32 spell) const override
ChrSpecializationEntry const * GetPrimarySpecializationEntry() const
void OnCharmed(bool isNew) override
bool CanAIAttack(Unit const *who) const override
TargetedSpell SelectAppropriateCastForSpec()
void UpdateAI(uint32 diff) override
Unit * SelectAttackTarget() const override
void SetUnitTarget(Unit *target)
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
bool HasAttribute(SpellAttr0 attribute) const
SpellCastResult prepare(SpellCastTargets const &targets, AuraEffect const *triggeredByAura=nullptr)
SpellCastResult CheckPetCast(Unit *target)
bool CanAutoCast(Unit *target)
void AttackStartCaster(Unit *victim, float dist)
virtual void AttackStart(Unit *victim)
virtual bool CanAIAttack(Unit const *) const
virtual void OnCharmed(bool isNew)
void CastStop(uint32 except_spellid=0)
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
bool HasBreakableByDamageCrowdControlAura(Unit *excludeCasterChannel=nullptr) const
Unit * GetCharmer() const
std::forward_list< AuraEffect * > AuraEffectList
MotionMaster * GetMotionMaster()
void SetFacingTo(float const ori, bool force=true)
bool HasUnitState(const uint32 f) const
SpellHistory * GetSpellHistory()
ObjectGuid GetCharmerGUID() const
bool isAttackReady(WeaponAttackType type=BASE_ATTACK) const
void KillSelf(bool durabilityLoss=true, bool skipSettingDeathState=false)
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
bool IsWithinLOSInMap(WorldObject const *obj, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
EnumFlag< ChrSpecializationFlag > GetFlags() const
ChrSpecializationRole GetRole() const
float GetAbsoluteAngle(float x, float y) const
constexpr void GetPosition(float &x, float &y) const
constexpr float GetOrientation() const
ValidTargetSelectPredicate(UnitAI const *ai)
bool operator()(Unit const *target) const