diff options
-rw-r--r-- | src/server/game/AI/PlayerAI/PlayerAI.cpp | 86 | ||||
-rw-r--r-- | src/server/game/AI/PlayerAI/PlayerAI.h | 14 |
2 files changed, 61 insertions, 39 deletions
diff --git a/src/server/game/AI/PlayerAI/PlayerAI.cpp b/src/server/game/AI/PlayerAI/PlayerAI.cpp index 9d1e65701bc..1809f02f4fe 100644 --- a/src/server/game/AI/PlayerAI/PlayerAI.cpp +++ b/src/server/game/AI/PlayerAI/PlayerAI.cpp @@ -27,62 +27,78 @@ enum Spells SPELL_THROW = 2764, SPELL_SHOOT_WAND = 5019, + /* Paladin */ + PASSIVE_ILLUMINATION = 20215, + /* Priest */ + SPELL_SOUL_WARDING = 63574, + SPELL_SPIRIT_REDEMPTION = 20711, SPELL_SHADOWFORM = 15473, /* Shaman */ + SPELL_TIDAL_FORCE = 582, + SPELL_MANA_TIDE_TOTEM = 590, + SPELL_SHA_NATURE_SWIFT = 591, SPELL_STORMSTRIKE = 17364, /* Druid */ - SPELL_MOONKIN_FORM = 24858 + SPELL_MOONKIN_FORM = 24858, + SPELL_SWIFTMEND = 18562, + SPELL_DRU_NATURE_SWIFT = 17116, + SPELL_TREE_OF_LIFE = 33891 }; -PlayerAI::PlayerAI(Player* player) : UnitAI(static_cast<Unit*>(player)), me(player), _isRangedAttacker(false) + +bool PlayerAI::IsPlayerHealer(Player const* who) +{ + switch (who->getClass()) + { + case CLASS_WARRIOR: + case CLASS_HUNTER: + case CLASS_ROGUE: + case CLASS_DEATH_KNIGHT: + case CLASS_MAGE: + case CLASS_WARLOCK: + default: + return false; + case CLASS_PALADIN: + return who->HasSpell(PASSIVE_ILLUMINATION); + case CLASS_PRIEST: + return who->HasSpell(SPELL_SOUL_WARDING) || who->HasSpell(SPELL_SPIRIT_REDEMPTION); + case CLASS_SHAMAN: + return who->HasSpell(SPELL_MANA_TIDE_TOTEM) || who->HasSpell(SPELL_SHA_NATURE_SWIFT) || who->HasSpell(SPELL_TIDAL_FORCE); + case CLASS_DRUID: + return who->HasSpell(SPELL_SWIFTMEND) || who->HasSpell(SPELL_DRU_NATURE_SWIFT) || who->HasSpell(SPELL_TREE_OF_LIFE); + } +} + +bool PlayerAI::IsPlayerRangedAttacker(Player const* who) { - switch (me->getClass()) + switch (who->getClass()) { case CLASS_WARRIOR: - _isRangedAttacker = false; - break; case CLASS_PALADIN: - _isRangedAttacker = false; - break; + case CLASS_ROGUE: + case CLASS_DEATH_KNIGHT: + default: + return false; + case CLASS_MAGE: + case CLASS_WARLOCK: + return true; case CLASS_HUNTER: { // check if we have a ranged weapon equipped - Item const* rangedSlot = me->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED); + Item const* rangedSlot = who->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED); if (ItemTemplate const* rangedTemplate = rangedSlot ? rangedSlot->GetTemplate() : nullptr) if ((1 << rangedTemplate->SubClass) & ITEM_SUBCLASS_MASK_WEAPON_RANGED) - { - _isRangedAttacker = true; - break; - } - _isRangedAttacker = false; - break; + return true; + return false; } - case CLASS_ROGUE: - _isRangedAttacker = false; - break; case CLASS_PRIEST: - _isRangedAttacker = me->HasSpell(SPELL_SHADOWFORM); - break; - case CLASS_DEATH_KNIGHT: - _isRangedAttacker = false; - break; + return who->HasSpell(SPELL_SHADOWFORM); case CLASS_SHAMAN: - _isRangedAttacker = !me->HasSpell(SPELL_STORMSTRIKE); - break; - case CLASS_MAGE: - _isRangedAttacker = true; - break; - case CLASS_WARLOCK: - _isRangedAttacker = true; - break; + return !who->HasSpell(SPELL_STORMSTRIKE); case CLASS_DRUID: - _isRangedAttacker = me->HasAura(SPELL_MOONKIN_FORM); - break; - default: - TC_LOG_WARN("entities.unit", "Possessed player %s (possessed by %s) does not have any recognized class (class = %u).", me->GetGUID().ToString().c_str(), me->GetCharmerGUID().ToString().c_str(), me->getClass()); - break; + return who->HasSpell(SPELL_MOONKIN_FORM); } } diff --git a/src/server/game/AI/PlayerAI/PlayerAI.h b/src/server/game/AI/PlayerAI/PlayerAI.h index 39b04a70d67..dcc35bce934 100644 --- a/src/server/game/AI/PlayerAI/PlayerAI.h +++ b/src/server/game/AI/PlayerAI/PlayerAI.h @@ -25,20 +25,26 @@ class PlayerAI : public UnitAI { public: - explicit PlayerAI(Player* player); + explicit PlayerAI(Player* player) : UnitAI(static_cast<Unit*>(player)), me(player), _isSelfHealer(PlayerAI::IsPlayerHealer(player)), _isSelfRangedAttacker(PlayerAI::IsPlayerRangedAttacker(player)) { } void OnCharmed(bool /*apply*/) override { } // charm AI application for players is handled by Unit::SetCharmedBy / Unit::RemoveCharmedBy + + // helper functions to determine player info + static bool IsPlayerHealer(Player const* who); + bool IsHealer(Player const* who = nullptr) const { return (!who || who == me) ? _isSelfHealer : IsPlayerHealer(who); } + static bool IsPlayerRangedAttacker(Player const* who); + bool IsRangedAttacker(Player const* who = nullptr) const { return (!who || who == me) ? _isSelfRangedAttacker : IsPlayerRangedAttacker(who); } protected: Player* const me; - void SetIsRangedAttacker(bool state) { _isRangedAttacker = state; } - bool IsRangedAttacker() const { return _isRangedAttacker; } + void SetIsRangedAttacker(bool state) { _isSelfRangedAttacker = state; } // this allows overriding of the default ranged attacker detection void DoRangedAttackIfReady(); void DoAutoAttackIfReady(); private: - bool _isRangedAttacker; + bool _isSelfHealer; + bool _isSelfRangedAttacker; }; class SimpleCharmedPlayerAI : public PlayerAI |