Skip to content

Commit 80e099e

Browse files
committed
Make bots break CC effects on themselves.
1 parent 3de62e0 commit 80e099e

File tree

4 files changed

+123
-8
lines changed

4 files changed

+123
-8
lines changed

src/game/PlayerBots/BattleBotAI.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,10 @@ void BattleBotAI::UpdateAI(uint32 const diff)
813813
}
814814

815815
if (me->HasUnitState(UNIT_STATE_CAN_NOT_REACT_OR_LOST_CONTROL))
816+
{
817+
BreakCrowdControlEffects();
816818
return;
819+
}
817820

818821
if (me->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL))
819822
{

src/game/PlayerBots/CombatBotBaseAI.cpp

Lines changed: 114 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
30473155
bool CombatBotBaseAI::IsWearingShield(Player* pPlayer) const
30483156
{
30493157
Item* pItem = pPlayer->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);

src/game/PlayerBots/CombatBotBaseAI.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,9 @@ class CombatBotBaseAI : public PlayerBotAI
135135

136136
bool SummonShamanTotems();
137137
SpellCastResult CastWeaponBuff(SpellEntry const* pSpellEntry, EquipmentSlots slot);
138-
void UseTrinketEffects();
139-
bool UseItemEffect(Item* pItem);
138+
bool UseTrinketEffects(bool onlyToBreakCC = false);
139+
bool UseItemEffect(Item* pItem, bool onlyToBreakCC = false);
140+
void BreakCrowdControlEffects();
140141

141142
virtual void UpdateInCombatAI() = 0;
142143
virtual void UpdateOutOfCombatAI() = 0;

src/game/PlayerBots/PartyBotAI.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,10 @@ void PartyBotAI::UpdateAI(uint32 const diff)
699699
me->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
700700

701701
if (me->HasUnitState(UNIT_STATE_CAN_NOT_REACT_OR_LOST_CONTROL))
702+
{
703+
BreakCrowdControlEffects();
702704
return;
705+
}
703706

704707
if (me->IsDead())
705708
{

0 commit comments

Comments
 (0)