naxxramas gluth

This commit is contained in:
Yunfan Li
2023-09-03 17:52:44 +08:00
parent 0be6cc11aa
commit bb1ea0c395
33 changed files with 410 additions and 310 deletions

View File

@@ -2,6 +2,7 @@
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version.
*/ */
#include "MotionMaster.h"
#include "MoveSpline.h" #include "MoveSpline.h"
#include "MoveSplineInit.h" #include "MoveSplineInit.h"
#include "ObjectGuid.h" #include "ObjectGuid.h"
@@ -31,6 +32,7 @@
#include "SharedDefines.h" #include "SharedDefines.h"
#include "SocialMgr.h" #include "SocialMgr.h"
#include "SpellAuraEffects.h" #include "SpellAuraEffects.h"
#include "Unit.h"
#include "UpdateTime.h" #include "UpdateTime.h"
#include "Vehicle.h" #include "Vehicle.h"
#include "GuildMgr.h" #include "GuildMgr.h"
@@ -210,6 +212,34 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal)
TellMaster("Logout cancelled!"); TellMaster("Logout cancelled!");
} }
} }
// if (bot->HasUnitMovementFlag(MOVEMENTFLAG_FALLING)) {
// bot->Say("Falling!", LANG_UNIVERSAL);
// }
// if (!bot->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) && bot->GetPositionZ() - bot->GetFloorZ() > 0.1f) {
// bot->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
// // bot->GetMotionMaster()->MoveFall();
// }
// if (bot->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) && bot->GetPositionZ() - bot->GetFloorZ() <= 0.1f) {
// bot->RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
// }
// else {
// bot->RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
// }
// bot->SendMovementFlagUpdate();
// bot->GetMotionMaster()->MoveFall();
// if (bot->HasUnitMovementFlag(MOVEMENTFLAG_FALLING)) {
// // bot->GetUnitMovementFlags();
// bot->Say("falling... flag: " + std::to_string(bot->GetUnitMovementFlags()), LANG_UNIVERSAL);
// }
// bot->SendMovementFlagUpdate();
// float x, y, z;
// bot->GetPosition(x, y, z);
// bot->UpdateGroundPositionZ(x, y, z);
// if (bot->GetPositionZ() - z > 0.1f) {
// }
// wake up if in combat // wake up if in combat
// if (bot->IsInCombat()) // if (bot->IsInCombat())
@@ -804,6 +834,11 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet)
// bot->Say(speak, LANG_UNIVERSAL); // bot->Say(speak, LANG_UNIVERSAL);
// bot->GetClosePoint(x, y, z, bot->GetObjectSize(), dist, bot->GetAngle(vcos, vsin)); // bot->GetClosePoint(x, y, z, bot->GetObjectSize(), dist, bot->GetAngle(vcos, vsin));
bot->GetMotionMaster()->MoveJump(x, y, z, horizontalSpeed, verticalSpeed, 0, bot->GetSelectedUnit()); bot->GetMotionMaster()->MoveJump(x, y, z, horizontalSpeed, verticalSpeed, 0, bot->GetSelectedUnit());
// bot->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
// bot->AddUnitMovementFlag(MOVEMENTFLAG_FORWARD);
// bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_PENDING_STOP);
// if (bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION))
// bot->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
// bot->GetMotionMaster()->MoveIdle(); // bot->GetMotionMaster()->MoveIdle();
// Position dest = bot->GetPosition(); // Position dest = bot->GetPosition();
// float moveTimeHalf = verticalSpeed / Movement::gravity; // float moveTimeHalf = verticalSpeed / Movement::gravity;
@@ -818,33 +853,30 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet)
// SetNextCheckDelay((uint32)((newdis / dis) * moveTimeHalf * 4 * IN_MILLISECONDS)); // SetNextCheckDelay((uint32)((newdis / dis) * moveTimeHalf * 4 * IN_MILLISECONDS));
// // add moveflags // // add moveflags
// bot->m_movementInfo.SetMovementFlags(MOVEMENTFLAG_FALLING);
// bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_FORWARD);
// bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_PENDING_STOP);
// if (bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION))
// bot->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
// // copy MovementInfo // // copy MovementInfo
// MovementInfo movementInfo = bot->m_movementInfo; // MovementInfo movementInfo = bot->m_movementInfo;
// // send ack // // send ack
// WorldPacket ack(CMSG_MOVE_KNOCK_BACK_ACK); // WorldPacket ack(CMSG_MOVE_KNOCK_BACK_ACK);
// movementInfo.jump.cosAngle = vcos; // // movementInfo.jump.cosAngle = vcos;
// movementInfo.jump.sinAngle = vsin; // // movementInfo.jump.sinAngle = vsin;
// movementInfo.jump.zspeed = -verticalSpeed; // // movementInfo.jump.zspeed = -verticalSpeed;
// movementInfo.jump.xyspeed = horizontalSpeed; // // movementInfo.jump.xyspeed = horizontalSpeed;
// ack << bot->GetGUID().WriteAsPacked(); // ack << bot->GetGUID().WriteAsPacked();
// bot->m_mover->BuildMovementPacket(&ack); // // bot->m_mover->BuildMovementPacket(&ack);
// ack << movementInfo.jump.sinAngle; // ack << (uint32)0;
// ack << movementInfo.jump.cosAngle; // bot->BuildMovementPacket(&ack);
// ack << movementInfo.jump.xyspeed; // // ack << movementInfo.jump.sinAngle;
// ack << movementInfo.jump.zspeed; // // ack << movementInfo.jump.cosAngle;
// // ack << movementInfo.jump.xyspeed;
// // ack << movementInfo.jump.zspeed;
// bot->GetSession()->HandleMoveKnockBackAck(ack); // bot->GetSession()->HandleMoveKnockBackAck(ack);
// // set jump destination for MSG_LAND packet // // // set jump destination for MSG_LAND packet
// SetJumpDestination(Position(fx, fy, fz, bot->GetOrientation())); // SetJumpDestination(Position(x, y, z, bot->GetOrientation()));
//bot->SendHeartBeat(); // bot->Heart();
// */ // */
return; return;
@@ -1619,6 +1651,37 @@ bool PlayerbotAI::IsAssistTank(Player* player)
return IsTank(player) && !IsMainTank(player); return IsTank(player) && !IsMainTank(player);
} }
bool PlayerbotAI::IsAssistTankOfIndex(Player* player, int index)
{
Group* group = bot->GetGroup();
if (!group) {
return false;
}
Group::MemberSlotList const& slots = group->GetMemberSlots();
int counter = 0;
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) {
Player* member = ref->GetSource();
if (group->IsAssistant(member->GetGUID()) && IsAssistTank(member)) {
if (index == counter) {
return player == member;
}
counter++;
}
}
// not enough
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) {
Player* member = ref->GetSource();
if (!group->IsAssistant(member->GetGUID()) && IsAssistTank(member)) {
if (index == counter) {
return player == member;
}
counter++;
}
}
return false;
}
namespace acore namespace acore
{ {
class UnitByGuidInRangeCheck class UnitByGuidInRangeCheck
@@ -2876,8 +2939,8 @@ void PlayerbotAI::WaitForSpellCast(Spell* spell)
castTime = ceil(castTime); castTime = ceil(castTime);
uint32 globalCooldown = CalculateGlobalCooldown(spellInfo->Id); uint32 globalCooldown = CalculateGlobalCooldown(spellInfo->Id);
if (castTime < globalCooldown) // if (castTime < globalCooldown)
castTime = globalCooldown; // castTime = globalCooldown;
SetNextCheckDelay(castTime + sPlayerbotAIConfig->reactDelay); SetNextCheckDelay(castTime + sPlayerbotAIConfig->reactDelay);
} }

