Compare commits

..

No commits in common. "9f875a7c81124baca6392d83240c637e17b6140e" and "2b273f6a2c8ffea04fc41d3bb58788af1a67d1d9" have entirely different histories.

16 changed files with 189 additions and 119 deletions

View File

@ -1387,8 +1387,8 @@ bool MovementAction::Flee(Unit* target)
} }
} }
Unit* currentVictim = target->GetThreatMgr().GetCurrentVictim(); HostileReference* ref = target->GetThreatMgr().getCurrentVictim();
if (currentVictim && currentVictim == bot) // bot is target - try to flee to tank or master if (ref && ref->getTarget() == bot) // bot is target - try to flee to tank or master
{ {
if (Group* group = bot->GetGroup()) if (Group* group = bot->GetGroup())
{ {

View File

@ -6,8 +6,7 @@
#include "TellTargetAction.h" #include "TellTargetAction.h"
#include "Event.h" #include "Event.h"
#include "CombatManager.h" #include "ThreatMgr.h"
#include "ThreatManager.h"
#include "AiObjectContext.h" #include "AiObjectContext.h"
#include "PlayerbotAI.h" #include "PlayerbotAI.h"
@ -43,21 +42,21 @@ bool TellAttackersAction::Execute(Event /*event*/)
botAI->TellMaster("--- Threat ---"); botAI->TellMaster("--- Threat ---");
auto const& threatenedByMe = bot->GetThreatMgr().GetThreatenedByMeList(); HostileReference* ref = bot->getHostileRefMgr().getFirst();
if (threatenedByMe.empty()) if (!ref)
return true; return true;
for (auto const& [guid, ref] : threatenedByMe) while (ref)
{ {
Unit* unit = ref->GetOwner(); ThreatMgr* threatMgr = ref->GetSource();
if (!unit) Unit* unit = threatMgr->GetOwner();
continue;
float threat = ref->GetThreat(); float threat = ref->GetThreat();
std::ostringstream out; std::ostringstream out;
out << unit->GetName() << " (" << threat << ")"; out << unit->GetName() << " (" << threat << ")";
botAI->TellMaster(out); botAI->TellMaster(out);
ref = ref->next();
} }
return true; return true;

View File

@ -16,7 +16,7 @@
#include "PositionValue.h" #include "PositionValue.h"
#include "SharedDefines.h" #include "SharedDefines.h"
#include "TemporarySummon.h" #include "TemporarySummon.h"
#include "ThreatManager.h" #include "ThreatMgr.h"
#include "Timer.h" #include "Timer.h"
#include "PlayerbotAI.h" #include "PlayerbotAI.h"
#include "Player.h" #include "Player.h"
@ -217,7 +217,7 @@ bool LowTankThreatTrigger::IsActive()
if (!current_target) if (!current_target)
return false; return false;
ThreatManager& mgr = current_target->GetThreatMgr(); ThreatMgr& mgr = current_target->GetThreatMgr();
float threat = mgr.GetThreat(bot); float threat = mgr.GetThreat(bot);
float tankThreat = mgr.GetThreat(mt); float tankThreat = mgr.GetThreat(mt);
return tankThreat == 0.0f || threat > tankThreat * 0.5f; return tankThreat == 0.0f || threat > tankThreat * 0.5f;

View File

@ -92,15 +92,21 @@ void AttackersValue::AddAttackersOf(Player* player, std::unordered_set<Unit*>& t
if (!player || !player->IsInWorld() || player->IsBeingTeleported()) if (!player || !player->IsInWorld() || player->IsBeingTeleported())
return; return;
for (auto const& [guid, ref] : player->GetThreatMgr().GetThreatenedByMeList()) HostileRefMgr& refManager = player->getHostileRefMgr();
HostileReference* ref = refManager.getFirst();
if (!ref)
return;
while (ref)
{ {
Unit* attacker = ref->GetOwner(); ThreatMgr* threatMgr = ref->GetSource();
if (!attacker) Unit* attacker = threatMgr->GetOwner();
continue;
if (player->IsValidAttackTarget(attacker) && if (player->IsValidAttackTarget(attacker) &&
player->GetDistance2d(attacker) < sPlayerbotAIConfig.sightDistance) player->GetDistance2d(attacker) < sPlayerbotAIConfig.sightDistance)
targets.insert(attacker); targets.insert(attacker);
ref = ref->next();
} }
} }
@ -125,6 +131,7 @@ bool AttackersValue::hasRealThreat(Unit* attacker)
return attacker && attacker->IsInWorld() && attacker->IsAlive() && !attacker->IsPolymorphed() && return attacker && attacker->IsInWorld() && attacker->IsAlive() && !attacker->IsPolymorphed() &&
// !attacker->isInRoots() && // !attacker->isInRoots() &&
!attacker->IsFriendlyTo(bot); !attacker->IsFriendlyTo(bot);
(attacker->GetThreatMgr().getCurrentVictim() || dynamic_cast<Player*>(attacker));
} }
bool AttackersValue::IsPossibleTarget(Unit* attacker, Player* bot, float /*range*/) bool AttackersValue::IsPossibleTarget(Unit* attacker, Player* bot, float /*range*/)
@ -234,6 +241,9 @@ bool AttackersValue::IsPossibleTarget(Unit* attacker, Player* bot, float /*range
bool AttackersValue::IsValidTarget(Unit* attacker, Player* bot) bool AttackersValue::IsValidTarget(Unit* attacker, Player* bot)
{ {
return IsPossibleTarget(attacker, bot) && bot->IsWithinLOSInMap(attacker); return IsPossibleTarget(attacker, bot) && bot->IsWithinLOSInMap(attacker);
// (attacker->GetThreatMgr().getCurrentVictim() || attacker->GetGuidValue(UNIT_FIELD_TARGET) ||
// attacker->GetGUID().IsPlayer() || attacker->GetGUID() ==
// GET_PLAYERBOT_AI(bot)->GetAiObjectContext()->GetValue<ObjectGuid>("pull target")->Get());
} }
bool PossibleAddsValue::Calculate() bool PossibleAddsValue::Calculate()
@ -245,24 +255,27 @@ bool PossibleAddsValue::Calculate()
{ {
if (find(attackers.begin(), attackers.end(), guid) != attackers.end()) if (find(attackers.begin(), attackers.end(), guid) != attackers.end())
continue; continue;
Unit* add = botAI->GetUnit(guid);
if (!add || !add->IsInWorld() || add->IsDuringRemoveFromWorld())
continue;
if (!add->GetTarget() && !add->GetThreatMgr().GetLastVictim() && add->IsHostileTo(bot)) if (Unit* add = botAI->GetUnit(guid))
{ {
for (ObjectGuid const attackerGUID : attackers) if (!add->IsInWorld() || add->IsDuringRemoveFromWorld())
continue;
if (!add->GetTarget() && !add->GetThreatMgr().getCurrentVictim() && add->IsHostileTo(bot))
{ {
Unit* attacker = botAI->GetUnit(attackerGUID); for (ObjectGuid const attackerGUID : attackers)
if (!attacker) {
continue; Unit* attacker = botAI->GetUnit(attackerGUID);
if (!attacker)
continue;
float dist = ServerFacade::instance().GetDistance2d(attacker, add); float dist = ServerFacade::instance().GetDistance2d(attacker, add);
if (ServerFacade::instance().IsDistanceLessOrEqualThan(dist, sPlayerbotAIConfig.aoeRadius * 1.5f)) if (ServerFacade::instance().IsDistanceLessOrEqualThan(dist, sPlayerbotAIConfig.aoeRadius * 1.5f))
continue; continue;
if (ServerFacade::instance().IsDistanceLessOrEqualThan(dist, sPlayerbotAIConfig.aggroDistance)) if (ServerFacade::instance().IsDistanceLessOrEqualThan(dist, sPlayerbotAIConfig.aggroDistance))
return true; return true;
}
} }
} }
} }

View File

@ -20,7 +20,7 @@ public:
} }
public: public:
void CheckAttacker(Unit* creature, ThreatManager* threatMgr) override void CheckAttacker(Unit* creature, ThreatMgr* threatMgr) override
{ {
Player* bot = botAI->GetBot(); Player* bot = botAI->GetBot();
if (!botAI->CanCastSpell(spell, creature)) if (!botAI->CanCastSpell(spell, creature))

View File

@ -13,7 +13,7 @@ public:
{ {
} }
void CheckAttacker(Unit* attacker, ThreatManager* threatMgr) override void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) override
{ {
if (botAI->HasAura(spell, attacker)) if (botAI->HasAura(spell, attacker))
result = attacker; result = attacker;

View File

@ -13,14 +13,16 @@ class FindMaxThreatGapTargetStrategy : public FindTargetStrategy
public: public:
FindMaxThreatGapTargetStrategy(PlayerbotAI* botAI) : FindTargetStrategy(botAI), minThreat(0) {} FindMaxThreatGapTargetStrategy(PlayerbotAI* botAI) : FindTargetStrategy(botAI), minThreat(0) {}
void CheckAttacker(Unit* attacker, ThreatManager* threatMgr) override void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) override
{ {
if (!attacker->IsAlive()) if (!attacker->IsAlive())
{
return; return;
}
if (foundHighPriority) if (foundHighPriority)
{
return; return;
}
if (IsHighPriority(attacker)) if (IsHighPriority(attacker))
{ {
result = attacker; result = attacker;
@ -30,7 +32,7 @@ public:
if (!result || CalcThreatGap(attacker, threatMgr) > CalcThreatGap(result, &result->GetThreatMgr())) if (!result || CalcThreatGap(attacker, threatMgr) > CalcThreatGap(result, &result->GetThreatMgr()))
result = attacker; result = attacker;
} }
float CalcThreatGap(Unit* attacker, ThreatManager* threatMgr) float CalcThreatGap(Unit* attacker, ThreatMgr* threatMgr)
{ {
Unit* victim = attacker->GetVictim(); Unit* victim = attacker->GetVictim();
return threatMgr->GetThreat(victim) - threatMgr->GetThreat(attacker); return threatMgr->GetThreat(victim) - threatMgr->GetThreat(attacker);
@ -50,7 +52,7 @@ public:
result = nullptr; result = nullptr;
} }
void CheckAttacker(Unit* attacker, ThreatManager* threatMgr) override void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) override
{ {
if (Group* group = botAI->GetBot()->GetGroup()) if (Group* group = botAI->GetBot()->GetGroup())
{ {
@ -59,11 +61,13 @@ public:
return; return;
} }
if (!attacker->IsAlive()) if (!attacker->IsAlive())
{
return; return;
}
if (foundHighPriority) if (foundHighPriority)
{
return; return;
}
if (IsHighPriority(attacker)) if (IsHighPriority(attacker))
{ {
result = attacker; result = attacker;
@ -86,19 +90,24 @@ public:
int new_level = GetIntervalLevel(new_unit); int new_level = GetIntervalLevel(new_unit);
int old_level = GetIntervalLevel(old_unit); int old_level = GetIntervalLevel(old_unit);
if (new_level != old_level) if (new_level != old_level)
{
return new_level > old_level; return new_level > old_level;
}
int32_t level = new_level; int32_t level = new_level;
if (level % 10 == 2 || level % 10 == 0) if (level % 10 == 2 || level % 10 == 0)
{
return new_time < old_time; return new_time < old_time;
}
// dont switch targets when all of them with low health // dont switch targets when all of them with low health
Unit* currentTarget = botAI->GetAiObjectContext()->GetValue<Unit*>("current target")->Get(); Unit* currentTarget = botAI->GetAiObjectContext()->GetValue<Unit*>("current target")->Get();
if (currentTarget == new_unit) if (currentTarget == new_unit)
{
return true; return true;
}
if (currentTarget == old_unit) if (currentTarget == old_unit)
{
return false; return false;
}
return new_time > old_time; return new_time > old_time;
} }
int32_t GetIntervalLevel(Unit* unit) int32_t GetIntervalLevel(Unit* unit)
@ -110,11 +119,13 @@ public:
attackRange += 5.0f; attackRange += 5.0f;
int level = dis < attackRange ? 10 : 0; int level = dis < attackRange ? 10 : 0;
if (time >= 5 && time <= 30) if (time >= 5 && time <= 30)
{
return level + 2; return level + 2;
}
if (time > 30) if (time > 30)
{
return level; return level;
}
return level + 1; return level + 1;
} }
@ -132,7 +143,7 @@ public:
{ {
} }
void CheckAttacker(Unit* attacker, ThreatManager*) override void CheckAttacker(Unit* attacker, ThreatMgr*) override
{ {
if (Group* group = botAI->GetBot()->GetGroup()) if (Group* group = botAI->GetBot()->GetGroup())
{ {
@ -141,11 +152,13 @@ public:
return; return;
} }
if (!attacker->IsAlive()) if (!attacker->IsAlive())
{
return; return;
}
if (foundHighPriority) if (foundHighPriority)
{
return; return;
}
if (IsHighPriority(attacker)) if (IsHighPriority(attacker))
{ {
result = attacker; result = attacker;
@ -173,8 +186,9 @@ public:
// attack enemy in range and with lowest health // attack enemy in range and with lowest health
int level = new_level; int level = new_level;
if (level == 10) if (level == 10)
{
return new_time < old_time; return new_time < old_time;
}
// all targets are far away, choose the closest one // all targets are far away, choose the closest one
return botAI->GetBot()->GetDistance(new_unit) < botAI->GetBot()->GetDistance(old_unit); return botAI->GetBot()->GetDistance(new_unit) < botAI->GetBot()->GetDistance(old_unit);
} }
@ -202,7 +216,7 @@ public:
{ {
} }
void CheckAttacker(Unit* attacker, ThreatManager*) override void CheckAttacker(Unit* attacker, ThreatMgr*) override
{ {
if (Group* group = botAI->GetBot()->GetGroup()) if (Group* group = botAI->GetBot()->GetGroup())
{ {
@ -211,11 +225,13 @@ public:
return; return;
} }
if (!attacker->IsAlive()) if (!attacker->IsAlive())
{
return; return;
}
if (foundHighPriority) if (foundHighPriority)
{
return; return;
}
if (IsHighPriority(attacker)) if (IsHighPriority(attacker))
{ {
result = attacker; result = attacker;
@ -238,8 +254,9 @@ public:
int new_level = GetIntervalLevel(new_unit); int new_level = GetIntervalLevel(new_unit);
int old_level = GetIntervalLevel(old_unit); int old_level = GetIntervalLevel(old_unit);
if (new_level != old_level) if (new_level != old_level)
{
return new_level > old_level; return new_level > old_level;
}
// attack enemy in range and with lowest health // attack enemy in range and with lowest health
int level = new_level; int level = new_level;
Player* bot = botAI->GetBot(); Player* bot = botAI->GetBot();
@ -247,8 +264,9 @@ public:
{ {
Unit* combo_unit = bot->GetComboTarget(); Unit* combo_unit = bot->GetComboTarget();
if (new_unit == combo_unit) if (new_unit == combo_unit)
{
return true; return true;
}
return new_time < old_time; return new_time < old_time;
} }
// all targets are far away, choose the closest one // all targets are far away, choose the closest one
@ -301,7 +319,7 @@ class FindMaxHpTargetStrategy : public FindTargetStrategy
public: public:
FindMaxHpTargetStrategy(PlayerbotAI* botAI) : FindTargetStrategy(botAI), maxHealth(0) {} FindMaxHpTargetStrategy(PlayerbotAI* botAI) : FindTargetStrategy(botAI), maxHealth(0) {}
void CheckAttacker(Unit* attacker, ThreatManager*) override void CheckAttacker(Unit* attacker, ThreatMgr*) override
{ {
if (Group* group = botAI->GetBot()->GetGroup()) if (Group* group = botAI->GetBot()->GetGroup())
{ {

View File

@ -5,7 +5,6 @@
#include "EnemyPlayerValue.h" #include "EnemyPlayerValue.h"
#include "CombatManager.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "ServerFacade.h" #include "ServerFacade.h"
#include "Vehicle.h" #include "Vehicle.h"
@ -52,21 +51,34 @@ Unit* EnemyPlayerValue::Calculate()
controllingVehicle = true; controllingVehicle = true;
} }
// 1. Check units we are currently in PvP combat with. // 1. Check units we are currently in combat with.
std::vector<Unit*> targets; std::vector<Unit*> targets;
Unit* pVictim = bot->GetVictim(); Unit* pVictim = bot->GetVictim();
for (auto const& [guid, combatRef] : bot->GetCombatManager().GetPvPCombatRefs()) HostileReference* pReference = bot->getHostileRefMgr().getFirst();
while (pReference)
{ {
Unit* pTarget = combatRef->GetOther(bot); ThreatMgr* threatMgr = pReference->GetSource();
if (!pTarget || pTarget == pVictim || !pTarget->IsPlayer() || !pTarget->CanSeeOrDetect(bot) || if (Unit* pTarget = threatMgr->GetOwner())
!bot->IsWithinDist(pTarget, VISIBILITY_DISTANCE_NORMAL)) {
continue; if (pTarget != pVictim && pTarget->IsPlayer() && pTarget->CanSeeOrDetect(bot) &&
bot->IsWithinDist(pTarget, VISIBILITY_DISTANCE_NORMAL))
{
if (bot->GetTeamId() == TEAM_HORDE)
{
if (pTarget->HasAura(23333))
return pTarget;
}
else
{
if (pTarget->HasAura(23335))
return pTarget;
}
if ((bot->GetTeamId() == TEAM_HORDE && Target->HasAura(23333)) || targets.push_back(pTarget);
(bot->GetTeamId() == TEAM_ALLIANCE && pTarget->HasAura(23335))) }
return pTarget; }
targets.push_back(pTarget); pReference = pReference->next();
} }
if (!targets.empty()) if (!targets.empty())

View File

@ -13,7 +13,7 @@ class FindLeastHpTargetStrategy : public FindNonCcTargetStrategy
public: public:
FindLeastHpTargetStrategy(PlayerbotAI* botAI) : FindNonCcTargetStrategy(botAI), minHealth(0) {} FindLeastHpTargetStrategy(PlayerbotAI* botAI) : FindNonCcTargetStrategy(botAI), minHealth(0) {}
void CheckAttacker(Unit* attacker, ThreatManager* threatMgr) override void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) override
{ {
if (IsCcTarget(attacker)) if (IsCcTarget(attacker))
return; return;

View File

@ -15,11 +15,12 @@ class FindTargetForTankStrategy : public FindNonCcTargetStrategy
public: public:
FindTargetForTankStrategy(PlayerbotAI* botAI) : FindNonCcTargetStrategy(botAI), minThreat(0) {} FindTargetForTankStrategy(PlayerbotAI* botAI) : FindNonCcTargetStrategy(botAI), minThreat(0) {}
void CheckAttacker(Unit* creature, ThreatManager* threatMgr) override void CheckAttacker(Unit* creature, ThreatMgr* threatMgr) override
{ {
if (!creature || !creature->IsAlive()) if (!creature || !creature->IsAlive())
{
return; return;
}
Player* bot = botAI->GetBot(); Player* bot = botAI->GetBot();
float threat = threatMgr->GetThreat(bot); float threat = threatMgr->GetThreat(bot);
if (!result) if (!result)
@ -28,10 +29,14 @@ public:
result = creature; result = creature;
} }
// neglect if victim is main tank, or no victim (for untauntable target) // neglect if victim is main tank, or no victim (for untauntable target)
if (Unit* victim = threatMgr->GetCurrentVictim()) if (threatMgr->getCurrentVictim())
{ {
if (victim->ToPlayer() && botAI->IsMainTank(victim->ToPlayer())) // float max_threat = threatMgr->GetThreat(threatMgr->getCurrentVictim()->getTarget());
Unit* victim = threatMgr->getCurrentVictim()->getTarget();
if (victim && victim->ToPlayer() && botAI->IsMainTank(victim->ToPlayer()))
{
return; return;
}
} }
if (minThreat >= threat) if (minThreat >= threat)
{ {
@ -49,7 +54,7 @@ class FindTankTargetSmartStrategy : public FindTargetStrategy
public: public:
FindTankTargetSmartStrategy(PlayerbotAI* botAI) : FindTargetStrategy(botAI) {} FindTankTargetSmartStrategy(PlayerbotAI* botAI) : FindTargetStrategy(botAI) {}
void CheckAttacker(Unit* attacker, ThreatManager* threatMgr) override void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) override
{ {
if (Group* group = botAI->GetBot()->GetGroup()) if (Group* group = botAI->GetBot()->GetGroup())
{ {
@ -58,10 +63,13 @@ public:
return; return;
} }
if (!attacker->IsAlive()) if (!attacker->IsAlive())
{
return; return;
}
if (!result || IsBetter(attacker, result)) if (!result || IsBetter(attacker, result))
{
result = attacker; result = attacker;
}
} }
bool IsBetter(Unit* new_unit, Unit* old_unit) bool IsBetter(Unit* new_unit, Unit* old_unit)
{ {
@ -72,7 +80,6 @@ public:
{ {
if (old_unit == currentTarget) if (old_unit == currentTarget)
return false; return false;
if (new_unit == currentTarget) if (new_unit == currentTarget)
return true; return true;
} }
@ -82,22 +89,26 @@ public:
float old_dis = bot->GetDistance(old_unit); float old_dis = bot->GetDistance(old_unit);
// hasAggro? -> withinMelee? -> threat // hasAggro? -> withinMelee? -> threat
if (GetIntervalLevel(new_unit) != GetIntervalLevel(old_unit)) if (GetIntervalLevel(new_unit) != GetIntervalLevel(old_unit))
{
return GetIntervalLevel(new_unit) > GetIntervalLevel(old_unit); return GetIntervalLevel(new_unit) > GetIntervalLevel(old_unit);
}
int32_t interval = GetIntervalLevel(new_unit); int32_t interval = GetIntervalLevel(new_unit);
if (interval == 2) if (interval == 2)
{
return new_dis < old_dis; return new_dis < old_dis;
}
return new_threat < old_threat; return new_threat < old_threat;
} }
int32_t GetIntervalLevel(Unit* unit) int32_t GetIntervalLevel(Unit* unit)
{ {
if (!botAI->HasAggro(unit)) if (!botAI->HasAggro(unit))
{
return 2; return 2;
}
if (botAI->GetBot()->IsWithinMeleeRange(unit)) if (botAI->GetBot()->IsWithinMeleeRange(unit))
{
return 1; return 1;
}
return 0; return 0;
} }
}; };

View File

@ -5,13 +5,12 @@
#include "TargetValue.h" #include "TargetValue.h"
#include "CombatManager.h"
#include "LastMovementValue.h" #include "LastMovementValue.h"
#include "ObjectGuid.h" #include "ObjectGuid.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "RtiTargetValue.h" #include "RtiTargetValue.h"
#include "ScriptedCreature.h" #include "ScriptedCreature.h"
#include "ThreatManager.h" #include "ThreatMgr.h"
Unit* FindTargetStrategy::GetResult() { return result; } Unit* FindTargetStrategy::GetResult() { return result; }
@ -24,8 +23,8 @@ Unit* TargetValue::FindTarget(FindTargetStrategy* strategy)
if (!unit) if (!unit)
continue; continue;
ThreatManager& threatMgr = unit->GetThreatMgr(); ThreatMgr& ThreatMgr = unit->GetThreatMgr();
strategy->CheckAttacker(unit, &threatMgr); strategy->CheckAttacker(unit, &ThreatMgr);
} }
return strategy->GetResult(); return strategy->GetResult();
@ -145,23 +144,24 @@ Unit* FindTargetValue::Calculate()
{ {
return nullptr; return nullptr;
} }
for (auto const& [guid, ref] : bot->GetThreatMgr().GetThreatenedByMeList()) HostileReference* ref = bot->getHostileRefMgr().getFirst();
while (ref)
{ {
Unit* unit = ref->GetOwner(); ThreatMgr* threatManager = ref->GetSource();
if (!unit) Unit* unit = threatManager->GetOwner();
continue;
std::wstring wnamepart; std::wstring wnamepart;
Utf8toWStr(unit->GetName(), wnamepart); Utf8toWStr(unit->GetName(), wnamepart);
wstrToLower(wnamepart); wstrToLower(wnamepart);
if (!qualifier.empty() && qualifier.length() == wnamepart.length() && Utf8FitTo(qualifier, wnamepart)) if (!qualifier.empty() && qualifier.length() == wnamepart.length() && Utf8FitTo(qualifier, wnamepart))
{
return unit; return unit;
}
ref = ref->next();
} }
return nullptr; return nullptr;
} }
void FindBossTargetStrategy::CheckAttacker(Unit* attacker, ThreatManager* threatManager) void FindBossTargetStrategy::CheckAttacker(Unit* attacker, ThreatMgr* threatManager)
{ {
UnitAI* unitAI = attacker->GetAI(); UnitAI* unitAI = attacker->GetAI();
BossAI* bossAI = dynamic_cast<BossAI*>(unitAI); BossAI* bossAI = dynamic_cast<BossAI*>(unitAI);

View File

@ -11,7 +11,7 @@
#include "Value.h" #include "Value.h"
class PlayerbotAI; class PlayerbotAI;
class ThreatManager; class ThreatMgr;
class Unit; class Unit;
class FindTargetStrategy class FindTargetStrategy
@ -20,7 +20,7 @@ public:
FindTargetStrategy(PlayerbotAI* botAI) : result(nullptr), botAI(botAI) {} FindTargetStrategy(PlayerbotAI* botAI) : result(nullptr), botAI(botAI) {}
Unit* GetResult(); Unit* GetResult();
virtual void CheckAttacker(Unit* attacker, ThreatManager* threatMgr) = 0; virtual void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) = 0;
void GetPlayerCount(Unit* creature, uint32* tankCount, uint32* dpsCount); void GetPlayerCount(Unit* creature, uint32* tankCount, uint32* dpsCount);
bool IsHighPriority(Unit* attacker); bool IsHighPriority(Unit* attacker);
@ -129,7 +129,7 @@ class FindBossTargetStrategy : public FindTargetStrategy
{ {
public: public:
FindBossTargetStrategy(PlayerbotAI* ai) : FindTargetStrategy(ai) {} FindBossTargetStrategy(PlayerbotAI* ai) : FindTargetStrategy(ai) {}
virtual void CheckAttacker(Unit* attacker, ThreatManager* threatManager); virtual void CheckAttacker(Unit* attacker, ThreatMgr* threatManager);
}; };
class BossTargetValue : public TargetValue, public Qualified class BossTargetValue : public TargetValue, public Qualified

View File

@ -6,7 +6,7 @@
#include "ThreatValues.h" #include "ThreatValues.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "ThreatManager.h" #include "ThreatMgr.h"
uint8 ThreatValue::Calculate() uint8 ThreatValue::Calculate()
{ {

View File

@ -15,6 +15,9 @@ public:
{ {
creators["sanctity aura"] = &sanctity_aura; creators["sanctity aura"] = &sanctity_aura;
creators["retribution aura"] = &retribution_aura; creators["retribution aura"] = &retribution_aura;
creators["seal of corruption"] = &seal_of_corruption;
creators["seal of vengeance"] = &seal_of_vengeance;
creators["seal of command"] = &seal_of_command;
creators["blessing of might"] = &blessing_of_might; creators["blessing of might"] = &blessing_of_might;
creators["crusader strike"] = &crusader_strike; creators["crusader strike"] = &crusader_strike;
creators["repentance"] = &repentance; creators["repentance"] = &repentance;
@ -24,6 +27,36 @@ public:
} }
private: private:
static ActionNode* seal_of_corruption([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode(
"seal of corruption",
/*P*/ {},
/*A*/ { NextAction("seal of vengeance") },
/*C*/ {}
);
}
static ActionNode* seal_of_vengeance([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode(
"seal of vengeance",
/*P*/ {},
/*A*/ { NextAction("seal of command") },
/*C*/ {}
);
}
static ActionNode* seal_of_command([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode(
"seal of command",
/*P*/ {},
/*A*/ { NextAction("seal of righteousness") },
/*C*/ {}
);
}
static ActionNode* blessing_of_might([[maybe_unused]] PlayerbotAI* botAI) static ActionNode* blessing_of_might([[maybe_unused]] PlayerbotAI* botAI)
{ {
return new ActionNode( return new ActionNode(

View File

@ -22,9 +22,6 @@ public:
creators["cleanse magic"] = &cleanse_magic; creators["cleanse magic"] = &cleanse_magic;
creators["cleanse poison on party"] = &cleanse_poison_on_party; creators["cleanse poison on party"] = &cleanse_poison_on_party;
creators["cleanse disease on party"] = &cleanse_disease_on_party; creators["cleanse disease on party"] = &cleanse_disease_on_party;
creators["seal of corruption"] = &seal_of_corruption;
creators["seal of vengeance"] = &seal_of_vengeance;
creators["seal of command"] = &seal_of_command;
creators["seal of wisdom"] = &seal_of_wisdom; creators["seal of wisdom"] = &seal_of_wisdom;
creators["seal of justice"] = &seal_of_justice; creators["seal of justice"] = &seal_of_justice;
creators["hand of reckoning"] = &hand_of_reckoning; creators["hand of reckoning"] = &hand_of_reckoning;
@ -44,6 +41,7 @@ public:
creators["blessing of wisdom on party"] = &blessing_of_wisdom_on_party; creators["blessing of wisdom on party"] = &blessing_of_wisdom_on_party;
creators["blessing of sanctuary on party"] = &blessing_of_sanctuary_on_party; creators["blessing of sanctuary on party"] = &blessing_of_sanctuary_on_party;
creators["blessing of sanctuary"] = &blessing_of_sanctuary; creators["blessing of sanctuary"] = &blessing_of_sanctuary;
creators["seal of command"] = &seal_of_command;
creators["taunt spell"] = &hand_of_reckoning; creators["taunt spell"] = &hand_of_reckoning;
creators["righteous defense"] = &righteous_defense; creators["righteous defense"] = &righteous_defense;
creators["avenger's shield"] = &avengers_shield; creators["avenger's shield"] = &avengers_shield;
@ -157,39 +155,18 @@ private:
/*A*/ { NextAction("purify disease on party") }, /*A*/ { NextAction("purify disease on party") },
/*C*/ {}); /*C*/ {});
} }
static ActionNode* seal_of_corruption(PlayerbotAI* /* ai */)
{
return new ActionNode("seal of corruption",
/*P*/ {},
/*A*/ { NextAction("seal of vengeance") },
/*C*/ {});
}
static ActionNode* seal_of_vengeance(PlayerbotAI* /* ai */)
{
return new ActionNode("seal of vengeance",
/*P*/ {},
/*A*/ { NextAction("seal of command") },
/*C*/ {});
}
static ActionNode* seal_of_command(PlayerbotAI* /* ai */)
{
return new ActionNode("seal of command",
/*P*/ {},
/*A*/ { NextAction("seal of righteousness") },
/*C*/ {});
}
static ActionNode* seal_of_wisdom(PlayerbotAI* /* ai */) static ActionNode* seal_of_wisdom(PlayerbotAI* /* ai */)
{ {
return new ActionNode ("seal of wisdom", return new ActionNode ("seal of wisdom",
/*P*/ {}, /*P*/ {},
/*A*/ { NextAction("seal of corruption") }, /*A*/ { NextAction("seal of righteousness") },
/*C*/ {}); /*C*/ {});
} }
static ActionNode* seal_of_justice(PlayerbotAI* /* ai */) static ActionNode* seal_of_justice(PlayerbotAI* /* ai */)
{ {
return new ActionNode("seal of justice", return new ActionNode("seal of justice",
/*P*/ {}, /*P*/ {},
/*A*/ { NextAction("seal of corruption") }, /*A*/ { NextAction("seal of righteousness") },
/*C*/ {}); /*C*/ {});
} }
static ActionNode* hand_of_reckoning(PlayerbotAI* /* ai */) static ActionNode* hand_of_reckoning(PlayerbotAI* /* ai */)
@ -269,6 +246,13 @@ private:
/*A*/ {}, /*A*/ {},
/*C*/ {}); /*C*/ {});
} }
static ActionNode* seal_of_command(PlayerbotAI* /* ai */)
{
return new ActionNode("seal of command",
/*P*/ {},
/*A*/ { NextAction("seal of righteousness") },
/*C*/ {});
}
}; };
#endif #endif

View File

@ -30,7 +30,7 @@ void HealPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
new TriggerNode( new TriggerNode(
"seal", "seal",
{ {
NextAction("seal of wisdom", ACTION_HIGH), NextAction("seal of wisdom", ACTION_HIGH)
} }
) )
); );