diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 1d5de49b..b1d5558b 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -1513,22 +1513,22 @@ void PlayerbotAI::ApplyInstanceStrategies(uint32 mapId, bool tellMaster) switch (mapId) { case 249: - strategyName = "onyxia"; + strategyName = "onyxia"; // Onyxia's Lair break; case 409: - strategyName = "mc"; + strategyName = "mc"; // Molten Core break; case 469: - strategyName = "bwl"; + strategyName = "bwl"; // Blackwing Lair break; case 509: - strategyName = "aq20"; + strategyName = "aq20"; // Ruins of Ahn'Qiraj break; case 532: - strategyName = "karazhan"; + strategyName = "karazhan"; // Karazhan break; case 533: - strategyName = "naxx"; + strategyName = "naxx"; // Naxxramas break; case 574: strategyName = "wotlk-uk"; // Utgarde Keep diff --git a/src/strategy/AiObjectContext.cpp b/src/strategy/AiObjectContext.cpp index 2e516c54..e525ec75 100644 --- a/src/strategy/AiObjectContext.cpp +++ b/src/strategy/AiObjectContext.cpp @@ -27,49 +27,30 @@ #include "WarriorAiObjectContext.h" #include "WorldPacketActionContext.h" #include "WorldPacketTriggerContext.h" -#include "raids/RaidStrategyContext.h" -#include "raids/blackwinglair/RaidBwlActionContext.h" -#include "raids/blackwinglair/RaidBwlTriggerContext.h" -#include "raids/naxxramas/RaidNaxxActionContext.h" -#include "raids/naxxramas/RaidNaxxTriggerContext.h" -#include "raids/icecrown/RaidIccActionContext.h" -#include "raids/icecrown/RaidIccTriggerContext.h" -#include "raids/obsidiansanctum/RaidOsActionContext.h" -#include "raids/obsidiansanctum/RaidOsTriggerContext.h" -#include "raids/eyeofeternity/RaidEoEActionContext.h" -#include "raids/vaultofarchavon/RaidVoATriggerContext.h" -#include "raids/onyxia/RaidOnyxiaActionContext.h" -#include "raids/onyxia/RaidOnyxiaTriggerContext.h" -#include "raids/vaultofarchavon/RaidVoAActionContext.h" -#include "raids/eyeofeternity/RaidEoETriggerContext.h" -#include "raids/moltencore/RaidMcActionContext.h" -#include "raids/moltencore/RaidMcTriggerContext.h" -#include "raids/aq20/RaidAq20ActionContext.h" -#include "raids/aq20/RaidAq20TriggerContext.h" -#include "raids/karazhan/RaidKarazhanActionContext.h" -#include "raids/karazhan/RaidKarazhanTriggerContext.h" #include "dungeons/DungeonStrategyContext.h" #include "dungeons/wotlk/WotlkDungeonActionContext.h" #include "dungeons/wotlk/WotlkDungeonTriggerContext.h" #include "raids/RaidStrategyContext.h" #include "raids/aq20/RaidAq20ActionContext.h" #include "raids/aq20/RaidAq20TriggerContext.h" -#include "raids/blackwinglair/RaidBwlActionContext.h" -#include "raids/blackwinglair/RaidBwlTriggerContext.h" -#include "raids/eyeofeternity/RaidEoEActionContext.h" -#include "raids/eyeofeternity/RaidEoETriggerContext.h" -#include "raids/icecrown/RaidIccActionContext.h" -#include "raids/icecrown/RaidIccTriggerContext.h" #include "raids/moltencore/RaidMcActionContext.h" #include "raids/moltencore/RaidMcTriggerContext.h" +#include "raids/blackwinglair/RaidBwlActionContext.h" +#include "raids/blackwinglair/RaidBwlTriggerContext.h" +#include "raids/karazhan/RaidKarazhanActionContext.h" +#include "raids/karazhan/RaidKarazhanTriggerContext.h" #include "raids/naxxramas/RaidNaxxActionContext.h" #include "raids/naxxramas/RaidNaxxTriggerContext.h" +#include "raids/eyeofeternity/RaidEoEActionContext.h" +#include "raids/eyeofeternity/RaidEoETriggerContext.h" +#include "raids/vaultofarchavon/RaidVoAActionContext.h" +#include "raids/vaultofarchavon/RaidVoATriggerContext.h" #include "raids/obsidiansanctum/RaidOsActionContext.h" #include "raids/obsidiansanctum/RaidOsTriggerContext.h" #include "raids/onyxia/RaidOnyxiaActionContext.h" #include "raids/onyxia/RaidOnyxiaTriggerContext.h" -#include "raids/vaultofarchavon/RaidVoAActionContext.h" -#include "raids/vaultofarchavon/RaidVoATriggerContext.h" +#include "raids/icecrown/RaidIccActionContext.h" +#include "raids/icecrown/RaidIccTriggerContext.h" SharedNamedObjectContextList AiObjectContext::sharedStrategyContexts; SharedNamedObjectContextList AiObjectContext::sharedActionContexts; @@ -117,8 +98,8 @@ void AiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList& actionContexts) @@ -126,17 +107,17 @@ void AiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList { public: RaidStrategyContext() : NamedObjectContext(false, true) { - // TODO should we give these prefixes (eg: "naxx" -> "raid naxx")? because if we don't it's going to end up - // very crowded (with possible conflicts) once we have strats for all raids and some dungeons - // (mc already very similiar to nc) + creators["aq20"] = &RaidStrategyContext::aq20; creators["mc"] = &RaidStrategyContext::mc; creators["bwl"] = &RaidStrategyContext::bwl; - creators["aq20"] = &RaidStrategyContext::aq20; + creators["karazhan"] = &RaidStrategyContext::karazhan; creators["naxx"] = &RaidStrategyContext::naxx; creators["wotlk-os"] = &RaidStrategyContext::wotlk_os; creators["wotlk-eoe"] = &RaidStrategyContext::wotlk_eoe; creators["voa"] = &RaidStrategyContext::voa; creators["uld"] = &RaidStrategyContext::uld; - creators["icc"] = &RaidStrategyContext::icc; creators["onyxia"] = &RaidStrategyContext::onyxia; - creators["karazhan"] = &RaidStrategyContext::karazhan; + creators["icc"] = &RaidStrategyContext::icc; } private: + static Strategy* aq20(PlayerbotAI* botAI) { return new RaidAq20Strategy(botAI); } static Strategy* mc(PlayerbotAI* botAI) { return new RaidMcStrategy(botAI); } static Strategy* bwl(PlayerbotAI* botAI) { return new RaidBwlStrategy(botAI); } - static Strategy* aq20(PlayerbotAI* botAI) { return new RaidAq20Strategy(botAI); } + static Strategy* karazhan(PlayerbotAI* botAI) { return new RaidKarazhanStrategy(botAI); } static Strategy* naxx(PlayerbotAI* botAI) { return new RaidNaxxStrategy(botAI); } static Strategy* wotlk_os(PlayerbotAI* botAI) { return new RaidOsStrategy(botAI); } static Strategy* wotlk_eoe(PlayerbotAI* botAI) { return new RaidEoEStrategy(botAI); } static Strategy* voa(PlayerbotAI* botAI) { return new RaidVoAStrategy(botAI); } + static Strategy* onyxia(PlayerbotAI* botAI) { return new RaidOnyxiaStrategy(botAI); } static Strategy* uld(PlayerbotAI* botAI) { return new RaidUlduarStrategy(botAI); } static Strategy* icc(PlayerbotAI* botAI) { return new RaidIccStrategy(botAI); } - static Strategy* onyxia(PlayerbotAI* botAI) { return new RaidOnyxiaStrategy(botAI); } - static Strategy* karazhan(PlayerbotAI* botAI) { return new RaidKarazhanStrategy(botAI); } }; #endif diff --git a/src/strategy/raids/karazhan/RaidKarazhanActionContext.h b/src/strategy/raids/karazhan/RaidKarazhanActionContext.h index ac338cba..2c1f7168 100644 --- a/src/strategy/raids/karazhan/RaidKarazhanActionContext.h +++ b/src/strategy/raids/karazhan/RaidKarazhanActionContext.h @@ -16,6 +16,7 @@ public: creators["karazhan maiden of virtue position boss"] = &RaidKarazhanActionContext::karazhan_maiden_of_virtue_position_boss; creators["karazhan maiden of virtue position ranged"] = &RaidKarazhanActionContext::karazhan_maiden_of_virtue_position_ranged; + creators["karazhan big bad wolf position boss"] = &RaidKarazhanActionContext::karazhan_big_bad_wolf_position_boss; creators["karazhan big bad wolf run away"] = &RaidKarazhanActionContext::karazhan_big_bad_wolf_run_away; creators["karazhan romulo and julianne mark target"] = &RaidKarazhanActionContext::karazhan_romulo_and_julianne_mark_target; @@ -52,6 +53,7 @@ private: static Action* karazhan_maiden_of_virtue_position_boss(PlayerbotAI* botAI) { return new KarazhanMaidenOfVirtuePositionBossAction(botAI); } static Action* karazhan_maiden_of_virtue_position_ranged(PlayerbotAI* botAI) { return new KarazhanMaidenOfVirtuePositionRangedAction(botAI); } + static Action* karazhan_big_bad_wolf_position_boss(PlayerbotAI* botAI) { return new KarazhanBigBadWolfPositionBossAction(botAI); } static Action* karazhan_big_bad_wolf_run_away(PlayerbotAI* botAI) { return new KarazhanBigBadWolfRunAwayAction(botAI); } static Action* karazhan_romulo_and_julianne_mark_target(PlayerbotAI* botAI) { return new KarazhanRomuloAndJulianneMarkTargetAction(botAI); } diff --git a/src/strategy/raids/karazhan/RaidKarazhanActions.cpp b/src/strategy/raids/karazhan/RaidKarazhanActions.cpp index 5f0e6064..24335251 100644 --- a/src/strategy/raids/karazhan/RaidKarazhanActions.cpp +++ b/src/strategy/raids/karazhan/RaidKarazhanActions.cpp @@ -4,9 +4,13 @@ #include "Playerbots.h" #include "PlayerbotMgr.h" #include "PlayerbotAI.h" +#include "Position.h" namespace { + // Big Bad Wolf + static int currentIndex = 0; + // Netherspite static std::map beamMoveTimes; static std::map lastBeamMoveSideways; } @@ -149,24 +153,56 @@ bool KarazhanMaidenOfVirtuePositionRangedAction::isUseful() return boss && botAI->IsRanged(bot); } -bool KarazhanBigBadWolfRunAwayAction::Execute(Event event) +bool KarazhanBigBadWolfPositionBossAction::Execute(Event event) { Unit* boss = AI_VALUE2(Unit*, "find target", "the big bad wolf"); - bot->AttackStop(); - bot->InterruptNonMeleeSpells(false); + const float maxDistance = 3.0f; + const float distanceToBossPosition = boss->GetExactDist2d(KARAZHAN_BIG_BAD_WOLF_BOSS_POSITION); + if (distanceToBossPosition > maxDistance) + { + float dX = KARAZHAN_BIG_BAD_WOLF_BOSS_POSITION.GetPositionX() - boss->GetPositionX(); + float dY = KARAZHAN_BIG_BAD_WOLF_BOSS_POSITION.GetPositionY() - boss->GetPositionY(); + + float mX = KARAZHAN_BIG_BAD_WOLF_BOSS_POSITION.GetPositionX() + (dX / distanceToBossPosition) * maxDistance; + float mY = KARAZHAN_BIG_BAD_WOLF_BOSS_POSITION.GetPositionY() + (dY / distanceToBossPosition) * maxDistance; + + float moveDistance = bot->GetExactDist2d(mX, mY); + if (moveDistance < 0.5f) + { + return false; + } + + return MoveTo(bot->GetMapId(), mX, mY, bot->GetPositionZ(), false, false, false, false, + MovementPriority::MOVEMENT_COMBAT, true, false); + } + + return false; +} + +bool KarazhanBigBadWolfPositionBossAction::isUseful() +{ + Unit* boss = AI_VALUE2(Unit*, "find target", "the big bad wolf"); + + return boss && botAI->IsTank(bot) && botAI->HasAggro(boss) && boss->GetVictim() == bot && + !bot->HasAura(SPELL_LITTLE_RED_RIDING_HOOD); +} + +bool KarazhanBigBadWolfRunAwayAction::Execute(Event event) +{ constexpr float threshold = 1.0f; + Position target = KARAZHAN_BIG_BAD_WOLF_RUN_POSITION[currentIndex]; - if (bot->GetExactDist2d(target.GetPositionX(), target.GetPositionY()) < threshold) + while (bot->GetExactDist2d(target.GetPositionX(), target.GetPositionY()) < threshold) { currentIndex = (currentIndex + 1) % 4; target = KARAZHAN_BIG_BAD_WOLF_RUN_POSITION[currentIndex]; } - return MoveTo(bot->GetMapId(), target.GetPositionX(), target.GetPositionY(), target.GetPositionZ(), false, false, - false, true, MovementPriority::MOVEMENT_FORCED); + return MoveTo(bot->GetMapId(), target.GetPositionX(), target.GetPositionY(), target.GetPositionZ(), + false, false, false, true, MovementPriority::MOVEMENT_FORCED); } bool KarazhanBigBadWolfRunAwayAction::isUseful() @@ -222,8 +258,6 @@ bool KarazhanWizardOfOzScorchStrawmanAction::Execute(Event event) if (!group) return false; - const std::vector scorchSpellIds = {42859, 42858, 10207}; - for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* member = itr->GetSource(); @@ -237,19 +271,10 @@ bool KarazhanWizardOfOzScorchStrawmanAction::Execute(Event event) if (!mageAI) continue; - uint32 knownScorchId = 0; - for (uint32 spellId : scorchSpellIds) + if (mageAI->CanCastSpell("scorch", strawman)) { - if (member->HasSpell(spellId)) - { - knownScorchId = spellId; - break; - } + mageAI->CastSpell("scorch", strawman); } - if (!knownScorchId) - continue; - - mageAI->CastSpell(knownScorchId, strawman); } return false; } @@ -507,7 +532,8 @@ bool KarazhanNetherspiteBlockRedBeamAction::Execute(Event event) float sideY = beamPos.GetPositionY() + perpDy * 3.0f; float sideZ = beamPos.GetPositionZ(); - return MoveTo(bot->GetMapId(), sideX, sideY, sideZ, false, false, false, true, MovementPriority::MOVEMENT_FORCED); + return MoveTo(bot->GetMapId(), sideX, sideY, sideZ, false, false, false, true, + MovementPriority::MOVEMENT_FORCED); } } return false; @@ -595,7 +621,8 @@ bool KarazhanNetherspiteBlockBlueBeamAction::Execute(Event event) bool outsideAllVoidZones = true; for (Unit* voidZone : voidZones) { - float voidZoneDist = sqrt(pow(candidateX - voidZone->GetPositionX(), 2) + pow(candidateY - voidZone->GetPositionY(), 2)); + float voidZoneDist = sqrt(pow(candidateX - voidZone->GetPositionX(), 2) + + pow(candidateY - voidZone->GetPositionY(), 2)); if (voidZoneDist < 4.0f) { outsideAllVoidZones = false; @@ -635,8 +662,8 @@ bool KarazhanNetherspiteBlockBlueBeamAction::isUseful() return boss && bluePortal && !boss->HasAura(SPELL_NETHERSPITE_BANISHED); } -// Two healers will block the green beam for each phase (swap at 25 debuff stacks -// OR one rogue or DPS warrior will block the green beam for any entire phase +// Two healers will block the green beam for each phase (swap at 25 debuff stacks) +// OR one rogue or DPS warrior will block the green beam for an entire phase (if they begin the phase as the blocker) // When avoiding void zones, blocking bots will move along the beam to continue blocking bool KarazhanNetherspiteBlockGreenBeamAction::Execute(Event event) { @@ -686,7 +713,8 @@ bool KarazhanNetherspiteBlockGreenBeamAction::Execute(Event event) bool outsideAllVoidZones = true; for (Unit* voidZone : voidZones) { - float voidZoneDist = sqrt(pow(candidateX - voidZone->GetPositionX(), 2) + pow(candidateY - voidZone->GetPositionY(), 2)); + float voidZoneDist = sqrt(pow(candidateX - voidZone->GetPositionX(), 2) + + pow(candidateY - voidZone->GetPositionY(), 2)); if (voidZoneDist < 4.0f) { outsideAllVoidZones = false; @@ -842,11 +870,12 @@ bool KarazhanNetherspiteAvoidBeamAndVoidZoneAction::Execute(Event event) } } } - if (found && karazhanHelper.IsSafePosition(bestCandidate.GetPositionX(), bestCandidate.GetPositionY(), bestCandidate.GetPositionZ(), + if (found && karazhanHelper.IsSafePosition(bestCandidate.GetPositionX(), + bestCandidate.GetPositionY(), bestCandidate.GetPositionZ(), voidZones, 4.0f)) - return MoveTo(bot->GetMapId(), bestCandidate.GetPositionX(), bestCandidate.GetPositionY(), bestCandidate.GetPositionZ(), - false, false, false, true, MovementPriority::MOVEMENT_COMBAT); + return MoveTo(bot->GetMapId(), bestCandidate.GetPositionX(), bestCandidate.GetPositionY(), + bestCandidate.GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT); return false; } @@ -929,7 +958,8 @@ bool KarazhanPrinceMalchezaarNonTankAvoidHazardAction::Execute(Event event) float destZ = bossZ; if (!bot->IsWithinLOS(x, y, destZ)) continue; - bool pathSafe = karazhanHelper.IsStraightPathSafe(Position(bx, by, bz), Position(x, y, destZ), infernals, safeInfernalDistance, stepSize); + bool pathSafe = karazhanHelper.IsStraightPathSafe(Position(bx, by, bz), Position(x, y, destZ), + infernals, safeInfernalDistance, stepSize); float moveDist = sqrt(pow(x - bx, 2) + pow(y - by, 2)); if (pathSafe && moveDist < bestMoveDist) { @@ -946,7 +976,8 @@ bool KarazhanPrinceMalchezaarNonTankAvoidHazardAction::Execute(Event event) bot->AttackStop(); bot->InterruptNonMeleeSpells(false); - return MoveTo(bot->GetMapId(), bestDestX, bestDestY, bestDestZ, false, false, false, true, MovementPriority::MOVEMENT_FORCED); + return MoveTo(bot->GetMapId(), bestDestX, bestDestY, bestDestZ, false, false, false, true, + MovementPriority::MOVEMENT_FORCED); } return false; } @@ -981,7 +1012,8 @@ bool KarazhanPrinceMalchezaarNonTankAvoidHazardAction::Execute(Event event) float destZ = bossZ; if (!bot->IsWithinLOS(x, y, destZ)) continue; - bool pathSafe = karazhanHelper.IsStraightPathSafe(Position(bx, by, bz), Position(x, y, destZ), infernals, safeInfernalDistance, stepSize); + bool pathSafe = karazhanHelper.IsStraightPathSafe(Position(bx, by, bz), Position(x, y, destZ), + infernals, safeInfernalDistance, stepSize); float moveDist = sqrt(pow(x - bx, 2) + pow(y - by, 2)); if (pathSafe && moveDist < bestMoveDist) { @@ -994,20 +1026,23 @@ bool KarazhanPrinceMalchezaarNonTankAvoidHazardAction::Execute(Event event) } if (!pathSafe) { - Position arcPoint = karazhanHelper.CalculateArcPoint(Position(bx, by, bz), Position(x, y, destZ), Position(bossX, bossY, bossZ)); + Position arcPoint = karazhanHelper.CalculateArcPoint(Position(bx, by, bz), Position(x, y, destZ), + Position(bossX, bossY, bossZ)); if (!bot->IsWithinLOS(arcPoint.GetPositionX(), arcPoint.GetPositionY(), arcPoint.GetPositionZ())) continue; bool arcSafe = true; for (Unit* infernal : infernals) { - float infernalDist = sqrt(pow(arcPoint.GetPositionX() - infernal->GetPositionX(), 2) + pow(arcPoint.GetPositionY() - infernal->GetPositionY(), 2)); + float infernalDist = sqrt(pow(arcPoint.GetPositionX() - infernal->GetPositionX(), 2) + + pow(arcPoint.GetPositionY() - infernal->GetPositionY(), 2)); if (infernalDist < safeInfernalDistance) { arcSafe = false; break; } } - float arcMoveDist = sqrt(pow(arcPoint.GetPositionX() - bx, 2) + pow(arcPoint.GetPositionY() - by, 2)); + float arcMoveDist = sqrt(pow(arcPoint.GetPositionX() - bx, 2) + + pow(arcPoint.GetPositionY() - by, 2)); if (arcSafe && arcMoveDist < bestMoveDist) { bestMoveDist = arcMoveDist; @@ -1025,7 +1060,8 @@ bool KarazhanPrinceMalchezaarNonTankAvoidHazardAction::Execute(Event event) bot->AttackStop(); bot->InterruptNonMeleeSpells(false); - return MoveTo(bot->GetMapId(), bestDestX, bestDestY, bestDestZ, false, false, false, true, MovementPriority::MOVEMENT_COMBAT); + return MoveTo(bot->GetMapId(), bestDestX, bestDestY, bestDestZ, false, false, false, true, + MovementPriority::MOVEMENT_COMBAT); } } } @@ -1082,7 +1118,8 @@ bool KarazhanPrinceMalchezaarTankAvoidHazardAction::Execute(Event event) float z = bz; if (!bot->IsWithinLOS(x, y, z)) continue; - bool safe = karazhanHelper.IsStraightPathSafe(Position(bx, by, bz), Position(x, y, z), infernals, safeInfernalDistance, stepSize); + bool safe = karazhanHelper.IsStraightPathSafe(Position(bx, by, bz), Position(x, y, z), + infernals, safeInfernalDistance, stepSize); float moveDist = sqrt(pow(x - bx, 2) + pow(y - by, 2)); if (safe && moveDist < bestMoveDist) { @@ -1095,13 +1132,15 @@ bool KarazhanPrinceMalchezaarTankAvoidHazardAction::Execute(Event event) } if (!safe) { - Position arcPoint = karazhanHelper.CalculateArcPoint(Position(bx, by, bz), Position(x, y, z), Position(bx, by, bz)); + Position arcPoint = karazhanHelper.CalculateArcPoint(Position(bx, by, bz), Position(x, y, z), + Position(bx, by, bz)); if (!bot->IsWithinLOS(arcPoint.GetPositionX(), arcPoint.GetPositionY(), arcPoint.GetPositionZ())) continue; bool arcSafe = true; for (Unit* infernal : infernals) { - float infernalDist = sqrt(pow(arcPoint.GetPositionX() - infernal->GetPositionX(), 2) + pow(arcPoint.GetPositionY() - infernal->GetPositionY(), 2)); + float infernalDist = sqrt(pow(arcPoint.GetPositionX() - infernal->GetPositionX(), 2) + + pow(arcPoint.GetPositionY() - infernal->GetPositionY(), 2)); if (infernalDist < safeInfernalDistance) { arcSafe = false; @@ -1125,7 +1164,8 @@ bool KarazhanPrinceMalchezaarTankAvoidHazardAction::Execute(Event event) { bot->AttackStop(); bot->InterruptNonMeleeSpells(false); - return MoveTo(bot->GetMapId(), bestDestX, bestDestY, bestDestZ, false, false, false, true, MovementPriority::MOVEMENT_COMBAT); + return MoveTo(bot->GetMapId(), bestDestX, bestDestY, bestDestZ, false, false, false, true, + MovementPriority::MOVEMENT_COMBAT); } } return false; diff --git a/src/strategy/raids/karazhan/RaidKarazhanActions.h b/src/strategy/raids/karazhan/RaidKarazhanActions.h index c9b34d03..4ab24ed9 100644 --- a/src/strategy/raids/karazhan/RaidKarazhanActions.h +++ b/src/strategy/raids/karazhan/RaidKarazhanActions.h @@ -39,6 +39,15 @@ public: bool isUseful() override; }; +class KarazhanBigBadWolfPositionBossAction : public MovementAction +{ +public: + KarazhanBigBadWolfPositionBossAction(PlayerbotAI* botAI, std::string const name = "karazhan big bad wolf position boss") : MovementAction(botAI, name) {} + + bool Execute(Event event) override; + bool isUseful() override; +}; + class KarazhanBigBadWolfRunAwayAction : public MovementAction { public: diff --git a/src/strategy/raids/karazhan/RaidKarazhanHelpers.cpp b/src/strategy/raids/karazhan/RaidKarazhanHelpers.cpp index 21b08e47..81479e7e 100644 --- a/src/strategy/raids/karazhan/RaidKarazhanHelpers.cpp +++ b/src/strategy/raids/karazhan/RaidKarazhanHelpers.cpp @@ -8,6 +8,30 @@ #include "Position.h" #include "Spell.h" +const Position KARAZHAN_MAIDEN_OF_VIRTUE_BOSS_POSITION = Position(-10945.881f, -2103.782f, 92.712f); +const Position KARAZHAN_MAIDEN_OF_VIRTUE_RANGED_POSITION[8] = +{ + { -10931.178f, -2116.580f, 92.179f }, + { -10925.828f, -2102.425f, 92.180f }, + { -10933.089f, -2088.5017f, 92.180f }, + { -10947.59f, -2082.8147f, 92.180f }, + { -10960.912f, -2090.4368f, 92.179f }, + { -10966.017f, -2105.288f, 92.175f }, + { -10959.242f, -2119.6172f, 92.180f }, + { -10944.495f, -2123.857f, 92.180f }, +}; + +const Position KARAZHAN_BIG_BAD_WOLF_BOSS_POSITION = Position(-10913.391f, -1773.508f, 90.477f); +const Position KARAZHAN_BIG_BAD_WOLF_RUN_POSITION[4] = +{ + { -10875.456f, -1779.036f, 90.477f }, + { -10872.281f, -1751.638f, 90.477f }, + { -10910.492f, -1747.401f, 90.477f }, + { -10913.391f, -1773.508f, 90.477f }, +}; + +const Position KARAZHAN_THE_CURATOR_BOSS_POSITION = Position(-11139.463f, -1884.645f, 165.765f); + void RaidKarazhanHelpers::MarkTargetWithSkull(Unit* target) { if (!target) diff --git a/src/strategy/raids/karazhan/RaidKarazhanHelpers.h b/src/strategy/raids/karazhan/RaidKarazhanHelpers.h index 39335de6..42db6580 100644 --- a/src/strategy/raids/karazhan/RaidKarazhanHelpers.h +++ b/src/strategy/raids/karazhan/RaidKarazhanHelpers.h @@ -3,6 +3,7 @@ #include "AiObject.h" #include "Playerbots.h" +#include "Position.h" enum KarazhanSpells { @@ -11,7 +12,6 @@ enum KarazhanSpells // Opera Event SPELL_LITTLE_RED_RIDING_HOOD = 30756, - SPELL_FEAR = 6215, // Rank 3 // Shade of Aran SPELL_FLAME_WREATH = 30004, @@ -29,9 +29,6 @@ enum KarazhanSpells // Prince Malchezaar SPELL_ENFEEBLE = 30843, - - // Nightbane - SPELL_CHARRED_EARTH = 30129 }; enum KarazhanNpcs @@ -54,32 +51,13 @@ enum KarazhanNpcs // Prince Malchezaar NPC_NETHERSPITE_INFERNAL = 17646, - - // Nightbane - NPC_RESTLESS_SKELETON = 17261, }; -const Position KARAZHAN_MAIDEN_OF_VIRTUE_BOSS_POSITION = Position(-10945.881f, -2103.7817f, 92.71163f); -const Position KARAZHAN_MAIDEN_OF_VIRTUE_RANGED_POSITION[8] = -{ - { -10931.178f, -2116.58f, 92.1787f }, - { -10925.828f, -2102.425f, 92.18016f }, - { -10933.089f, -2088.5017f, 92.18028f }, - { -10947.59f, -2082.8147f, 92.18024f }, - { -10960.912f, -2090.4368f, 92.17964f }, - { -10966.017f, -2105.288f, 92.17582f }, - { -10959.242f, -2119.6172f, 92.18062f }, - { -10944.495f, -2123.857f, 92.18021f }, -}; - -const Position KARAZHAN_BIG_BAD_WOLF_RUN_POSITION[4] = { - { -10913.391f, -1773.5083f, 90.47706f }, - { -10875.456f, -1779.0358f, 90.47706f }, - { -10872.281f, -1751.6376f, 90.47716f }, - { -10910.492f, -1747.401f, 90.477165f }, -}; - -const Position KARAZHAN_THE_CURATOR_BOSS_POSITION = Position(-11139.463f, -1884.6451f, 165.76564f); +extern const Position KARAZHAN_MAIDEN_OF_VIRTUE_BOSS_POSITION; +extern const Position KARAZHAN_MAIDEN_OF_VIRTUE_RANGED_POSITION[8]; +extern const Position KARAZHAN_BIG_BAD_WOLF_BOSS_POSITION; +extern const Position KARAZHAN_BIG_BAD_WOLF_RUN_POSITION[4]; +extern const Position KARAZHAN_THE_CURATOR_BOSS_POSITION; class RaidKarazhanHelpers : public AiObject { @@ -99,7 +77,8 @@ public: bool IsSafePosition (float x, float y, float z, const std::vector& hazards, float hazardRadius); std::vector GetSpawnedInfernals() const; - bool IsStraightPathSafe(const Position& start, const Position& target, const std::vector& hazards, float hazardRadius, float stepSize); + bool IsStraightPathSafe(const Position& start, const Position& target, + const std::vector& hazards, float hazardRadius, float stepSize); Position CalculateArcPoint(const Position& current, const Position& target, const Position& center); }; diff --git a/src/strategy/raids/karazhan/RaidKarazhanMultipliers.cpp b/src/strategy/raids/karazhan/RaidKarazhanMultipliers.cpp index 4843e27b..a1b25ee5 100644 --- a/src/strategy/raids/karazhan/RaidKarazhanMultipliers.cpp +++ b/src/strategy/raids/karazhan/RaidKarazhanMultipliers.cpp @@ -2,6 +2,7 @@ #include "RaidKarazhanActions.h" #include "RaidKarazhanHelpers.h" #include "AiObjectContext.h" +#include "AttackAction.h" #include "DruidBearActions.h" #include "DruidCatActions.h" #include "WarriorActions.h" @@ -14,18 +15,33 @@ static bool IsChargeAction(Action* action) dynamic_cast(action); } +float KarazhanBigBadWolfMultiplier::GetValue(Action* action) +{ + Unit* boss = AI_VALUE2(Unit*, "find target", "the big bad wolf"); + if (!boss) + return 1.0f; + + if (bot->HasAura(SPELL_LITTLE_RED_RIDING_HOOD)) + { + if ((dynamic_cast(action) && !dynamic_cast(action)) || + (dynamic_cast(action))) + return 0.0f; + } + return 1.0f; +} + float KarazhanShadeOfAranMultiplier::GetValue(Action* action) { Unit* boss = AI_VALUE2(Unit*, "find target", "shade of aran"); if (!boss) return 1.0f; - if (boss && boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(SPELL_ARCANE_EXPLOSION)) + if (boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(SPELL_ARCANE_EXPLOSION)) { if (IsChargeAction(action)) return 0.0f; - if (dynamic_cast(action) || IsChargeAction(action)) + if (dynamic_cast(action)) { const float safeDistance = 20.0f; if (bot->GetDistance2d(boss) >= safeDistance) diff --git a/src/strategy/raids/karazhan/RaidKarazhanMultipliers.h b/src/strategy/raids/karazhan/RaidKarazhanMultipliers.h index e2066554..d29aa027 100644 --- a/src/strategy/raids/karazhan/RaidKarazhanMultipliers.h +++ b/src/strategy/raids/karazhan/RaidKarazhanMultipliers.h @@ -3,6 +3,13 @@ #include "Multiplier.h" +class KarazhanBigBadWolfMultiplier : public Multiplier +{ +public: + KarazhanBigBadWolfMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "karazhan big bad wolf multiplier") {} + virtual float GetValue(Action* action); +}; + class KarazhanShadeOfAranMultiplier : public Multiplier { public: diff --git a/src/strategy/raids/karazhan/RaidKarazhanStrategy.cpp b/src/strategy/raids/karazhan/RaidKarazhanStrategy.cpp index 8e39f254..f93c923c 100644 --- a/src/strategy/raids/karazhan/RaidKarazhanStrategy.cpp +++ b/src/strategy/raids/karazhan/RaidKarazhanStrategy.cpp @@ -22,6 +22,7 @@ void RaidKarazhanStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode( "karazhan big bad wolf", NextAction::array(0, new NextAction("karazhan big bad wolf run away", ACTION_EMERGENCY + 6), + new NextAction("karazhan big bad wolf position boss", ACTION_RAID + 1), nullptr))); triggers.push_back(new TriggerNode(