View File

@@ -325,7 +325,7 @@ class PlayerbotAI : public PlayerbotAIBase
bool ContainsStrategy(StrategyType type); bool ContainsStrategy(StrategyType type);
bool HasStrategy(std::string const name, BotState type); bool HasStrategy(std::string const name, BotState type);
BotState GetState() { return currentState; }; BotState GetState() { return currentState; };
void ResetStrategies(bool load = true); void ResetStrategies(bool load = false);
void ReInitCurrentEngine(); void ReInitCurrentEngine();
void Reset(bool full = false); void Reset(bool full = false);
bool IsTank(Player* player); bool IsTank(Player* player);
@@ -335,7 +335,6 @@ class PlayerbotAI : public PlayerbotAIBase
bool IsRangedDps(Player* player); bool IsRangedDps(Player* player);
bool IsMainTank(Player* player); bool IsMainTank(Player* player);
bool IsAssistTank(Player* player); bool IsAssistTank(Player* player);
bool IsAssistTankOfIndex(Player* player, int index); bool IsAssistTankOfIndex(Player* player, int index);
bool IsHealAssistantOfIndex(Player* player, int index); bool IsHealAssistantOfIndex(Player* player, int index);
bool IsRangedDpsAssistantOfIndex(Player* player, int index); bool IsRangedDpsAssistantOfIndex(Player* player, int index);

View File

@@ -407,7 +407,8 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
} }
else else
{ {
botAI->ResetStrategies(!sRandomPlayerbotMgr->IsRandomBot(bot)); // botAI->ResetStrategies(!sRandomPlayerbotMgr->IsRandomBot(bot));
botAI->ResetStrategies();
} }
if (master && !master->HasUnitState(UNIT_STATE_IN_FLIGHT)) if (master && !master->HasUnitState(UNIT_STATE_IN_FLIGHT))

View File

@@ -104,16 +104,17 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
if (Pet* pet = bot->GetPet()) if (Pet* pet = bot->GetPet())
{ {
pet->SetReactState(REACT_PASSIVE);
if (with_pet) { if (with_pet) {
pet->SetReactState(REACT_DEFENSIVE);
pet->SetTarget(target->GetGUID()); pet->SetTarget(target->GetGUID());
pet->GetCharmInfo()->SetIsCommandAttack(true); pet->GetCharmInfo()->SetIsCommandAttack(true);
pet->AI()->AttackStart(target); pet->AI()->AttackStart(target);
// pet->SetReactState(REACT_DEFENSIVE); // pet->SetReactState(REACT_DEFENSIVE);
} else { } else {
pet->SetReactState(REACT_PASSIVE);
pet->GetCharmInfo()->SetIsCommandFollow(true); pet->GetCharmInfo()->SetIsCommandFollow(true);
pet->GetCharmInfo()->IsReturning(); pet->GetCharmInfo()->IsReturning();
pet->GetMotionMaster()->MoveFollow(bot, PET_FOLLOW_DIST, pet->GetFollowAngle()); // pet->GetMotionMaster()->MoveFollow(bot, PET_FOLLOW_DIST, pet->GetFollowAngle());
} }
} }

View File

@@ -146,6 +146,7 @@ class CastGhoulFrenzyAction : public CastBuffSpellAction
{ {
public: public:
CastGhoulFrenzyAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "ghoul frenzy") { } CastGhoulFrenzyAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "ghoul frenzy") { }
std::string const GetTargetName() override { return "pet target"; }
}; };
BEGIN_MELEE_SPELL_ACTION(CastCorpseExplosionAction, "corpse explosion") BEGIN_MELEE_SPELL_ACTION(CastCorpseExplosionAction, "corpse explosion")

View File

@@ -63,23 +63,30 @@ class UnholyDKStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
} }
}; };
UnholyDKStrategy::UnholyDKStrategy(PlayerbotAI* botAI) : GenericDKStrategy(botAI)
{
actionNodeFactories.Add(new UnholyDKStrategyActionNodeFactory());
}
NextAction** UnholyDKStrategy::getDefaultActions() NextAction** UnholyDKStrategy::getDefaultActions()
{ {
return NextAction::array(0, return NextAction::array(0,
new NextAction("scourge strike", ACTION_NORMAL + 6), new NextAction("scourge strike", ACTION_NORMAL + 6),
new NextAction("blood strike", ACTION_NORMAL + 5), new NextAction("blood strike", ACTION_NORMAL + 5),
new NextAction("death coil", ACTION_NORMAL + 4), new NextAction("ghoul frenzy", ACTION_NORMAL + 4),
new NextAction("plague strike", ACTION_NORMAL + 3), new NextAction("death coil", ACTION_NORMAL + 3),
new NextAction("icy touch", ACTION_NORMAL + 2), new NextAction("plague strike", ACTION_NORMAL + 2),
new NextAction("icy touch", ACTION_NORMAL + 1),
new NextAction("melee", ACTION_NORMAL), new NextAction("melee", ACTION_NORMAL),
NULL); nullptr);
} }
void UnholyDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void UnholyDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
GenericDKStrategy::InitTriggers(triggers); GenericDKStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("ghoul frenzy", ACTION_NORMAL + 2), nullptr))); // triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction(, ACTION_NORMAL + 2), nullptr)));
triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("death pact", ACTION_EMERGENCY + 1), nullptr))); triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("death pact", ACTION_EMERGENCY + 1), nullptr)));
} }

View File

@@ -12,7 +12,7 @@ class PlayerbotAI;
class UnholyDKStrategy : public GenericDKStrategy class UnholyDKStrategy : public GenericDKStrategy
{ {
public: public:
UnholyDKStrategy(PlayerbotAI* botAI) : GenericDKStrategy(botAI) { } UnholyDKStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override; void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "unholy"; } std::string const getName() override { return "unholy"; }

View File

@@ -22,6 +22,7 @@ class BearTankDruidStrategyActionNodeFactory : public NamedObjectFactory<ActionN
creators["swipe"] = &swipe; creators["swipe"] = &swipe;
creators["lacerate"] = &lacerate; creators["lacerate"] = &lacerate;
creators["demoralizing roar"] = &demoralizing_roar; creators["demoralizing roar"] = &demoralizing_roar;
creators["taunt spell"] = &growl;
} }
private: private:

View File

