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.
*/
#include "MotionMaster.h"
#include "MoveSpline.h"
#include "MoveSplineInit.h"
#include "ObjectGuid.h"
@@ -31,6 +32,7 @@
#include "SharedDefines.h"
#include "SocialMgr.h"
#include "SpellAuraEffects.h"
#include "Unit.h"
#include "UpdateTime.h"
#include "Vehicle.h"
#include "GuildMgr.h"
@@ -210,6 +212,34 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal)
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
// if (bot->IsInCombat())
@@ -804,6 +834,11 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet)
// bot->Say(speak, LANG_UNIVERSAL);
// bot->GetClosePoint(x, y, z, bot->GetObjectSize(), dist, bot->GetAngle(vcos, vsin));
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();
// Position dest = bot->GetPosition();
// float moveTimeHalf = verticalSpeed / Movement::gravity;
@@ -818,33 +853,30 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet)
// SetNextCheckDelay((uint32)((newdis / dis) * moveTimeHalf * 4 * IN_MILLISECONDS));
// // 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
// MovementInfo movementInfo = bot->m_movementInfo;
// // send ack
// WorldPacket ack(CMSG_MOVE_KNOCK_BACK_ACK);
// movementInfo.jump.cosAngle = vcos;
// movementInfo.jump.sinAngle = vsin;
// movementInfo.jump.zspeed = -verticalSpeed;
// movementInfo.jump.xyspeed = horizontalSpeed;
// // movementInfo.jump.cosAngle = vcos;
// // movementInfo.jump.sinAngle = vsin;
// // movementInfo.jump.zspeed = -verticalSpeed;
// // movementInfo.jump.xyspeed = horizontalSpeed;
// ack << bot->GetGUID().WriteAsPacked();
// bot->m_mover->BuildMovementPacket(&ack);
// ack << movementInfo.jump.sinAngle;
// ack << movementInfo.jump.cosAngle;
// ack << movementInfo.jump.xyspeed;
// ack << movementInfo.jump.zspeed;
// // bot->m_mover->BuildMovementPacket(&ack);
// ack << (uint32)0;
// bot->BuildMovementPacket(&ack);
// // ack << movementInfo.jump.sinAngle;
// // ack << movementInfo.jump.cosAngle;
// // ack << movementInfo.jump.xyspeed;
// // ack << movementInfo.jump.zspeed;
// bot->GetSession()->HandleMoveKnockBackAck(ack);
// // set jump destination for MSG_LAND packet
// SetJumpDestination(Position(fx, fy, fz, bot->GetOrientation()));
// // // set jump destination for MSG_LAND packet
// SetJumpDestination(Position(x, y, z, bot->GetOrientation()));
//bot->SendHeartBeat();
// bot->Heart();
// */
return;
@@ -1619,6 +1651,37 @@ bool PlayerbotAI::IsAssistTank(Player* 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
{
class UnitByGuidInRangeCheck
@@ -2876,8 +2939,8 @@ void PlayerbotAI::WaitForSpellCast(Spell* spell)
castTime = ceil(castTime);
uint32 globalCooldown = CalculateGlobalCooldown(spellInfo->Id);
if (castTime < globalCooldown)
castTime = globalCooldown;
// if (castTime < globalCooldown)
// castTime = globalCooldown;
SetNextCheckDelay(castTime + sPlayerbotAIConfig->reactDelay);
}

View File

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

View File

@@ -407,7 +407,8 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
}
else
{
botAI->ResetStrategies(!sRandomPlayerbotMgr->IsRandomBot(bot));
// botAI->ResetStrategies(!sRandomPlayerbotMgr->IsRandomBot(bot));
botAI->ResetStrategies();
}
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())
{
pet->SetReactState(REACT_PASSIVE);
if (with_pet) {
pet->SetReactState(REACT_DEFENSIVE);
pet->SetTarget(target->GetGUID());
pet->GetCharmInfo()->SetIsCommandAttack(true);
pet->AI()->AttackStart(target);
// pet->SetReactState(REACT_DEFENSIVE);
} else {
pet->SetReactState(REACT_PASSIVE);
pet->GetCharmInfo()->SetIsCommandFollow(true);
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:
CastGhoulFrenzyAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "ghoul frenzy") { }
std::string const GetTargetName() override { return "pet target"; }
};
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()
{
return NextAction::array(0,
new NextAction("scourge strike", ACTION_NORMAL + 6),
new NextAction("blood strike", ACTION_NORMAL + 5),
new NextAction("death coil", ACTION_NORMAL + 4),
new NextAction("plague strike", ACTION_NORMAL + 3),
new NextAction("icy touch", ACTION_NORMAL + 2),
new NextAction("ghoul frenzy", ACTION_NORMAL + 4),
new NextAction("death coil", ACTION_NORMAL + 3),
new NextAction("plague strike", ACTION_NORMAL + 2),
new NextAction("icy touch", ACTION_NORMAL + 1),
new NextAction("melee", ACTION_NORMAL),
NULL);
nullptr);
}
void UnholyDKStrategy::InitTriggers(std::vector<TriggerNode*>& 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)));
}

