mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Naxx fourhorsemen strategy
This commit is contained in:
@@ -14,8 +14,7 @@ We've provided a simple method to clone the module:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/liyunfan1223/azerothcore-wotlk.git --branch=Playerbot
|
git clone https://github.com/liyunfan1223/azerothcore-wotlk.git --branch=Playerbot
|
||||||
cd azerothcore-wotlk
|
cd azerothcore-wotlk/modules
|
||||||
cd module
|
|
||||||
git clone https://github.com/liyunfan1223/mod-playerbots.git --branch=master
|
git clone https://github.com/liyunfan1223/mod-playerbots.git --branch=master
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1383,6 +1383,36 @@ bool PlayerbotAI::IsRangedDps(Player* player)
|
|||||||
return IsRanged(player) && IsDps(player);
|
return IsRanged(player) && IsDps(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PlayerbotAI::IsHealAssistantOfIndex(Player* player, int index)
|
||||||
|
{
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Group::MemberSlotList const& slots = group->GetMemberSlots();
|
||||||
|
int counter = 0;
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) {
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (group->IsAssistant(member->GetGUID()) && IsHeal(member)) {
|
||||||
|
if (index == counter) {
|
||||||
|
return player == member;
|
||||||
|
}
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// not enough
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) {
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (!group->IsAssistant(member->GetGUID()) && IsHeal(member)) {
|
||||||
|
if (index == counter) {
|
||||||
|
return player == member;
|
||||||
|
}
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool PlayerbotAI::IsRangedDpsAssistantOfIndex(Player* player, int index)
|
bool PlayerbotAI::IsRangedDpsAssistantOfIndex(Player* player, int index)
|
||||||
{
|
{
|
||||||
Group* group = bot->GetGroup();
|
Group* group = bot->GetGroup();
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ class RaidNaxxActionContext : public NamedObjectContext<Action>
|
|||||||
creators["razuvious use obedience crystal"] = &RaidNaxxActionContext::razuvious_use_obedience_crystal;
|
creators["razuvious use obedience crystal"] = &RaidNaxxActionContext::razuvious_use_obedience_crystal;
|
||||||
creators["razuvious target"] = &RaidNaxxActionContext::razuvious_target;
|
creators["razuvious target"] = &RaidNaxxActionContext::razuvious_target;
|
||||||
|
|
||||||
// creators["horseman attract alternatively"] = &RaidNaxxActionContext::horseman_attract_alternatively;
|
creators["horseman attract alternatively"] = &RaidNaxxActionContext::horseman_attract_alternatively;
|
||||||
// creators["horseman attack in order"] = &RaidNaxxActionContext::horseman_attack_in_order;
|
creators["horseman attack in order"] = &RaidNaxxActionContext::horseman_attack_in_order;
|
||||||
|
|
||||||
creators["sapphiron ground position"] = &RaidNaxxActionContext::sapphiron_ground_position;
|
creators["sapphiron ground position"] = &RaidNaxxActionContext::sapphiron_ground_position;
|
||||||
creators["sapphiron flight position"] = &RaidNaxxActionContext::sapphiron_flight_position;
|
creators["sapphiron flight position"] = &RaidNaxxActionContext::sapphiron_flight_position;
|
||||||
@@ -60,8 +60,8 @@ class RaidNaxxActionContext : public NamedObjectContext<Action>
|
|||||||
// static Action* thaddius_move_polarity(PlayerbotAI* ai) { return new ThaddiusMovePolarityAction(ai); }
|
// static Action* thaddius_move_polarity(PlayerbotAI* ai) { return new ThaddiusMovePolarityAction(ai); }
|
||||||
static Action* razuvious_target(PlayerbotAI* ai) { return new RazuviousTargetAction(ai); }
|
static Action* razuvious_target(PlayerbotAI* ai) { return new RazuviousTargetAction(ai); }
|
||||||
static Action* razuvious_use_obedience_crystal(PlayerbotAI* ai) { return new RazuviousUseObedienceCrystalAction(ai); }
|
static Action* razuvious_use_obedience_crystal(PlayerbotAI* ai) { return new RazuviousUseObedienceCrystalAction(ai); }
|
||||||
// static Action* horseman_attract_alternatively(PlayerbotAI* ai) { return new HorsemanAttractAlternativelyAction(ai); }
|
static Action* horseman_attract_alternatively(PlayerbotAI* ai) { return new HorsemanAttractAlternativelyAction(ai); }
|
||||||
// static Action* horseman_attack_in_order(PlayerbotAI* ai) { return new HorsemanAttactInOrderAction(ai); }
|
static Action* horseman_attack_in_order(PlayerbotAI* ai) { return new HorsemanAttactInOrderAction(ai); }
|
||||||
// static Action* sapphiron_ground_main_tank_position(PlayerbotAI* ai) { return new SapphironGroundMainTankPositionAction(ai); }
|
// static Action* sapphiron_ground_main_tank_position(PlayerbotAI* ai) { return new SapphironGroundMainTankPositionAction(ai); }
|
||||||
static Action* sapphiron_ground_position(PlayerbotAI* ai) { return new SapphironGroundPositionAction(ai); }
|
static Action* sapphiron_ground_position(PlayerbotAI* ai) { return new SapphironGroundPositionAction(ai); }
|
||||||
static Action* sapphiron_flight_position(PlayerbotAI* ai) { return new SapphironFlightPositionAction(ai); }
|
static Action* sapphiron_flight_position(PlayerbotAI* ai) { return new SapphironFlightPositionAction(ai); }
|
||||||
|
|||||||
@@ -56,15 +56,6 @@ bool GrobbulusGoBehindAction::Execute(Event event)
|
|||||||
return MoveTo(bot->GetMapId(), rx, ry, z);
|
return MoveTo(bot->GetMapId(), rx, ry, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool MoveToPointForceAction::Execute(Event event)
|
|
||||||
// {
|
|
||||||
// return MoveTo(bot->GetMapId(), x, y, bot->GetPositionZ(), true);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32 RotateAroundTheCenterPointAction::FindNearestWaypoint()
|
uint32 RotateAroundTheCenterPointAction::FindNearestWaypoint()
|
||||||
{
|
{
|
||||||
float minDistance = 0;
|
float minDistance = 0;
|
||||||
@@ -409,119 +400,53 @@ bool RazuviousTargetAction::Execute(Event event)
|
|||||||
return Attack(target);
|
return Attack(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool HorsemanAttractAlternativelyAction::Execute(Event event)
|
bool HorsemanAttractAlternativelyAction::Execute(Event event)
|
||||||
// {
|
{
|
||||||
// Unit* sir = AI_VALUE2(Unit*, "find target", "sir zeliek");
|
if (!helper.UpdateBossAI()) {
|
||||||
// Unit* lady = AI_VALUE2(Unit*, "find target", "lady blaumeux");
|
return false;
|
||||||
// bool raid25 = bot->GetRaidDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL;
|
}
|
||||||
// if (!sir) {
|
helper.CalculatePosToGo(bot);
|
||||||
// return false;
|
auto [posX, posY] = helper.CurrentAttractPos();
|
||||||
// }
|
if (MoveTo(bot->GetMapId(), posX, posY, helper.posZ)) {
|
||||||
// std::vector<std::pair<float, float>> position = {
|
return true;
|
||||||
// // left (sir zeliek)
|
}
|
||||||
// {2502.03f, -2910.90f},
|
Unit* attackTarget = helper.CurrentAttackTarget();
|
||||||
// // right (lady blaumeux)
|
if (context->GetValue<Unit*>("current target")->Get() != attackTarget) {
|
||||||
// {2484.61f, -2947.07f},
|
return Attack(attackTarget);
|
||||||
// };
|
}
|
||||||
// float pos_z = 241.27f;
|
return false;
|
||||||
// BossAI* boss_ai = dynamic_cast<BossAI*>(sir->GetAI());
|
}
|
||||||
// EventMap* eventMap = boss_botAI->GetEvents();
|
|
||||||
// const uint32 timer = eventMap->GetTimer();
|
|
||||||
// if (lady) {
|
|
||||||
// BossAI* lady_ai = dynamic_cast<BossAI*>(lady->GetAI());
|
|
||||||
// EventMap* ladyEventMap = lady_botAI->GetEvents();
|
|
||||||
// const uint32 voidZone = ladyEventMap->GetNextEventTime(5);
|
|
||||||
// if (!voidZone) {
|
|
||||||
// voidzone_counter = 0;
|
|
||||||
// }
|
|
||||||
// if (voidZone && last_voidzone != voidZone) {
|
|
||||||
// voidzone_counter = (voidzone_counter + 1) % 8;
|
|
||||||
// }
|
|
||||||
// last_voidzone = voidZone;
|
|
||||||
// }
|
|
||||||
// int pos_to_go;
|
|
||||||
// if (!lady) {
|
|
||||||
// pos_to_go = 0;
|
|
||||||
// } else {
|
|
||||||
// // 24 - 15 - 15 - ...
|
|
||||||
// if (timer <= 9000 || ((timer - 9000) / 67500) % 2 == 0) {
|
|
||||||
// pos_to_go = 0;
|
|
||||||
// } else {
|
|
||||||
// pos_to_go = 1;
|
|
||||||
// }
|
|
||||||
// if (botAI->IsRangedDpsAssistantOfIndex(bot, 0) || (raid25 && botAI->IsHealAssistantOfIndex(bot, 1))) {
|
|
||||||
// pos_to_go = 1 - pos_to_go;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // bot->Yell("pos to go: " + std::to_string(pos_to_go), LANG_UNIVERSAL);
|
|
||||||
// float pos_x = position[pos_to_go].first, pos_y = position[pos_to_go].second;
|
|
||||||
// if (pos_to_go == 1) {
|
|
||||||
// float offset_x;
|
|
||||||
// float offset_y;
|
|
||||||
// if (voidzone_counter < 4) {
|
|
||||||
// offset_x = voidzone_counter * (-4.5f);
|
|
||||||
// offset_y = voidzone_counter * (4.5f);
|
|
||||||
// }
|
|
||||||
// if (voidzone_counter >= 4) {
|
|
||||||
// offset_x = (7 - voidzone_counter) * (-4.5f);
|
|
||||||
// offset_y = (7 - voidzone_counter) * (4.5f);
|
|
||||||
// offset_x += 4.5f;
|
|
||||||
// offset_y += 4.5f;
|
|
||||||
// }
|
|
||||||
// pos_x += offset_x;
|
|
||||||
// pos_y += offset_y;
|
|
||||||
// }
|
|
||||||
// if (MoveTo(bot->GetMapId(), pos_x, pos_y, pos_z)) {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// Unit* attackTarget;
|
|
||||||
// if (pos_to_go == 0) {
|
|
||||||
// attackTarget = sir;
|
|
||||||
// } else {
|
|
||||||
// attackTarget = lady;
|
|
||||||
// }
|
|
||||||
// if (context->GetValue<Unit*>("current target")->Get() != attackTarget) {
|
|
||||||
// return Attack(attackTarget);
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// bool HorsemanAttactInOrderAction::Execute(Event event)
|
bool HorsemanAttactInOrderAction::Execute(Event event)
|
||||||
// {
|
{
|
||||||
// Unit* target = nullptr;
|
Unit* target = nullptr;
|
||||||
// Unit* thane = AI_VALUE2(Unit*, "find target", "thane korth'azz");
|
Unit* thane = AI_VALUE2(Unit*, "find target", "thane korth'azz");
|
||||||
// Unit* baron = AI_VALUE2(Unit*, "find target", "baron rivendare");
|
Unit* baron = AI_VALUE2(Unit*, "find target", "baron rivendare");
|
||||||
// Unit* lady = AI_VALUE2(Unit*, "find target", "lady blaumeux");
|
Unit* lady = AI_VALUE2(Unit*, "find target", "lady blaumeux");
|
||||||
// Unit* sir = AI_VALUE2(Unit*, "find target", "sir zeliek");
|
Unit* sir = AI_VALUE2(Unit*, "find target", "sir zeliek");
|
||||||
// vector<Unit*> attack_order;
|
std::vector<Unit*> attack_order;
|
||||||
// if (botAI->IsAssistTank(bot)) {
|
if (botAI->IsAssistTank(bot)) {
|
||||||
// attack_order = {baron, thane, lady, sir};
|
attack_order = {baron, thane, lady, sir};
|
||||||
// } else {
|
} else {
|
||||||
// attack_order = {thane, baron, lady, sir};
|
attack_order = {thane, baron, lady, sir};
|
||||||
// }
|
}
|
||||||
// for (Unit* t : attack_order) {
|
for (Unit* t : attack_order) {
|
||||||
// if (t) {
|
if (t) {
|
||||||
// target = t;
|
target = t;
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// if (target) {
|
if (target) {
|
||||||
// if (context->GetValue<Unit*>("current target")->Get() == target && botAI->GetCurrentState() == BOT_STATE_COMBAT) {
|
if (context->GetValue<Unit*>("current target")->Get() == target && botAI->GetState() == BOT_STATE_COMBAT) {
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
// if (!bot->IsWithinLOSInMap(target)) {
|
if (!bot->IsWithinLOSInMap(target)) {
|
||||||
// return MoveNear(target, 10.0f);
|
return MoveNear(target, 22.0f);
|
||||||
// }
|
}
|
||||||
// return Attack(target);
|
return Attack(target);
|
||||||
// }
|
}
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// bool SapphironGroundMainTankPositionAction::Execute(Event event)
|
|
||||||
// {
|
|
||||||
// return MoveTo(533, 3512.07f, -5274.06f, 137.29f);
|
|
||||||
// // return MoveTo(533, 3498.58f, -5245.35f, 137.29f);
|
|
||||||
// }
|
|
||||||
|
|
||||||
bool SapphironGroundPositionAction::Execute(Event event)
|
bool SapphironGroundPositionAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
@@ -982,9 +907,6 @@ bool GluthSlowdownAction::Execute(Event event)
|
|||||||
case CLASS_HUNTER:
|
case CLASS_HUNTER:
|
||||||
return botAI->CastSpell("frost trap", bot);
|
return botAI->CastSpell("frost trap", bot);
|
||||||
break;
|
break;
|
||||||
// case CLASS_MAGE:
|
|
||||||
// return botAI->CastSpell("frost nova", bot);
|
|
||||||
// break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,24 +145,23 @@ class RazuviousTargetAction : public AttackAction
|
|||||||
RazuviousBossHelper helper;
|
RazuviousBossHelper helper;
|
||||||
};
|
};
|
||||||
|
|
||||||
// class HorsemanAttractAlternativelyAction : public AttackAction
|
class HorsemanAttractAlternativelyAction : public AttackAction
|
||||||
// {
|
{
|
||||||
// public:
|
public:
|
||||||
// HorsemanAttractAlternativelyAction(PlayerbotAI* ai) : AttackAction(ai, "horseman attract alternatively") {
|
HorsemanAttractAlternativelyAction(PlayerbotAI* ai) : AttackAction(ai, "horseman attract alternatively"), helper(ai) {}
|
||||||
// this->last_voidzone = 0;
|
bool Execute(Event event) override;
|
||||||
// this->voidzone_counter = 0;
|
protected:
|
||||||
// }
|
FourhorsemanBossHelper helper;
|
||||||
// virtual bool Execute(Event event);
|
};
|
||||||
// protected:
|
|
||||||
// uint32 last_voidzone, voidzone_counter;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// class HorsemanAttactInOrderAction : public AttackAction
|
class HorsemanAttactInOrderAction : public AttackAction
|
||||||
// {
|
{
|
||||||
// public:
|
public:
|
||||||
// HorsemanAttactInOrderAction(PlayerbotAI* ai) : AttackAction(ai, "horseman attact in order") {}
|
HorsemanAttactInOrderAction(PlayerbotAI* ai) : AttackAction(ai, "horseman attact in order"), helper(ai) {}
|
||||||
// virtual bool Execute(Event event);
|
bool Execute(Event event) override;
|
||||||
// };
|
protected:
|
||||||
|
FourhorsemanBossHelper helper;
|
||||||
|
};
|
||||||
|
|
||||||
// class SapphironGroundMainTankPositionAction : public MovementAction
|
// class SapphironGroundMainTankPositionAction : public MovementAction
|
||||||
// {
|
// {
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ class GenericBossHelper : public AiObject {
|
|||||||
public:
|
public:
|
||||||
GenericBossHelper(PlayerbotAI* botAI, std::string name): AiObject(botAI), _name(name) {}
|
GenericBossHelper(PlayerbotAI* botAI, std::string name): AiObject(botAI), _name(name) {}
|
||||||
virtual bool UpdateBossAI() {
|
virtual bool UpdateBossAI() {
|
||||||
|
if (!bot->IsInCombat()) {
|
||||||
|
_unit = nullptr;
|
||||||
|
}
|
||||||
if(_unit && (!_unit->IsInWorld() || !_unit->IsAlive())) {
|
if(_unit && (!_unit->IsInWorld() || !_unit->IsAlive())) {
|
||||||
_unit = nullptr;
|
_unit = nullptr;
|
||||||
}
|
}
|
||||||
@@ -46,10 +49,17 @@ class GenericBossHelper : public AiObject {
|
|||||||
_timer = _event_map->GetTimer();
|
_timer = _event_map->GetTimer();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
virtual void Reset() {
|
||||||
|
_unit = nullptr;
|
||||||
|
_target = nullptr;
|
||||||
|
_ai = nullptr;
|
||||||
|
_event_map = nullptr;
|
||||||
|
_timer = 0;
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
|
std::string _name;
|
||||||
Unit* _unit = nullptr;
|
Unit* _unit = nullptr;
|
||||||
Creature* _target = nullptr;
|
Creature* _target = nullptr;
|
||||||
std::string _name = nullptr;
|
|
||||||
BossAiType *_ai = nullptr;
|
BossAiType *_ai = nullptr;
|
||||||
EventMap* _event_map = nullptr;
|
EventMap* _event_map = nullptr;
|
||||||
uint32 _timer = 0;
|
uint32 _timer = 0;
|
||||||
@@ -187,4 +197,102 @@ class LoathebBossHelper: public GenericBossHelper<boss_loatheb::boss_loathebAI>
|
|||||||
LoathebBossHelper(PlayerbotAI *botAI): GenericBossHelper(botAI, "loatheb") {}
|
LoathebBossHelper(PlayerbotAI *botAI): GenericBossHelper(botAI, "loatheb") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
class FourhorsemanBossHelper: public GenericBossHelper<boss_four_horsemen::boss_four_horsemenAI> {
|
||||||
|
public:
|
||||||
|
const float posZ = 241.27f;
|
||||||
|
const std::pair<float, float> attractPos[2] = {{2502.03f, -2910.90f}, {2484.61f, -2947.07f}}; // left (sir zeliek), right (lady blaumeux)
|
||||||
|
FourhorsemanBossHelper(PlayerbotAI *botAI): GenericBossHelper(botAI, "sir zeliek") {}
|
||||||
|
bool UpdateBossAI() override {
|
||||||
|
if (!GenericBossHelper::UpdateBossAI()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!bot->IsInCombat()) {
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
sir = _unit;
|
||||||
|
lady = AI_VALUE2(Unit*, "find target", "lady blaumeux");
|
||||||
|
if (!lady) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ladyAI = dynamic_cast<boss_four_horsemen::boss_four_horsemenAI *>(lady->GetAI());
|
||||||
|
if (!ladyAI) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ladyEvent = &ladyAI->events;
|
||||||
|
const uint32 voidZone = ladyEvent->GetNextEventTime(EVENT_SECONDARY_SPELL);
|
||||||
|
if (voidZone && lastEventVoidZone != voidZone) {
|
||||||
|
voidZoneCounter++;
|
||||||
|
voidZoneCounter %= 8;
|
||||||
|
lastEventVoidZone = voidZone;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void Reset() override {
|
||||||
|
GenericBossHelper::Reset();
|
||||||
|
sir = nullptr;
|
||||||
|
lady = nullptr;
|
||||||
|
ladyAI = nullptr;
|
||||||
|
ladyEvent = nullptr;
|
||||||
|
lastEventVoidZone = 0;
|
||||||
|
voidZoneCounter = 0;
|
||||||
|
posToGo = 0;
|
||||||
|
}
|
||||||
|
bool IsAttracter(Player* bot) {
|
||||||
|
Difficulty diff = bot->GetRaidDifficulty();
|
||||||
|
if (diff == RAID_DIFFICULTY_25MAN_NORMAL) {
|
||||||
|
return botAI->IsRangedDpsAssistantOfIndex(bot, 0) || botAI->IsHealAssistantOfIndex(bot, 0) ||
|
||||||
|
botAI->IsHealAssistantOfIndex(bot, 1) || botAI->IsHealAssistantOfIndex(bot, 2);
|
||||||
|
}
|
||||||
|
return botAI->IsRangedDpsAssistantOfIndex(bot, 0) || botAI->IsHealAssistantOfIndex(bot, 0);
|
||||||
|
}
|
||||||
|
void CalculatePosToGo(Player* bot) {
|
||||||
|
bool raid25 = bot->GetRaidDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL;
|
||||||
|
if (!lady) {
|
||||||
|
posToGo = 0;
|
||||||
|
} else {
|
||||||
|
// Interval: 24s - 15s - 15s - ...
|
||||||
|
posToGo = !(_timer <= 9000 || ((_timer - 9000) / 67500) % 2 == 0);
|
||||||
|
if (botAI->IsRangedDpsAssistantOfIndex(bot, 0) || (raid25 && botAI->IsHealAssistantOfIndex(bot, 1))) {
|
||||||
|
posToGo = 1 - posToGo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::pair<float, float> CurrentAttractPos()
|
||||||
|
{
|
||||||
|
float posX = attractPos[posToGo].first, posY = attractPos[posToGo].second;
|
||||||
|
if (posToGo == 1) {
|
||||||
|
float offset_x;
|
||||||
|
float offset_y;
|
||||||
|
if (voidZoneCounter < 4) {
|
||||||
|
offset_x = voidZoneCounter * (-4.5f);
|
||||||
|
offset_y = voidZoneCounter * (4.5f);
|
||||||
|
}
|
||||||
|
if (voidZoneCounter >= 4) {
|
||||||
|
offset_x = (7 - voidZoneCounter) * (-4.5f);
|
||||||
|
offset_y = (7 - voidZoneCounter) * (4.5f);
|
||||||
|
offset_x += 4.5f;
|
||||||
|
offset_y += 4.5f;
|
||||||
|
}
|
||||||
|
posX += offset_x;
|
||||||
|
posY += offset_y;
|
||||||
|
}
|
||||||
|
return {posX, posY};
|
||||||
|
}
|
||||||
|
Unit* CurrentAttackTarget()
|
||||||
|
{
|
||||||
|
if (posToGo == 0) {
|
||||||
|
return sir;
|
||||||
|
}
|
||||||
|
return lady;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
Unit* sir = nullptr;
|
||||||
|
Unit* lady = nullptr;
|
||||||
|
boss_four_horsemen::boss_four_horsemenAI* ladyAI = nullptr;
|
||||||
|
EventMap* ladyEvent = nullptr;
|
||||||
|
uint32 lastEventVoidZone = 0;
|
||||||
|
uint32 voidZoneCounter = 0;
|
||||||
|
int posToGo = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -210,18 +210,19 @@ float AnubrekhanGenericMultiplier::GetValue(Action* action)
|
|||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// float FourhorsemanGenericMultiplier::GetValue(Action* action)
|
float FourhorsemanGenericMultiplier::GetValue(Action* action)
|
||||||
// {
|
{
|
||||||
// Unit* boss = AI_VALUE2(Unit*, "find target", "sir zeliek");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "sir zeliek");
|
||||||
// if (!boss) {
|
if (!boss) {
|
||||||
// return 1.0f;
|
return 1.0f;
|
||||||
// }
|
}
|
||||||
// if ((dynamic_cast<DpsAssistAction*>(action) ||
|
context->GetValue<bool>("neglect threat")->Set(true);
|
||||||
// dynamic_cast<TankAssistAction*>(action))) {
|
if ((dynamic_cast<DpsAssistAction*>(action) ||
|
||||||
// return 0.0f;
|
dynamic_cast<TankAssistAction*>(action))) {
|
||||||
// }
|
return 0.0f;
|
||||||
// return 1.0f;
|
}
|
||||||
// }
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// float GothikGenericMultiplier::GetValue(Action* action)
|
// float GothikGenericMultiplier::GetValue(Action* action)
|
||||||
// {
|
// {
|
||||||
|
|||||||
@@ -69,14 +69,14 @@ public:
|
|||||||
virtual float GetValue(Action* action);
|
virtual float GetValue(Action* action);
|
||||||
};
|
};
|
||||||
|
|
||||||
// class FourhorsemanGenericMultiplier : public Multiplier
|
class FourhorsemanGenericMultiplier : public Multiplier
|
||||||
// {
|
{
|
||||||
// public:
|
public:
|
||||||
// FourhorsemanGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "fourhorseman generic") {}
|
FourhorsemanGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "fourhorseman generic") {}
|
||||||
|
|
||||||
// public:
|
public:
|
||||||
// virtual float GetValue(Action* action);
|
virtual float GetValue(Action* action);
|
||||||
// };
|
};
|
||||||
|
|
||||||
// class GothikGenericMultiplier : public Multiplier
|
// class GothikGenericMultiplier : public Multiplier
|
||||||
// {
|
// {
|
||||||
|
|||||||
@@ -4,10 +4,6 @@
|
|||||||
|
|
||||||
void RaidNaxxStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
void RaidNaxxStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||||
{
|
{
|
||||||
// triggers.push_back(new TriggerNode(
|
|
||||||
// "often",
|
|
||||||
// NextAction::array(0, new NextAction("try to get boss ai", ACTION_RAID), nullptr)));
|
|
||||||
|
|
||||||
// Grobbulus
|
// Grobbulus
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"mutating injection",
|
"mutating injection",
|
||||||
@@ -41,8 +37,7 @@ void RaidNaxxStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
|||||||
// Anub'Rekhan
|
// Anub'Rekhan
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"anub'rekhan",
|
"anub'rekhan",
|
||||||
NextAction::array(0,
|
NextAction::array(0,
|
||||||
// new NextAction("anub'rekhan choose target", ACTION_RAID + 1),
|
|
||||||
new NextAction("anub'rekhan position", ACTION_RAID + 1),
|
new NextAction("anub'rekhan position", ACTION_RAID + 1),
|
||||||
nullptr)));
|
nullptr)));
|
||||||
|
|
||||||
@@ -76,14 +71,14 @@ void RaidNaxxStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
|||||||
"razuvious nontank",
|
"razuvious nontank",
|
||||||
NextAction::array(0, new NextAction("razuvious target", ACTION_RAID + 1), nullptr)));
|
NextAction::array(0, new NextAction("razuvious target", ACTION_RAID + 1), nullptr)));
|
||||||
|
|
||||||
// // four horseman
|
// four horseman
|
||||||
// triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
// "horseman attractors",
|
"horseman attractors",
|
||||||
// NextAction::array(0, new NextAction("horseman attract alternatively", ACTION_RAID + 1), nullptr)));
|
NextAction::array(0, new NextAction("horseman attract alternatively", ACTION_RAID + 1), nullptr)));
|
||||||
|
|
||||||
// triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
// "horseman except attractors",
|
"horseman except attractors",
|
||||||
// NextAction::array(0, new NextAction("horseman attack in order", ACTION_RAID + 1), nullptr)));
|
NextAction::array(0, new NextAction("horseman attack in order", ACTION_RAID + 1), nullptr)));
|
||||||
|
|
||||||
// sapphiron
|
// sapphiron
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
@@ -126,7 +121,7 @@ void RaidNaxxStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers)
|
|||||||
multipliers.push_back(new InstructorRazuviousGenericMultiplier(botAI));
|
multipliers.push_back(new InstructorRazuviousGenericMultiplier(botAI));
|
||||||
multipliers.push_back(new KelthuzadGenericMultiplier(botAI));
|
multipliers.push_back(new KelthuzadGenericMultiplier(botAI));
|
||||||
multipliers.push_back(new AnubrekhanGenericMultiplier(botAI));
|
multipliers.push_back(new AnubrekhanGenericMultiplier(botAI));
|
||||||
// multipliers.push_back(new FourhorsemanGenericMultiplier(botAI));
|
multipliers.push_back(new FourhorsemanGenericMultiplier(botAI));
|
||||||
// multipliers.push_back(new GothikGenericMultiplier(botAI));
|
// multipliers.push_back(new GothikGenericMultiplier(botAI));
|
||||||
multipliers.push_back(new GluthGenericMultiplier(botAI));
|
multipliers.push_back(new GluthGenericMultiplier(botAI));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ class RaidNaxxTriggerContext : public NamedObjectContext<Trigger>
|
|||||||
creators["razuvious tank"] = &RaidNaxxTriggerContext::razuvious_tank;
|
creators["razuvious tank"] = &RaidNaxxTriggerContext::razuvious_tank;
|
||||||
creators["razuvious nontank"] = &RaidNaxxTriggerContext::razuvious_nontank;
|
creators["razuvious nontank"] = &RaidNaxxTriggerContext::razuvious_nontank;
|
||||||
|
|
||||||
// creators["horseman attractors"] = &RaidNaxxTriggerContext::horseman_attractors;
|
creators["horseman attractors"] = &RaidNaxxTriggerContext::horseman_attractors;
|
||||||
// creators["horseman except attractors"] = &RaidNaxxTriggerContext::horseman_except_attractors;
|
creators["horseman except attractors"] = &RaidNaxxTriggerContext::horseman_except_attractors;
|
||||||
|
|
||||||
creators["sapphiron ground"] = &RaidNaxxTriggerContext::sapphiron_ground;
|
creators["sapphiron ground"] = &RaidNaxxTriggerContext::sapphiron_ground;
|
||||||
creators["sapphiron flight"] = &RaidNaxxTriggerContext::sapphiron_flight;
|
creators["sapphiron flight"] = &RaidNaxxTriggerContext::sapphiron_flight;
|
||||||
@@ -56,8 +56,8 @@ class RaidNaxxTriggerContext : public NamedObjectContext<Trigger>
|
|||||||
static Trigger* razuvious_tank(PlayerbotAI* ai) { return new RazuviousTankTrigger(ai); }
|
static Trigger* razuvious_tank(PlayerbotAI* ai) { return new RazuviousTankTrigger(ai); }
|
||||||
static Trigger* razuvious_nontank(PlayerbotAI* ai) { return new RazuviousNontankTrigger(ai); }
|
static Trigger* razuvious_nontank(PlayerbotAI* ai) { return new RazuviousNontankTrigger(ai); }
|
||||||
|
|
||||||
// static Trigger* horseman_attractors(PlayerbotAI* ai) { return new HorsemanAttractorsTrigger(ai); }
|
static Trigger* horseman_attractors(PlayerbotAI* ai) { return new HorsemanAttractorsTrigger(ai); }
|
||||||
// static Trigger* horseman_except_attractors(PlayerbotAI* ai) { return new HorsemanExceptAttractorsTrigger(ai); }
|
static Trigger* horseman_except_attractors(PlayerbotAI* ai) { return new HorsemanExceptAttractorsTrigger(ai); }
|
||||||
static Trigger* sapphiron_ground(PlayerbotAI* ai) { return new SapphironGroundTrigger(ai); }
|
static Trigger* sapphiron_ground(PlayerbotAI* ai) { return new SapphironGroundTrigger(ai); }
|
||||||
static Trigger* sapphiron_flight(PlayerbotAI* ai) { return new SapphironFlightTrigger(ai); }
|
static Trigger* sapphiron_flight(PlayerbotAI* ai) { return new SapphironFlightTrigger(ai); }
|
||||||
static Trigger* kelthuzad(PlayerbotAI* ai) { return new KelthuzadTrigger(ai); }
|
static Trigger* kelthuzad(PlayerbotAI* ai) { return new KelthuzadTrigger(ai); }
|
||||||
|
|||||||
@@ -110,22 +110,21 @@ bool RazuviousNontankTrigger::IsActive()
|
|||||||
return helper.UpdateBossAI() && !(bot->getClass() == CLASS_PRIEST);
|
return helper.UpdateBossAI() && !(bot->getClass() == CLASS_PRIEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool HorsemanAttractorsTrigger::IsActive()
|
bool HorsemanAttractorsTrigger::IsActive()
|
||||||
// {
|
{
|
||||||
// Difficulty diff = bot->GetRaidDifficulty();
|
if (!helper.UpdateBossAI()) {
|
||||||
// if (diff == RAID_DIFFICULTY_25MAN_NORMAL) {
|
return false;
|
||||||
// return BossPhaseTrigger::IsActive() && (botAI->IsRangedDpsAssistantOfIndex(bot, 0) || botAI->IsHealAssistantOfIndex(bot, 0) ||
|
}
|
||||||
// botAI->IsHealAssistantOfIndex(bot, 1) || botAI->IsHealAssistantOfIndex(bot, 2));
|
return helper.IsAttracter(bot);
|
||||||
// }
|
}
|
||||||
// return BossPhaseTrigger::IsActive() && (botAI->IsRangedDpsAssistantOfIndex(bot, 0) || botAI->IsHealAssistantOfIndex(bot, 0));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// bool HorsemanExceptAttractorsTrigger::IsActive()
|
bool HorsemanExceptAttractorsTrigger::IsActive()
|
||||||
// {
|
{
|
||||||
// return BossPhaseTrigger::IsActive() &&
|
if (!helper.UpdateBossAI()) {
|
||||||
// !(botAI->IsRangedDpsAssistantOfIndex(bot, 0) || botAI->IsHealAssistantOfIndex(bot, 0) ||
|
return false;
|
||||||
// botAI->IsHealAssistantOfIndex(bot, 1) || botAI->IsHealAssistantOfIndex(bot, 2));
|
}
|
||||||
// }
|
return !helper.IsAttracter(bot);
|
||||||
|
}
|
||||||
|
|
||||||
bool SapphironGroundTrigger::IsActive()
|
bool SapphironGroundTrigger::IsActive()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -143,19 +143,23 @@ public:
|
|||||||
// ThaddiusPhaseThaddiusTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "thaddius", 1 << (4 - 1), "thaddius phase thaddius") {}
|
// ThaddiusPhaseThaddiusTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "thaddius", 1 << (4 - 1), "thaddius phase thaddius") {}
|
||||||
// };
|
// };
|
||||||
|
|
||||||
// class HorsemanAttractorsTrigger : public BossPhaseTrigger
|
class HorsemanAttractorsTrigger : public Trigger
|
||||||
// {
|
{
|
||||||
// public:
|
public:
|
||||||
// HorsemanAttractorsTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "sir zeliek", 0, "horseman attractors") {}
|
HorsemanAttractorsTrigger(PlayerbotAI* ai) : Trigger(ai, "fourhorsemen"), helper(ai) {}
|
||||||
// virtual bool IsActive();
|
bool IsActive() override;
|
||||||
// };
|
private:
|
||||||
|
FourhorsemanBossHelper helper;
|
||||||
|
};
|
||||||
|
|
||||||
// class HorsemanExceptAttractorsTrigger : public BossPhaseTrigger
|
class HorsemanExceptAttractorsTrigger : public Trigger
|
||||||
// {
|
{
|
||||||
// public:
|
public:
|
||||||
// HorsemanExceptAttractorsTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "sir zeliek", 0, "horseman except attractors") {}
|
HorsemanExceptAttractorsTrigger(PlayerbotAI* ai) : Trigger(ai, "fourhorsemen"), helper(ai) {}
|
||||||
// virtual bool IsActive();
|
bool IsActive() override;
|
||||||
// };
|
private:
|
||||||
|
FourhorsemanBossHelper helper;
|
||||||
|
};
|
||||||
|
|
||||||
class SapphironGroundTrigger : public Trigger
|
class SapphironGroundTrigger : public Trigger
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ bool InvalidTargetValue::Calculate()
|
|||||||
target->isFeared() ||
|
target->isFeared() ||
|
||||||
target->HasUnitState(UNIT_STATE_ISOLATED) ||
|
target->HasUnitState(UNIT_STATE_ISOLATED) ||
|
||||||
target->IsFriendlyTo(bot) ||
|
target->IsFriendlyTo(bot) ||
|
||||||
!bot->IsWithinDistInMap(target, sPlayerbotAIConfig->sightDistance) ||
|
// !bot->IsWithinDistInMap(target, sPlayerbotAIConfig->sightDistance) ||
|
||||||
!bot->IsWithinLOSInMap(target);
|
!bot->IsWithinLOSInMap(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user