@@ -115,7 +115,7 @@ void CasterDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
GenericDruidStrategy::InitTriggers(triggers); GenericDruidStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_MOVE), nullptr))); // triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_MOVE), nullptr)));
triggers.push_back(new TriggerNode("insect swarm", NextAction::array(0, new NextAction("insect swarm", ACTION_NORMAL + 5), nullptr))); triggers.push_back(new TriggerNode("insect swarm", NextAction::array(0, new NextAction("insect swarm", ACTION_NORMAL + 5), nullptr)));
triggers.push_back(new TriggerNode("moonfire", NextAction::array(0, new NextAction("moonfire", ACTION_NORMAL + 4), nullptr))); triggers.push_back(new TriggerNode("moonfire", NextAction::array(0, new NextAction("moonfire", ACTION_NORMAL + 4), nullptr)));
triggers.push_back(new TriggerNode("eclipse (solar)", NextAction::array(0, new NextAction("wrath", ACTION_NORMAL + 6), nullptr))); triggers.push_back(new TriggerNode("eclipse (solar)", NextAction::array(0, new NextAction("wrath", ACTION_NORMAL + 6), nullptr)));

View File

@@ -20,7 +20,7 @@ void HealDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
GenericDruidStrategy::InitTriggers(triggers); GenericDruidStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_NORMAL + 9), nullptr))); // triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_NORMAL + 9), nullptr)));
triggers.push_back(new TriggerNode("tree form", NextAction::array(0, new NextAction("tree form", ACTION_HIGH + 1), nullptr))); triggers.push_back(new TriggerNode("tree form", NextAction::array(0, new NextAction("tree form", ACTION_HIGH + 1), nullptr)));
triggers.push_back(new TriggerNode("party member to heal out of spell range", NextAction::array(0, new NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 9), nullptr))); triggers.push_back(new TriggerNode("party member to heal out of spell range", NextAction::array(0, new NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 9), nullptr)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(

View File

@@ -24,7 +24,7 @@ class CastAutoShotAction : public CastSpellAction
{ {
public: public:
CastAutoShotAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "auto shot") { } CastAutoShotAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "auto shot") { }
ActionThreatType getThreatType() override { return ActionThreatType::None; }
bool isUseful() override; bool isUseful() override;
}; };

View File

@@ -122,7 +122,7 @@ void GenericMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
CombatStrategy::InitTriggers(triggers); CombatStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_MOVE + 9), nullptr))); // triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_MOVE + 9), nullptr)));
triggers.push_back(new TriggerNode("enemy is close", NextAction::array(0, new NextAction("frost nova", 50.0f), nullptr))); triggers.push_back(new TriggerNode("enemy is close", NextAction::array(0, new NextAction("frost nova", 50.0f), nullptr)));
triggers.push_back(new TriggerNode("counterspell on enemy healer", NextAction::array(0, new NextAction("counterspell on enemy healer", 40.0f), nullptr))); triggers.push_back(new TriggerNode("counterspell on enemy healer", NextAction::array(0, new NextAction("counterspell on enemy healer", 40.0f), nullptr)));
triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("ice block", 80.0f), nullptr))); triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("ice block", 80.0f), nullptr)));

View File

@@ -15,6 +15,7 @@ class TankPaladinStrategyActionNodeFactory : public NamedObjectFactory<ActionNod
creators["seal of vengeance"] = &seal_of_vengeance; creators["seal of vengeance"] = &seal_of_vengeance;
creators["seal of command"] = &seal_of_command; creators["seal of command"] = &seal_of_command;
creators["hand of reckoning"] = &hand_of_reckoning; creators["hand of reckoning"] = &hand_of_reckoning;
creators["taunt spell"] = &hand_of_reckoning;
} }
private: private:

View File

@@ -7,7 +7,7 @@
#include "HealPriestStrategy.h" #include "HealPriestStrategy.h"
#include "Playerbots.h" #include "Playerbots.h"
GenericPriestStrategy::GenericPriestStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) GenericPriestStrategy::GenericPriestStrategy(PlayerbotAI* botAI) : RangedCombatStrategy(botAI)
{ {
actionNodeFactories.Add(new GenericPriestStrategyActionNodeFactory()); actionNodeFactories.Add(new GenericPriestStrategyActionNodeFactory());
} }

View File

@@ -6,10 +6,11 @@
#define _PLAYERBOT_GENERICPRIESTSTRATEGY_H #define _PLAYERBOT_GENERICPRIESTSTRATEGY_H
#include "CombatStrategy.h" #include "CombatStrategy.h"
#include "RangedCombatStrategy.h"
class PlayerbotAI; class PlayerbotAI;
class GenericPriestStrategy : public CombatStrategy class GenericPriestStrategy : public RangedCombatStrategy
{ {
public: public:
GenericPriestStrategy(PlayerbotAI* botAI); GenericPriestStrategy(PlayerbotAI* botAI);

View File

@@ -20,9 +20,9 @@ void HealPriestStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
GenericPriestStrategy::InitTriggers(triggers); GenericPriestStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode( // triggers.push_back(new TriggerNode(
"enemy out of spell", // "enemy out of spell",
NextAction::array(0, new NextAction("reach spell", ACTION_NORMAL + 9), NULL))); // NextAction::array(0, new NextAction("reach spell", ACTION_NORMAL + 9), NULL)));
// triggers.push_back(new TriggerNode( // triggers.push_back(new TriggerNode(
// "medium aoe heal", // "medium aoe heal",

View File

@@ -25,7 +25,7 @@ void ShadowPriestStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
GenericPriestStrategy::InitTriggers(triggers); GenericPriestStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_MOVE + 9), nullptr))); // triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_MOVE + 9), nullptr)));
triggers.push_back(new TriggerNode("shadowform", NextAction::array(0, new NextAction("shadowform", ACTION_HIGH), nullptr))); triggers.push_back(new TriggerNode("shadowform", NextAction::array(0, new NextAction("shadowform", ACTION_HIGH), nullptr)));
//triggers.push_back(new TriggerNode("low mana", NextAction::array(0, new NextAction("dispersion", ACTION_EMERGENCY + 5), nullptr))); //triggers.push_back(new TriggerNode("low mana", NextAction::array(0, new NextAction("dispersion", ACTION_EMERGENCY + 5), nullptr)));
triggers.push_back(new TriggerNode("vampiric embrace", NextAction::array(0, new NextAction("vampiric embrace", 16.0f), nullptr))); triggers.push_back(new TriggerNode("vampiric embrace", NextAction::array(0, new NextAction("vampiric embrace", 16.0f), nullptr)));

View File

