refactor: naxxramas and kel'thuzad strategy

This commit is contained in:
Yunfan Li
2023-07-18 17:58:51 +08:00
parent 7f328b6e32
commit 7c70f42f34
26 changed files with 647 additions and 425 deletions

View File

@@ -1,8 +1,12 @@
#include "ObjectGuid.h"
#include "Playerbots.h"
#include "RaidNaxxActions.h"
#include "RaidNaxxStrategy.h"
#include "ScriptedCreature.h"
#include "SharedDefines.h"
#include "raids/naxxramas/RaidNaxxBossHelper.h"
#include <algorithm>
using namespace std;
@@ -39,7 +43,7 @@ using namespace std;
// }
bool GoBehindTheBossAction::Execute(Event event)
bool GrobbulusGoBehindAction::Execute(Event event)
{
Unit* boss = AI_VALUE(Unit*, "boss target");
if (!boss) {
@@ -60,22 +64,9 @@ bool GoBehindTheBossAction::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 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()
{
@@ -92,7 +83,7 @@ uint32 RotateAroundTheCenterPointAction::FindNearestWaypoint()
return ret;
}
uint32 RotateGrobbulusAction::GetCurrWaypoint()
uint32 GrobbulusRotateAction::GetCurrWaypoint()
{
Unit* boss = AI_VALUE(Unit*, "boss target");
if (!boss) {
@@ -375,7 +366,7 @@ bool HeiganDanceRangedAction::Execute(Event event) {
// }
// } else {
// list<ObjectGuid> attackers = context->GetValue<list<ObjectGuid> >("attackers")->Get();
// Unit* target = NULL;
// Unit* target = nullptr;
// for (list<ObjectGuid>::iterator i = attackers.begin(); i != attackers.end(); ++i) {
// Unit* unit = botAI->GetUnit(*i);
// if (!unit)
@@ -401,7 +392,7 @@ bool HeiganDanceRangedAction::Execute(Event event) {
// {
// Unit* razuvious = AI_VALUE2(Unit*, "find target", "instructor razuvious");
// Unit* understudy = AI_VALUE2(Unit*, "find target", "death knight understudy");
// Unit* target = NULL;
// Unit* target = nullptr;
// if (botAI->IsTank(bot)) {
// target = understudy;
// } else {
@@ -492,7 +483,7 @@ bool HeiganDanceRangedAction::Execute(Event event) {
// bool HorsemanAttactInOrderAction::Execute(Event event)
// {
// Unit* target = NULL;
// Unit* target = nullptr;
// Unit* thane = AI_VALUE2(Unit*, "find target", "thane korth'azz");
// Unit* baron = AI_VALUE2(Unit*, "find target", "baron rivendare");
// Unit* lady = AI_VALUE2(Unit*, "find target", "lady blaumeux");
@@ -621,7 +612,7 @@ bool HeiganDanceRangedAction::Execute(Event event) {
// }
// Group::MemberSlotList const& slots = group->GetMemberSlots();
// int counter = 0;
// Player* playerWithIcebolt = NULL;
// Player* playerWithIcebolt = nullptr;
// float minDistance;
// for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) {
// Player* member = ref->GetSource();
@@ -679,188 +670,153 @@ bool HeiganDanceRangedAction::Execute(Event event) {
// return MoveTo(bot->GetMapId(), bot->GetPositionX() + cos(angle) * 5.0f, bot->GetPositionY() + sin(angle) * 5.0f, bot->GetPositionZ());
// }
// bool KelthuzadChooseTargetAction::Execute(Event event)
// {
// Unit* boss = AI_VALUE2(Unit*, "find target", "kel'thuzad");
// if (!boss) {
// return false;
// }
// BossAI* boss_ai = dynamic_cast<BossAI*>(boss->GetAI());
// EventMap* eventMap = boss_botAI->GetEvents();
// std::pair<float, float> center = {3716.19f, -5106.58f};
// list<ObjectGuid> attackers = context->GetValue<list<ObjectGuid> >("attackers")->Get();
// Unit* target = NULL;
// Unit *target_soldier = NULL, *target_weaver = NULL, *target_abomination = NULL, *target_kelthuzad = NULL, *target_guardian = NULL;
// for (list<ObjectGuid>::iterator i = attackers.begin(); i != attackers.end(); ++i)
// {
// Unit* unit = botAI->GetUnit(*i);
// if (!unit)
// continue;
bool KelthuzadChooseTargetAction::Execute(Event event)
{
if (!helper.UpdateBossAI()) {
return false;
}
GuidVector attackers = context->GetValue<GuidVector>("attackers")->Get();
Unit* target = nullptr;
Unit *target_soldier = nullptr, *target_weaver = nullptr, *target_abomination = nullptr, *target_kelthuzad = nullptr, *target_guardian = nullptr;
for (auto i = attackers.begin(); i != attackers.end(); ++i)
{
Unit* unit = botAI->GetUnit(*i);
if (!unit)
continue;
// if (botAI->EqualLowercaseName(unit->GetName(), "guardian of icecrown")) {
// if (!target_guardian) {
// target_guardian = unit;
// } else if (unit->GetVictim() && target_guardian->GetVictim() &&
// unit->GetVictim()->ToPlayer() && target_guardian->GetVictim()->ToPlayer() &&
// !botAI->IsAssistTank(unit->GetVictim()->ToPlayer()) && botAI->IsAssistTank(target_guardian->GetVictim()->ToPlayer())) {
// target_guardian = unit;
// } else if (unit->GetVictim() && target_guardian->GetVictim() &&
// unit->GetVictim()->ToPlayer() && target_guardian->GetVictim()->ToPlayer() &&
// !botAI->IsAssistTank(unit->GetVictim()->ToPlayer()) && !botAI->IsAssistTank(target_guardian->GetVictim()->ToPlayer()) &&
// target_guardian->GetDistance2d(center.first, center.second) > bot->GetDistance2d(unit)) {
// target_guardian = unit;
// }
// }
if (botAI->EqualLowercaseName(unit->GetName(), "guardian of icecrown")) {
if (!target_guardian) {
target_guardian = unit;
} else if (unit->GetVictim() && target_guardian->GetVictim() &&
unit->GetVictim()->ToPlayer() && target_guardian->GetVictim()->ToPlayer() &&
!botAI->IsAssistTank(unit->GetVictim()->ToPlayer()) && botAI->IsAssistTank(target_guardian->GetVictim()->ToPlayer())) {
target_guardian = unit;
} else if (unit->GetVictim() && target_guardian->GetVictim() &&
unit->GetVictim()->ToPlayer() && target_guardian->GetVictim()->ToPlayer() &&
!botAI->IsAssistTank(unit->GetVictim()->ToPlayer()) && !botAI->IsAssistTank(target_guardian->GetVictim()->ToPlayer()) &&
target_guardian->GetDistance2d(helper.center.first, helper.center.second) > bot->GetDistance2d(unit)) {
target_guardian = unit;
}
}
// if (unit->GetDistance2d(center.first, center.second) > 30.0f) {
// continue;
// }
// if (bot->GetDistance2d(unit) > sPlayerbotAIConfig.spellDistance) {
// continue;
// }
// if (botAI->EqualLowercaseName(unit->GetName(), "unstoppable abomination")) {
// if (target_abomination == NULL ||
// target_abomination->GetDistance2d(center.first, center.second) > unit->GetDistance2d(center.first, center.second)) {
// target_abomination = unit;
// }
// }
// if (botAI->EqualLowercaseName(unit->GetName(), "soldier of the frozen wastes")) {
// if (target_soldier == NULL ||
// target_soldier->GetDistance2d(center.first, center.second) > unit->GetDistance2d(center.first, center.second)) {
// target_soldier = unit;
// }
// }
// if (botAI->EqualLowercaseName(unit->GetName(), "soul weaver")) {
// if (target_weaver == NULL ||
// target_weaver->GetDistance2d(center.first, center.second) > unit->GetDistance2d(center.first, center.second)) {
// target_weaver = unit;
// }
// }
// if (botAI->EqualLowercaseName(unit->GetName(), "kel'thuzad")) {
// target_kelthuzad = unit;
// }
// }
// vector<Unit*> targets;
// if (botAI->IsRanged(bot)) {
// if (botAI->GetRangedDpsIndex(bot) <= 1) {
// targets = {target_soldier, target_weaver, target_abomination, target_kelthuzad};
// } else {
// targets = {target_weaver, target_soldier, target_abomination, target_kelthuzad};
// }
// } else if (botAI->IsAssistTank(bot)) {
// targets = {target_abomination, target_guardian, target_kelthuzad};
// } else {
// targets = {target_abomination, target_kelthuzad};
// }
// for (Unit* t : targets) {
// if (t) {
// target = t;
// break;
// }
// }
// if (context->GetValue<Unit*>("current target")->Get() == target) {
// return false;
// }
// // if (target) {
// // bot->Yell("Target name: " + target->GetName(), LANG_UNIVERSAL);
// // }
// if (target_kelthuzad && target == target_kelthuzad) {
// return Attack(target, true);
// }
// return Attack(target, false);
// }
if (unit->GetDistance2d(helper.center.first, helper.center.second) > 30.0f) {
continue;
}
if (bot->GetDistance2d(unit) > sPlayerbotAIConfig->spellDistance) {
continue;
}
if (botAI->EqualLowercaseName(unit->GetName(), "unstoppable abomination")) {
if (target_abomination == nullptr ||
target_abomination->GetDistance2d(helper.center.first, helper.center.second) > unit->GetDistance2d(helper.center.first, helper.center.second)) {
target_abomination = unit;
}
}
if (botAI->EqualLowercaseName(unit->GetName(), "soldier of the frozen wastes")) {
if (target_soldier == nullptr ||
target_soldier->GetDistance2d(helper.center.first, helper.center.second) > unit->GetDistance2d(helper.center.first, helper.center.second)) {
target_soldier = unit;
}
}
if (botAI->EqualLowercaseName(unit->GetName(), "soul weaver")) {
if (target_weaver == nullptr ||
target_weaver->GetDistance2d(helper.center.first, helper.center.second) > unit->GetDistance2d(helper.center.first, helper.center.second)) {
target_weaver = unit;
}
}
if (botAI->EqualLowercaseName(unit->GetName(), "kel'thuzad")) {
target_kelthuzad = unit;
}
}
vector<Unit*> targets;
if (botAI->IsRanged(bot)) {
if (botAI->GetRangedDpsIndex(bot) <= 1) {
targets = {target_soldier, target_weaver, target_abomination, target_kelthuzad};
} else {
targets = {target_weaver, target_soldier, target_abomination, target_kelthuzad};
}
} else if (botAI->IsAssistTank(bot)) {
targets = {target_abomination, target_guardian, target_kelthuzad};
} else {
targets = {target_abomination, target_kelthuzad};
}
for (Unit* t : targets) {
if (t) {
target = t;
break;
}
}
if (context->GetValue<Unit*>("current target")->Get() == target) {
return false;
}
if (target_kelthuzad && target == target_kelthuzad) {
return Attack(target, true);
}
return Attack(target, false);
}
// bool KelthuzadPositionAction::Execute(Event event)
// {
// Unit* boss = AI_VALUE2(Unit*, "find target", "kel'thuzad");
// if (!boss) {
// return false;
// }
// BossAI* b_ai = dynamic_cast<BossAI*>(boss->GetAI());
// if (!b_ai) {
// return false;
// }
// EventMap *eventMap = b_botAI->GetEvents();
// uint8 phase_mask = eventMap->GetPhaseMask();
// if (phase_mask == 1) {
// if (AI_VALUE(Unit*, "current target") == NULL) {
// return MoveInside(533, 3716.19f, -5106.58f, bot->GetPositionZ(), 3.0f);
// }
// } else if (phase_mask == 2) {
// Unit* shadow_fissure = NULL;
// list<ObjectGuid> units = *context->GetValue<list<ObjectGuid> >("possible targets");
// for (list<ObjectGuid>::iterator i = units.begin(); i != units.end(); i++)
// {
// Unit* unit = botAI->GetUnit(*i);
// if (!unit)
// continue;
// if (botAI->EqualLowercaseName(unit->GetName(), "shadow fissure")) {
// shadow_fissure = unit;
// }
// }
// if (!shadow_fissure || bot->GetDistance2d(shadow_fissure) > 8.0f) {
// float distance, angle;
// if (botAI->IsMainTank(bot)) {
// if (AI_VALUE2(bool, "has aggro", "current target")) {
// return MoveTo(533, 3709.19f, -5104.86f, bot->GetPositionZ());
// // return false;
// }
// } else if (botAI->IsRanged(bot)) {
// uint32 index = botAI->GetRangedIndex(bot);
// if (index < 8) {
// distance = 20.0f;
// angle = index * M_PI / 4;
// } else {
// distance = 32.0f;
// angle = (index - 8) * M_PI / 4;
// }
// } else if (botAI->IsTank(bot)) {
// Unit* cur_tar = AI_VALUE(Unit*, "current target");
// if (cur_tar && cur_tar->GetVictim() && cur_tar->GetVictim()->ToPlayer() &&
// botAI->EqualLowercaseName(cur_tar->GetName(), "guardian of icecrown") &&
// botAI->IsAssistTank(cur_tar->GetVictim()->ToPlayer()) ) {
// return MoveTo(533, 3746.05f, -5112.74f, bot->GetPositionZ());
// } else {
// return false;
// }
// } else {
// return false;
// }
// std::pair<float, float> center = {3716.19f, -5106.58f};
// float dx, dy;
// dx = center.first + cos(angle) * distance;
// dy = center.second + sin(angle) * distance;
// return MoveTo(533, dx, dy, bot->GetPositionZ());
// } else {
// float dx, dy;
// float angle;
// if (!botAI->IsRanged(bot)) {
// angle = shadow_fissure->GetAngle(3716.19f, -5106.58f);
// } else {
// angle = bot->GetAngle(shadow_fissure) + M_PI;
// }
// dx = shadow_fissure->GetPositionX() + cos(angle) * 8.0f;
// dy = shadow_fissure->GetPositionY() + sin(angle) * 8.0f;
// return MoveTo(533, dx, dy, bot->GetPositionZ());
// }
// }
// return false;
// }
bool KelthuzadPositionAction::Execute(Event event)
{
if (!helper.UpdateBossAI()) {
return false;
}
if (helper.IsPhaseOne()) {
if (AI_VALUE(Unit*, "current target") == nullptr) {
return MoveInside(NAXX_MAP_ID, helper.center.first, helper.center.second, bot->GetPositionZ(), 3.0f);
}
} else if (helper.IsPhaseTwo()) {
Unit* shadow_fissure = helper.GetAnyShadowFissure();
if (!shadow_fissure || bot->GetDistance2d(shadow_fissure) > 10.0f) {
float distance, angle;
if (botAI->IsMainTank(bot)) {
if (AI_VALUE2(bool, "has aggro", "current target")) {
return MoveTo(NAXX_MAP_ID, helper.tank_pos.first, helper.tank_pos.second, bot->GetPositionZ());
} else {
return false;
}
} else if (botAI->IsRanged(bot)) {
uint32 index = botAI->GetRangedIndex(bot);
if (index < 8) {
distance = 20.0f;
angle = index * M_PI / 4;
} else {
distance = 32.0f;
angle = (index - 8) * M_PI / 4;
}
float dx, dy;
dx = helper.center.first + cos(angle) * distance;
dy = helper.center.second + sin(angle) * distance;
return MoveTo(NAXX_MAP_ID, dx, dy, bot->GetPositionZ());
} else if (botAI->IsTank(bot)) {
Unit* cur_tar = AI_VALUE(Unit*, "current target");
if (cur_tar && cur_tar->GetVictim() && cur_tar->GetVictim()->ToPlayer() &&
botAI->EqualLowercaseName(cur_tar->GetName(), "guardian of icecrown") &&
botAI->IsAssistTank(cur_tar->GetVictim()->ToPlayer()) ) {
return MoveTo(NAXX_MAP_ID, helper.assist_tank_pos.first, helper.assist_tank_pos.second, bot->GetPositionZ());
} else {
return false;
}
}
} else {
float dx, dy;
float angle;
if (!botAI->IsRanged(bot)) {
angle = shadow_fissure->GetAngle(helper.center.first, helper.center.second);
} else {
angle = bot->GetAngle(shadow_fissure) + M_PI;
}
dx = shadow_fissure->GetPositionX() + cos(angle) * 10.0f;
dy = shadow_fissure->GetPositionY() + sin(angle) * 10.0f;
return MoveTo(NAXX_MAP_ID, dx, dy, bot->GetPositionZ());
}
}
return false;
}
bool AnubrekhanChooseTargetAction::Execute(Event event)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "anub'rekhan");
if (!boss) {
return false;
}
BossAI* boss_ai = dynamic_cast<BossAI*>(boss->GetAI());
GuidVector attackers = context->GetValue<GuidVector >("attackers")->Get();
Unit* target = NULL;
Unit *target_boss = NULL;
Unit* target = nullptr;
Unit *target_boss = nullptr;
vector<Unit*> target_guards;
for (ObjectGuid const guid : attackers)
{
@@ -882,13 +838,13 @@ bool AnubrekhanChooseTargetAction::Execute(Event event)
} else {
if (botAI->IsAssistTank(bot)) {
for (Unit* t : target_guards) {
if (target == NULL || (target->GetVictim() && target->GetVictim()->ToPlayer() && botAI->IsTank(target->GetVictim()->ToPlayer()))) {
if (target == nullptr || (target->GetVictim() && target->GetVictim()->ToPlayer() && botAI->IsTank(target->GetVictim()->ToPlayer()))) {
target = t;
}
}
} else {
for (Unit* t : target_guards) {
if (target == NULL || target->GetHealthPct() > t->GetHealthPct()) {
if (target == nullptr || target->GetHealthPct() > t->GetHealthPct()) {
target = t;
}
}
@@ -941,8 +897,8 @@ bool AnubrekhanPositionAction::Execute(Event event)
// BossAI* boss_ai = dynamic_cast<BossAI*>(boss->GetAI());
// EventMap* eventMap = boss_botAI->GetEvents();
// list<ObjectGuid> attackers = context->GetValue<list<ObjectGuid> >("attackers")->Get();
// Unit* target = NULL;
// Unit *target_boss = NULL;
// Unit* target = nullptr;
// Unit *target_boss = nullptr;
// vector<Unit*> target_zombies;
// for (list<ObjectGuid>::iterator i = attackers.begin(); i != attackers.end(); ++i)
// {
@@ -971,12 +927,12 @@ bool AnubrekhanPositionAction::Execute(Event event)
// } else {
// for (Unit* t : target_zombies) {
// if (t->GetHealthPct() <= 10.0f) {
// if (target == NULL || target->GetDistance2d(3331.48f, -3109.06f) > t->GetDistance2d(3331.48f, -3109.06f)) {
// if (target == nullptr || target->GetDistance2d(3331.48f, -3109.06f) > t->GetDistance2d(3331.48f, -3109.06f)) {
// target = t;
// }
// }
// }
// if (target == NULL) {
// if (target == nullptr) {
// target = target_boss;
// }
// }
@@ -1099,9 +1055,9 @@ bool AnubrekhanPositionAction::Execute(Event event)
// BossAI* boss_ai = dynamic_cast<BossAI*>(boss->GetAI());
// EventMap* eventMap = boss_botAI->GetEvents();
// list<ObjectGuid> attackers = context->GetValue<list<ObjectGuid> >("attackers")->Get();
// Unit* target = NULL;
// Unit *target_boss = NULL;
// Unit *target_spore = NULL;
// Unit* target = nullptr;
// Unit *target_boss = nullptr;
// Unit *target_spore = nullptr;
// for (list<ObjectGuid>::iterator i = attackers.begin(); i != attackers.end(); ++i)
// {
// Unit* unit = botAI->GetUnit(*i);