From a430786133a4846eff6d4e1fa9fa7fa2b40e3390 Mon Sep 17 00:00:00 2001 From: Bobblybook Date: Sat, 19 Oct 2024 22:44:11 +1100 Subject: [PATCH 1/3] Reapply "Preferred mount selection for bots" This reverts commit eb5dd450cdcf3de57805f221d95faf8d4d8d5f89. --- .../base/playerbots_preferred_mounts.sql | 10 ++++++ .../actions/CheckMountStateAction.cpp | 36 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 sql/playerbots/base/playerbots_preferred_mounts.sql diff --git a/sql/playerbots/base/playerbots_preferred_mounts.sql b/sql/playerbots/base/playerbots_preferred_mounts.sql new file mode 100644 index 00000000..6d904fb3 --- /dev/null +++ b/sql/playerbots/base/playerbots_preferred_mounts.sql @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS `playerbots_preferred_mounts`; +CREATE TABLE `playerbots_preferred_mounts` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `guid` INT(11) NOT NULL, + `type` TINYINT(3) NOT NULL COMMENT '0: Ground, 1: Flying', + `spellid` INT(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `guid` (`guid`), + KEY `type` (`type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/src/strategy/actions/CheckMountStateAction.cpp b/src/strategy/actions/CheckMountStateAction.cpp index 0300827b..7ae52f74 100644 --- a/src/strategy/actions/CheckMountStateAction.cpp +++ b/src/strategy/actions/CheckMountStateAction.cpp @@ -270,6 +270,42 @@ bool CheckMountStateAction::Mount() : 0; } + // Check for preferred mounts table in db + QueryResult checkTable = PlayerbotsDatabase.Query( + "SELECT EXISTS(SELECT * FROM information_schema.tables WHERE table_schema = 'acore_playerbots' AND table_name = 'playerbots_preferred_mounts')"); + + if (checkTable) + { + uint32 tableExists = checkTable->Fetch()[0].Get(); + if (tableExists == 1) + { + // Check for preferred mount entry + QueryResult result = PlayerbotsDatabase.Query( + "SELECT spellid FROM playerbots_preferred_mounts WHERE guid = {} AND type = {}", + bot->GetGUID().GetCounter(), masterMountType); + + if (result) + { + std::vector mounts; + do + { + Field* fields = result->Fetch(); + uint32 spellId = fields[0].Get(); + mounts.push_back(spellId); + } while (result->NextRow()); + + uint32 index = urand(0, mounts.size() - 1); + // Validate spell ID + if (index < mounts.size() && sSpellMgr->GetSpellInfo(mounts[index])) + { + // TODO: May want to do checks for 'bot riding skill > skill required to ride the mount' + return botAI->CastSpell(mounts[index], bot); + } + } + } + } + + // No preferred mount found (or invalid), continue with random mount selection std::map>& spells = allSpells[masterMountType]; if (hasSwiftMount) { From d0a9e98801ac3a98ed477f58f4aee02cc74aa7b6 Mon Sep 17 00:00:00 2001 From: Bobblybook Date: Sun, 20 Oct 2024 15:49:10 +1100 Subject: [PATCH 2/3] Dungeon code cleanup Consistent code, easier to read logic flow and some missing nullptr checks --- .../hallsofstone/HallsOfStoneActions.cpp | 6 +-- .../hallsofstone/HallsOfStoneStrategy.cpp | 1 + .../dungeons/wotlk/nexus/NexusActions.cpp | 34 ++++++++------ .../dungeons/wotlk/nexus/NexusActions.h | 16 ------- .../dungeons/wotlk/nexus/NexusMultipliers.cpp | 6 +-- .../dungeons/wotlk/nexus/NexusMultipliers.h | 9 ---- .../dungeons/wotlk/nexus/NexusStrategy.cpp | 1 - .../wotlk/oldkingdom/OldKingdomActions.cpp | 10 ++-- .../oldkingdom/OldKingdomMultipliers.cpp | 14 +++--- .../wotlk/oldkingdom/OldKingdomTriggers.cpp | 18 ++++---- .../wotlk/utgardekeep/UtgardeKeepActions.cpp | 26 ++++------- .../utgardekeep/UtgardeKeepMultipliers.cpp | 32 ++++--------- .../wotlk/utgardekeep/UtgardeKeepTriggers.cpp | 46 ++++++------------- .../wotlk/violethold/VioletHoldActions.cpp | 12 +++-- .../wotlk/violethold/VioletHoldActions.h | 2 - .../wotlk/violethold/VioletHoldTriggers.cpp | 24 +++++++--- 16 files changed, 106 insertions(+), 151 deletions(-) diff --git a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneActions.cpp b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneActions.cpp index 25f19341..754d28df 100644 --- a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneActions.cpp +++ b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneActions.cpp @@ -12,12 +12,12 @@ 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); } diff --git a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp index 09e77dc3..b1c66b66 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 1a918614..775925e7 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,13 +51,16 @@ bool FirebombSpreadAction::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 (bot->GetExactDist2d(botAI->GetUnit(member)) < targetDist) + + if (bot->GetExactDist2d(unit) < targetDist) { - return MoveAway(botAI->GetUnit(member), targetDist); + float bossDistance = bot->GetExactDist2d(boss->GetPosition()); + return MoveAway(unit, targetDist - bossDistance); } } return false; @@ -70,24 +74,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; } } @@ -139,11 +141,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 145efba7..96790c36 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 4b8ab97a..117be85c 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 c7321a40..00373ebd 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 b86c1aa4..566a1381 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 c5b27cca..41b410bf 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 9fc90802..73ce27bb 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 951ab755..04dcd590 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 f26823f4..a8966e8b 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 31d310fa..c13f898d 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 ff07c78e..a3f03b94 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) + if (!boss) { return false; } + + if (boss->HasUnitState(UNIT_STATE_CASTING) && + boss->FindCurrentSpellBySpellId(SPELL_DREADFUL_ROAR)) { - return false; - } - if (boss->HasUnitState(UNIT_STATE_CASTING)) - { - 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/violethold/VioletHoldActions.cpp b/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.cpp index a108b323..df36baa1 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 2d2dada0..fc7ce9d2 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 cf9e9ab1..bd2eee76 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); } From 3f7f3061249771a145484de114071a31a0e9c09d Mon Sep 17 00:00:00 2001 From: Bobblybook Date: Sun, 20 Oct 2024 15:58:14 +1100 Subject: [PATCH 3/3] Revert "Dungeon code cleanup" This reverts commit d0a9e98801ac3a98ed477f58f4aee02cc74aa7b6. --- .../hallsofstone/HallsOfStoneActions.cpp | 6 +-- .../hallsofstone/HallsOfStoneStrategy.cpp | 1 - .../dungeons/wotlk/nexus/NexusActions.cpp | 34 ++++++-------- .../dungeons/wotlk/nexus/NexusActions.h | 16 +++++++ .../dungeons/wotlk/nexus/NexusMultipliers.cpp | 6 ++- .../dungeons/wotlk/nexus/NexusMultipliers.h | 9 ++++ .../dungeons/wotlk/nexus/NexusStrategy.cpp | 1 + .../wotlk/oldkingdom/OldKingdomActions.cpp | 10 ++-- .../oldkingdom/OldKingdomMultipliers.cpp | 14 +++--- .../wotlk/oldkingdom/OldKingdomTriggers.cpp | 18 ++++---- .../wotlk/utgardekeep/UtgardeKeepActions.cpp | 26 +++++++---- .../utgardekeep/UtgardeKeepMultipliers.cpp | 32 +++++++++---- .../wotlk/utgardekeep/UtgardeKeepTriggers.cpp | 46 +++++++++++++------ .../wotlk/violethold/VioletHoldActions.cpp | 12 ++--- .../wotlk/violethold/VioletHoldActions.h | 2 + .../wotlk/violethold/VioletHoldTriggers.cpp | 24 +++------- 16 files changed, 151 insertions(+), 106 deletions(-) diff --git a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneActions.cpp b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneActions.cpp index 754d28df..25f19341 100644 --- a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneActions.cpp +++ b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneActions.cpp @@ -12,12 +12,12 @@ bool ShatterSpreadAction::Execute(Event event) GuidVector members = AI_VALUE(GuidVector, "group members"); for (auto& member : members) { - Unit* unit = botAI->GetUnit(member); - if (!unit || bot->GetGUID() == member) + if (bot->GetGUID() == member) { continue; } - if (!closestMember || bot->GetExactDist2d(unit) < bot->GetExactDist2d(closestMember)) + if (!closestMember || + bot->GetExactDist2d(botAI->GetUnit(member)) < bot->GetExactDist2d(closestMember)) { closestMember = botAI->GetUnit(member); } diff --git a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp index b1c66b66..09e77dc3 100644 --- a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp +++ b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp @@ -26,5 +26,4 @@ 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 775925e7..1a918614 100644 --- a/src/strategy/dungeons/wotlk/nexus/NexusActions.cpp +++ b/src/strategy/dungeons/wotlk/nexus/NexusActions.cpp @@ -33,12 +33,11 @@ bool MoveFromWhirlwindAction::Execute(Event event) default: break; } - float bossDistance = bot->GetExactDist2d(boss->GetPosition()); - if (!boss || bossDistance > targetDist) + if (!boss || bot->GetExactDist2d(boss->GetPosition()) > targetDist) { return false; } - return MoveAway(boss, targetDist - bossDistance); + return MoveAway(boss, targetDist - bot->GetExactDist2d(boss->GetPosition())); } bool FirebombSpreadAction::Execute(Event event) @@ -51,16 +50,13 @@ bool FirebombSpreadAction::Execute(Event event) GuidVector members = AI_VALUE(GuidVector, "group members"); for (auto& member : members) { - Unit* unit = botAI->GetUnit(member); - if (!unit || bot->GetGUID() == member) + if (bot->GetGUID() == member) { continue; } - - if (bot->GetExactDist2d(unit) < targetDist) + if (bot->GetExactDist2d(botAI->GetUnit(member)) < targetDist) { - float bossDistance = bot->GetExactDist2d(boss->GetPosition()); - return MoveAway(unit, targetDist - bossDistance); + return MoveAway(botAI->GetUnit(member), targetDist); } } return false; @@ -74,22 +70,24 @@ bool TelestraSplitTargetAction::Execute(Event event) for (auto& attacker : attackers) { - Unit* unit = botAI->GetUnit(attacker); - if (!unit) { continue; } - - switch (unit->GetEntry()) + Unit* npc = botAI->GetUnit(attacker); + if (!npc) + { + continue; + } + switch (npc->GetEntry()) { // Focus arcane clone first case NPC_ARCANE_MAGUS: - splitTargets[0] = unit; + splitTargets[0] = npc; break; // Then the frost clone case NPC_FROST_MAGUS: - splitTargets[1] = unit; + splitTargets[1] = npc; break; // Fire clone last case NPC_FIRE_MAGUS: - splitTargets[2] = unit; + splitTargets[2] = npc; break; } } @@ -141,15 +139,11 @@ 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 96790c36..145efba7 100644 --- a/src/strategy/dungeons/wotlk/nexus/NexusActions.h +++ b/src/strategy/dungeons/wotlk/nexus/NexusActions.h @@ -7,6 +7,22 @@ #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 117be85c..4b8ab97a 100644 --- a/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.cpp +++ b/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.cpp @@ -77,8 +77,10 @@ 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 00373ebd..c7321a40 100644 --- a/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.h +++ b/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.h @@ -39,4 +39,13 @@ 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 566a1381..b86c1aa4 100644 --- a/src/strategy/dungeons/wotlk/nexus/NexusStrategy.cpp +++ b/src/strategy/dungeons/wotlk/nexus/NexusStrategy.cpp @@ -50,4 +50,5 @@ 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 41b410bf..c5b27cca 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* unit = AI_VALUE2(Unit*, "find target", "forgotten one"); + Unit* npc = AI_VALUE2(Unit*, "find target", "forgotten one"); Unit* victim = nullptr; float radius = 10.0f; float targetDist = radius + 2.0f; - if (!unit) { return false; } + if (!npc) { return false; } // Actively move if targeted by a shadow crash. // Spell check not needed, they don't have any other non-instant casts - if (unit->HasUnitState(UNIT_STATE_CASTING)) // && unit->FindCurrentSpellBySpellId(SPELL_SHADOW_CRASH)) + if (npc->HasUnitState(UNIT_STATE_CASTING)) // && npc->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(unit->GetTarget()); + victim = botAI->GetUnit(npc->GetTarget()); if (victim && bot->GetExactDist2d(victim) < radius) { - return MoveAway(victim, targetDist - bot->GetExactDist2d(victim->GetPosition())); + return MoveAway(victim, targetDist - bot->GetExactDist2d(victim)); } } diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.cpp b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.cpp index 73ce27bb..9fc90802 100644 --- a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.cpp +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.cpp @@ -9,10 +9,9 @@ float ElderNadoxMultiplier::GetValue(Action* action) { Unit* boss = AI_VALUE2(Unit*, "find target", "elder nadox"); - if (!boss) { return 1.0f; } - Unit* guardian = AI_VALUE2(Unit*, "find target", "ahn'kahar guardian"); - if (guardian) + + if (boss && guardian) { if (dynamic_cast(action)) { @@ -25,7 +24,7 @@ float ElderNadoxMultiplier::GetValue(Action* action) float JedogaShadowseekerMultiplier::GetValue(Action* action) { Unit* boss = AI_VALUE2(Unit*, "find target", "jedoga shadowseeker"); - if (!boss) { return 1.0f; } + // Unit* volunteer = AI_VALUE2(Unit*, "find target", "twilight volunteer"); Unit* volunteer = nullptr; // Target is not findable from threat table using AI_VALUE2(), @@ -42,7 +41,7 @@ float JedogaShadowseekerMultiplier::GetValue(Action* action) } } - if (volunteer) + if (boss && volunteer) { if (dynamic_cast(action)) { @@ -54,10 +53,9 @@ float JedogaShadowseekerMultiplier::GetValue(Action* action) float ForgottenOneMultiplier::GetValue(Action* action) { - Unit* unit = AI_VALUE2(Unit*, "find target", "forgotten one"); - if (!unit) { return 1.0f; } + Unit* npc = AI_VALUE2(Unit*, "find target", "forgotten one"); - if (bot->isMoving()) + if (npc && 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 04dcd590..951ab755 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"); - if (!boss) { return false; } - - // Volunteer is not findable from threat table using AI_VALUE2(), + // Unit* volunteer = AI_VALUE2(Unit*, "find target", "twilight volunteer"); + Unit* volunteer = nullptr; + // Target 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) { - return true; + volunteer = unit; + break; } } - return false; + + return boss && volunteer; } bool ShadowCrashTrigger::IsActive() { - Unit* unit = AI_VALUE2(Unit*, "find target", "forgotten one"); - if (!unit) { return false; } - - return !botAI->IsMelee(bot); + if (botAI->IsMelee(bot)) { return false; } + return !botAI->IsMelee(bot) && AI_VALUE2(Unit*, "find target", "forgotten one"); } diff --git a/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepActions.cpp b/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepActions.cpp index a8966e8b..f26823f4 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->GetEntry() == NPC_FROST_TOMB) + if (unit && unit->GetName() == "Frost Tomb") { frostTomb = unit; break; @@ -31,9 +31,7 @@ bool AttackFrostTombAction::Execute(Event event) bool AttackDalronnAction::Execute(Event event) { Unit* boss = AI_VALUE2(Unit*, "find target", "dalronn the controller"); - if (!boss) { return false; } - - if (AI_VALUE(Unit*, "current target") == boss) + if (!boss || AI_VALUE(Unit*, "current target") == boss) { return false; } @@ -44,7 +42,10 @@ 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) @@ -53,7 +54,10 @@ 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); @@ -67,7 +71,10 @@ 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. @@ -81,7 +88,10 @@ 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 c13f898d..31d310fa 100644 --- a/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepMultipliers.cpp +++ b/src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepMultipliers.cpp @@ -7,8 +7,10 @@ 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; @@ -18,9 +20,13 @@ float PrinceKelesethMultiplier::GetValue(Action* action) float SkarvaldAndDalronnMultiplier::GetValue(Action* action) { - // 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; } + // 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; + } if (dynamic_cast(action)) { @@ -33,7 +39,10 @@ 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)) @@ -51,7 +60,10 @@ 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) @@ -61,8 +73,10 @@ 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 a3f03b94..ff07c78e 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(SPELL_FROST_TOMB)) + if (unit && unit->HasAura(DEBUFF_FROST_TOMB)) { return true; } @@ -19,17 +19,21 @@ bool KelesethFrostTombTrigger::IsActive() bool DalronnNontankTrigger::IsActive() { - Unit* boss = AI_VALUE2(Unit*, "find target", "dalronn the controller"); - if (!boss) { return false; } - + Unit* dalronn = AI_VALUE2(Unit*, "find target", "dalronn the controller"); + if (!dalronn) + { + 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)) @@ -43,12 +47,16 @@ 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) && - boss->FindCurrentSpellBySpellId(SPELL_DREADFUL_ROAR)) + if (!boss) { - return true; + return false; + } + if (boss->HasUnitState(UNIT_STATE_CASTING)) + { + if (boss->FindCurrentSpellBySpellId(SPELL_DREADFUL_ROAR)) + { + return true; + } } return false; } @@ -56,7 +64,10 @@ 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)) { @@ -75,15 +86,20 @@ 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/violethold/VioletHoldActions.cpp b/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.cpp index df36baa1..a108b323 100644 --- a/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.cpp +++ b/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.cpp @@ -7,8 +7,6 @@ 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); @@ -21,8 +19,6 @@ 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)) { @@ -42,6 +38,7 @@ 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 @@ -53,7 +50,7 @@ bool AttackIchorGlobuleAction::Execute(Event event) } } // No ichor globules left alive, fall back to targeting boss - if (currentTarget != boss) + if (AI_VALUE(Unit*, "current target") != boss) { return Attack(boss); } @@ -65,8 +62,6 @@ 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 @@ -78,6 +73,7 @@ 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 @@ -89,7 +85,7 @@ bool AttackVoidSentryAction::Execute(Event event) } } // No void sentries left alive, fall back to targeting boss - if (currentTarget != boss) + if (AI_VALUE(Unit*, "current target") != boss) { return Attack(boss); } diff --git a/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.h b/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.h index fc7ce9d2..2d2dada0 100644 --- a/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.h +++ b/src/strategy/dungeons/wotlk/violethold/VioletHoldActions.h @@ -8,6 +8,8 @@ #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 bd2eee76..cf9e9ab1 100644 --- a/src/strategy/dungeons/wotlk/violethold/VioletHoldTriggers.cpp +++ b/src/strategy/dungeons/wotlk/violethold/VioletHoldTriggers.cpp @@ -6,42 +6,30 @@ bool ErekemTargetTrigger::IsActive() { - Unit* boss = AI_VALUE2(Unit*, "find target", "erekem"); - if (!boss) { return false; } - - return botAI->IsDps(bot); + return AI_VALUE2(Unit*, "find target", "erekem") && botAI->IsDps(bot); } bool IchoronTargetTrigger::IsActive() { - Unit* boss = AI_VALUE2(Unit*, "find target", "ichoron"); - if (!boss) { return false; } - - return !botAI->IsHeal(bot); + return AI_VALUE2(Unit*, "find target", "ichoron") && !botAI->IsHeal(bot); } bool VoidShiftTrigger::IsActive() { Unit* boss = AI_VALUE2(Unit*, "find target", "zuramat the obliterator"); - if (!boss) { return false; } - - return bot->HasAura(SPELL_VOID_SHIFTED) && !botAI->IsHeal(bot); + return boss && bot->HasAura(SPELL_VOID_SHIFTED) && !botAI->IsHeal(bot); } bool ShroudOfDarknessTrigger::IsActive() { Unit* boss = AI_VALUE2(Unit*, "find target", "zuramat the obliterator"); - if (!boss) { return false; } - - return boss->HasAura(SPELL_SHROUD_OF_DARKNESS); + return boss && 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 !botAI->IsTank(bot) && !botAI->IsRangedDps(bot); - // return botAI->IsMelee(bot) && !botAI->IsTank(bot); + return boss && !botAI->IsTank(bot) && !botAI->IsRangedDps(bot); + // return boss && botAI->IsMelee(bot) && !botAI->IsTank(bot); }