@@ -42,9 +42,9 @@ class RaidNaxxActionContext : public NamedObjectContext<Action>
creators["anub'rekhan choose target"] = &RaidNaxxActionContext::anubrekhan_choose_target; creators["anub'rekhan choose target"] = &RaidNaxxActionContext::anubrekhan_choose_target;
creators["anub'rekhan position"] = &RaidNaxxActionContext::anubrekhan_position; creators["anub'rekhan position"] = &RaidNaxxActionContext::anubrekhan_position;
// creators["gluth choose target"] = &RaidNaxxActionContext::gluth_choose_target; creators["gluth choose target"] = &RaidNaxxActionContext::gluth_choose_target;
// creators["gluth position"] = &RaidNaxxActionContext::gluth_position; creators["gluth position"] = &RaidNaxxActionContext::gluth_position;
// creators["gluth slowdown"] = &RaidNaxxActionContext::gluth_slowdown; creators["gluth slowdown"] = &RaidNaxxActionContext::gluth_slowdown;
// creators["loatheb position"] = &RaidNaxxActionContext::loatheb_position; // creators["loatheb position"] = &RaidNaxxActionContext::loatheb_position;
// creators["loatheb choose target"] = &RaidNaxxActionContext::loatheb_choose_target; // creators["loatheb choose target"] = &RaidNaxxActionContext::loatheb_choose_target;
@@ -72,9 +72,9 @@ class RaidNaxxActionContext : public NamedObjectContext<Action>
static Action* kelthuzad_position(PlayerbotAI* ai) { return new KelthuzadPositionAction(ai); } static Action* kelthuzad_position(PlayerbotAI* ai) { return new KelthuzadPositionAction(ai); }
static Action* anubrekhan_choose_target(PlayerbotAI* ai) { return new AnubrekhanChooseTargetAction(ai); } static Action* anubrekhan_choose_target(PlayerbotAI* ai) { return new AnubrekhanChooseTargetAction(ai); }
static Action* anubrekhan_position(PlayerbotAI* ai) { return new AnubrekhanPositionAction(ai); } static Action* anubrekhan_position(PlayerbotAI* ai) { return new AnubrekhanPositionAction(ai); }
// static Action* gluth_choose_target(PlayerbotAI* ai) { return new GluthChooseTargetAction(ai); } static Action* gluth_choose_target(PlayerbotAI* ai) { return new GluthChooseTargetAction(ai); }
// static Action* gluth_position(PlayerbotAI* ai) { return new GluthPositionAction(ai); } static Action* gluth_position(PlayerbotAI* ai) { return new GluthPositionAction(ai); }
// static Action* gluth_slowdown(PlayerbotAI* ai) { return new GluthSlowdownAction(ai); } static Action* gluth_slowdown(PlayerbotAI* ai) { return new GluthSlowdownAction(ai); }
// static Action* loatheb_position(PlayerbotAI* ai) { return new LoathebPositionAction(ai); } // static Action* loatheb_position(PlayerbotAI* ai) { return new LoathebPositionAction(ai); }
// static Action* loatheb_choose_target(PlayerbotAI* ai) { return new LoathebChooseTargetAction(ai); } // static Action* loatheb_choose_target(PlayerbotAI* ai) { return new LoathebChooseTargetAction(ai); }
}; };

View File