View File

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

View File

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

View File

@@ -115,7 +115,7 @@ void CasterDruidStrategy::InitTriggers(std::vector<TriggerNode*>& 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("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)));

View File

@@ -20,7 +20,7 @@ void HealDruidStrategy::InitTriggers(std::vector<TriggerNode*>& 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("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(

View File

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

View File

@@ -122,7 +122,7 @@ void GenericMageStrategy::InitTriggers(std::vector<TriggerNode*>& 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("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)));

View File

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

View File

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

View File

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

View File

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

View File

@@ -25,7 +25,7 @@ void ShadowPriestStrategy::InitTriggers(std::vector<TriggerNode*>& 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("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)));

View File

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

View File

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

View File

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

View File

@@ -110,11 +110,6 @@ class SapphironBossHelper: public GenericBossHelper<boss_sapphiron::boss_sapphir
return !IsPhaseGround();
}
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;
}
bool WaitForExplosion() {
@@ -162,7 +157,27 @@ class SapphironBossHelper: public GenericBossHelper<boss_sapphiron::boss_sapphir
const uint32 POSITION_TIME_AFTER_LANDED = 5000;
const uint32 EVENT_FLIGHT_INTERVAL = 45000;
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

View File

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

View File

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

View File

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

View File

@@ -39,8 +39,8 @@ class RaidNaxxTriggerContext : public NamedObjectContext<Trigger>
creators["anub'rekhan"] = &RaidNaxxTriggerContext::anubrekhan;
// creators["gluth"] = &RaidNaxxTriggerContext::gluth;
// creators["gluth main tank mortal wound"] = &RaidNaxxTriggerContext::gluth_main_tank_mortal_wound;
creators["gluth"] = &RaidNaxxTriggerContext::gluth;
creators["gluth main tank mortal wound"] = &RaidNaxxTriggerContext::gluth_main_tank_mortal_wound;
// 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_phase_two(PlayerbotAI* ai) { return new KelthuzadPhaseTwoTrigger(ai); }
static Trigger* anubrekhan(PlayerbotAI* ai) { return new AnubrekhanTrigger(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(PlayerbotAI* ai) { return new GluthTrigger(ai); }
static Trigger* gluth_main_tank_mortal_wound(PlayerbotAI* ai) { return new GluthMainTankMortalWoundTrigger(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);
// }
// bool GluthMainTankMortalWoundTrigger::IsActive()
// {
// if (!BossPhaseTrigger::IsActive()) {
// 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 GluthTrigger::IsActive()
{
return helper.UpdateBossAI();
}
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();
}

View File

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

View File

@@ -48,7 +48,7 @@ void CasterShamanStrategy::InitTriggers(std::vector<TriggerNode*>& 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("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)));

View File

@@ -41,7 +41,7 @@ void HealShamanStrategy::InitTriggers(std::vector<TriggerNode*>& 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(
"group heal occasion",

View File

@@ -15,7 +15,7 @@ class NearestUnitsValue : public ObjectGuidListCalculatedValue
{
public:
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;

View File

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

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 taunt"] = &heroic_throw_taunt;
creators["taunt"] = &taunt;
creators["taunt spell"] = &taunt;
}
private: