mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
refactor: naxxramas and kel'thuzad strategy
This commit is contained in:
@@ -1304,6 +1304,151 @@ bool PlayerbotAI::IsRanged(Player* player)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlayerbotAI::IsRangedDps(Player* player)
|
||||
{
|
||||
return IsRanged(player) && IsDps(player);
|
||||
}
|
||||
|
||||
bool PlayerbotAI::IsRangedDpsAssistantOfIndex(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()) && IsRangedDps(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()) && IsRangedDps(member)) {
|
||||
if (index == counter) {
|
||||
return player == member;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 PlayerbotAI::GetGroupSlotIndex(Player* player)
|
||||
{
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group) {
|
||||
return -1;
|
||||
}
|
||||
Group::MemberSlotList const& slots = group->GetMemberSlots();
|
||||
int counter = 0;
|
||||
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) {
|
||||
Player* member = ref->GetSource();
|
||||
if (player == member) {
|
||||
return counter;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 PlayerbotAI::GetRangedIndex(Player* player)
|
||||
{
|
||||
if (!IsRanged(player)) {
|
||||
return -1;
|
||||
}
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group) {
|
||||
return -1;
|
||||
}
|
||||
Group::MemberSlotList const& slots = group->GetMemberSlots();
|
||||
int counter = 0;
|
||||
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) {
|
||||
Player* member = ref->GetSource();
|
||||
if (player == member) {
|
||||
return counter;
|
||||
}
|
||||
if (IsRanged(member)) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 PlayerbotAI::GetClassIndex(Player* player, uint8_t cls)
|
||||
{
|
||||
if (player->getClass() != cls) {
|
||||
return -1;
|
||||
}
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group) {
|
||||
return -1;
|
||||
}
|
||||
Group::MemberSlotList const& slots = group->GetMemberSlots();
|
||||
int counter = 0;
|
||||
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) {
|
||||
Player* member = ref->GetSource();
|
||||
if (player == member) {
|
||||
return counter;
|
||||
}
|
||||
if (member->getClass() == cls) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int32 PlayerbotAI::GetRangedDpsIndex(Player* player)
|
||||
{
|
||||
if (!IsRangedDps(player)) {
|
||||
return -1;
|
||||
}
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group) {
|
||||
return -1;
|
||||
}
|
||||
Group::MemberSlotList const& slots = group->GetMemberSlots();
|
||||
int counter = 0;
|
||||
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) {
|
||||
Player* member = ref->GetSource();
|
||||
if (player == member) {
|
||||
return counter;
|
||||
}
|
||||
if (IsRangedDps(member)) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 PlayerbotAI::GetMeleeIndex(Player* player)
|
||||
{
|
||||
if (IsRanged(player)) {
|
||||
return -1;
|
||||
}
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group) {
|
||||
return -1;
|
||||
}
|
||||
Group::MemberSlotList const& slots = group->GetMemberSlots();
|
||||
int counter = 0;
|
||||
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next()) {
|
||||
Player* member = ref->GetSource();
|
||||
if (player == member) {
|
||||
return counter;
|
||||
}
|
||||
if (!IsRanged(member)) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool PlayerbotAI::IsTank(Player* player)
|
||||
{
|
||||
PlayerbotAI* botAi = GET_PLAYERBOT_AI(player);
|
||||
@@ -1370,6 +1515,54 @@ bool PlayerbotAI::IsHeal(Player* player)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlayerbotAI::IsDps(Player* player)
|
||||
{
|
||||
PlayerbotAI* botAi = GET_PLAYERBOT_AI(player);
|
||||
if (botAi)
|
||||
return botAi->ContainsStrategy(STRATEGY_TYPE_DPS);
|
||||
|
||||
int tab = AiFactory::GetPlayerSpecTab(player);
|
||||
switch (player->getClass())
|
||||
{
|
||||
case CLASS_MAGE:
|
||||
case CLASS_WARLOCK:
|
||||
case CLASS_HUNTER:
|
||||
case CLASS_ROGUE:
|
||||
return true;
|
||||
case CLASS_PRIEST:
|
||||
if (tab == PRIEST_TAB_SHADOW) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case CLASS_DRUID:
|
||||
if (tab == DRUID_TAB_BALANCE) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case CLASS_SHAMAN:
|
||||
if (tab != SHAMAN_TAB_RESTORATION) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case CLASS_PALADIN:
|
||||
if (tab == PALADIN_TAB_RETRIBUTION) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case CLASS_DEATH_KNIGHT:
|
||||
if (tab != DEATHKNIGT_TAB_BLOOD) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case CLASS_WARRIOR:
|
||||
if (tab != WARRIOR_TAB_PROTECTION) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlayerbotAI::IsMainTank(Player* player)
|
||||
{
|
||||
Group* group = bot->GetGroup();
|
||||
@@ -1379,8 +1572,10 @@ bool PlayerbotAI::IsMainTank(Player* player)
|
||||
ObjectGuid mainTank = ObjectGuid();
|
||||
Group::MemberSlotList const& slots = group->GetMemberSlots();
|
||||
for (Group::member_citerator itr = slots.begin(); itr != slots.end(); ++itr) {
|
||||
if (itr->flags & MEMBER_FLAG_MAINTANK)
|
||||
if (itr->flags & MEMBER_FLAG_MAINTANK) {
|
||||
mainTank = itr->guid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mainTank != ObjectGuid::Empty) {
|
||||
return player->GetGUID() == mainTank;
|
||||
|
||||
@@ -330,9 +330,21 @@ class PlayerbotAI : public PlayerbotAIBase
|
||||
void Reset(bool full = false);
|
||||
bool IsTank(Player* player);
|
||||
bool IsHeal(Player* player);
|
||||
bool IsDps(Player* player);
|
||||
bool IsRanged(Player* player);
|
||||
bool IsRangedDps(Player* player);
|
||||
bool IsMainTank(Player* player);
|
||||
bool IsAssistTank(Player* player);
|
||||
|
||||
bool IsAssistTankOfIndex(Player* player, int index);
|
||||
bool IsHealAssistantOfIndex(Player* player, int index);
|
||||
bool IsRangedDpsAssistantOfIndex(Player* player, int index);
|
||||
int32 GetGroupSlotIndex(Player* player);
|
||||
int32 GetRangedIndex(Player* player);
|
||||
int32 GetClassIndex(Player* player, uint8_t cls);
|
||||
int32 GetRangedDpsIndex(Player* player);
|
||||
int32 GetMeleeIndex(Player* player);
|
||||
|
||||
Creature* GetCreature(ObjectGuid guid);
|
||||
Unit* GetUnit(ObjectGuid guid);
|
||||
Player* GetPlayer(ObjectGuid guid);
|
||||
|
||||
@@ -104,18 +104,16 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
|
||||
|
||||
if (Pet* pet = bot->GetPet())
|
||||
{
|
||||
pet->SetReactState(REACT_PASSIVE);
|
||||
if (with_pet) {
|
||||
pet->SetTarget(target->GetGUID());
|
||||
// pet->GetCharmInfo()->SetCommandState(COMMAND_ATTACK);
|
||||
pet->GetCharmInfo()->SetIsCommandAttack(true);
|
||||
pet->AI()->AttackStart(target);
|
||||
pet->SetReactState(REACT_DEFENSIVE);
|
||||
// pet->SetReactState(REACT_DEFENSIVE);
|
||||
} else {
|
||||
// pet->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
|
||||
pet->GetCharmInfo()->SetIsCommandFollow(true);
|
||||
pet->GetCharmInfo()->IsReturning();
|
||||
pet->GetMotionMaster()->MoveFollow(bot, PET_FOLLOW_DIST, pet->GetFollowAngle());
|
||||
pet->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1399,3 +1399,17 @@ bool MoveRandomAction::isUseful()
|
||||
return !botAI->HasRealPlayerMaster() && botAI->GetAiObjectContext()->GetValue<GuidVector>("nearest friendly players")->Get().size() > urand(25, 100);
|
||||
}
|
||||
|
||||
bool MoveInsideAction::Execute(Event event)
|
||||
{
|
||||
return MoveInside(bot->GetMapId(), x, y, bot->GetPositionZ(), distance);
|
||||
}
|
||||
|
||||
bool RotateAroundTheCenterPointAction::Execute(Event event)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "Action.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include <cmath>
|
||||
|
||||
class Player;
|
||||
class PlayerbotAI;
|
||||
@@ -123,4 +124,43 @@ class MoveRandomAction : public MovementAction
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
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, 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<std::pair<float, float>> waypoints;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -33,7 +33,7 @@ void HealDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
new NextAction("swiftmend on party", ACTION_CRITICAL_HEAL + 3),
|
||||
new NextAction("wild growth", ACTION_CRITICAL_HEAL + 2),
|
||||
new NextAction("nourish on party", ACTION_CRITICAL_HEAL + 1),
|
||||
// new NextAction("healing touch on party", ACTION_CRITICAL_HEAL + 0),
|
||||
new NextAction("healing touch on party", ACTION_CRITICAL_HEAL + 0),
|
||||
NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
@@ -41,7 +41,7 @@ void HealDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
NextAction::array(0, new NextAction("nature's swiftness", ACTION_CRITICAL_HEAL + 4), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"group heal occasion",
|
||||
"medium group heal occasion",
|
||||
NextAction::array(0, new NextAction("tranquility", ACTION_CRITICAL_HEAL + 5), NULL)));
|
||||
|
||||
// LOW
|
||||
@@ -51,7 +51,7 @@ void HealDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 8),
|
||||
new NextAction("swiftmend on party", ACTION_MEDIUM_HEAL + 7),
|
||||
new NextAction("nourish on party", ACTION_MEDIUM_HEAL + 6),
|
||||
// new NextAction("healing touch on party", ACTION_MEDIUM_HEAL + 5),
|
||||
new NextAction("healing touch on party", ACTION_MEDIUM_HEAL + 5),
|
||||
NULL)));
|
||||
|
||||
// MEDIUM
|
||||
|
||||
@@ -47,8 +47,8 @@ void DpsHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
GenericHunterStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("black arrow", NextAction::array(0, new NextAction("black arrow", 15.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("low mana", NextAction::array(0, new NextAction("viper sting", 23), nullptr)));
|
||||
triggers.push_back(new TriggerNode("hunter's mark", NextAction::array(0, new NextAction("hunter's mark", 19.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("low mana", NextAction::array(0, new NextAction("viper sting", 23.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("hunter's mark", NextAction::array(0, new NextAction("hunter's mark", 11.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("concussive shot on snare target", NextAction::array(0, new NextAction("concussive shot", 20.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no pet", NextAction::array(0, new NextAction("call pet", 21.0f), NULL)));
|
||||
triggers.push_back(new TriggerNode("hunters pet low health", NextAction::array(0, new NextAction("mend pet", 21.0f), NULL)));
|
||||
@@ -58,7 +58,7 @@ void DpsHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
void DpsAoeHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("light aoe", NextAction::array(0, new NextAction("multi-shot", 20.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("volley", 20.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("volley", 21.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("serpent sting on attacker", NextAction::array(0, new NextAction("serpent sting on attacker", 17.0f), nullptr)));
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
inline std::string const GetActualBlessingOfMight(Unit* target)
|
||||
{
|
||||
if (!target->ToPlayer()) {
|
||||
return {""};
|
||||
return "blessing of might";
|
||||
}
|
||||
int tab = AiFactory::GetPlayerSpecTab(target->ToPlayer());
|
||||
switch (target->getClass())
|
||||
@@ -46,7 +46,7 @@ inline std::string const GetActualBlessingOfMight(Unit* target)
|
||||
inline std::string const GetActualBlessingOfWisdom(Unit* target)
|
||||
{
|
||||
if (!target->ToPlayer()) {
|
||||
return {""};
|
||||
return "blessing of might";
|
||||
}
|
||||
int tab = AiFactory::GetPlayerSpecTab(target->ToPlayer());
|
||||
switch (target->getClass())
|
||||
|
||||
@@ -36,8 +36,8 @@ class RaidNaxxActionContext : public NamedObjectContext<Action>
|
||||
// creators["sapphiron flight position"] = &RaidNaxxActionContext::sapphiron_flight_position;
|
||||
// creators["sapphiron avoid chill"] = &RaidNaxxActionContext::sapphiron_avoid_chill;
|
||||
|
||||
// creators["kel'thuzad choose target"] = &RaidNaxxActionContext::kelthuzad_choose_target;
|
||||
// creators["kel'thuzad position"] = &RaidNaxxActionContext::kelthuzad_position;
|
||||
creators["kel'thuzad choose target"] = &RaidNaxxActionContext::kelthuzad_choose_target;
|
||||
creators["kel'thuzad position"] = &RaidNaxxActionContext::kelthuzad_position;
|
||||
|
||||
creators["anub'rekhan choose target"] = &RaidNaxxActionContext::anubrekhan_choose_target;
|
||||
creators["anub'rekhan position"] = &RaidNaxxActionContext::anubrekhan_position;
|
||||
@@ -50,8 +50,8 @@ class RaidNaxxActionContext : public NamedObjectContext<Action>
|
||||
// creators["loatheb choose target"] = &RaidNaxxActionContext::loatheb_choose_target;
|
||||
}
|
||||
private:
|
||||
static Action* go_behind_the_boss(PlayerbotAI* ai) { return new GoBehindTheBossAction(ai); }
|
||||
static Action* rotate_grobbulus(PlayerbotAI* ai) { return new RotateGrobbulusAction(ai); }
|
||||
static Action* go_behind_the_boss(PlayerbotAI* ai) { return new GrobbulusGoBehindAction(ai); }
|
||||
static Action* rotate_grobbulus(PlayerbotAI* ai) { return new GrobbulusRotateAction(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); }
|
||||
@@ -68,8 +68,8 @@ class RaidNaxxActionContext : public NamedObjectContext<Action>
|
||||
// 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_avoid_chill(PlayerbotAI* ai) { return new SapphironAvoidChillAction(ai); }
|
||||
// static Action* kelthuzad_choose_target(PlayerbotAI* ai) { return new KelthuzadChooseTargetAction(ai); }
|
||||
// static Action* kelthuzad_position(PlayerbotAI* ai) { return new KelthuzadPositionAction(ai); }
|
||||
static Action* kelthuzad_choose_target(PlayerbotAI* ai) { return new KelthuzadChooseTargetAction(ai); }
|
||||
static Action* kelthuzad_position(PlayerbotAI* ai) { return new KelthuzadPositionAction(ai); }
|
||||
static Action* anubrekhan_choose_target(PlayerbotAI* ai) { return new AnubrekhanChooseTargetAction(ai); }
|
||||
static Action* anubrekhan_position(PlayerbotAI* ai) { return new AnubrekhanPositionAction(ai); }
|
||||
// static Action* gluth_choose_target(PlayerbotAI* ai) { return new GluthChooseTargetAction(ai); }
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Playerbots.h"
|
||||
#include "RaidNaxxScripts.h"
|
||||
#include "RaidNaxxBossHelper.h"
|
||||
|
||||
// just for test
|
||||
// class TryToGetBossAIAction : public Action
|
||||
@@ -19,10 +20,10 @@
|
||||
// virtual bool Execute(Event event);
|
||||
// };
|
||||
|
||||
class GoBehindTheBossAction : public MovementAction
|
||||
class GrobbulusGoBehindAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
GoBehindTheBossAction(PlayerbotAI* ai, float distance = 24.0f, float delta_angle = M_PI / 8) : MovementAction(ai, "grobbulus go behind the boss") {
|
||||
GrobbulusGoBehindAction(PlayerbotAI* ai, float distance = 24.0f, float delta_angle = M_PI / 8) : MovementAction(ai, "grobbulus go behind") {
|
||||
this->distance = distance;
|
||||
this->delta_angle = delta_angle;
|
||||
}
|
||||
@@ -31,67 +32,14 @@ protected:
|
||||
float distance, delta_angle;
|
||||
};
|
||||
|
||||
// class MoveToPointForceAction : public MovementAction
|
||||
// {
|
||||
// public:
|
||||
// MoveToPointForceAction(PlayerbotAI* ai, float x, float y) : MovementAction(ai, "move to point force") {
|
||||
// this->x = x;
|
||||
// this->y = y;
|
||||
// }
|
||||
// virtual bool Execute(Event event);
|
||||
// protected:
|
||||
// float x, y;
|
||||
// };
|
||||
|
||||
class MoveInsideAction : public MovementAction
|
||||
class GrobbulusRotateAction : public RotateAroundTheCenterPointAction
|
||||
{
|
||||
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, 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<std::pair<float, float>> waypoints;
|
||||
};
|
||||
|
||||
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() {
|
||||
GrobbulusRotateAction(PlayerbotAI* botAI): RotateAroundTheCenterPointAction(botAI, "rotate grobbulus", 3281.23f, -3310.38f, 35.0f, 8, true, M_PI) {}
|
||||
virtual bool isUseful() override {
|
||||
return RotateAroundTheCenterPointAction::isUseful() && botAI->IsMainTank(bot) && AI_VALUE2(bool, "has aggro", "boss target");
|
||||
}
|
||||
virtual uint32 GetCurrWaypoint();
|
||||
protected:
|
||||
uint32 GetCurrWaypoint() override;
|
||||
};
|
||||
|
||||
class GrobblulusMoveCenterAction : public MoveInsideAction
|
||||
@@ -254,19 +202,23 @@ protected:
|
||||
// virtual bool Execute(Event event);
|
||||
// };
|
||||
|
||||
// class KelthuzadChooseTargetAction : public AttackAction
|
||||
// {
|
||||
// public:
|
||||
// KelthuzadChooseTargetAction(PlayerbotAI* ai) : AttackAction(ai, "kel'thuzad choose target") {}
|
||||
// virtual bool Execute(Event event);
|
||||
// };
|
||||
class KelthuzadChooseTargetAction : public AttackAction
|
||||
{
|
||||
public:
|
||||
KelthuzadChooseTargetAction(PlayerbotAI* ai) : AttackAction(ai, "kel'thuzad choose target"), helper(ai) {}
|
||||
virtual bool Execute(Event event);
|
||||
private:
|
||||
KelthuzadBossHelper helper;
|
||||
};
|
||||
|
||||
// class KelthuzadPositionAction : public MovementAction
|
||||
// {
|
||||
// public:
|
||||
// KelthuzadPositionAction(PlayerbotAI* ai) : MovementAction(ai, "kel'thuzad position") {}
|
||||
// virtual bool Execute(Event event);
|
||||
// };
|
||||
class KelthuzadPositionAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
KelthuzadPositionAction(PlayerbotAI* ai) : MovementAction(ai, "kel'thuzad position"), helper(ai) {}
|
||||
virtual bool Execute(Event event);
|
||||
private:
|
||||
KelthuzadBossHelper helper;
|
||||
};
|
||||
|
||||
class AnubrekhanChooseTargetAction : public AttackAction
|
||||
{
|
||||
|
||||
72
src/strategy/raids/naxxramas/RaidNaxxBossHelper.h
Normal file
72
src/strategy/raids/naxxramas/RaidNaxxBossHelper.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef _PLAYERBOT_RAIDNAXXBOSSHELPER_H
|
||||
#define _PLAYERBOT_RAIDNAXXBOSSHELPER_H
|
||||
|
||||
#include "AiObject.h"
|
||||
#include "AiObjectContext.h"
|
||||
#include "EventMap.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "Player.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "RaidNaxxScripts.h"
|
||||
#include "SharedDefines.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
const uint32 NAXX_MAP_ID = 533;
|
||||
|
||||
template<class BossAiType>
|
||||
class GenericBossHelper : public AiObject {
|
||||
|
||||
};
|
||||
|
||||
class KelthuzadBossHelper: public AiObject {
|
||||
public:
|
||||
std::pair<float, float> center = {3716.19f, -5106.58f};
|
||||
std::pair<float, float> tank_pos = {3709.19f, -5104.86f};
|
||||
std::pair<float, float> assist_tank_pos = {3746.05f, -5112.74f};
|
||||
KelthuzadBossHelper(PlayerbotAI *botAI): AiObject(botAI) {}
|
||||
|
||||
bool UpdateBossAI() {
|
||||
Unit* target = AI_VALUE2(Unit*, "find target", "kel'thuzad");
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
ai_ = dynamic_cast<boss_kelthuzad::boss_kelthuzadAI *>(target->GetAI());
|
||||
if (!ai_) {
|
||||
return false;
|
||||
}
|
||||
event_map_ = &ai_->events;
|
||||
if (!event_map_) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool IsPhaseOne() {
|
||||
return event_map_->GetNextEventTime(KELTHUZAD_EVENT_PHASE_2) != 0;
|
||||
}
|
||||
bool IsPhaseTwo() {
|
||||
return !IsPhaseOne();
|
||||
}
|
||||
Unit* GetAnyShadowFissure() {
|
||||
Unit* shadow_fissure = nullptr;
|
||||
GuidVector units = *context->GetValue<GuidVector>("nearest triggers");
|
||||
for (auto 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;
|
||||
}
|
||||
}
|
||||
return shadow_fissure;
|
||||
}
|
||||
private:
|
||||
boss_kelthuzad::boss_kelthuzadAI *ai_;
|
||||
EventMap* event_map_;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -167,42 +167,36 @@ float HeiganDanceMultiplier::GetValue(Action* action)
|
||||
// return 1.0f;
|
||||
// }
|
||||
|
||||
// float KelthuzadGenericMultiplier::GetValue(Action* action)
|
||||
// {
|
||||
// Unit* boss = AI_VALUE2(Unit*, "find target", "kel'thuzad");
|
||||
// if (!boss) {
|
||||
// return 1.0f;
|
||||
// }
|
||||
// if ((dynamic_cast<AttackLeastHpTargetAction*>(action) ||
|
||||
// dynamic_cast<TankAssistAction*>(action) ||
|
||||
// dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) ||
|
||||
// dynamic_cast<FollowAction*>(action) ||
|
||||
// dynamic_cast<FleeAction*>(action))) {
|
||||
// return 0.0f;
|
||||
// }
|
||||
// BossAI* boss_ai = dynamic_cast<BossAI*>(boss->GetAI());
|
||||
// EventMap* eventMap = boss_botAI->GetEvents();
|
||||
// uint32 curr_phase = eventMap->GetPhaseMask();
|
||||
|
||||
// if (curr_phase == 1) {
|
||||
// if (dynamic_cast<CastTotemAction*>(action) ||
|
||||
// dynamic_cast<CastShadowfiendAction*>(action) ||
|
||||
// dynamic_cast<CastRaiseDeadAction*>(action) ||
|
||||
// dynamic_cast<CastFeignDeathAction*>(action) ||
|
||||
// dynamic_cast<CastInvisibilityAction*>(action) ||
|
||||
// dynamic_cast<CastVanishAction*>(action)) {
|
||||
// return 0.0f;
|
||||
// }
|
||||
// }
|
||||
// if (curr_phase == 2) {
|
||||
// if (dynamic_cast<CastBlizzardAction*>(action) ||
|
||||
// dynamic_cast<CastFrostNovaAction*>(action)) {
|
||||
// return 0.0f;
|
||||
// }
|
||||
|
||||
// }
|
||||
// return 1.0f;
|
||||
// }
|
||||
float KelthuzadGenericMultiplier::GetValue(Action* action)
|
||||
{
|
||||
if (!helper.UpdateBossAI()) {
|
||||
return 1.0f;
|
||||
}
|
||||
if ((dynamic_cast<DpsAssistAction*>(action) ||
|
||||
dynamic_cast<TankAssistAction*>(action) ||
|
||||
dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) ||
|
||||
dynamic_cast<FollowAction*>(action) ||
|
||||
dynamic_cast<FleeAction*>(action))) {
|
||||
return 0.0f;
|
||||
}
|
||||
if (helper.IsPhaseOne()) {
|
||||
if (dynamic_cast<CastTotemAction*>(action) ||
|
||||
dynamic_cast<CastShadowfiendAction*>(action) ||
|
||||
dynamic_cast<CastRaiseDeadAction*>(action) ||
|
||||
dynamic_cast<CastFeignDeathAction*>(action) ||
|
||||
dynamic_cast<CastInvisibilityAction*>(action) ||
|
||||
dynamic_cast<CastVanishAction*>(action)) {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
if (helper.IsPhaseTwo()) {
|
||||
if (dynamic_cast<CastBlizzardAction*>(action) ||
|
||||
dynamic_cast<CastFrostNovaAction*>(action)) {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
float AnubrekhanGenericMultiplier::GetValue(Action* action)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#define _PLAYERRBOT_RAIDNAXXMULTIPLIERS_H_
|
||||
|
||||
#include "Multiplier.h"
|
||||
#include "raids/naxxramas/RaidNaxxBossHelper.h"
|
||||
|
||||
class HeiganDanceMultiplier : public Multiplier
|
||||
{
|
||||
@@ -49,14 +50,14 @@ public:
|
||||
// virtual float GetValue(Action* action);
|
||||
// };
|
||||
|
||||
// class KelthuzadGenericMultiplier : public Multiplier
|
||||
// {
|
||||
// public:
|
||||
// KelthuzadGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "kelthuzad generic") {}
|
||||
|
||||
// public:
|
||||
// virtual float GetValue(Action* action);
|
||||
// };
|
||||
class KelthuzadGenericMultiplier : public Multiplier
|
||||
{
|
||||
public:
|
||||
KelthuzadGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "kelthuzad generic"), helper(ai) {}
|
||||
virtual float GetValue(Action* action);
|
||||
private:
|
||||
KelthuzadBossHelper helper;
|
||||
};
|
||||
|
||||
class AnubrekhanGenericMultiplier : public Multiplier
|
||||
{
|
||||
|
||||
@@ -1,8 +1,24 @@
|
||||
#ifndef _PLAYERBOT_RAIDNAXXSCRIPTS_H
|
||||
#define _PLAYERBOT_RAIDNAXXSCRIPTS_H
|
||||
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_heigan.h"
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.h"
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_grobbulus.h"
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_faerlina.h"
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_maexxna.h"
|
||||
|
||||
#endif
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_noth.h"
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_heigan.h"
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_loatheb.h"
|
||||
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_patchwerk.h"
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_grobbulus.h"
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_gluth.h"
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_thaddius.h"
|
||||
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_razuvious.h"
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_gothik.h"
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.h"
|
||||
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_sapphiron.h"
|
||||
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -86,13 +86,13 @@ void RaidNaxxStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
// "sapphiron chill",
|
||||
// NextAction::array(0, new NextAction("sapphiron avoid chill", ACTION_RAID + 1), NULL)));
|
||||
|
||||
// // Kel'Thuzad
|
||||
// triggers.push_back(new TriggerNode(
|
||||
// "kel'thuzad",
|
||||
// NextAction::array(0,
|
||||
// new NextAction("kel'thuzad choose target", ACTION_RAID + 1),
|
||||
// new NextAction("kel'thuzad position", ACTION_RAID + 1),
|
||||
// NULL)));
|
||||
// Kel'Thuzad
|
||||
triggers.push_back(new TriggerNode(
|
||||
"kel'thuzad",
|
||||
NextAction::array(0,
|
||||
new NextAction("kel'thuzad choose target", ACTION_RAID + 1),
|
||||
new NextAction("kel'thuzad position", ACTION_RAID + 1),
|
||||
NULL)));
|
||||
|
||||
// Anub'Rekhan
|
||||
triggers.push_back(new TriggerNode(
|
||||
@@ -131,7 +131,7 @@ void RaidNaxxStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers)
|
||||
// multipliers.push_back(new ThaddiusGenericMultiplier(ai));
|
||||
// multipliers.push_back(new SapphironGenericMultiplier(ai));
|
||||
// multipliers.push_back(new InstructorRazuviousGenericMultiplier(ai));
|
||||
// multipliers.push_back(new KelthuzadGenericMultiplier(ai));
|
||||
multipliers.push_back(new KelthuzadGenericMultiplier(botAI));
|
||||
multipliers.push_back(new AnubrekhanGenericMultiplier(botAI));
|
||||
// multipliers.push_back(new FourhorsemanGenericMultiplier(ai));
|
||||
// multipliers.push_back(new GothikGenericMultiplier(ai));
|
||||
|
||||
@@ -36,7 +36,7 @@ class RaidNaxxTriggerContext : public NamedObjectContext<Trigger>
|
||||
// creators["sapphiron flight"] = &RaidNaxxTriggerContext::sapphiron_flight;
|
||||
// creators["sapphiron chill"] = &RaidNaxxTriggerContext::sapphiron_ground_chill;
|
||||
|
||||
// creators["kel'thuzad"] = &RaidNaxxTriggerContext::kelthuzad;
|
||||
creators["kel'thuzad"] = &RaidNaxxTriggerContext::kelthuzad;
|
||||
// creators["kel'thuzad phase two"] = &RaidNaxxTriggerContext::kelthuzad_phase_two;
|
||||
|
||||
creators["anub'rekhan"] = &RaidNaxxTriggerContext::anubrekhan;
|
||||
@@ -65,7 +65,7 @@ class RaidNaxxTriggerContext : public NamedObjectContext<Trigger>
|
||||
// static Trigger* sapphiron_ground_except_main_tank(PlayerbotAI* ai) { return new SapphironGroundExceptMainTankTrigger(ai); }
|
||||
// static Trigger* sapphiron_flight(PlayerbotAI* ai) { return new SapphironFlightTrigger(ai); }
|
||||
// static Trigger* sapphiron_ground_chill(PlayerbotAI* ai) { return new SapphironGroundChillTrigger(ai); }
|
||||
// static Trigger* kelthuzad(PlayerbotAI* ai) { return new KelthuzadTrigger(ai); }
|
||||
static Trigger* kelthuzad(PlayerbotAI* ai) { return new KelthuzadTrigger(ai); }
|
||||
// static Trigger* kelthuzad_phase_two(PlayerbotAI* ai) { return new KelthuzadPhaseTwoTrigger(ai); }
|
||||
static Trigger* anubrekhan(PlayerbotAI* ai) { return new AnubrekhanTrigger(ai); }
|
||||
// static Trigger* gluth(PlayerbotAI* ai) { return new GluthTrigger(ai); }
|
||||
|
||||
@@ -166,5 +166,9 @@ bool HeiganRangedTrigger::IsActive()
|
||||
// return true;
|
||||
// }
|
||||
|
||||
bool KelthuzadTrigger::IsActive() {
|
||||
return helper.UpdateBossAI();
|
||||
}
|
||||
|
||||
template bool BossEventTrigger<boss_grobbulus::boss_grobbulusAI>::IsActive();
|
||||
template bool BossPhaseTrigger<boss_anubrekhan::boss_anubrekhanAI>::IsActive();
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "GenericTriggers.h"
|
||||
#include "RaidNaxxScripts.h"
|
||||
#include "raids/naxxramas/RaidNaxxBossHelper.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -167,11 +168,14 @@ public:
|
||||
// virtual bool IsActive();
|
||||
// };
|
||||
|
||||
// class KelthuzadTrigger : public BossPhaseTrigger
|
||||
// {
|
||||
// public:
|
||||
// KelthuzadTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "kel'thuzad", 0, "kel'thuzad trigger") {}
|
||||
// };
|
||||
class KelthuzadTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
KelthuzadTrigger(PlayerbotAI* ai) : Trigger(ai, "kel'thuzad trigger"), helper(ai) {}
|
||||
bool IsActive() override;
|
||||
private:
|
||||
KelthuzadBossHelper helper;
|
||||
};
|
||||
|
||||
class AnubrekhanTrigger : public BossPhaseTrigger<boss_anubrekhan::boss_anubrekhanAI>
|
||||
{
|
||||
|
||||
@@ -123,6 +123,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
||||
creators["low aoe heal"] = &TriggerContext::low_aoe_heal;
|
||||
creators["medium aoe heal"] = &TriggerContext::medium_aoe_heal;
|
||||
creators["group heal occasion"] = &TriggerContext::group_heal_occasion;
|
||||
creators["medium group heal occasion"] = &TriggerContext::medium_group_heal_occasion;
|
||||
creators["invalid target"] = &TriggerContext::invalid_target;
|
||||
creators["lfg proposal active"] = &TriggerContext::lfg_proposal_active;
|
||||
|
||||
@@ -216,6 +217,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
||||
static Trigger* low_aoe_heal(PlayerbotAI* botAI) { return new AoeHealTrigger(botAI, "low aoe heal", "low", 2); }
|
||||
static Trigger* medium_aoe_heal(PlayerbotAI* botAI) { return new AoeHealTrigger(botAI, "medium aoe heal", "medium", 2); }
|
||||
static Trigger* group_heal_occasion(PlayerbotAI* ai) { return new AoeInGroupTrigger(ai, "group heal occasion", "almost full", 0.4); }
|
||||
static Trigger* medium_group_heal_occasion(PlayerbotAI* ai) { return new AoeInGroupTrigger(ai, "group heal occasion", "medium", 0.4); }
|
||||
static Trigger* target_changed(PlayerbotAI* botAI) { return new TargetChangedTrigger(botAI); }
|
||||
static Trigger* swimming(PlayerbotAI* botAI) { return new IsSwimmingTrigger(botAI); }
|
||||
static Trigger* no_possible_targets(PlayerbotAI* botAI) { return new NoPossibleTargetsTrigger(botAI); }
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "AttackerCountValues.h"
|
||||
#include "Playerbots.h"
|
||||
#include "SharedDefines.h"
|
||||
|
||||
uint8 MyAttackerCountValue::Calculate()
|
||||
{
|
||||
@@ -13,80 +14,17 @@ uint8 MyAttackerCountValue::Calculate()
|
||||
bool HasAggroValue::Calculate()
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
if (!target) {
|
||||
return true;
|
||||
|
||||
}
|
||||
Unit* victim = target->GetVictim();
|
||||
|
||||
if (!victim) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (victim->GetGUID() == bot->GetGUID() || (victim->ToPlayer() && botAI->IsMainTank(victim->ToPlayer()))) {
|
||||
if (victim && (victim->GetGUID() == bot->GetGUID() || (victim->ToPlayer() && botAI->IsMainTank(victim->ToPlayer())))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// botAI->TellMaster("target: " + target->GetName() + " victim: " + victim->GetName());
|
||||
// if (victim->ToPlayer() ) {
|
||||
// botAI->TellMaster("victim is mt: " + std::to_string(botAI->IsMainTank(victim->ToPlayer())));
|
||||
// }
|
||||
return false;
|
||||
// HostileReference *ref = bot->getHostileRefMgr().getFirst();
|
||||
// if (!ref)
|
||||
// return true; // simulate as target is not atacking anybody yet
|
||||
|
||||
// while( ref )
|
||||
// {
|
||||
// ThreatMgr *threatManager = ref->GetSource();
|
||||
// Unit *attacker = threatManager->GetOwner();
|
||||
// if (attacker->GetGUID() != target->GetGUID()) {
|
||||
// ref = ref->next();
|
||||
// continue;
|
||||
// }
|
||||
// Unit *victim = attacker->GetVictim();
|
||||
// if (!victim) {
|
||||
// return true;
|
||||
// }
|
||||
// if ((victim->GetGUID() == bot->GetGUID() || (victim && victim->ToPlayer() && botAI->IsMainTank(victim->ToPlayer()))) &&
|
||||
// target->GetGUID() == attacker->GetGUID())
|
||||
// return true;
|
||||
// ref = ref->next();
|
||||
// }
|
||||
// Unit* target = GetTarget();
|
||||
// if (!target)
|
||||
// return true;
|
||||
|
||||
// HostileReference *ref = bot->getHostileRefMgr().getFirst();
|
||||
// if (!ref)
|
||||
// return true; // simulate as target is not atacking anybody yet
|
||||
|
||||
// while( ref )
|
||||
// {
|
||||
// ThreatMgr* threatMgr = ref->GetSource();
|
||||
// Unit* attacker = threatMgr->GetOwner();
|
||||
// Unit* victim = attacker->GetVictim();
|
||||
// if (victim == bot && target == attacker)
|
||||
// return true;
|
||||
|
||||
// ref = ref->next();
|
||||
// }
|
||||
|
||||
// ref = target->GetThreatMgr().getCurrentVictim();
|
||||
// if (ref)
|
||||
// {
|
||||
// if (Unit* victim = ref->getTarget())
|
||||
// {
|
||||
// if (Player* pl = victim->ToPlayer())
|
||||
// {
|
||||
// if (botAI->IsMainTank(pl))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// return false;
|
||||
}
|
||||
|
||||
uint8 AttackerCountValue::Calculate()
|
||||
|
||||
@@ -208,7 +208,7 @@ ItemUsage ItemUsageValue::QueryItemUsageForEquip(ItemTemplate const* itemProto)
|
||||
float oldScore = PlayerbotFactory::CalculateItemScore(oldItemProto->ItemId, bot);
|
||||
if (itemScore || oldScore)
|
||||
{
|
||||
shouldEquip = itemScore >= oldScore * 1.2;
|
||||
shouldEquip = itemScore >= oldScore * 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,3 +39,15 @@ bool NearestVehiclesValue::AcceptUnit(Unit* unit)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NearestTriggersValue::FindUnits(std::list<Unit*>& targets)
|
||||
{
|
||||
Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(bot, bot, range);
|
||||
Acore::UnitListSearcher<Acore::AnyUnfriendlyUnitInObjectRangeCheck> searcher(bot, targets, u_check);
|
||||
Cell::VisitAllObjects(bot, searcher, range);
|
||||
}
|
||||
|
||||
bool NearestTriggersValue::AcceptUnit(Unit* unit)
|
||||
{
|
||||
return !unit->IsPlayer();
|
||||
}
|
||||
@@ -30,4 +30,13 @@ class NearestVehiclesValue : public NearestUnitsValue
|
||||
bool AcceptUnit(Unit* unit) override;
|
||||
};
|
||||
|
||||
class NearestTriggersValue : public NearestUnitsValue
|
||||
{
|
||||
public:
|
||||
NearestTriggersValue(PlayerbotAI* botAI, float range = sPlayerbotAIConfig->sightDistance) : NearestUnitsValue(botAI, "nearest triggers", range) { }
|
||||
|
||||
protected:
|
||||
void FindUnits(std::list<Unit*>& targets) override;
|
||||
bool AcceptUnit(Unit* unit) override;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,7 @@ class FindTargetStrategy
|
||||
FindTargetStrategy(PlayerbotAI* botAI) : result(nullptr), botAI(botAI) { }
|
||||
|
||||
Unit* GetResult();
|
||||
virtual void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) = 0;
|
||||
virtual void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) = 0;
|
||||
void GetPlayerCount(Unit* creature, uint32* tankCount, uint32* dpsCount);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
#include "TankTargetValue.h"
|
||||
#include "ThreatValues.h"
|
||||
#include "TradeValues.h"
|
||||
#include "Value.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
@@ -289,6 +290,7 @@ class ValueContext : public NamedObjectContext<UntypedValue>
|
||||
creators["main tank"] = &ValueContext::main_tank;
|
||||
creators["find target"] = &ValueContext::find_target;
|
||||
creators["boss target"] = &ValueContext::boss_target;
|
||||
creators["nearest triggers"] = &ValueContext::nearest_triggers;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -483,6 +485,7 @@ class ValueContext : public NamedObjectContext<UntypedValue>
|
||||
static UntypedValue* main_tank(PlayerbotAI* ai) { return new PartyMemberMainTankValue(ai); }
|
||||
static UntypedValue* find_target(PlayerbotAI* ai) { return new FindTargetValue(ai); }
|
||||
static UntypedValue* boss_target(PlayerbotAI* ai) { return new BossTargetValue(ai); }
|
||||
static UntypedValue* nearest_triggers(PlayerbotAI* ai) { return new NearestTriggersValue(ai); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user