@@ -1,5 +1,6 @@
#include "ObjectGuid.h" #include "ObjectGuid.h"
#include "PlayerbotAIConfig.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "RaidNaxxActions.h" #include "RaidNaxxActions.h"
#include "RaidNaxxStrategy.h" #include "RaidNaxxStrategy.h"
@@ -838,11 +839,11 @@ bool AnubrekhanPositionAction::Execute(Event event)
uint32 locust = eventMap->GetNextEventTime(2); uint32 locust = eventMap->GetNextEventTime(2);
uint32 timer = eventMap->GetTimer(); uint32 timer = eventMap->GetTimer();
bool inPhase = botAI->HasAura("locust swarm", boss) || boss->GetCurrentSpell(CURRENT_GENERIC_SPELL); bool inPhase = botAI->HasAura("locust swarm", boss) || boss->GetCurrentSpell(CURRENT_GENERIC_SPELL);
if (inPhase || (locust && locust - timer <= 5000)) { if (inPhase || (locust && locust - timer <= 8000)) {
if (botAI->IsMainTank(bot)) { if (botAI->IsMainTank(bot)) {
uint32 nearest = FindNearestWaypoint(); uint32 nearest = FindNearestWaypoint();
uint32 next_point; uint32 next_point;
if (inPhase) { if (inPhase || (locust && locust - timer <= 3000)) {
next_point = (nearest + 1) % intervals; next_point = (nearest + 1) % intervals;
} else { } else {
next_point = nearest; next_point = nearest;
@@ -855,147 +856,140 @@ bool AnubrekhanPositionAction::Execute(Event event)
return false; return false;
} }
// bool GluthChooseTargetAction::Execute(Event event) bool GluthChooseTargetAction::Execute(Event event)
// { {
// Unit* boss = AI_VALUE2(Unit*, "find target", "gluth"); if (!helper.UpdateBossAI()) {
// if (!boss) { return false;
// return false; }
// } GuidVector attackers = context->GetValue<GuidVector>("possible targets")->Get();
// BossAI* boss_ai = dynamic_cast<BossAI*>(boss->GetAI()); Unit* target = nullptr;
// EventMap* eventMap = boss_botAI->GetEvents(); Unit *target_boss = nullptr;
// list<ObjectGuid> attackers = context->GetValue<list<ObjectGuid> >("attackers")->Get(); std::vector<Unit*> target_zombies;
// Unit* target = nullptr; for (GuidVector::iterator i = attackers.begin(); i != attackers.end(); ++i)
// Unit *target_boss = nullptr; {
// vector<Unit*> target_zombies; Unit* unit = botAI->GetUnit(*i);
// for (list<ObjectGuid>::iterator i = attackers.begin(); i != attackers.end(); ++i) if (!unit)
// { continue;
// Unit* unit = botAI->GetUnit(*i); if (!unit->IsAlive()) {
// if (!unit) continue;
// continue; }
// if (!unit->IsAlive()) { if (botAI->EqualLowercaseName(unit->GetName(), "zombie chow")) {
// continue; target_zombies.push_back(unit);
// } }
// if (botAI->EqualLowercaseName(unit->GetName(), "zombie chow")) { if (botAI->EqualLowercaseName(unit->GetName(), "gluth")) {
// target_zombies.push_back(unit); target_boss = unit;
// } }
// if (botAI->EqualLowercaseName(unit->GetName(), "gluth")) { }
// target_boss = unit; if (botAI->IsMainTank(bot) || botAI->IsAssistTankOfIndex(bot, 0)) {
// } target = target_boss;
// } } else if (botAI->IsAssistTankOfIndex(bot, 1)) {
// if (botAI->IsMainTank(bot) || botAI->IsAssistTankOfIndex(bot, 0)) { for (Unit* t : target_zombies) {
// target = target_boss; if (t->GetHealthPct() > helper.decimatedZombiePct && t->GetVictim() != bot && t->GetDistance2d(bot) <= 10.0f) {
// } else if (botAI->IsAssistTankOfIndex(bot, 1)) { if (!target || t->GetDistance2d(bot) < target->GetDistance2d(bot)) {
// for (Unit* t : target_zombies) { target = t;
// if (t->GetHealthPct() > 10.0f && t->GetVictim() != bot && t->GetDistance2d(bot) <= 10.0f) { }
// target = t; }
// break; }
// } } else if (botAI->GetClassIndex(bot, CLASS_HUNTER) == 0 || botAI->GetClassIndex(bot, CLASS_HUNTER) == 1) {
// } // prevent zombie go straight to gluth
// } else { for (Unit* t : target_zombies) {
// for (Unit* t : target_zombies) { if (t->GetHealthPct() > helper.decimatedZombiePct && t->GetVictim() == target_boss && t->GetDistance2d(bot) <= sPlayerbotAIConfig->spellDistance) {
// if (t->GetHealthPct() <= 10.0f) { if (!target || t->GetDistance2d(bot) < target->GetDistance2d(bot)) {
// if (target == nullptr || target->GetDistance2d(3331.48f, -3109.06f) > t->GetDistance2d(3331.48f, -3109.06f)) { target = t;
// target = t; }
// } }
// } }
// } if (!target) {
// if (target == nullptr) { target = target_boss;
// target = target_boss; }
// } } else {
// } for (Unit* t : target_zombies) {
// if (!target || context->GetValue<Unit*>("current target")->Get() == target) { if (t->GetHealthPct() <= helper.decimatedZombiePct) {
// return false; if (target == nullptr ||
// } target->GetDistance2d(helper.mainTankPos25.first, helper.mainTankPos25.second) >
// return Attack(target); t->GetDistance2d(helper.mainTankPos25.first, helper.mainTankPos25.second)) {
// } target = t;
}
}
}
if (target == nullptr) {
target = target_boss;
}
}
if (!target || context->GetValue<Unit*>("current target")->Get() == target) {
return false;
}
if (target_boss && target == target_boss)
return Attack(target, true);
return Attack(target, false);
// return Attack(target);
}
// bool GluthPositionAction::Execute(Event event) bool GluthPositionAction::Execute(Event event)
// { {
// Unit* boss = AI_VALUE2(Unit*, "find target", "gluth"); if (!helper.UpdateBossAI()) {
// if (!boss) { return false;
// return false; }
// } bool raid25 = bot->GetRaidDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL;
// BossAI* b_ai = dynamic_cast<BossAI*>(boss->GetAI()); if (botAI->IsMainTank(bot) || botAI->IsAssistTankOfIndex(bot, 0)) {
// if (!b_ai) { if (AI_VALUE2(bool, "has aggro", "boss target")) {
// return false; if (raid25) {
// } return MoveTo(NAXX_MAP_ID, helper.mainTankPos25.first, helper.mainTankPos25.second, bot->GetPositionZ());
// EventMap *eventMap = b_botAI->GetEvents(); } else {
// uint8 phase_mask = eventMap->GetPhaseMask(); return MoveTo(NAXX_MAP_ID, helper.mainTankPos10.first, helper.mainTankPos10.second, bot->GetPositionZ());
// uint32 timer = eventMap->GetTimer(); }
// uint32 decimate = eventMap->GetNextEventTime(3); }
// bool raid25 = bot->GetRaidDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL; } else if (botAI->IsAssistTankOfIndex(bot, 1)) {
// if (botAI->IsMainTank(bot) || botAI->IsAssistTankOfIndex(bot, 0)) { if (helper.BeforeDecimate()) {
// if (AI_VALUE2(bool, "has aggro", "boss target")) { return MoveTo(bot->GetMapId(), helper.beforeDecimatePos.first, helper.beforeDecimatePos.second, bot->GetPositionZ());
// if (raid25) { } else {
// return MoveTo(533, 3331.48f, -3109.06f, bot->GetPositionZ()); if (AI_VALUE2(bool, "has aggro", "current target")) {
// } else { uint32 nearest = FindNearestWaypoint();
// return MoveTo(533, 3278.29f, -3162.06f, bot->GetPositionZ()); uint32 next_point = (nearest + 1) % intervals;
// } return MoveTo(bot->GetMapId(), waypoints[next_point].first, waypoints[next_point].second, bot->GetPositionZ());
// // return MoveTo(533, 3322.52f, -3117.11f, bot->GetPositionZ()); }
// // return MoveTo(533, 3285.15f, -3167.02f, bot->GetPositionZ()); }
// } } else if (botAI->IsRangedDps(bot)) {
// } else if (botAI->IsAssistTankOfIndex(bot, 1)) { if (raid25) {
// if (decimate && decimate - timer <= 3000) { if (botAI->GetClassIndex(bot, CLASS_HUNTER) == 0) {
// return MoveTo(bot->GetMapId(), 3267.34f, -3175.68f, bot->GetPositionZ()); return MoveInside(NAXX_MAP_ID, helper.leftSlowDownPos.first, helper.leftSlowDownPos.second, bot->GetPositionZ(), 0.0f);
// } else { }
// if (AI_VALUE2(bool, "has aggro", "current target")) { if (botAI->GetClassIndex(bot, CLASS_HUNTER) == 1) {
// uint32 nearest = FindNearestWaypoint(); return MoveInside(NAXX_MAP_ID, helper.rightSlowDownPos.first, helper.rightSlowDownPos.second, bot->GetPositionZ(), 0.0f);
// uint32 next_point = (nearest + 1) % intervals; }
// return MoveTo(bot->GetMapId(), waypoints[next_point].first, waypoints[next_point].second, bot->GetPositionZ()); }
// } return MoveInside(NAXX_MAP_ID, helper.rangedPos.first, helper.rangedPos.second, bot->GetPositionZ(), 3.0f);
// } } else if (botAI->IsHeal(bot)) {
// } else if (botAI->IsRangedDps(bot)) { return MoveInside(NAXX_MAP_ID, helper.healPos.first, helper.healPos.second, bot->GetPositionZ(), 0.0f);
// if (raid25) { }
// if (botAI->GetClassIndex(bot, CLASS_HUNTER) == 0) { return false;
// // return MoveInside(533, 3301.14f, -3155.33f, bot->GetPositionZ(), 0.0f); }
// return MoveInside(533, 3290.68f, -3141.65f, bot->GetPositionZ(), 0.0f);
// }
// if (botAI->GetClassIndex(bot, CLASS_HUNTER) == 1) {
// // return MoveInside(533, 3286.66f, -3141.42f, bot->GetPositionZ(), 0.0f);
// return MoveInside(533, 3300.78f, -3151.98f, bot->GetPositionZ(), 0.0f);
// }
// }
// // return MoveInside(533, 3293.61f, -3149.01f, bot->GetPositionZ(), 10.0f);
// return MoveInside(533, 3301.45f, -3139.29f, bot->GetPositionZ(), 3.0f);
// } else if (botAI->IsHeal(bot)) {
// return MoveInside(533, 3303.09f, -3135.24f, bot->GetPositionZ(), 0.0f);
// }
// return false;
// }
// bool GluthSlowdownAction::Execute(Event event) bool GluthSlowdownAction::Execute(Event event)
// { {
// Unit* boss = AI_VALUE2(Unit*, "find target", "gluth"); if (!helper.UpdateBossAI()) {
// if (!boss) { return false;
// return false; }
// } bool raid25 = bot->GetRaidDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL;
// bool raid25 = bot->GetRaidDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL; if (!raid25) {
// if (!raid25) { return false;
// return false; }
// } if (helper.JustStartCombat()) {
// BossAI* b_ai = dynamic_cast<BossAI*>(boss->GetAI()); return false;
// if (!b_ai) { }
// return false; switch (bot->getClass())
// } {
// EventMap *eventMap = b_botAI->GetEvents(); case CLASS_HUNTER:
// uint8 phase_mask = eventMap->GetPhaseMask(); return botAI->CastSpell("frost trap", bot);
// uint32 timer = eventMap->GetTimer(); break;
// if (timer < 10000) { // case CLASS_MAGE:
// return false; // return botAI->CastSpell("frost nova", bot);
// } // break;
// switch (bot->getClass()) default:
// { break;
// case CLASS_HUNTER: }
// return botAI->CastSpell("frost trap", bot); return false;
// break; }
// // case CLASS_MAGE:
// // return botAI->CastSpell("frost nova", bot);
// // break;
// default:
// break;
// }
// return false;
// }
// bool LoathebPositionAction::Execute(Event event) // bool LoathebPositionAction::Execute(Event event)
// { // {

