diff --git a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneActions.cpp b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneActions.cpp index 25f193418..29f9b3ca3 100644 --- a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneActions.cpp +++ b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneActions.cpp @@ -12,14 +12,14 @@ bool ShatterSpreadAction::Execute(Event event) GuidVector members = AI_VALUE(GuidVector, "group members"); for (auto& member : members) { - if (bot->GetGUID() == member) + Unit* unit = botAI->GetUnit(member); + if (!unit || bot->GetGUID() == member) { continue; } - if (!closestMember || - bot->GetExactDist2d(botAI->GetUnit(member)) < bot->GetExactDist2d(closestMember)) + if (!closestMember || bot->GetExactDist2d(unit) < bot->GetExactDist2d(closestMember)) { - closestMember = botAI->GetUnit(member); + closestMember = unit; } } diff --git a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp index 09e77dc32..b1c66b66f 100644 --- a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp +++ b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp @@ -26,4 +26,5 @@ void WotlkDungeonHoSStrategy::InitTriggers(std::vector &triggers) void WotlkDungeonHoSStrategy::InitMultipliers(std::vector &multipliers) { multipliers.push_back(new KrystallusMultiplier(botAI)); + multipliers.push_back(new SjonnirMultiplier(botAI)); } diff --git a/src/strategy/dungeons/wotlk/nexus/NexusActions.cpp b/src/strategy/dungeons/wotlk/nexus/NexusActions.cpp index e494251e4..90233543f 100644 --- a/src/strategy/dungeons/wotlk/nexus/NexusActions.cpp +++ b/src/strategy/dungeons/wotlk/nexus/NexusActions.cpp @@ -33,11 +33,12 @@ bool MoveFromWhirlwindAction::Execute(Event event) default: break; } - if (!boss || bot->GetExactDist2d(boss->GetPosition()) > targetDist) + float bossDistance = bot->GetExactDist2d(boss->GetPosition()); + if (!boss || bossDistance > targetDist) { return false; } - return MoveAway(boss, targetDist - bot->GetExactDist2d(boss->GetPosition())); + return MoveAway(boss, targetDist - bossDistance); } bool FirebombSpreadAction::Execute(Event event) @@ -50,16 +51,8 @@ bool FirebombSpreadAction::Execute(Event event) GuidVector members = AI_VALUE(GuidVector, "group members"); for (auto& member : members) { - if (bot->GetGUID() == member) - { - continue; - } - Unit* unit = botAI->GetUnit(member); - if (!unit) - { - continue; - } + if (!unit || bot->GetGUID() == member) { continue; } if (bot->GetExactDist2d(unit) < targetDist) { @@ -77,24 +70,22 @@ bool TelestraSplitTargetAction::Execute(Event event) for (auto& attacker : attackers) { - Unit* npc = botAI->GetUnit(attacker); - if (!npc) - { - continue; - } - switch (npc->GetEntry()) + Unit* unit = botAI->GetUnit(attacker); + if (!unit) { continue; } + + switch (unit->GetEntry()) { // Focus arcane clone first case NPC_ARCANE_MAGUS: - splitTargets[0] = npc; + splitTargets[0] = unit; break; // Then the frost clone case NPC_FROST_MAGUS: - splitTargets[1] = npc; + splitTargets[1] = unit; break; // Fire clone last case NPC_FIRE_MAGUS: - splitTargets[2] = npc; + splitTargets[2] = unit; break; } } @@ -146,11 +137,15 @@ bool ChaoticRiftTargetAction::Execute(Event event) bool DodgeSpikesAction::isUseful() { Unit* boss = AI_VALUE2(Unit*, "find target", "ormorok the tree-shaper"); + if (!boss) { return false; } + return bot->GetExactDist2d(boss) > 0.5f; } bool DodgeSpikesAction::Execute(Event event) { Unit* boss = AI_VALUE2(Unit*, "find target", "ormorok the tree-shaper"); + if (!boss) { return false; } + return Move(bot->GetAngle(boss), bot->GetExactDist2d(boss) - 0.3f); } diff --git a/src/strategy/dungeons/wotlk/nexus/NexusActions.h b/src/strategy/dungeons/wotlk/nexus/NexusActions.h index 145efba7e..96790c367 100644 --- a/src/strategy/dungeons/wotlk/nexus/NexusActions.h +++ b/src/strategy/dungeons/wotlk/nexus/NexusActions.h @@ -7,22 +7,6 @@ #include "Playerbots.h" #include "NexusTriggers.h" -#define ANGLE_45_DEG (static_cast(M_PI) / 4.f) -#define ANGLE_90_DEG M_PI_2 -#define ANGLE_120_DEG (2.f * static_cast(M_PI) / 3.f) - -// Slice of the circle that we want melee dps to attack from. -// Measured from boss orientation, on one side. - -// Even though the breath cone is not the full 180 degrees, -// avoid melee dps from the front due to parry potential. -// Bots should learn good dps etiquette :) -#define DRAGON_MELEE_MIN_ANGLE ANGLE_90_DEG -// This leaves a danger zone of 60 degrees at the tail end on both sides. -// This is a total of 120 degrees tail arc that bots will avoid - -// number just happens to be the same in this case, but this is always measured from the front. -#define DRAGON_MELEE_MAX_ANGLE ANGLE_120_DEG - class MoveFromWhirlwindAction : public MovementAction { public: diff --git a/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.cpp b/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.cpp index 4b8ab97af..117be85c5 100644 --- a/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.cpp +++ b/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.cpp @@ -77,10 +77,8 @@ float AnomalusMultiplier::GetValue(Action* action) float OrmorokMultiplier::GetValue(Action* action) { Unit* boss = AI_VALUE2(Unit*, "find target", "ormorok the tree-shaper"); - if (!boss) - { - return 1.0f; - } + if (!boss) { return 1.0f; } + // These are used for auto ranged repositioning, need to suppress so ranged dps don't ping-pong if (dynamic_cast(action)) { diff --git a/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.h b/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.h index c7321a405..00373ebd9 100644 --- a/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.h +++ b/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.h @@ -39,13 +39,4 @@ class OrmorokMultiplier : public Multiplier virtual float GetValue(Action* action); }; -class KeristraszaMultiplier : public Multiplier -{ - public: - KeristraszaMultiplier(PlayerbotAI* ai) : Multiplier(ai, "keristrasza") {} - - public: - virtual float GetValue(Action* action); -}; - #endif diff --git a/src/strategy/dungeons/wotlk/nexus/NexusStrategy.cpp b/src/strategy/dungeons/wotlk/nexus/NexusStrategy.cpp index b86c1aa46..566a1381d 100644 --- a/src/strategy/dungeons/wotlk/nexus/NexusStrategy.cpp +++ b/src/strategy/dungeons/wotlk/nexus/NexusStrategy.cpp @@ -50,5 +50,4 @@ void WotlkDungeonNexStrategy::InitMultipliers(std::vector &multipli multipliers.push_back(new TelestraMultiplier(botAI)); multipliers.push_back(new AnomalusMultiplier(botAI)); multipliers.push_back(new OrmorokMultiplier(botAI)); - // multipliers.push_back(new KeristraszaMultiplier(botAI)); } diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.cpp b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.cpp index c5b27ccad..41b410bf7 100644 --- a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.cpp +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.cpp @@ -42,22 +42,22 @@ bool AvoidShadowCrashAction::Execute(Event event) { // Could check all enemy units in range as it's possible to pull multiple of these mobs. // They should really be killed 1 by 1, multipulls are messy so we just handle singles for now - Unit* npc = AI_VALUE2(Unit*, "find target", "forgotten one"); + Unit* unit = AI_VALUE2(Unit*, "find target", "forgotten one"); Unit* victim = nullptr; float radius = 10.0f; float targetDist = radius + 2.0f; - if (!npc) { return false; } + if (!unit) { return false; } // Actively move if targeted by a shadow crash. // Spell check not needed, they don't have any other non-instant casts - if (npc->HasUnitState(UNIT_STATE_CASTING)) // && npc->FindCurrentSpellBySpellId(SPELL_SHADOW_CRASH)) + if (unit->HasUnitState(UNIT_STATE_CASTING)) // && unit->FindCurrentSpellBySpellId(SPELL_SHADOW_CRASH)) { // This doesn't seem to avoid casts very well, perhaps because this isn't checked while allies are casting. // TODO: Revisit if this is an issue in heroics, otherwise ignore shadow crashes for the most part. - victim = botAI->GetUnit(npc->GetTarget()); + victim = botAI->GetUnit(unit->GetTarget()); if (victim && bot->GetExactDist2d(victim) < radius) { - return MoveAway(victim, targetDist - bot->GetExactDist2d(victim)); + return MoveAway(victim, targetDist - bot->GetExactDist2d(victim->GetPosition())); } } diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.cpp b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.cpp index 9fc908024..73ce27bbc 100644 --- a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.cpp +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.cpp @@ -9,9 +9,10 @@ float ElderNadoxMultiplier::GetValue(Action* action) { Unit* boss = AI_VALUE2(Unit*, "find target", "elder nadox"); - Unit* guardian = AI_VALUE2(Unit*, "find target", "ahn'kahar guardian"); + if (!boss) { return 1.0f; } - if (boss && guardian) + Unit* guardian = AI_VALUE2(Unit*, "find target", "ahn'kahar guardian"); + if (guardian) { if (dynamic_cast(action)) { @@ -24,7 +25,7 @@ float ElderNadoxMultiplier::GetValue(Action* action) float JedogaShadowseekerMultiplier::GetValue(Action* action) { Unit* boss = AI_VALUE2(Unit*, "find target", "jedoga shadowseeker"); - // Unit* volunteer = AI_VALUE2(Unit*, "find target", "twilight volunteer"); + if (!boss) { return 1.0f; } Unit* volunteer = nullptr; // Target is not findable from threat table using AI_VALUE2(), @@ -41,7 +42,7 @@ float JedogaShadowseekerMultiplier::GetValue(Action* action) } } - if (boss && volunteer) + if (volunteer) { if (dynamic_cast(action)) { @@ -53,9 +54,10 @@ float JedogaShadowseekerMultiplier::GetValue(Action* action) float ForgottenOneMultiplier::GetValue(Action* action) { - Unit* npc = AI_VALUE2(Unit*, "find target", "forgotten one"); + Unit* unit = AI_VALUE2(Unit*, "find target", "forgotten one"); + if (!unit) { return 1.0f; } - if (npc && bot->isMoving()) + if (bot->isMoving()) { if (dynamic_cast(action)) { diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.cpp b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.cpp index 951ab7555..04dcd5901 100644 --- a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.cpp +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.cpp @@ -17,9 +17,9 @@ bool NadoxGuardianTrigger::IsActive() bool JedogaVolunteerTrigger::IsActive() { Unit* boss = AI_VALUE2(Unit*, "find target", "jedoga shadowseeker"); - // Unit* volunteer = AI_VALUE2(Unit*, "find target", "twilight volunteer"); - Unit* volunteer = nullptr; - // Target is not findable from threat table using AI_VALUE2(), + if (!boss) { return false; } + + // Volunteer is not findable from threat table using AI_VALUE2(), // therefore need to search manually for the unit name GuidVector targets = AI_VALUE(GuidVector, "possible targets no los"); @@ -28,16 +28,16 @@ bool JedogaVolunteerTrigger::IsActive() Unit* unit = botAI->GetUnit(*i); if (unit && unit->GetEntry() == NPC_TWILIGHT_VOLUNTEER) { - volunteer = unit; - break; + return true; } } - - return boss && volunteer; + return false; } bool ShadowCrashTrigger::IsActive() { - if (botAI->IsMelee(bot)) { return false; } - return !botAI->IsMelee(bot) && AI_VALUE2(Unit*, "find target", "forgotten one"); + Unit* unit = AI_VALUE2(Unit*, "find target", "forgotten one"); + if (!unit) { return false; } + + return !botAI->IsMelee(bot); } diff --git a/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepActions.cpp b/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepActions.cpp index f26823f4f..a8966e8bb 100644 --- a/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepActions.cpp +++ b/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepActions.cpp @@ -14,7 +14,7 @@ bool AttackFrostTombAction::Execute(Event event) for (auto i = targets.begin(); i != targets.end(); ++i) { Unit* unit = botAI->GetUnit(*i); - if (unit && unit->GetName() == "Frost Tomb") + if (unit && unit->GetEntry() == NPC_FROST_TOMB) { frostTomb = unit; break; @@ -31,7 +31,9 @@ bool AttackFrostTombAction::Execute(Event event) bool AttackDalronnAction::Execute(Event event) { Unit* boss = AI_VALUE2(Unit*, "find target", "dalronn the controller"); - if (!boss || AI_VALUE(Unit*, "current target") == boss) + if (!boss) { return false; } + + if (AI_VALUE(Unit*, "current target") == boss) { return false; } @@ -42,10 +44,7 @@ bool IngvarStopCastingAction::Execute(Event event) { // Doesn't work, this action gets queued behind the current spell instead of interrupting it Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); - if (!boss) - { - return false; - } + if (!boss) { return false; } int32 my_spell_id = AI_VALUE(uint32, "active spell"); if (!my_spell_id || my_spell_id == 0) @@ -54,10 +53,7 @@ bool IngvarStopCastingAction::Execute(Event event) } Spell* spell = bot->FindCurrentSpellBySpellId(my_spell_id); - if (!spell) - { - return false; - } + if (!spell) { return false; } // bot->Yell("cancelling spell="+std::to_string(my_spell_id), LANG_UNIVERSAL); bot->InterruptSpell(spell->GetCurrentContainer(), false, true, true); @@ -71,10 +67,7 @@ bool IngvarDodgeSmashAction::isUseful() { return !AI_VALUE2(bool, "behind", "cur bool IngvarDodgeSmashAction::Execute(Event event) { Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); - if (!boss) - { - return false; - } + if (!boss) { return false; } float distance = bot->GetExactDist2d(boss->GetPosition()); // Extra units to move into the boss, instead of being just 1 pixel past his midpoint. @@ -88,10 +81,7 @@ bool IngvarSmashReturnAction::isUseful() { return AI_VALUE2(bool, "behind", "cur bool IngvarSmashReturnAction::Execute(Event event) { Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); - if (!boss) - { - return false; - } + if (!boss) { return false; } float distance = bot->GetExactDist2d(boss->GetPosition()); return Move(bot->GetAngle(boss), distance + bot->GetMeleeReach()); diff --git a/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepMultipliers.cpp b/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepMultipliers.cpp index 31d310faf..c13f898d1 100644 --- a/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepMultipliers.cpp +++ b/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepMultipliers.cpp @@ -7,10 +7,8 @@ float PrinceKelesethMultiplier::GetValue(Action* action) { Unit* boss = AI_VALUE2(Unit*, "find target", "prince keleseth"); - if (!boss) - { - return 1.0f; - } + if (!boss) { return 1.0f; } + if (dynamic_cast(action)) { return 0.0f; @@ -20,13 +18,9 @@ float PrinceKelesethMultiplier::GetValue(Action* action) float SkarvaldAndDalronnMultiplier::GetValue(Action* action) { - // Unit* skarvald = AI_VALUE2(Unit*, "find target", "skarvald the constructor"); - Unit* dalronn = AI_VALUE2(Unit*, "find target", "dalronn the controller"); - - if (!dalronn) - { - return 1.0f; - } + // Only need to deal with Dalronn here. If he's dead, just fall back to normal dps strat + Unit* boss = AI_VALUE2(Unit*, "find target", "dalronn the controller"); + if (!boss) { return 1.0f; } if (dynamic_cast(action)) { @@ -39,10 +33,7 @@ float IngvarThePlundererMultiplier::GetValue(Action* action) { Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); bool isTank = botAI->IsTank(bot); - if (!boss) - { - return 1.0f; - } + if (!boss) { return 1.0f; } // Prevent movement actions overriding current movement, we're probably dodging a slam if (isTank && bot->isMoving() && dynamic_cast(action)) @@ -60,10 +51,7 @@ float IngvarThePlundererMultiplier::GetValue(Action* action) { uint32 spellId = AI_VALUE2(uint32, "spell id", action->getName()); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); - if (!spellInfo) - { - return 1.0f; - } + if (!spellInfo) { return 1.0f; } uint32 castTime = spellInfo->CalcCastTime(bot); if (castTime != 0) @@ -73,10 +61,8 @@ float IngvarThePlundererMultiplier::GetValue(Action* action) } } // Done with non-tank logic - if (!isTank) - { - return 1.0f; - } + if (!isTank) { return 1.0f; } + // TANK ONLY if (boss->FindCurrentSpellBySpellId(SPELL_SMASH) || boss->FindCurrentSpellBySpellId(SPELL_DARK_SMASH)) diff --git a/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepTriggers.cpp b/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepTriggers.cpp index ff07c78e8..a3f03b942 100644 --- a/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepTriggers.cpp +++ b/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepTriggers.cpp @@ -9,7 +9,7 @@ bool KelesethFrostTombTrigger::IsActive() for (auto& member : members) { Unit* unit = botAI->GetUnit(member); - if (unit && unit->HasAura(DEBUFF_FROST_TOMB)) + if (unit && unit->HasAura(SPELL_FROST_TOMB)) { return true; } @@ -19,21 +19,17 @@ bool KelesethFrostTombTrigger::IsActive() bool DalronnNontankTrigger::IsActive() { - Unit* dalronn = AI_VALUE2(Unit*, "find target", "dalronn the controller"); - if (!dalronn) - { - return false; - } + Unit* boss = AI_VALUE2(Unit*, "find target", "dalronn the controller"); + if (!boss) { return false; } + return !botAI->IsTank(bot); } bool IngvarStaggeringRoarTrigger::IsActive() { Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); - if (!boss) - { - return false; - } + if (!boss) { return false; } + if (boss->HasUnitState(UNIT_STATE_CASTING)) { if (boss->FindCurrentSpellBySpellId(SPELL_STAGGERING_ROAR)) @@ -47,16 +43,12 @@ bool IngvarStaggeringRoarTrigger::IsActive() bool IngvarDreadfulRoarTrigger::IsActive() { Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); - if (!boss) - { - return false; - } - if (boss->HasUnitState(UNIT_STATE_CASTING)) + if (!boss) { return false; } + + if (boss->HasUnitState(UNIT_STATE_CASTING) && + boss->FindCurrentSpellBySpellId(SPELL_DREADFUL_ROAR)) { - if (boss->FindCurrentSpellBySpellId(SPELL_DREADFUL_ROAR)) - { - return true; - } + return true; } return false; } @@ -64,10 +56,7 @@ bool IngvarDreadfulRoarTrigger::IsActive() bool IngvarSmashTankTrigger::IsActive() { Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); - if (!boss || !botAI->IsTank(bot)) - { - return false; - } + if (!boss || !botAI->IsTank(bot)) { return false; } if (boss->HasUnitState(UNIT_STATE_CASTING)) { @@ -86,20 +75,15 @@ bool IngvarSmashTankReturnTrigger::IsActive() // if (!boss || !botAI->IsTank(bot) || boss->HasUnitState(UNIT_STATE_CASTING)) // Ignore casting state as Ingvar will sometimes chain-cast a roar after a smash.. // We don't want this to prevent our tank from repositioning properly. - if (!boss || !botAI->IsTank(bot)) - { - return false; - } + if (!boss || !botAI->IsTank(bot)) { return false; } + return true; } bool NotBehindIngvarTrigger::IsActive() { Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); - if (!boss || botAI->IsTank(bot)) - { - return false; - } + if (!boss || botAI->IsTank(bot)) { return false; } return AI_VALUE2(bool, "behind", "current target"); } diff --git a/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepTriggers.h b/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepTriggers.h index db2032aa7..6ea92a15c 100644 --- a/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepTriggers.h +++ b/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepTriggers.h @@ -8,35 +8,25 @@ enum UtgardeKeepIDs { - SPELL_SUMMON_VALKYR = 42912, - SPELL_RESURRECTION_BEAM = 42857, - SPELL_RESURRECTION_BALL = 42862, - SPELL_RESURRECTION_HEAL = 42704, - SPELL_INGVAR_TRANSFORM = 42796, + // Prince Keleseth + SPELL_FROST_TOMB = 48400, + NPC_FROST_TOMB = 23965, + // Ingvar the Plunderer SPELL_STAGGERING_ROAR_N = 42708, SPELL_STAGGERING_ROAR_H = 59708, - SPELL_CLEAVE = 42724, SPELL_SMASH_N = 42669, SPELL_SMASH_H = 59706, - SPELL_ENRAGE_N = 42705, - SPELL_ENRAGE_H = 59707, - SPELL_DREADFUL_ROAR_N = 42729, SPELL_DREADFUL_ROAR_H = 59734, SPELL_WOE_STRIKE_N = 42730, SPELL_WOE_STRIKE_H = 59735, SPELL_DARK_SMASH = 42723, - SPELL_SHADOW_AXE = 42749, - - DEBUFF_FROST_TOMB = 48400, }; #define SPELL_STAGGERING_ROAR DUNGEON_MODE(bot, SPELL_STAGGERING_ROAR_N, SPELL_STAGGERING_ROAR_H) #define SPELL_DREADFUL_ROAR DUNGEON_MODE(bot, SPELL_DREADFUL_ROAR_N, SPELL_DREADFUL_ROAR_H) -#define SPELL_WOE_STRIKE DUNGEON_MODE(bot, SPELL_WOE_STRIKE_N, SPELL_WOE_STRIKE_H) #define SPELL_SMASH DUNGEON_MODE(bot, SPELL_SMASH_N, SPELL_SMASH_H) -#define SPELL_ENRAGE DUNGEON_MODE(bot, SPELL_ENRAGE_N, SPELL_ENRAGE_H) class KelesethFrostTombTrigger : public Trigger { diff --git a/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.cpp b/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.cpp index a108b3233..df36baa13 100644 --- a/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.cpp +++ b/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.cpp @@ -7,6 +7,8 @@ bool AttackErekemAction::Execute(Event event) { // Focus boss first, adds after Unit* boss = AI_VALUE2(Unit*, "find target", "erekem"); + if (!boss) { return false; } + if (AI_VALUE(Unit*, "current target") != boss) { return Attack(boss); @@ -19,6 +21,8 @@ bool AttackIchorGlobuleAction::Execute(Event event) Unit* boss = AI_VALUE2(Unit*, "find target", "ichoron"); if (!boss) { return false; } + Unit* currentTarget = AI_VALUE(Unit*, "current target"); + // Tank prioritise boss if it's up if (botAI->IsTank(bot) && !boss->HasAura(SPELL_DRAINED)) { @@ -38,7 +42,6 @@ bool AttackIchorGlobuleAction::Execute(Event event) Unit* unit = botAI->GetUnit(*i); if (unit && unit->GetEntry() == NPC_ICHOR_GLOBULE) { - Unit* currentTarget = AI_VALUE(Unit*, "current target"); // Check IDs here, NOT Unit* pointers: // Don't keep swapping between sentries. // If we're already attacking one, don't retarget another @@ -50,7 +53,7 @@ bool AttackIchorGlobuleAction::Execute(Event event) } } // No ichor globules left alive, fall back to targeting boss - if (AI_VALUE(Unit*, "current target") != boss) + if (currentTarget != boss) { return Attack(boss); } @@ -62,6 +65,8 @@ bool AttackVoidSentryAction::Execute(Event event) { Unit* boss = AI_VALUE2(Unit*, "find target", "zuramat the obliterator"); if (!boss) { return false; } + + Unit* currentTarget = AI_VALUE(Unit*, "current target"); // Target is not findable from threat table using AI_VALUE2(), // therefore need to search manually for the unit name @@ -73,7 +78,6 @@ bool AttackVoidSentryAction::Execute(Event event) Unit* unit = botAI->GetUnit(*i); if (unit && unit->GetEntry() == NPC_VOID_SENTRY) { - Unit* currentTarget = AI_VALUE(Unit*, "current target"); // Check IDs here, NOT Unit* pointers: // Don't keep swapping between sentries. // If we're already attacking one, don't retarget another @@ -85,7 +89,7 @@ bool AttackVoidSentryAction::Execute(Event event) } } // No void sentries left alive, fall back to targeting boss - if (AI_VALUE(Unit*, "current target") != boss) + if (currentTarget != boss) { return Attack(boss); } diff --git a/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.h b/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.h index 2d2dada0a..fc7ce9d29 100644 --- a/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.h +++ b/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.h @@ -8,8 +8,6 @@ #include "Playerbots.h" #include "VioletHoldTriggers.h" -// const Position NOVOS_PARTY_POSITION = Position(-378.852f, -760.349f, 28.587f); - class AttackErekemAction : public AttackAction { public: diff --git a/src/strategy/dungeons/wotlk/violethold/VioletHoldTriggers.cpp b/src/strategy/dungeons/wotlk/violethold/VioletHoldTriggers.cpp index cf9e9ab1e..bd2eee765 100644 --- a/src/strategy/dungeons/wotlk/violethold/VioletHoldTriggers.cpp +++ b/src/strategy/dungeons/wotlk/violethold/VioletHoldTriggers.cpp @@ -6,30 +6,42 @@ bool ErekemTargetTrigger::IsActive() { - return AI_VALUE2(Unit*, "find target", "erekem") && botAI->IsDps(bot); + Unit* boss = AI_VALUE2(Unit*, "find target", "erekem"); + if (!boss) { return false; } + + return botAI->IsDps(bot); } bool IchoronTargetTrigger::IsActive() { - return AI_VALUE2(Unit*, "find target", "ichoron") && !botAI->IsHeal(bot); + Unit* boss = AI_VALUE2(Unit*, "find target", "ichoron"); + if (!boss) { return false; } + + return !botAI->IsHeal(bot); } bool VoidShiftTrigger::IsActive() { Unit* boss = AI_VALUE2(Unit*, "find target", "zuramat the obliterator"); - return boss && bot->HasAura(SPELL_VOID_SHIFTED) && !botAI->IsHeal(bot); + if (!boss) { return false; } + + return bot->HasAura(SPELL_VOID_SHIFTED) && !botAI->IsHeal(bot); } bool ShroudOfDarknessTrigger::IsActive() { Unit* boss = AI_VALUE2(Unit*, "find target", "zuramat the obliterator"); - return boss && boss->HasAura(SPELL_SHROUD_OF_DARKNESS); + if (!boss) { return false; } + + return boss->HasAura(SPELL_SHROUD_OF_DARKNESS); } bool CyanigosaPositioningTrigger::IsActive() { Unit* boss = AI_VALUE2(Unit*, "find target", "cyanigosa"); + if (!boss) { return false; } + // Include healers here for now, otherwise they stand in things - return boss && !botAI->IsTank(bot) && !botAI->IsRangedDps(bot); - // return boss && botAI->IsMelee(bot) && !botAI->IsTank(bot); + return !botAI->IsTank(bot) && !botAI->IsRangedDps(bot); + // return botAI->IsMelee(bot) && !botAI->IsTank(bot); }