From 634ce3d1835f7a26798ad09173d32d1ffc0f5cfa Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Thu, 8 Jun 2023 11:46:14 +0800 Subject: [PATCH] naxx raid grobbulus --- src/strategy/actions/ActionContext.h | 10 +- src/strategy/actions/RaidNaxxAction.cpp | 111 +++++++++---------- src/strategy/actions/RaidNaxxAction.h | 128 +++++++++++----------- src/strategy/generic/RaidStrategy.cpp | 18 +-- src/strategy/triggers/RaidNaxxTrigger.cpp | 57 ++++++---- src/strategy/triggers/RaidNaxxTrigger.h | 68 ++++++------ src/strategy/triggers/TriggerContext.h | 4 +- 7 files changed, 203 insertions(+), 193 deletions(-) diff --git a/src/strategy/actions/ActionContext.h b/src/strategy/actions/ActionContext.h index 8d87f607..da824cab 100644 --- a/src/strategy/actions/ActionContext.h +++ b/src/strategy/actions/ActionContext.h @@ -223,8 +223,9 @@ class ActionContext : public NamedObjectContext creators["toggle pet spell"] = &ActionContext::toggle_pet_spell; - // creators["rotate grobbulus"] = &ActionContext::rotate_grobbulus; - // creators["grobbulus move center"] = &ActionContext::grobbulus_move_center; + creators["grobbulus go behind the boss"] = &ActionContext::go_behind_the_boss; + creators["rotate grobbulus"] = &ActionContext::rotate_grobbulus; + creators["grobbulus move center"] = &ActionContext::grobbulus_move_center; creators["heigan dance melee"] = &ActionContext::heigan_dance_melee; creators["heigan dance ranged"] = &ActionContext::heigan_dance_ranged; @@ -420,8 +421,9 @@ class ActionContext : public NamedObjectContext static Action* toggle_pet_spell(PlayerbotAI* ai) { return new TogglePetSpellAutoCastAction(ai); } - // static Action* rotate_grobbulus(PlayerbotAI* ai) { return new RotateGrobbulusAction(ai); } - // static Action* grobbulus_move_center(PlayerbotAI* ai) { return new GrobblulusMoveCenterAction(ai); } + static Action* go_behind_the_boss(PlayerbotAI* ai) { return new GoBehindTheBossAction(ai); } + static Action* rotate_grobbulus(PlayerbotAI* ai) { return new RotateGrobbulusAction(ai); } + static Action* grobbulus_move_center(PlayerbotAI* ai) { return new GrobblulusMoveCenterAction(ai); } static Action* heigan_dance_melee(PlayerbotAI* ai) { return new HeiganDanceMeleeAction(ai); } static Action* heigan_dance_ranged(PlayerbotAI* ai) { return new HeiganDanceRangedAction(ai); } // static Action* thaddius_attack_nearest_pet(PlayerbotAI* ai) { return new ThaddiusAttackNearestPetAction(ai); } diff --git a/src/strategy/actions/RaidNaxxAction.cpp b/src/strategy/actions/RaidNaxxAction.cpp index ca4f8307..bcdf61b9 100644 --- a/src/strategy/actions/RaidNaxxAction.cpp +++ b/src/strategy/actions/RaidNaxxAction.cpp @@ -4,6 +4,7 @@ #include "RaidStrategy.h" #include "ScriptedCreature.h" #include "../../../../src/server/scripts/Northrend/Naxxramas/boss_heigan.h" +#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_grobbulus.h" using namespace std; @@ -39,70 +40,70 @@ using namespace std; // } -// bool GoBehindTheBossAction::Execute(Event event) -// { -// Unit* boss = AI_VALUE(Unit*, "boss target"); -// if (!boss) { -// return false; -// } -// // Position* pos = boss->GetPosition(); -// float orientation = boss->GetOrientation() + M_PI + delta_angle; -// float x = boss->GetPositionX(); -// float y = boss->GetPositionY(); -// float z = boss->GetPositionZ(); -// float rx = x + cos(orientation) * distance; -// float ry = y + sin(orientation) * distance; -// return MoveTo(bot->GetMapId(), rx, ry, z); -// } +bool GoBehindTheBossAction::Execute(Event event) +{ + Unit* boss = AI_VALUE(Unit*, "boss target"); + if (!boss) { + return false; + } + // Position* pos = boss->GetPosition(); + float orientation = boss->GetOrientation() + M_PI + delta_angle; + float x = boss->GetPositionX(); + float y = boss->GetPositionY(); + float z = boss->GetPositionZ(); + float rx = x + cos(orientation) * distance; + float ry = y + sin(orientation) * distance; + return MoveTo(bot->GetMapId(), rx, ry, z); +} // bool MoveToPointForceAction::Execute(Event event) // { // return MoveTo(bot->GetMapId(), x, y, bot->GetPositionZ(), true); // } -// bool MoveInsideAction::Execute(Event event) -// { -// return MoveInside(bot->GetMapId(), x, y, bot->GetPositionZ(), distance); -// } +bool MoveInsideAction::Execute(Event event) +{ + return MoveInside(bot->GetMapId(), x, y, bot->GetPositionZ(), distance); +} -// bool RotateAroundTheCenterPointAction::Execute(Event event) -// { -// // uint32 nearest = FindNearestWaypoint(); -// // uint32 next_point = (nearest + 1) % intervals; -// uint32 next_point = GetCurrWaypoint(); -// if (MoveTo(bot->GetMapId(), waypoints[next_point].first, waypoints[next_point].second, bot->GetPositionZ())) { -// call_counters += 1; -// return true; -// } -// return false; -// } +bool RotateAroundTheCenterPointAction::Execute(Event event) +{ + // uint32 nearest = FindNearestWaypoint(); + // uint32 next_point = (nearest + 1) % intervals; + uint32 next_point = GetCurrWaypoint(); + if (MoveTo(bot->GetMapId(), waypoints[next_point].first, waypoints[next_point].second, bot->GetPositionZ())) { + call_counters += 1; + return true; + } + return false; +} -// uint32 RotateAroundTheCenterPointAction::FindNearestWaypoint() -// { -// float minDistance = 0; -// int ret = -1; -// for (int i = 0; i < intervals; i++) { -// float w_x = waypoints[i].first, w_y = waypoints[i].second; -// float dis = bot->GetDistance2d(w_x, w_y); -// if (ret == -1 || dis < minDistance) { -// ret = i; -// minDistance = dis; -// } -// } -// return ret; -// } +uint32 RotateAroundTheCenterPointAction::FindNearestWaypoint() +{ + float minDistance = 0; + int ret = -1; + for (int i = 0; i < intervals; i++) { + float w_x = waypoints[i].first, w_y = waypoints[i].second; + float dis = bot->GetDistance2d(w_x, w_y); + if (ret == -1 || dis < minDistance) { + ret = i; + minDistance = dis; + } + } + return ret; +} -// uint32 RotateGrobbulusAction::GetCurrWaypoint() -// { -// Unit* boss = AI_VALUE(Unit*, "boss target"); -// if (!boss) { -// return false; -// } -// BossAI* boss_ai = dynamic_cast(boss->GetAI()); -// EventMap* eventMap = boss_botAI->GetEvents(); -// const uint32 event_time = eventMap->GetNextEventTime(2); -// return (event_time / 15000) % intervals; -// } +uint32 RotateGrobbulusAction::GetCurrWaypoint() +{ + Unit* boss = AI_VALUE(Unit*, "boss target"); + if (!boss) { + return false; + } + BossAI* boss_ai = dynamic_cast(boss->GetAI()); + EventMap* eventMap = boss_ai->GetEvents(); + const uint32 event_time = eventMap->GetNextEventTime(2); + return (event_time / 15000) % intervals; +} bool HeiganDanceAction::CalculateSafe() { Unit* boss = AI_VALUE2(Unit*, "find target", "heigan the unclean"); diff --git a/src/strategy/actions/RaidNaxxAction.h b/src/strategy/actions/RaidNaxxAction.h index 1e9c1157..41052619 100644 --- a/src/strategy/actions/RaidNaxxAction.h +++ b/src/strategy/actions/RaidNaxxAction.h @@ -16,17 +16,17 @@ // virtual bool Execute(Event event); // }; -// class GoBehindTheBossAction : public MovementAction -// { -// public: -// GoBehindTheBossAction(PlayerbotAI* ai, float distance = 24.0f, float delta_angle = M_PI / 8) : MovementAction(ai, "grobbulus go behind the boss") { -// this->distance = distance; -// this->delta_angle = delta_angle; -// } -// virtual bool Execute(Event event); -// protected: -// float distance, delta_angle; -// }; +class GoBehindTheBossAction : public MovementAction +{ +public: + GoBehindTheBossAction(PlayerbotAI* ai, float distance = 24.0f, float delta_angle = M_PI / 8) : MovementAction(ai, "grobbulus go behind the boss") { + this->distance = distance; + this->delta_angle = delta_angle; + } + virtual bool Execute(Event event); +protected: + float distance, delta_angle; +}; // class MoveToPointForceAction : public MovementAction // { @@ -40,62 +40,62 @@ // float x, y; // }; -// class MoveInsideAction : public MovementAction -// { -// public: -// MoveInsideAction(PlayerbotAI* ai, float x, float y, float distance = 5.0f) : MovementAction(ai, "move inside") { -// this->x = x; -// this->y = y; -// this->distance = distance; -// } -// virtual bool Execute(Event event); -// protected: -// float x, y, distance; -// }; +class MoveInsideAction : public MovementAction +{ +public: + MoveInsideAction(PlayerbotAI* ai, float x, float y, float distance = 5.0f) : MovementAction(ai, "move inside") { + this->x = x; + this->y = y; + this->distance = distance; + } + virtual bool Execute(Event event); +protected: + float x, y, distance; +}; -// class RotateAroundTheCenterPointAction : public MovementAction -// { -// public: -// RotateAroundTheCenterPointAction(PlayerbotAI* ai, string name, -// float center_x, float center_y, float radius = 40.0f, -// uint32 intervals = 16, bool clockwise = true, float start_angle = 0) : MovementAction(ai, name) { -// this->center_x = center_x; -// this->center_y = center_y; -// this->radius = radius; -// this->intervals = intervals; -// this->clockwise = clockwise; -// this->call_counters = 0; -// for (int i = 0; i < intervals; i++) { -// float angle = start_angle + 2 * M_PI * i / intervals; -// waypoints.push_back(std::make_pair(center_x + cos(angle) * radius, center_y + sin(angle) * radius)); -// } -// } -// virtual bool Execute(Event event); -// protected: -// virtual uint32 GetCurrWaypoint() { return 0; } -// uint32 FindNearestWaypoint(); -// float center_x, center_y, radius; -// uint32 intervals, call_counters; -// bool clockwise; -// std::vector> waypoints; -// }; +class RotateAroundTheCenterPointAction : public MovementAction +{ +public: + RotateAroundTheCenterPointAction(PlayerbotAI* ai, std::string name, + float center_x, float center_y, float radius = 40.0f, + uint32 intervals = 16, bool clockwise = true, float start_angle = 0) : MovementAction(ai, name) { + this->center_x = center_x; + this->center_y = center_y; + this->radius = radius; + this->intervals = intervals; + this->clockwise = clockwise; + this->call_counters = 0; + for (int i = 0; i < intervals; i++) { + float angle = start_angle + 2 * M_PI * i / intervals; + waypoints.push_back(std::make_pair(center_x + cos(angle) * radius, center_y + sin(angle) * radius)); + } + } + virtual bool Execute(Event event); +protected: + virtual uint32 GetCurrWaypoint() { return 0; } + uint32 FindNearestWaypoint(); + float center_x, center_y, radius; + uint32 intervals, call_counters; + bool clockwise; + std::vector> waypoints; +}; -// class RotateGrobbulusAction : public RotateAroundTheCenterPointAction -// { -// public: -// RotateGrobbulusAction(PlayerbotAI* ai): RotateAroundTheCenterPointAction(ai, "rotate grobbulus", 3281.23f, -3310.38f, 35.0f, 8, true, M_PI) {} -// virtual bool isUseful() { -// return RotateAroundTheCenterPointAction::isUseful() && ai->IsMainTank(bot) && AI_VALUE2(bool, "has aggro", "boss target"); -// } -// virtual uint32 GetCurrWaypoint(); -// protected: -// }; +class RotateGrobbulusAction : public RotateAroundTheCenterPointAction +{ +public: + RotateGrobbulusAction(PlayerbotAI* botAI): RotateAroundTheCenterPointAction(botAI, "rotate grobbulus", 3281.23f, -3310.38f, 35.0f, 8, true, M_PI) {} + virtual bool isUseful() { + return RotateAroundTheCenterPointAction::isUseful() && botAI->IsMainTank(bot) && AI_VALUE2(bool, "has aggro", "boss target"); + } + virtual uint32 GetCurrWaypoint(); +protected: +}; -// class GrobblulusMoveCenterAction : public MoveInsideAction -// { -// public: -// GrobblulusMoveCenterAction(PlayerbotAI* ai) : MoveInsideAction(ai, 3281.23f, -3310.38f, 5.0f) {} -// }; +class GrobblulusMoveCenterAction : public MoveInsideAction +{ +public: + GrobblulusMoveCenterAction(PlayerbotAI* ai) : MoveInsideAction(ai, 3281.23f, -3310.38f, 5.0f) {} +}; class HeiganDanceAction : public MovementAction { diff --git a/src/strategy/generic/RaidStrategy.cpp b/src/strategy/generic/RaidStrategy.cpp index 126141f9..1fa82184 100644 --- a/src/strategy/generic/RaidStrategy.cpp +++ b/src/strategy/generic/RaidStrategy.cpp @@ -297,17 +297,17 @@ void RaidNaxxGenericStrategy::InitTriggers(std::vector &triggers) // NextAction::array(0, new NextAction("try to get boss ai", ACTION_RAID), NULL))); // Grobbulus - // triggers.push_back(new TriggerNode( - // "mutating injection", - // NextAction::array(0, new NextAction("grobbulus go behind the boss", ACTION_RAID + 2), NULL))); + triggers.push_back(new TriggerNode( + "mutating injection", + NextAction::array(0, new NextAction("grobbulus go behind the boss", ACTION_RAID + 2), NULL))); - // triggers.push_back(new TriggerNode( - // "mutating injection removed", - // NextAction::array(0, new NextAction("grobbulus move center", ACTION_RAID + 1), NULL))); + triggers.push_back(new TriggerNode( + "mutating injection removed", + NextAction::array(0, new NextAction("grobbulus move center", ACTION_RAID + 1), NULL))); - // triggers.push_back(new TriggerNode( - // "grobbulus cloud", - // NextAction::array(0, new NextAction("rotate grobbulus", ACTION_RAID + 1), NULL))); + triggers.push_back(new TriggerNode( + "grobbulus cloud", + NextAction::array(0, new NextAction("rotate grobbulus", ACTION_RAID + 1), NULL))); // Heigan the Unclean triggers.push_back(new TriggerNode( diff --git a/src/strategy/triggers/RaidNaxxTrigger.cpp b/src/strategy/triggers/RaidNaxxTrigger.cpp index 78087b2f..8994965e 100644 --- a/src/strategy/triggers/RaidNaxxTrigger.cpp +++ b/src/strategy/triggers/RaidNaxxTrigger.cpp @@ -2,30 +2,41 @@ #include "RaidNaxxTrigger.h" #include "ScriptedCreature.h" -// bool MutatingInjectionRemovedTrigger::IsActive() -// { -// Unit* boss = AI_VALUE2(Unit*, "find target", "grobbulus"); -// if (!boss) { -// return false; -// } -// return HasNotAuraTrigger::IsActive() && botAI->GetCurrentState() == BOT_STATE_COMBAT && botAI->IsRanged(bot); -// } +bool AuraRemovedTrigger::IsActive() { + bool check = botAI->HasAura(name, bot, false, false, -1, true); + bool ret = false; + if (prev_check && !check) { + ret = true; + } + prev_check = check; + return ret; +} -// bool BossEventTrigger::IsActive() -// { -// Unit* boss = AI_VALUE(Unit*, "boss target"); -// if (!boss || boss->GetEntry() != boss_entry) { -// return false; -// } -// BossAI* boss_ai = dynamic_cast(boss->GetAI()); -// EventMap* eventMap = boss_botAI->GetEvents(); -// const uint32 event_time = eventMap->GetNextEventTime(event_id); -// if (event_time != last_event_time) { -// last_event_time = event_time; -// return true; -// } -// return false; -// } +bool MutatingInjectionRemovedTrigger::IsActive() +{ + Unit* boss = AI_VALUE2(Unit*, "find target", "grobbulus"); + if (!boss) { + return false; + } + return HasNoAuraTrigger::IsActive() && botAI->GetState() == BOT_STATE_COMBAT && botAI->IsRanged(bot); +} + +bool BossEventTrigger::IsActive() +{ + Unit* boss = AI_VALUE(Unit*, "boss target"); + if (!boss || boss->GetEntry() != boss_entry) { + return false; + } + if (!eventMap) { + return false; + } + const uint32 event_time = eventMap->GetNextEventTime(event_id); + if (event_time != last_event_time) { + last_event_time = event_time; + return true; + } + return false; +} // bool BossPhaseTrigger::IsActive() // { diff --git a/src/strategy/triggers/RaidNaxxTrigger.h b/src/strategy/triggers/RaidNaxxTrigger.h index 10fbe5c8..98f7a27a 100644 --- a/src/strategy/triggers/RaidNaxxTrigger.h +++ b/src/strategy/triggers/RaidNaxxTrigger.h @@ -2,44 +2,37 @@ #ifndef _PLAYERBOT_RAIDNAXXTRIGGER_H #define _PLAYERBOT_RAIDNAXXTRIGGER_H +#include "EventMap.h" #include "Trigger.h" #include "PlayerbotAIConfig.h" #include "GenericTriggers.h" +#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_grobbulus.h" using namespace std; -// class MutatingInjectionTrigger : public HasAuraTrigger -// { -// public: -// MutatingInjectionTrigger(PlayerbotAI* ai): HasAuraTrigger(ai, "mutating injection", 1) {} -// }; +class MutatingInjectionTrigger : public HasAuraTrigger +{ +public: + MutatingInjectionTrigger(PlayerbotAI* ai): HasAuraTrigger(ai, "mutating injection", 1) {} +}; -// class AuraRemovedTrigger : public Trigger -// { -// public: -// AuraRemovedTrigger(PlayerbotAI* ai, string name): Trigger(ai, name, 1) { -// this->prev_check = false; -// } -// virtual bool IsActive() { -// bool check = ai->HasAuraWithDuration(name, bot); -// bool ret = false; -// // bot->Yell(to_string(prev_check) + to_string(check), LANG_UNIVERSAL); -// if (prev_check && !check) { -// ret = true; -// } -// prev_check = check; -// return ret; -// } -// protected: -// bool prev_check; -// }; +class AuraRemovedTrigger : public Trigger +{ +public: + AuraRemovedTrigger(PlayerbotAI* botAI, string name): Trigger(botAI, name, 1) { + this->prev_check = false; + } + virtual bool IsActive() override; +protected: + bool prev_check; +}; -// class MutatingInjectionRemovedTrigger : public HasNotAuraTrigger -// { -// public: -// MutatingInjectionRemovedTrigger(PlayerbotAI* ai): HasNotAuraTrigger(ai, "mutating injection", 1) {} -// virtual bool IsActive(); -// }; +class MutatingInjectionRemovedTrigger : public HasNoAuraTrigger +{ +public: + MutatingInjectionRemovedTrigger(PlayerbotAI* ai): HasNoAuraTrigger(ai, "mutating injection") {} + virtual bool IsActive(); +}; class BossEventTrigger : public Trigger { @@ -52,6 +45,7 @@ public: virtual bool IsActive(); protected: uint32 boss_entry, event_id, last_event_time; + EventMap *eventMap; }; class BossPhaseTrigger : public Trigger @@ -67,12 +61,14 @@ protected: uint32 phase_mask; }; -// class GrobbulusCloudTrigger : public BossEventTrigger -// { -// public: -// GrobbulusCloudTrigger(PlayerbotAI* ai): BossEventTrigger(ai, 15931, 2, "grobbulus cloud event") {} -// virtual bool IsActive(); -// }; +class GrobbulusCloudTrigger : public BossEventTrigger +{ +public: + GrobbulusCloudTrigger(PlayerbotAI* ai): BossEventTrigger(ai, 15931, 2, "grobbulus cloud event") { + this->eventMap = boss_grobbulus::boss_grobbulusAI + } + virtual bool IsActive(); +}; class HeiganMeleeTrigger : public Trigger { diff --git a/src/strategy/triggers/TriggerContext.h b/src/strategy/triggers/TriggerContext.h index c096f0f1..95281021 100644 --- a/src/strategy/triggers/TriggerContext.h +++ b/src/strategy/triggers/TriggerContext.h @@ -194,7 +194,7 @@ class TriggerContext : public NamedObjectContext creators["rpg trade useful"] = &TriggerContext::rpg_trade_useful; creators["rpg duel"] = &TriggerContext::rpg_duel; - // creators["mutating injection"] = &TriggerContext::mutating_injection; + creators["mutating injection"] = &TriggerContext::mutating_injection; // creators["mutating injection removed"] = &TriggerContext::mutating_injection_removed; // creators["grobbulus cloud"] = &TriggerContext::grobbulus_cloud; creators["heigan melee"] = &TriggerContext::heigan_melee; @@ -366,7 +366,7 @@ class TriggerContext : public NamedObjectContext static Trigger* rpg_trade_useful(PlayerbotAI* botAI) { return new RpgTradeUsefulTrigger(botAI); } static Trigger* rpg_duel(PlayerbotAI* botAI) { return new RpgDuelTrigger(botAI); } - // static Trigger* mutating_injection(PlayerbotAI* ai) { return new MutatingInjectionTrigger(ai); } + static Trigger* mutating_injection(PlayerbotAI* ai) { return new MutatingInjectionTrigger(ai); } // static Trigger* mutating_injection_removed(PlayerbotAI* ai) { return new MutatingInjectionRemovedTrigger(ai); } // static Trigger* grobbulus_cloud(PlayerbotAI* ai) { return new GrobbulusCloudTrigger(ai); } static Trigger* heigan_melee(PlayerbotAI* ai) { return new HeiganMeleeTrigger(ai); }