mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
naxxramas gluth
This commit is contained in:
@@ -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,7 +212,35 @@ 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()));
|
||||
|
||||
//bot->SendHeartBeat();
|
||||
// // // set jump destination for MSG_LAND packet
|
||||
// SetJumpDestination(Position(x, y, z, bot->GetOrientation()));
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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"; }
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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); }
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
// {
|
||||
|
||||
@@ -217,38 +217,44 @@ class KelthuzadPositionAction : public MovementAction
|
||||
|
||||
class AnubrekhanChooseTargetAction : public AttackAction
|
||||
{
|
||||
public:
|
||||
AnubrekhanChooseTargetAction(PlayerbotAI* ai) : AttackAction(ai, "anub'rekhan choose target") {}
|
||||
virtual bool Execute(Event event);
|
||||
public:
|
||||
AnubrekhanChooseTargetAction(PlayerbotAI* ai) : AttackAction(ai, "anub'rekhan choose target") {}
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class AnubrekhanPositionAction : public RotateAroundTheCenterPointAction
|
||||
{
|
||||
public:
|
||||
AnubrekhanPositionAction(PlayerbotAI* ai) : RotateAroundTheCenterPointAction(ai, "anub'rekhan position", 3272.49f, -3476.27f, 45.0f, 16) {}
|
||||
virtual bool Execute(Event event);
|
||||
public:
|
||||
AnubrekhanPositionAction(PlayerbotAI* ai) : RotateAroundTheCenterPointAction(ai, "anub'rekhan position", 3272.49f, -3476.27f, 45.0f, 16) {}
|
||||
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
|
||||
// {
|
||||
|
||||
@@ -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() {
|
||||
@@ -161,8 +156,28 @@ class SapphironBossHelper: public GenericBossHelper<boss_sapphiron::boss_sapphir
|
||||
private:
|
||||
const uint32 POSITION_TIME_AFTER_LANDED = 5000;
|
||||
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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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); }
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
// {
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user