@@ -3012,17 +3012,19 @@ SpellCastResult CombatBotBaseAI::CastWeaponBuff(SpellEntry const* pSpellEntry, E
30123012 return spell->prepare (std::move (targets), nullptr );
30133013}
30143014
3015- void CombatBotBaseAI::UseTrinketEffects ()
3015+ bool CombatBotBaseAI::UseTrinketEffects (bool onlyToBreakCC )
30163016{
30173017 if (Item* pItem = me->GetItemByPos (INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_TRINKET1))
3018- if (UseItemEffect (pItem))
3019- return ;
3018+ if (UseItemEffect (pItem, onlyToBreakCC ))
3019+ return true ;
30203020 if (Item* pItem = me->GetItemByPos (INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_TRINKET2))
3021- if (UseItemEffect (pItem))
3022- return ;
3021+ if (UseItemEffect (pItem, onlyToBreakCC))
3022+ return true ;
3023+
3024+ return false ;
30233025}
30243026
3025- bool CombatBotBaseAI::UseItemEffect (Item* pItem)
3027+ bool CombatBotBaseAI::UseItemEffect (Item* pItem, bool onlyToBreakCC )
30263028{
30273029 ItemPrototype const * pProto = pItem->GetProto ();
30283030 for (auto const & itr : pProto->Spells )
@@ -3033,6 +3035,9 @@ bool CombatBotBaseAI::UseItemEffect(Item* pItem)
30333035 {
30343036 if (me->IsSpellReady (*pSpellEntry, pProto))
30353037 {
3038+ if (onlyToBreakCC && !pSpellEntry->HasAttribute (SPELL_ATTR_EX_IMMUNITY_PURGES_EFFECT))
3039+ continue ;
3040+
30363041 if (pSpellEntry->IsPositiveSpell ())
30373042 return me->CastSpell (me, pSpellEntry, false , pItem) == SPELL_CAST_OK;
30383043 else if (me->GetVictim ())
@@ -3044,6 +3049,109 @@ bool CombatBotBaseAI::UseItemEffect(Item* pItem)
30443049 return false ;
30453050}
30463051
3052+ void CombatBotBaseAI::BreakCrowdControlEffects ()
3053+ {
3054+ if (UseTrinketEffects (true ))
3055+ return ;
3056+
3057+ switch (me->GetClass ())
3058+ {
3059+ case CLASS_PALADIN:
3060+ {
3061+ if (m_spells.paladin .pDivineShield &&
3062+ CanTryToCastSpell (me, m_spells.paladin .pDivineShield ))
3063+ {
3064+ if (DoCastSpell (me, m_spells.paladin .pDivineShield ) == SPELL_CAST_OK)
3065+ {
3066+ if (m_role != ROLE_HEALER)
3067+ {
3068+ me->m_Events .AddLambdaEventAtOffset ([player = me, spellId = m_spells.paladin .pDivineShield ->Id ]()
3069+ {
3070+ if (player->GetHealthPercent () > 75 .0f && player->GetAttackers ().size () < 3 )
3071+ player->RemoveAurasDueToSpellByCancel (spellId);
3072+ }, 1 * IN_MILLISECONDS);
3073+ }
3074+ return ;
3075+ }
3076+
3077+ }
3078+ break ;
3079+ }
3080+ case CLASS_MAGE:
3081+ {
3082+ if (me->HasUnitState (UNIT_STATE_STUNNED) && m_spells.mage .pBlink &&
3083+ CanTryToCastSpell (me, m_spells.mage .pBlink ))
3084+ {
3085+ if (DoCastSpell (me, m_spells.mage .pBlink ) == SPELL_CAST_OK)
3086+ return ;
3087+ }
3088+ if (m_spells.mage .pIceBlock &&
3089+ CanTryToCastSpell (me, m_spells.mage .pIceBlock ))
3090+ {
3091+ if (DoCastSpell (me, m_spells.mage .pIceBlock ) == SPELL_CAST_OK)
3092+ {
3093+ me->m_Events .AddLambdaEventAtOffset ([player = me, spellId = m_spells.mage .pIceBlock ->Id ]()
3094+ {
3095+ if (player->GetHealthPercent () > 75 .0f && player->GetAttackers ().size () < 3 )
3096+ player->RemoveAurasDueToSpellByCancel (spellId);
3097+ }, 1 * IN_MILLISECONDS);
3098+ return ;
3099+ }
3100+ }
3101+ break ;
3102+ }
3103+ case CLASS_DRUID:
3104+ {
3105+ bool polymorphed = false ;
3106+ auto const & auraList = me->GetAurasByType (SPELL_AURA_MOD_CONFUSE);
3107+ for (auto const & pAura : auraList)
3108+ {
3109+ if (pAura->GetSpellProto ()->Mechanic == MECHANIC_POLYMORPH)
3110+ {
3111+ polymorphed = true ;
3112+ break ;
3113+ }
3114+ }
3115+
3116+ if (polymorphed)
3117+ {
3118+ SpellEntry const * pShapeshift = nullptr ;
3119+
3120+ if (m_role == ROLE_TANK && m_spells.druid .pBearForm && CanTryToCastSpell (me, m_spells.druid .pBearForm ))
3121+ pShapeshift = m_spells.druid .pBearForm ;
3122+ else if (m_role == ROLE_MELEE_DPS && m_spells.druid .pCatForm && CanTryToCastSpell (me, m_spells.druid .pCatForm ))
3123+ pShapeshift = m_spells.druid .pCatForm ;
3124+ else if (m_role == ROLE_RANGE_DPS && m_spells.druid .pMoonkinForm && CanTryToCastSpell (me, m_spells.druid .pMoonkinForm ))
3125+ pShapeshift = m_spells.druid .pMoonkinForm ;
3126+ else
3127+ {
3128+ for (auto const & pSpell : m_spells.raw .spells )
3129+ {
3130+ if (pSpell && pSpell->HasAura (SPELL_AURA_MOD_SHAPESHIFT) && CanTryToCastSpell (me, pSpell))
3131+ {
3132+ pShapeshift = pSpell;
3133+ break ;
3134+ }
3135+ }
3136+ }
3137+
3138+ if (pShapeshift && DoCastSpell (me, pShapeshift) == SPELL_CAST_OK)
3139+ {
3140+ if (m_role == ROLE_HEALER)
3141+ {
3142+ me->m_Events .AddLambdaEventAtOffset ([player = me, spellId = pShapeshift->Id ]()
3143+ {
3144+ player->RemoveAurasDueToSpellByCancel (spellId);
3145+ }, 1 * IN_MILLISECONDS);
3146+ }
3147+ return ;
3148+ }
3149+ }
3150+ break ;
3151+ }
3152+ }
3153+ }
3154+
30473155bool CombatBotBaseAI::IsWearingShield (Player* pPlayer) const
30483156{
30493157 Item* pItem = pPlayer->GetItemByPos (INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
0 commit comments