View File

@@ -217,38 +217,44 @@ class KelthuzadPositionAction : public MovementAction
class AnubrekhanChooseTargetAction : public AttackAction class AnubrekhanChooseTargetAction : public AttackAction
{ {
public: public:
AnubrekhanChooseTargetAction(PlayerbotAI* ai) : AttackAction(ai, "anub'rekhan choose target") {} AnubrekhanChooseTargetAction(PlayerbotAI* ai) : AttackAction(ai, "anub'rekhan choose target") {}
virtual bool Execute(Event event); bool Execute(Event event) override;
}; };
class AnubrekhanPositionAction : public RotateAroundTheCenterPointAction class AnubrekhanPositionAction : public RotateAroundTheCenterPointAction
{ {
public: public:
AnubrekhanPositionAction(PlayerbotAI* ai) : RotateAroundTheCenterPointAction(ai, "anub'rekhan position", 3272.49f, -3476.27f, 45.0f, 16) {} AnubrekhanPositionAction(PlayerbotAI* ai) : RotateAroundTheCenterPointAction(ai, "anub'rekhan position", 3272.49f, -3476.27f, 45.0f, 16) {}
virtual bool Execute(Event event); bool Execute(Event event) override;
}; };
// class GluthChooseTargetAction : public AttackAction class GluthChooseTargetAction : public AttackAction
// { {
// public: public:
// GluthChooseTargetAction(PlayerbotAI* ai) : AttackAction(ai, "gluth choose target") {} GluthChooseTargetAction(PlayerbotAI* ai) : AttackAction(ai, "gluth choose target"), helper(ai) {}
// virtual bool Execute(Event event); bool Execute(Event event) override;
// }; private:
GluthBossHelper helper;
};
// class GluthPositionAction : public RotateAroundTheCenterPointAction class GluthPositionAction : public RotateAroundTheCenterPointAction
// { {
// public: public:
// GluthPositionAction(PlayerbotAI* ai) : RotateAroundTheCenterPointAction(ai, "gluth position", 3293.61f, -3149.01f, 12.0f, 12) {} GluthPositionAction(PlayerbotAI* ai) : RotateAroundTheCenterPointAction(ai, "gluth position", 3293.61f, -3149.01f, 12.0f, 12), helper(ai) {}
// virtual bool Execute(Event event); bool Execute(Event event) override;
// }; private:
GluthBossHelper helper;
};
// class GluthSlowdownAction : public Action class GluthSlowdownAction : public Action
// { {
// public: public:
// GluthSlowdownAction(PlayerbotAI* ai) : Action(ai, "slowdown") {} GluthSlowdownAction(PlayerbotAI* ai) : Action(ai, "gluth slowdown"), helper(ai) {}
// virtual bool Execute(Event event); bool Execute(Event event) override;
// }; private:
GluthBossHelper helper;
};
// class LoathebPositionAction : public MovementAction // class LoathebPositionAction : public MovementAction
// { // {

View File

@@ -110,11 +110,6 @@ class SapphironBossHelper: public GenericBossHelper<boss_sapphiron::boss_sapphir
return !IsPhaseGround(); return !IsPhaseGround();
} }
bool JustLanded() { bool JustLanded() {
// if (event_map_->GetTimer() <= POSITION_TIME_AFTER_LANDED) {
// return true;
// }
// LOG_DEBUG("playerbots", "JustLanded lastEventGround: {}", lastEventGround);
// return timer_ >= lastEventGround && timer_ - lastEventGround <= POSITION_TIME_AFTER_LANDED;
return (event_map_->GetNextEventTime(EVENT_FLIGHT_START) - timer_) >= EVENT_FLIGHT_INTERVAL - POSITION_TIME_AFTER_LANDED; return (event_map_->GetNextEventTime(EVENT_FLIGHT_START) - timer_) >= EVENT_FLIGHT_INTERVAL - POSITION_TIME_AFTER_LANDED;
} }
bool WaitForExplosion() { bool WaitForExplosion() {
@@ -162,7 +157,27 @@ class SapphironBossHelper: public GenericBossHelper<boss_sapphiron::boss_sapphir
const uint32 POSITION_TIME_AFTER_LANDED = 5000; const uint32 POSITION_TIME_AFTER_LANDED = 5000;
const uint32 EVENT_FLIGHT_INTERVAL = 45000; const uint32 EVENT_FLIGHT_INTERVAL = 45000;
uint32 lastEventGround = 0; uint32 lastEventGround = 0;
};
class GluthBossHelper: public GenericBossHelper<boss_gluth::boss_gluthAI> {
public:
const std::pair<float, float> mainTankPos25 = {3331.48f, -3109.06f};
const std::pair<float, float> mainTankPos10 = {3278.29f, -3162.06f};
const std::pair<float, float> beforeDecimatePos = {3267.34f, -3175.68f};
const std::pair<float, float> leftSlowDownPos = {3290.68f, -3141.65f};
const std::pair<float, float> rightSlowDownPos = {3300.78f, -3151.98f};
const std::pair<float, float> rangedPos = {3301.45f, -3139.29f};
const std::pair<float, float> healPos = {3303.09f, -3135.24f};
const float decimatedZombiePct = 10.0f;
GluthBossHelper(PlayerbotAI *botAI): GenericBossHelper(botAI, "gluth") {}
bool BeforeDecimate() {
uint32 decimate = event_map_->GetNextEventTime(GLUTH_EVENT_DECIMATE);
return decimate && decimate - timer_ <= 3000;
}
bool JustStartCombat() {
return timer_ < 10000;
}
}; };
#endif #endif

View File

@@ -244,30 +244,29 @@ float AnubrekhanGenericMultiplier::GetValue(Action* action)
// return 1.0f; // return 1.0f;
// } // }
// float GluthGenericMultiplier::GetValue(Action* action) float GluthGenericMultiplier::GetValue(Action* action)
// { {
// Unit* boss = AI_VALUE2(Unit*, "find target", "gluth"); if (!helper.UpdateBossAI()) {
// if (!boss) { return 1.0f;
// return 1.0f; }
// } if ((dynamic_cast<DpsAssistAction*>(action) ||
// if ((dynamic_cast<DpsAssistAction*>(action) || dynamic_cast<TankAssistAction*>(action) ||
// dynamic_cast<TankAssistAction*>(action) || dynamic_cast<FleeAction*>(action) ||
// dynamic_cast<FleeAction*>(action) || dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) ||
// dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) || dynamic_cast<CastStarfallAction*>(action))) {
// dynamic_cast<CastStarfallAction*>(action))) { return 0.0f;
// return 0.0f; }
// }
// if (botAI->IsMainTank(bot)) { if (botAI->IsMainTank(bot)) {
// Aura* aura = botAI->GetAuraWithDuration("mortal wound", bot); Aura* aura = botAI->GetAura("mortal wound", bot, false, true);
// if (aura && aura->GetStackAmount() >= 5) { if (aura && aura->GetStackAmount() >= 5) {
// if (dynamic_cast<CastTauntAction*>(action) || if (dynamic_cast<CastTauntAction*>(action) ||
// dynamic_cast<CastDarkCommandAction*>(action) || dynamic_cast<CastDarkCommandAction*>(action) ||
// dynamic_cast<CastHandOfReckoningAction*>(action) || dynamic_cast<CastHandOfReckoningAction*>(action) ||
// dynamic_cast<CastGrowlAction*>(action)) { dynamic_cast<CastGrowlAction*>(action)) {
// return 0.0f; return 0.0f;
// } }
// } }
// } }
// return 1.0f; return 1.0f;
// } }

View File

@@ -87,13 +87,13 @@ public:
// virtual float GetValue(Action* action); // virtual float GetValue(Action* action);
// }; // };
// class GluthGenericMultiplier : public Multiplier class GluthGenericMultiplier : public Multiplier
// { {
// public: public:
// GluthGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "gluth generic") {} GluthGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "gluth generic"), helper(ai) {}
float GetValue(Action* action) override;
// public: private:
// virtual float GetValue(Action* action); GluthBossHelper helper;
// }; };
#endif #endif

View File

@@ -98,21 +98,19 @@ void RaidNaxxStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
// "sapphiron chill", // "sapphiron chill",
// NextAction::array(0, new NextAction("sapphiron avoid chill", ACTION_RAID + 1), NULL))); // NextAction::array(0, new NextAction("sapphiron avoid chill", ACTION_RAID + 1), NULL)));
// Gluth
triggers.push_back(new TriggerNode(
"gluth",
NextAction::array(0,
new NextAction("gluth choose target", ACTION_RAID + 1),
new NextAction("gluth position", ACTION_RAID + 1),
new NextAction("gluth slowdown", ACTION_RAID),
NULL)));
triggers.push_back(new TriggerNode(
// // Gluth "gluth main tank mortal wound",
// triggers.push_back(new TriggerNode( NextAction::array(0,
// "gluth", new NextAction("taunt spell", ACTION_RAID + 1), NULL)));
// NextAction::array(0,
// new NextAction("gluth choose target", ACTION_RAID + 1),
// new NextAction("gluth position", ACTION_RAID + 1),
// new NextAction("gluth slowdown", ACTION_RAID),
// NULL)));
// triggers.push_back(new TriggerNode(
// "gluth main tank mortal wound",
// NextAction::array(0,
// new NextAction("taunt spell", ACTION_RAID + 1), NULL)));
// // Loatheb // // Loatheb
// triggers.push_back(new TriggerNode( // triggers.push_back(new TriggerNode(
@@ -126,13 +124,13 @@ void RaidNaxxStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
void RaidNaxxStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers) void RaidNaxxStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers)
{ {
multipliers.push_back(new HeiganDanceMultiplier(botAI)); multipliers.push_back(new HeiganDanceMultiplier(botAI));
// multipliers.push_back(new LoathebGenericMultiplier(ai)); // multipliers.push_back(new LoathebGenericMultiplier(botAI));
// multipliers.push_back(new ThaddiusGenericMultiplier(ai)); // multipliers.push_back(new ThaddiusGenericMultiplier(botAI));
multipliers.push_back(new SapphironGenericMultiplier(botAI)); multipliers.push_back(new SapphironGenericMultiplier(botAI));
multipliers.push_back(new InstructorRazuviousGenericMultiplier(botAI)); multipliers.push_back(new InstructorRazuviousGenericMultiplier(botAI));
multipliers.push_back(new KelthuzadGenericMultiplier(botAI)); multipliers.push_back(new KelthuzadGenericMultiplier(botAI));
multipliers.push_back(new AnubrekhanGenericMultiplier(botAI)); multipliers.push_back(new AnubrekhanGenericMultiplier(botAI));
// multipliers.push_back(new FourhorsemanGenericMultiplier(ai)); // multipliers.push_back(new FourhorsemanGenericMultiplier(botAI));
// multipliers.push_back(new GothikGenericMultiplier(ai)); // multipliers.push_back(new GothikGenericMultiplier(botAI));
// multipliers.push_back(new GluthGenericMultiplier(ai)); multipliers.push_back(new GluthGenericMultiplier(botAI));
} }

View File

@@ -39,8 +39,8 @@ class RaidNaxxTriggerContext : public NamedObjectContext<Trigger>
creators["anub'rekhan"] = &RaidNaxxTriggerContext::anubrekhan; creators["anub'rekhan"] = &RaidNaxxTriggerContext::anubrekhan;
// creators["gluth"] = &RaidNaxxTriggerContext::gluth; creators["gluth"] = &RaidNaxxTriggerContext::gluth;
// creators["gluth main tank mortal wound"] = &RaidNaxxTriggerContext::gluth_main_tank_mortal_wound; creators["gluth main tank mortal wound"] = &RaidNaxxTriggerContext::gluth_main_tank_mortal_wound;
// creators["loatheb"] = &RaidNaxxTriggerContext::loatheb; // creators["loatheb"] = &RaidNaxxTriggerContext::loatheb;
} }
@@ -66,8 +66,8 @@ class RaidNaxxTriggerContext : public NamedObjectContext<Trigger>
static Trigger* kelthuzad(PlayerbotAI* ai) { return new KelthuzadTrigger(ai); } static Trigger* kelthuzad(PlayerbotAI* ai) { return new KelthuzadTrigger(ai); }
// static Trigger* kelthuzad_phase_two(PlayerbotAI* ai) { return new KelthuzadPhaseTwoTrigger(ai); } // static Trigger* kelthuzad_phase_two(PlayerbotAI* ai) { return new KelthuzadPhaseTwoTrigger(ai); }
static Trigger* anubrekhan(PlayerbotAI* ai) { return new AnubrekhanTrigger(ai); } static Trigger* anubrekhan(PlayerbotAI* ai) { return new AnubrekhanTrigger(ai); }
// static Trigger* gluth(PlayerbotAI* ai) { return new GluthTrigger(ai); } static Trigger* gluth(PlayerbotAI* ai) { return new GluthTrigger(ai); }
// static Trigger* gluth_main_tank_mortal_wound(PlayerbotAI* ai) { return new GluthMainTankMortalWoundTrigger(ai); } static Trigger* gluth_main_tank_mortal_wound(PlayerbotAI* ai) { return new GluthMainTankMortalWoundTrigger(ai); }
// static Trigger* loatheb(PlayerbotAI* ai) { return new LoathebTrigger(ai); } // static Trigger* loatheb(PlayerbotAI* ai) { return new LoathebTrigger(ai); }
}; };

View File

@@ -158,27 +158,32 @@ bool SapphironFlightTrigger::IsActive()
// return BossPhaseTrigger::IsActive() && !botAI->IsMainTank(bot) && botAI->HasAura("chill", bot); // return BossPhaseTrigger::IsActive() && !botAI->IsMainTank(bot) && botAI->HasAura("chill", bot);
// } // }
// bool GluthMainTankMortalWoundTrigger::IsActive() bool GluthTrigger::IsActive()
// { {
// if (!BossPhaseTrigger::IsActive()) { return helper.UpdateBossAI();
// return false; }
// }
// if (!botAI->IsAssistTankOfIndex(bot, 0)) {
// return false;
// }
// Unit* mt = AI_VALUE(Unit*, "main tank");
// if (!mt) {
// return false;
// }
// Aura* aura = botAI->GetAuraWithDuration("mortal wound", mt);
// if (!aura || aura->GetStackAmount() < 5) {
// return false;
// }
// // bot->Yell("Time to taunt!", LANG_UNIVERSAL);
// return true;
// }
bool KelthuzadTrigger::IsActive() { bool GluthMainTankMortalWoundTrigger::IsActive()
{
if (!helper.UpdateBossAI()) {
return false;
}
if (!botAI->IsAssistTankOfIndex(bot, 0)) {
return false;
}
Unit* mt = AI_VALUE(Unit*, "main tank");
if (!mt) {
return false;
}
Aura* aura = botAI->GetAura("mortal wound", mt, false, true);
if (!aura || aura->GetStackAmount() < 5) {
return false;
}
return true;
}
bool KelthuzadTrigger::IsActive()
{
return helper.UpdateBossAI(); return helper.UpdateBossAI();
} }

View File

@@ -197,18 +197,23 @@ class SapphironFlightTrigger : public Trigger
// KelthuzadPhaseTwoTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "kel'thuzad", 1 << (2 - 1), "kel'thuzad trigger") {} // KelthuzadPhaseTwoTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "kel'thuzad", 1 << (2 - 1), "kel'thuzad trigger") {}
// }; // };
// class GluthTrigger : public BossPhaseTrigger class GluthTrigger : public Trigger
// { {
// public: public:
// GluthTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "gluth", 0, "gluth trigger") {} GluthTrigger(PlayerbotAI* ai) : Trigger(ai, "gluth trigger"), helper(ai) {}
// }; bool IsActive() override;
private:
GluthBossHelper helper;
};
// class GluthMainTankMortalWoundTrigger : public BossPhaseTrigger class GluthMainTankMortalWoundTrigger : public Trigger
// { {
// public: public:
// GluthMainTankMortalWoundTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "gluth", 0, "gluth main tank mortal wound trigger") {} GluthMainTankMortalWoundTrigger(PlayerbotAI* ai) : Trigger(ai, "gluth main tank mortal wound trigger"), helper(ai) {}
// virtual bool IsActive(); bool IsActive() override;
// }; private:
GluthBossHelper helper;
};
// class LoathebTrigger : public BossPhaseTrigger // class LoathebTrigger : public BossPhaseTrigger
// { // {

View File

@@ -48,7 +48,7 @@ void CasterShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
GenericShamanStrategy::InitTriggers(triggers); GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_NORMAL + 9), nullptr))); // triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_NORMAL + 9), nullptr)));
triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new NextAction("flametongue weapon", 23.0f), nullptr))); triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new NextAction("flametongue weapon", 23.0f), nullptr)));
// triggers.push_back(new TriggerNode("searing totem", NextAction::array(0, new NextAction("searing totem", 19.0f), nullptr))); // triggers.push_back(new TriggerNode("searing totem", NextAction::array(0, new NextAction("searing totem", 19.0f), nullptr)));
triggers.push_back(new TriggerNode("flame shock", NextAction::array(0, new NextAction("flame shock", 20.0f), nullptr))); triggers.push_back(new TriggerNode("flame shock", NextAction::array(0, new NextAction("flame shock", 20.0f), nullptr)));

View File

@@ -41,7 +41,7 @@ void HealShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
GenericShamanStrategy::InitTriggers(triggers); GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_NORMAL + 9), nullptr))); // triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_NORMAL + 9), nullptr)));
triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new NextAction("earthliving weapon", 22.0f), nullptr))); triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new NextAction("earthliving weapon", 22.0f), nullptr)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
"group heal occasion", "group heal occasion",

View File

@@ -15,7 +15,7 @@ class NearestUnitsValue : public ObjectGuidListCalculatedValue
{ {
public: public:
NearestUnitsValue(PlayerbotAI* botAI, std::string const name = "nearest units", float range = sPlayerbotAIConfig->sightDistance, bool ignoreLos = false) : NearestUnitsValue(PlayerbotAI* botAI, std::string const name = "nearest units", float range = sPlayerbotAIConfig->sightDistance, bool ignoreLos = false) :
ObjectGuidListCalculatedValue(botAI, name, 2 * 1000), range(range), ignoreLos(ignoreLos) { } ObjectGuidListCalculatedValue(botAI, name, 1 * 1000), range(range), ignoreLos(ignoreLos) { }
GuidVector Calculate() override; GuidVector Calculate() override;

View File

@@ -6,6 +6,7 @@
#define _PLAYERBOT_DPSWARLOCKSTRATEGY_H #define _PLAYERBOT_DPSWARLOCKSTRATEGY_H
#include "GenericWarlockStrategy.h" #include "GenericWarlockStrategy.h"
#include "Strategy.h"
class PlayerbotAI; class PlayerbotAI;
@@ -17,6 +18,7 @@ class DpsWarlockStrategy : public GenericWarlockStrategy
std::string const getName() override { return "dps"; } std::string const getName() override { return "dps"; }
void InitTriggers(std::vector<TriggerNode*>& triggers) override; void InitTriggers(std::vector<TriggerNode*>& triggers) override;
NextAction** getDefaultActions() override; NextAction** getDefaultActions() override;
uint32 GetType() const override { return GenericWarlockStrategy::GetType() | STRATEGY_TYPE_DPS; }
}; };
class DpsAoeWarlockStrategy : public CombatStrategy class DpsAoeWarlockStrategy : public CombatStrategy

View File

@@ -57,7 +57,7 @@ void FuryWarriorStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
triggers.push_back(new TriggerNode("pummel on enemy healer", NextAction::array(0, new NextAction("pummel on enemy healer", ACTION_INTERRUPT), nullptr))); triggers.push_back(new TriggerNode("pummel on enemy healer", NextAction::array(0, new NextAction("pummel on enemy healer", ACTION_INTERRUPT), nullptr)));
triggers.push_back(new TriggerNode("pummel", NextAction::array(0, new NextAction("pummel", ACTION_INTERRUPT), nullptr))); triggers.push_back(new TriggerNode("pummel", NextAction::array(0, new NextAction("pummel", ACTION_INTERRUPT), nullptr)));
triggers.push_back(new TriggerNode("victory rush", NextAction::array(0, new NextAction("victory rush", ACTION_INTERRUPT), nullptr))); triggers.push_back(new TriggerNode("victory rush", NextAction::array(0, new NextAction("victory rush", ACTION_INTERRUPT), 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("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("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)));

View File

@@ -19,6 +19,7 @@ class TankWarriorStrategyActionNodeFactory : public NamedObjectFactory<ActionNod
creators["heroic throw on snare target"] = &heroic_throw_on_snare_target; creators["heroic throw on snare target"] = &heroic_throw_on_snare_target;
creators["heroic throw taunt"] = &heroic_throw_taunt; creators["heroic throw taunt"] = &heroic_throw_taunt;
creators["taunt"] = &taunt; creators["taunt"] = &taunt;
creators["taunt spell"] = &taunt;
} }
private: private: