fix(spell): paladin and dk aggro spell, warrior

This commit is contained in:
Yunfan Li
2023-06-11 15:55:36 +08:00
parent b11fad1a46
commit 33576bd969
21 changed files with 117 additions and 62 deletions

View File

@@ -1387,7 +1387,7 @@ bool PlayerbotAI::IsMainTank(Player* player)
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) { for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) {
Player* member = ref->GetSource(); Player* member = ref->GetSource();
if (IsTank(member)) { if (IsTank(member)) {
return player == member; return player->GetGUID() == member->GetGUID();
} }
} }
return false; return false;
@@ -1882,7 +1882,7 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell,
} }
} }
ObjectGuid oldSel = bot->GetTarget(); ObjectGuid oldSel = bot->GetSelectedUnit()->GetGUID();
Spell* spell = new Spell(bot, spellInfo, TRIGGERED_NONE); Spell* spell = new Spell(bot, spellInfo, TRIGGERED_NONE);
spell->m_targets.SetUnitTarget(target); spell->m_targets.SetUnitTarget(target);
@@ -1901,7 +1901,7 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell,
} }
if (oldSel) if (oldSel)
bot->SetTarget(oldSel); bot->SetSelection(oldSel);
switch (result) switch (result)
{ {

View File

@@ -137,10 +137,16 @@ CastEnchantItemAction::CastEnchantItemAction(PlayerbotAI* botAI, std::string con
bool CastEnchantItemAction::isPossible() bool CastEnchantItemAction::isPossible()
{ {
if (!CastSpellAction::isPossible()) if (!CastSpellAction::isPossible()) {
botAI->TellMasterNoFacing("Impossible: " + spell);
return false; return false;
}
uint32 spellId = AI_VALUE2(uint32, "spell id", spell); uint32 spellId = AI_VALUE2(uint32, "spell id", spell);
bool ok = AI_VALUE2(Item*, "item for spell", spellId);
botAI->TellMasterNoFacing("spell: " + spell + ", spell id: " + std::to_string(spellId) + " item for spell: " + std::to_string(ok));
return spellId && AI_VALUE2(Item*, "item for spell", spellId); return spellId && AI_VALUE2(Item*, "item for spell", spellId);
} }

View File

@@ -116,7 +116,7 @@ bool HeiganDanceAction::CalculateSafe() {
uint32 curr_erupt = eventMap->GetNextEventTime(3); uint32 curr_erupt = eventMap->GetNextEventTime(3);
uint32 curr_dance = eventMap->GetNextEventTime(4); uint32 curr_dance = eventMap->GetNextEventTime(4);
uint32 curr_timer = eventMap->GetTimer(); uint32 curr_timer = eventMap->GetTimer();
if ((curr_phase == 0 && curr_dance - curr_timer >= 80000) || (curr_phase == 1 && curr_dance - curr_timer >= 40000)) { if ((curr_phase == 0 && curr_dance - curr_timer >= 85000) || (curr_phase == 1 && curr_dance - curr_timer >= 40000)) {
ResetSafe(); ResetSafe();
} else if (curr_erupt != prev_erupt) { } else if (curr_erupt != prev_erupt) {
NextSafe(); NextSafe();
@@ -131,6 +131,7 @@ bool HeiganDanceMeleeAction::Execute(Event event) {
if (prev_phase == 0 && botAI->IsMainTank(bot) && !AI_VALUE2(bool, "has aggro", "boss target")) { if (prev_phase == 0 && botAI->IsMainTank(bot) && !AI_VALUE2(bool, "has aggro", "boss target")) {
return false; return false;
} }
assert(curr_safe >= 0 && curr_safe <= 3);
return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(), botAI->IsMainTank(bot) ? 0 : 0); return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(), botAI->IsMainTank(bot) ? 0 : 0);
} }

View File

@@ -75,8 +75,8 @@ NextAction** BloodDKStrategy::getDefaultActions()
{ {
return NextAction::array(0, return NextAction::array(0,
new NextAction("rune strike", ACTION_NORMAL + 7), new NextAction("rune strike", ACTION_NORMAL + 7),
new NextAction("heart strike", ACTION_NORMAL + 6), new NextAction("icy touch", ACTION_NORMAL + 6),
new NextAction("icy touch", ACTION_NORMAL + 5), new NextAction("heart strike", ACTION_NORMAL + 5),
new NextAction("death coil", ACTION_NORMAL + 4), new NextAction("death coil", ACTION_NORMAL + 4),
new NextAction("plague strike", ACTION_NORMAL + 3), new NextAction("plague strike", ACTION_NORMAL + 3),
new NextAction("blood strike", ACTION_NORMAL + 2), new NextAction("blood strike", ACTION_NORMAL + 2),

View File

@@ -36,10 +36,10 @@ class CastDeathchillAction : public CastBuffSpellAction
NextAction** getPrerequisites() override; NextAction** getPrerequisites() override;
}; };
class CastDarkCommandAction : public CastBuffSpellAction class CastDarkCommandAction : public CastSpellAction
{ {
public: public:
CastDarkCommandAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "dark command") { } CastDarkCommandAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "dark command") { }
NextAction** getPrerequisites() override; NextAction** getPrerequisites() override;
}; };

View File

@@ -165,16 +165,16 @@ void GenericDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
triggers.push_back(new TriggerNode("bone shield", NextAction::array(0, new NextAction("bone shield", ACTION_NORMAL + 1), nullptr))); triggers.push_back(new TriggerNode("bone shield", NextAction::array(0, new NextAction("bone shield", ACTION_NORMAL + 1), nullptr)));
triggers.push_back(new TriggerNode("horn of winter", NextAction::array(0, new NextAction("horn of winter", ACTION_NORMAL + 1), nullptr))); triggers.push_back(new TriggerNode("horn of winter", NextAction::array(0, new NextAction("horn of winter", ACTION_NORMAL + 1), nullptr)));
triggers.push_back(new TriggerNode("mind freeze on enemy healer", NextAction::array(0, new NextAction("mind freeze on enemy healer", ACTION_HIGH + 1), nullptr))); triggers.push_back(new TriggerNode("mind freeze on enemy healer", NextAction::array(0, new NextAction("mind freeze on enemy healer", ACTION_HIGH + 1), nullptr)));
triggers.push_back(new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("reach melee", ACTION_NORMAL + 8), nullptr))); // triggers.push_back(new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("reach melee", ACTION_NORMAL + 8), nullptr)));
triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("icebound fortitude", ACTION_HIGH + 5), new NextAction("rune tap", ACTION_HIGH + 4), nullptr))); triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("icebound fortitude", ACTION_HIGH + 5), new NextAction("rune tap", ACTION_HIGH + 4), nullptr)));
triggers.push_back(new TriggerNode("medium health", NextAction::array(0, new NextAction("rune tap", ACTION_NORMAL + 4), new NextAction("death strike", ACTION_NORMAL + 3), nullptr))); triggers.push_back(new TriggerNode("medium health", NextAction::array(0, new NextAction("rune tap", ACTION_NORMAL + 4), new NextAction("death strike", ACTION_NORMAL + 3), nullptr)));
triggers.push_back(new TriggerNode("icy touch", NextAction::array(0, new NextAction("icy touch", ACTION_HIGH + 1), nullptr))); triggers.push_back(new TriggerNode("icy touch", NextAction::array(0, new NextAction("icy touch", ACTION_HIGH + 1), nullptr)));
// triggers.push_back(new TriggerNode("icy touch on attacker", NextAction::array(0, new NextAction("icy touch on attacker", ACTION_HIGH + 1), nullptr))); // triggers.push_back(new TriggerNode("icy touch on attacker", NextAction::array(0, new NextAction("icy touch on attacker", ACTION_HIGH + 1), nullptr)));
triggers.push_back(new TriggerNode("plague strike", NextAction::array(0, new NextAction("plague strike", ACTION_HIGH + 1), nullptr))); triggers.push_back(new TriggerNode("plague strike", NextAction::array(0, new NextAction("plague strike", ACTION_HIGH + 1), nullptr)));
// triggers.push_back(new TriggerNode("plague strike on attacker", NextAction::array(0, new NextAction("plague strike on attacker", ACTION_HIGH + 1), nullptr))); // triggers.push_back(new TriggerNode("plague strike on attacker", NextAction::array(0, new NextAction("plague strike on attacker", ACTION_HIGH + 1), nullptr)));
triggers.push_back(new TriggerNode("high aoe", NextAction::array(0, new NextAction("unholy blight", ACTION_NORMAL + 6), new NextAction("death and decay", ACTION_NORMAL + 5), triggers.push_back(new TriggerNode("high aoe", NextAction::array(0, new NextAction("unholy blight", ACTION_HIGH + 6), new NextAction("death and decay", ACTION_NORMAL + 5),
new NextAction("pestilence", ACTION_NORMAL + 4), new NextAction("blood boil", ACTION_NORMAL + 3), nullptr))); new NextAction("pestilence", ACTION_NORMAL + 4), new NextAction("blood boil", ACTION_NORMAL + 3), nullptr)));
triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("death and decay", ACTION_NORMAL + 5), triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("death and decay", ACTION_HIGH + 9),
new NextAction("pestilence", ACTION_NORMAL + 4), new NextAction("blood boil", ACTION_NORMAL + 3), nullptr))); new NextAction("pestilence", ACTION_NORMAL + 4), new NextAction("blood boil", ACTION_NORMAL + 3), nullptr)));
triggers.push_back(new TriggerNode("light aoe", NextAction::array(0, new NextAction("howling blast", ACTION_NORMAL + 5), new NextAction("pestilence", ACTION_NORMAL + 4), triggers.push_back(new TriggerNode("light aoe", NextAction::array(0, new NextAction("howling blast", ACTION_NORMAL + 5), new NextAction("pestilence", ACTION_NORMAL + 4),
new NextAction("hearth strike", ACTION_NORMAL + 3), new NextAction("blood boil", ACTION_NORMAL + 3), nullptr))); new NextAction("hearth strike", ACTION_NORMAL + 3), new NextAction("blood boil", ACTION_NORMAL + 3), nullptr)));

View File

@@ -77,7 +77,8 @@ class BearTankDruidStrategyActionNodeFactory : public NamedObjectFactory<ActionN
{ {
return new ActionNode ("mangle (bear)", return new ActionNode ("mangle (bear)",
/*P*/ nullptr, /*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("lacerate"), nullptr), // /*A*/ NextAction::array(0, new NextAction("lacerate"), nullptr),
nullptr,
/*C*/ nullptr); /*C*/ nullptr);
} }
@@ -138,10 +139,10 @@ BearTankDruidStrategy::BearTankDruidStrategy(PlayerbotAI* botAI) : FeralDruidStr
NextAction** BearTankDruidStrategy::getDefaultActions() NextAction** BearTankDruidStrategy::getDefaultActions()
{ {
return NextAction::array(0, return NextAction::array(0,
new NextAction("lacerate", ACTION_NORMAL + 4), new NextAction("mangle (bear)", ACTION_NORMAL + 5),
new NextAction("mangle (bear)", ACTION_NORMAL + 3), new NextAction("faerie fire (feral)", ACTION_NORMAL + 4),
new NextAction("lacerate", ACTION_NORMAL + 3),
new NextAction("maul", ACTION_NORMAL + 2), new NextAction("maul", ACTION_NORMAL + 2),
new NextAction("faerie fire (feral)", ACTION_NORMAL + 1),
new NextAction("melee", ACTION_NORMAL), new NextAction("melee", ACTION_NORMAL),
nullptr); nullptr);
} }

View File

@@ -17,10 +17,10 @@ class CastFaerieFireAction : public CastDebuffSpellAction
CastFaerieFireAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "faerie fire") { } CastFaerieFireAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "faerie fire") { }
}; };
class CastFaerieFireFeralAction : public CastDebuffSpellAction class CastFaerieFireFeralAction : public CastSpellAction
{ {
public: public:
CastFaerieFireFeralAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "faerie fire (feral)") { } CastFaerieFireFeralAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "faerie fire (feral)") { }
}; };
class CastRejuvenationAction : public CastHealingSpellAction class CastRejuvenationAction : public CastHealingSpellAction

View File

@@ -41,6 +41,6 @@ bool CastCasterFormAction::Execute(Event event)
} }
bool CastTreeFormAction::isUseful() { bool CastTreeFormAction::isUseful() {
return GetTarget() && (GetTarget() != nullptr) && (GetTarget() != nullptr) && return GetTarget() &&
CastSpellAction::isUseful() && !botAI->HasAura(33891, bot); CastSpellAction::isUseful() && !botAI->HasAura(33891, bot);
} }

View File

@@ -101,8 +101,6 @@ void FeralDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
triggers.push_back(new TriggerNode("enemy too close for melee", NextAction::array(0, new NextAction("move out of enemy contact", ACTION_NORMAL + 8), nullptr))); triggers.push_back(new TriggerNode("enemy too close for melee", NextAction::array(0, new NextAction("move out of enemy contact", ACTION_NORMAL + 8), nullptr)));
triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("survival instincts", ACTION_EMERGENCY + 1), nullptr))); triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("survival instincts", ACTION_EMERGENCY + 1), nullptr)));
triggers.push_back(new TriggerNode("omen of clarity", NextAction::array(0, new NextAction("omen of clarity", ACTION_HIGH + 9), nullptr))); triggers.push_back(new TriggerNode("omen of clarity", NextAction::array(0, new NextAction("omen of clarity", ACTION_HIGH + 9), nullptr)));
//triggers.push_back(new TriggerNode("player has no flag", NextAction::array(0, new NextAction("prowl", ACTION_HIGH + 1), nullptr)));
//triggers.push_back(new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("prowl", ACTION_INTERRUPT + 1), nullptr)));
triggers.push_back(new TriggerNode("player has flag", NextAction::array(0, new NextAction("dash", ACTION_EMERGENCY + 2), nullptr))); triggers.push_back(new TriggerNode("player has flag", NextAction::array(0, new NextAction("dash", ACTION_EMERGENCY + 2), nullptr)));
triggers.push_back(new TriggerNode("enemy flagcarrier near", NextAction::array(0, new NextAction("dash", ACTION_EMERGENCY + 2), nullptr))); triggers.push_back(new TriggerNode("enemy flagcarrier near", NextAction::array(0, new NextAction("dash", ACTION_EMERGENCY + 2), nullptr)));
} }

View File

@@ -173,7 +173,7 @@ class GenericPaladinStrategyActionNodeFactory : public NamedObjectFactory<Action
} }
static ActionNode* avengers_shield(PlayerbotAI* ai) static ActionNode* avengers_shield(PlayerbotAI* ai)
{ {
return new ActionNode ("righteous defense", return new ActionNode ("avenger's shield",
/*P*/ NULL, /*P*/ NULL,
/*A*/ NextAction::array(0, new NextAction("judgement of wisdom"), NULL), /*A*/ NextAction::array(0, new NextAction("judgement of wisdom"), NULL),
/*C*/ NULL); /*C*/ NULL);

View File

@@ -53,12 +53,12 @@ void TankPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
// triggers.push_back(new TriggerNode("medium mana", NextAction::array(0, new NextAction("judgement of wisdom", ACTION_HIGH + 6), nullptr))); // triggers.push_back(new TriggerNode("medium mana", NextAction::array(0, new NextAction("judgement of wisdom", ACTION_HIGH + 6), nullptr)));
// triggers.push_back(new TriggerNode("judgement", NextAction::array(0, new NextAction("judgement", ACTION_HIGH + 6), nullptr))); // triggers.push_back(new TriggerNode("judgement", NextAction::array(0, new NextAction("judgement", ACTION_HIGH + 6), nullptr)));
// triggers.push_back(new TriggerNode("judgement", NextAction::array(0, new NextAction("exorcism", ACTION_HIGH + 6), nullptr))); // triggers.push_back(new TriggerNode("judgement", NextAction::array(0, new NextAction("exorcism", ACTION_HIGH + 6), nullptr)));
// triggers.push_back(new TriggerNode("light aoe", NextAction::array(0, new NextAction("hammer of the righteous", ACTION_HIGH + 8), new NextAction("avenger's shield", ACTION_HIGH + 7), nullptr))); triggers.push_back(new TriggerNode("light aoe", NextAction::array(0, new NextAction("hammer of the righteous", ACTION_HIGH + 8), new NextAction("avenger's shield", ACTION_HIGH + 7), nullptr)));
triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("consecration", ACTION_HIGH + 1), new NextAction("avenger's shield", ACTION_HIGH + 3), NULL))); triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("consecration", ACTION_HIGH + 1), new NextAction("avenger's shield", ACTION_HIGH + 3), NULL)));
triggers.push_back(new TriggerNode("avenger's shield", NextAction::array(0, new NextAction("avenger's shield", ACTION_HIGH + 7), nullptr))); // triggers.push_back(new TriggerNode("avenger's shield", NextAction::array(0, new NextAction("avenger's shield", ACTION_HIGH + 7), nullptr)));
triggers.push_back(new TriggerNode("lose aggro", NextAction::array(0, new NextAction("hand of reckoning", ACTION_HIGH + 7), nullptr))); triggers.push_back(new TriggerNode("lose aggro", NextAction::array(0, new NextAction("hand of reckoning", ACTION_HIGH + 7), nullptr)));
triggers.push_back(new TriggerNode("holy shield", NextAction::array(0, new NextAction("holy shield", ACTION_HIGH + 7), nullptr))); triggers.push_back(new TriggerNode("holy shield", NextAction::array(0, new NextAction("holy shield", ACTION_HIGH + 7), nullptr)));
triggers.push_back(new TriggerNode("blessing", NextAction::array(0, new NextAction("blessing of sanctuary", ACTION_HIGH + 9), nullptr))); // triggers.push_back(new TriggerNode("blessing", NextAction::array(0, new NextAction("blessing of sanctuary", ACTION_HIGH + 9), nullptr)));
triggers.push_back(new TriggerNode("target critical health", NextAction::array(0, new NextAction("hammer of wrath", ACTION_CRITICAL_HEAL), nullptr))); triggers.push_back(new TriggerNode("target critical health", NextAction::array(0, new NextAction("hammer of wrath", ACTION_CRITICAL_HEAL), nullptr)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
"righteous fury", "righteous fury",

View File

@@ -113,13 +113,17 @@ void DpsRogueStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
"light aoe", "light aoe",
NextAction::array(0, new NextAction("blade flurry", ACTION_HIGH + 3), NULL))); NextAction::array(0, new NextAction("blade flurry", ACTION_HIGH + 3), NULL)));
triggers.push_back(new TriggerNode( // triggers.push_back(new TriggerNode(
"enemy out of melee", // "enemy out of melee",
NextAction::array(0, new NextAction("stealth", ACTION_NORMAL + 9), new NextAction("reach melee", ACTION_NORMAL + 8), NULL))); // NextAction::array(0, new NextAction("stealth", ACTION_NORMAL + 9), new NextAction("reach melee", ACTION_NORMAL + 8), NULL)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
"expose armor", "expose armor",
NextAction::array(0, new NextAction("expose armor", ACTION_HIGH + 3), NULL))); NextAction::array(0, new NextAction("expose armor", ACTION_HIGH + 3), NULL)));
triggers.push_back(new TriggerNode(
"tricks of the trade on main tank",
NextAction::array(0, new NextAction("tricks of the trade on main tank", ACTION_HIGH + 7), NULL)));
} }
class StealthedRogueStrategyActionNodeFactory : public NamedObjectFactory<ActionNode> class StealthedRogueStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>

View File

@@ -60,6 +60,14 @@ bool ComboPointsAvailableTrigger::IsActive()
bool LoseAggroTrigger::IsActive() bool LoseAggroTrigger::IsActive()
{ {
Unit* mt = AI_VALUE(Unit*, "main tank");
if (mt) {
botAI->TellMasterNoFacing("Has aggro: " + std::to_string(AI_VALUE2(bool, "has aggro", "current target"))
+ " My main tank is: " + mt->GetName());
} else {
botAI->TellMasterNoFacing("Has aggro: " + std::to_string(AI_VALUE2(bool, "has aggro", "current target"))
+ " No main tank detected");
}
return !AI_VALUE2(bool, "has aggro", "current target"); return !AI_VALUE2(bool, "has aggro", "current target");
} }

View File

@@ -16,28 +16,42 @@ bool HasAggroValue::Calculate()
if (!target) if (!target)
return true; return true;
HostileReference *ref = bot->getHostileRefMgr().getFirst(); Unit* victim = target->GetVictim();
if (!ref)
return true; // simulate as target is not atacking anybody yet
while( ref )
{
ThreatMgr *threatManager = ref->GetSource();
Unit *attacker = threatManager->GetOwner();
if (attacker != target) {
ref = ref->next();
continue;
}
Unit *victim = attacker->GetVictim();
if (!victim) { if (!victim) {
return true; return true;
} }
if ((victim == bot || (victim && victim->ToPlayer() && botAI->IsMainTank(victim->ToPlayer()))) && target == attacker)
if (victim->GetGUID() == bot->GetGUID() || (victim->ToPlayer() && botAI->IsMainTank(victim->ToPlayer()))) {
return true; return true;
ref = ref->next(); }
botAI->TellMaster("target: " + target->GetName() + " victim: " + victim->GetName());
if (victim->ToPlayer() ) {
botAI->TellMaster("victim is mt: " + std::to_string(botAI->IsMainTank(victim->ToPlayer())));
} }
return false; return false;
// HostileReference *ref = bot->getHostileRefMgr().getFirst();
// if (!ref)
// return true; // simulate as target is not atacking anybody yet
// while( ref )
// {
// ThreatMgr *threatManager = ref->GetSource();
// Unit *attacker = threatManager->GetOwner();
// if (attacker->GetGUID() != target->GetGUID()) {
// ref = ref->next();
// continue;
// }
// Unit *victim = attacker->GetVictim();
// if (!victim) {
// return true;
// }
// if ((victim->GetGUID() == bot->GetGUID() || (victim && victim->ToPlayer() && botAI->IsMainTank(victim->ToPlayer()))) &&
// target->GetGUID() == attacker->GetGUID())
// return true;
// ref = ref->next();
// }
// Unit* target = GetTarget(); // Unit* target = GetTarget();
// if (!target) // if (!target)
// return true; // return true;

View File

@@ -32,8 +32,6 @@ Unit* PartyMemberValue::FindPartyMember(FindPlayerPredicate& predicate, bool ign
if (Group* group = bot->GetGroup()) if (Group* group = bot->GetGroup())
{ {
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
{
if (ref->GetSource() != bot)
{ {
if (ref->getSubGroup() != bot->GetSubGroup()) if (ref->getSubGroup() != bot->GetSubGroup())
{ {
@@ -44,7 +42,6 @@ Unit* PartyMemberValue::FindPartyMember(FindPlayerPredicate& predicate, bool ign
nearestGroupPlayers.push_front(ref->GetSource()->GetGUID()); nearestGroupPlayers.push_front(ref->GetSource()->GetGUID());
} }
} }
}
} else { } else {
std::vector<Player*> vec; std::vector<Player*> vec;
vec.push_back(bot); vec.push_back(bot);
@@ -69,7 +66,7 @@ Unit* PartyMemberValue::FindPartyMember(FindPlayerPredicate& predicate, bool ign
for (ObjectGuid const guid : nearestPlayers) for (ObjectGuid const guid : nearestPlayers)
{ {
Player* player = botAI->GetPlayer(guid); Player* player = botAI->GetPlayer(guid);
if (!player || player == bot) if (!player)
continue; continue;
if (botAI->IsHeal(player)) if (botAI->IsHeal(player))
@@ -115,7 +112,7 @@ bool PartyMemberValue::IsTargetOfSpellCast(Player* target, SpellEntryPredicate &
for (ObjectGuid const guid : nearestPlayers) for (ObjectGuid const guid : nearestPlayers)
{ {
Player* player = botAI->GetPlayer(guid); Player* player = botAI->GetPlayer(guid);
if (!player || player == bot) if (!player)
continue; continue;
if (player->IsNonMeleeSpellCast(true)) if (player->IsNonMeleeSpellCast(true))

View File

@@ -34,7 +34,14 @@ FuryWarriorStrategy::FuryWarriorStrategy(PlayerbotAI* botAI) : GenericWarriorStr
NextAction** FuryWarriorStrategy::getDefaultActions() NextAction** FuryWarriorStrategy::getDefaultActions()
{ {
return NextAction::array(0, new NextAction("melee", ACTION_NORMAL), nullptr); return NextAction::array(0,
new NextAction("bloodthirst", ACTION_NORMAL + 5),
new NextAction("whirlwind", ACTION_NORMAL + 4),
new NextAction("sunder armor", ACTION_NORMAL + 3),
new NextAction("execute", ACTION_NORMAL + 2),
new NextAction("overpower", ACTION_NORMAL + 1),
new NextAction("melee", ACTION_NORMAL),
NULL);
} }
void FuryWarriorStrategy::InitTriggers(std::vector<TriggerNode*> &triggers) void FuryWarriorStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
@@ -53,10 +60,16 @@ void FuryWarriorStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
triggers.push_back(new TriggerNode("intercept on snare target", NextAction::array(0, new NextAction("intercept on snare target", ACTION_HIGH), nullptr))); triggers.push_back(new TriggerNode("intercept on snare target", NextAction::array(0, new NextAction("intercept on snare target", ACTION_HIGH), nullptr)));
triggers.push_back(new TriggerNode("bloodthirst", NextAction::array(0, new NextAction("bloodthirst", ACTION_HIGH + 2), nullptr))); triggers.push_back(new TriggerNode("bloodthirst", NextAction::array(0, new NextAction("bloodthirst", ACTION_HIGH + 2), nullptr)));
triggers.push_back(new TriggerNode("instant slam", NextAction::array(0, new NextAction("slam", ACTION_HIGH + 1), nullptr))); triggers.push_back(new TriggerNode("instant slam", NextAction::array(0, new NextAction("slam", ACTION_HIGH + 1), nullptr)));
triggers.push_back(new TriggerNode("medium rage available", NextAction::array(0, new NextAction("heroic strike", ACTION_HIGH + 10), nullptr))); // triggers.push_back(new TriggerNode("medium rage available", NextAction::array(0, new NextAction("heroic strike", ACTION_HIGH + 10), nullptr)));
triggers.push_back(new TriggerNode("berserker rage", NextAction::array(0, new NextAction("berserker rage", ACTION_HIGH + 2), nullptr))); triggers.push_back(new TriggerNode("berserker rage", NextAction::array(0, new NextAction("berserker rage", ACTION_HIGH + 2), nullptr)));
triggers.push_back(new TriggerNode("bloodrage", NextAction::array(0, new NextAction("bloodrage", ACTION_HIGH + 2), nullptr))); triggers.push_back(new TriggerNode("bloodrage", NextAction::array(0, new NextAction("bloodrage", ACTION_HIGH + 2), nullptr)));
triggers.push_back(new TriggerNode("death wish", NextAction::array(0, new NextAction("death wish", ACTION_HIGH + 2), nullptr))); triggers.push_back(new TriggerNode("death wish", NextAction::array(0, new NextAction("death wish", ACTION_HIGH + 2), nullptr)));
triggers.push_back(new TriggerNode("rampage", NextAction::array(0, new NextAction("rampage", ACTION_INTERRUPT + 1), nullptr))); triggers.push_back(new TriggerNode("rampage", NextAction::array(0, new NextAction("rampage", ACTION_INTERRUPT + 1), nullptr)));
triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("intimidating shout", ACTION_EMERGENCY), nullptr))); // triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("intimidating shout", ACTION_EMERGENCY), nullptr)));
// triggers.push_back(new TriggerNode(
// "slam",
// NextAction::array(0, new NextAction("slam", ACTION_HIGH + 2), NULL)));
triggers.push_back(new TriggerNode(
"high rage available",
NextAction::array(0, new NextAction("heroic strike", ACTION_HIGH + 1), NULL)));
} }

View File

@@ -41,7 +41,11 @@ TankWarriorStrategy::TankWarriorStrategy(PlayerbotAI* botAI) : GenericWarriorStr
NextAction** TankWarriorStrategy::getDefaultActions() NextAction** TankWarriorStrategy::getDefaultActions()
{ {
return NextAction::array(0, new NextAction("melee", ACTION_NORMAL), nullptr); return NextAction::array(0,
new NextAction("devastate", ACTION_NORMAL + 2),
new NextAction("revenge", ACTION_NORMAL + 1),
new NextAction("melee", ACTION_NORMAL),
NULL);
} }
void TankWarriorStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void TankWarriorStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)

View File

@@ -7,5 +7,6 @@
bool CastSunderArmorAction::isUseful() bool CastSunderArmorAction::isUseful()
{ {
return CastSpellAction::isUseful(); Aura *aura = botAI->GetAura("sunder armor", GetTarget(), false, true);
return !aura || aura->GetStackAmount() < 5 || aura->GetDuration() <= 3000;
} }

View File

@@ -94,6 +94,7 @@ class WarriorTriggerFactoryInternal : public NamedObjectContext<Trigger>
creators["intercept can cast"] = &WarriorTriggerFactoryInternal::intercept_can_cast; creators["intercept can cast"] = &WarriorTriggerFactoryInternal::intercept_can_cast;
creators["intercept and far enemy"] = &WarriorTriggerFactoryInternal::intercept_and_far_enemy; creators["intercept and far enemy"] = &WarriorTriggerFactoryInternal::intercept_and_far_enemy;
creators["intercept and rage"] = &WarriorTriggerFactoryInternal::intercept_and_rage; creators["intercept and rage"] = &WarriorTriggerFactoryInternal::intercept_and_rage;
// creators["slam"] = &WarriorTriggerFactoryInternal::slam;
} }
private: private:
@@ -142,6 +143,7 @@ class WarriorTriggerFactoryInternal : public NamedObjectContext<Trigger>
static Trigger* overpower(PlayerbotAI* botAI) { return new OverpowerAvailableTrigger(botAI); } static Trigger* overpower(PlayerbotAI* botAI) { return new OverpowerAvailableTrigger(botAI); }
static Trigger* revenge(PlayerbotAI* botAI) { return new RevengeAvailableTrigger(botAI); } static Trigger* revenge(PlayerbotAI* botAI) { return new RevengeAvailableTrigger(botAI); }
static Trigger* sunder_armor(PlayerbotAI* botAI) { return new SunderArmorDebuffTrigger(botAI); } static Trigger* sunder_armor(PlayerbotAI* botAI) { return new SunderArmorDebuffTrigger(botAI); }
// static Trigger* slam(PlayerbotAI* ai) { return new SlamTrigger(ai); }
}; };

View File

@@ -52,4 +52,10 @@ class RendDebuffTrigger : public DebuffTrigger
public: public:
RendDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "rend", 1, true) { } RendDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "rend", 1, true) { }
}; };
// class SlamTrigger : public HasAuraTrigger
// {
// public:
// SlamTrigger(PlayerbotAI* ai) : HasAuraTrigger(ai, "slam!") {}
// };
#endif #endif