Skip to content

Commit

Permalink
NPCBots: Improve general casting rotation for bots in combat to allow…
Browse files Browse the repository at this point in the history
… next cast to start immediately after the last one finishes. Stop bots from trying to CC pacified enemies

(cherry picked from commit c11a15f14292f5f4a713004b15541048e53e04ef)
  • Loading branch information
trickerer committed Nov 9, 2024
1 parent 36caab6 commit 5a02fbc
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 14 deletions.
17 changes: 15 additions & 2 deletions src/server/game/AI/NpcBots/bot_GridNotifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ class PolyUnitCheck
u->isFrozen() ||
u->isInRoots() ||
u->HasAuraType(SPELL_AURA_PERIODIC_DAMAGE) ||
u->HasAuraType(SPELL_AURA_MOD_PACIFY) ||
u->HasAuraType(SPELL_AURA_MOD_PACIFY_SILENCE) ||
u->HasAuraTypeWithFamilyFlags(SPELL_AURA_MOD_STUN, SPELLFAMILY_PALADIN, 0x4))
return false;
Expand All @@ -382,7 +383,7 @@ class PolyUnitCheck
class FearUnitCheck
{
public:
explicit FearUnitCheck(Unit const* unit, float dist = 30) : me(unit), m_range(dist) {}
explicit FearUnitCheck(Unit const* unit, float dist, bot_ai const* ai) : me(unit), m_range(dist), m_ai(ai) {}
bool operator()(Unit const* u) const
{
if (!_botPvP && me->IsPvP() && u->IsControlledByPlayer())
Expand All @@ -397,6 +398,8 @@ class FearUnitCheck
return false;
if (u->isFeared())
return false;
if (u->HasAuraType(SPELL_AURA_MOD_PACIFY) || u->HasAuraType(SPELL_AURA_MOD_PACIFY_SILENCE))
return false;
if (!me->IsWithinDistInMap(u, m_range))
return false;
if (!u->IsVisible() || u->IsTotem())
Expand All @@ -408,7 +411,9 @@ class FearUnitCheck
return false;
if (!u->isTargetableForAttack())
return false;
if (u->getAttackers().size() > 1 && u->GetVictim() != me)
if (u->getAttackers().size() > 2)
return false;
if (!m_ai->IsInBotParty(u->GetVictim()))
return false;
//Unit::GetDiminishing() should be const but it isn't
if (const_cast<Unit*>(u)->GetDiminishing(DIMINISHING_FEAR) > DIMINISHING_LEVEL_3)
Expand All @@ -428,6 +433,7 @@ class FearUnitCheck
private:
Unit const* me;
float m_range;
bot_ai const* m_ai;
FearUnitCheck(FearUnitCheck const&);
};

Expand All @@ -447,6 +453,8 @@ class StunUnitCheck
return false;
if (u->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING | UNIT_STATE_DISTRACTED | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE))
return false;
if (u->HasAuraType(SPELL_AURA_MOD_PACIFY) || u->HasAuraType(SPELL_AURA_MOD_PACIFY_SILENCE))
return false;
if (!me->IsWithinDistInMap(u, m_range))
return false;
if (!u->IsVisible() || u->IsTotem())
Expand Down Expand Up @@ -532,6 +540,8 @@ class UndeadCCUnitCheck
return false;
if (u->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING | UNIT_STATE_DISTRACTED | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE))
return false;
if (u->HasAuraType(SPELL_AURA_MOD_PACIFY) || u->HasAuraType(SPELL_AURA_MOD_PACIFY_SILENCE))
return false;
if (me->ToCreature()->GetBotClass() == BOT_CLASS_PRIEST &&
!(u->GetCreatureType() == CREATURE_TYPE_UNDEAD && !u->HasAuraType(SPELL_AURA_PERIODIC_DAMAGE)))
return false;
Expand Down Expand Up @@ -596,6 +606,7 @@ class RootUnitCheck
if (u->GetReactionTo(me) > REP_NEUTRAL)
return false;
if (u->IsPolymorphed() ||
u->HasAuraType(SPELL_AURA_MOD_PACIFY) ||
u->HasAuraType(SPELL_AURA_MOD_PACIFY_SILENCE)/*hex*/ ||
u->HasAuraTypeWithFamilyFlags(SPELL_AURA_MOD_STUN, SPELLFAMILY_PALADIN, 0x4)/*repentance*/ ||
u->HasAuraTypeWithFamilyFlags(SPELL_AURA_MOD_STUN, SPELLFAMILY_PRIEST, 0x40000000)/*shackle undead*/)
Expand Down Expand Up @@ -992,6 +1003,8 @@ class FarTauntUnitCheck
return false;
if (u->HasUnitState(UNIT_STATE_CONFUSED|UNIT_STATE_STUNNED|UNIT_STATE_FLEEING|UNIT_STATE_DISTRACTED|UNIT_STATE_CONFUSED_MOVE))
return false;
if (u->HasAuraType(SPELL_AURA_MOD_PACIFY_SILENCE))
return false;
if (!u->GetVictim() || u->GetVictim() == me)
return false;
if (!u->CanHaveThreatList())
Expand Down
26 changes: 18 additions & 8 deletions src/server/game/AI/NpcBots/bot_ai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6516,7 +6516,7 @@ Unit* bot_ai::FindFearTarget(float dist) const
{
std::list<Unit*> unitList;

FearUnitCheck check(me, dist);
FearUnitCheck check(me, dist, this);
Bcore::UnitListSearcher <FearUnitCheck> searcher(me, unitList, check);
Cell::VisitAllObjects(me, searcher, dist);
//me->VisitNearbyObject(dist, searcher);
Expand Down Expand Up @@ -7634,8 +7634,8 @@ bool bot_ai::Wait()
return true;

if (IAmFree())
waitTimer = (me->IsInCombat() || me->GetVictim() || me->GetMap()->IsBattlegroundOrArena()) ? 500 : ((__rand + 100) * 20);
else if (!master->GetMap()->IsRaid())
waitTimer = (me->IsInCombat() || me->GetVictim() || IsCasting() || me->GetMap()->IsBattlegroundOrArena()) ? 500 : ((__rand + 100) * 20);
else if (master->GetMap()->GetEntry()->IsWorldMap() && !me->IsInCombat() && !IsCasting())
waitTimer = std::min<uint32>(uint32(50 * (master->GetNpcBotsCount() - 1) + __rand), 500);
else
waitTimer = __rand;
Expand Down Expand Up @@ -16024,8 +16024,14 @@ void bot_ai::OnBotSpellGo(Spell const* spell, bool ok)
SetSpellCooldown(curInfo->GetFirstRankSpell()->Id, rec);
SetSpellCategoryCooldown(curInfo->GetFirstRankSpell(), catrec);

if (GC_Timer < lastdiff && !IAmFree())
waitTimer = 0; //allow next cast to be immediate
if (!IAmFree())
{
//allow next cast to be immediate
if (GC_Timer < lastdiff)
waitTimer = 0;
else
waitTimer = std::min<uint32>(waitTimer, GC_Timer - lastdiff);
}
}

if (curInfo->Id == PVPTRINKET)
Expand Down Expand Up @@ -18438,10 +18444,14 @@ void bot_ai::Evade()
homepos.Relocate(nextNode);
if (me->GetMap()->GetEntry()->IsContinent())
evadeDelayTimer = urand(3000, 7000);
else if (_travel_node_cur->HasFlag(BotWPFlags::BOTWP_FLAG_OPTIONAL_PICKUP) && !IsCasting())
evadeDelayTimer = 1000;
else
evadeDelayTimer = 0;
{
if (_travel_node_cur->HasFlag(BotWPFlags::BOTWP_FLAG_OPTIONAL_PICKUP) && !IsCasting())
evadeDelayTimer = 1000;
else
evadeDelayTimer = 0;
waitTimer = std::min<uint32>(waitTimer, evadeDelayTimer);
}
}

BOT_LOG_TRACE("npcbots", "Bot {} id {} class {} level {} wandered from node {} to {}, next {} ('{}'), {}, dist {} yd!",
Expand Down
5 changes: 2 additions & 3 deletions src/server/game/AI/NpcBots/bot_priest_ai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,6 @@ class priest_bot : public CreatureScript
{
SummonBotPet(mytar);
SetSpellCooldown(SHADOWFIEND_1, 180000); // (5 - 2) min with Veiled Shadows
return;
}

if (!HasRole(BOT_ROLE_HEAL) || GetManaPCT(me) > 35 || botPet)
Expand All @@ -538,7 +537,7 @@ class priest_bot : public CreatureScript
!mytar->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x0, 0x400, 0x0, me->GetGUID()) &&
doCast(mytar, GetSpell(VAMPIRIC_TOUCH_1)))
return;
if (IsSpellReady(SW_PAIN_1, diff) && can_do_shadow && Rand() < 60 &&
if (IsSpellReady(SW_PAIN_1, diff) && can_do_shadow && Rand() < 100 &&
mytar->GetHealth() > me->GetMaxHealth()/2 * (1 + mytar->getAttackers().size()) &&
!mytar->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0x0, 0x0, me->GetGUID()))
{
Expand All @@ -547,7 +546,7 @@ class priest_bot : public CreatureScript
if (doCast(mytar, GetSpell(SW_PAIN_1)))
return;
}
if (IsSpellReady(DEVOURING_PLAGUE_1, diff) && can_do_shadow && !Devcheck && Rand() < 80 &&
if (IsSpellReady(DEVOURING_PLAGUE_1, diff) && can_do_shadow && !Devcheck && Rand() < 100 &&
(GetSpec() == BOT_SPEC_PRIEST_SHADOW || mytar->IsControlledByPlayer()) &&
mytar->GetHealth() > me->GetMaxHealth()/2 * (1 + mytar->getAttackers().size()) &&
!(mytar->GetTypeId() == TYPEID_UNIT && (mytar->ToCreature()->GetCreatureTemplate()->MechanicImmuneMask & (1<<(MECHANIC_INFECTED-1)))) &&
Expand Down
2 changes: 1 addition & 1 deletion src/server/game/AI/NpcBots/botmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1293,7 +1293,7 @@ bool BotMgr::RestrictBots(Creature const* bot, bool add) const
uint32 max_players = 0;
if (currMap->IsDungeon())
max_players = currMap->ToInstanceMap()->GetMaxPlayers();
else if (currMap->IsBattleground() || currMap->IsBattleArena())
else if (currMap->IsBattlegroundOrArena())
max_players = _owner->GetBattleground()->GetMaxPlayersPerTeam();

if (max_players)
Expand Down

0 comments on commit 5a02fbc

Please sign in to comment.