razuvious strategy

This commit is contained in:
Yunfan Li
2023-07-18 21:00:49 +08:00
parent 67a23fae3f
commit 9c1bb63d10
21 changed files with 326 additions and 265 deletions

View File

@@ -248,9 +248,9 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal)
// check activity // check activity
AllowActivity(); AllowActivity();
if (bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) { // if (bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) {
return; // return;
} // }
Spell* currentSpell = bot->GetCurrentSpell(CURRENT_GENERIC_SPELL); Spell* currentSpell = bot->GetCurrentSpell(CURRENT_GENERIC_SPELL);
if (currentSpell && currentSpell->getState() == SPELL_STATE_CASTING && currentSpell->GetCastTime()) if (currentSpell && currentSpell->getState() == SPELL_STATE_CASTING && currentSpell->GetCastTime())
{ {
@@ -2007,6 +2007,12 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell,
return false; return false;
} }
if (bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL) != nullptr) {
LOG_DEBUG("playerbot", "CanCastSpell() target name: {}, spellid: {}, bot name: {}, failed because has current channeled spell",
target->GetName(), spellid, bot->GetName());
return false;
}
if (bot->HasSpellCooldown(spellid)) { if (bot->HasSpellCooldown(spellid)) {
if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) {
LOG_DEBUG("playerbots", "Can cast spell failed. Spell not has cooldown. - target name: {}, spellid: {}, bot name: {}", LOG_DEBUG("playerbots", "Can cast spell failed. Spell not has cooldown. - target name: {}, spellid: {}, bot name: {}",

View File

@@ -7,6 +7,7 @@
#include "Formations.h" #include "Formations.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "ServerFacade.h" #include "ServerFacade.h"
#include <cstddef>
bool FollowAction::Execute(Event event) bool FollowAction::Execute(Event event)
{ {
@@ -23,8 +24,8 @@ bool FollowAction::Execute(Event event)
WorldLocation loc = formation->GetLocation(); WorldLocation loc = formation->GetLocation();
if (Formation::IsNullLocation(loc) || loc.GetMapId() == -1) if (Formation::IsNullLocation(loc) || loc.GetMapId() == -1)
return false; return false;
moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ()); moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ() + 2.0f);
} }
if (Pet* pet = bot->GetPet()) if (Pet* pet = bot->GetPet())
@@ -47,6 +48,9 @@ bool FollowAction::Execute(Event event)
bool FollowAction::isUseful() bool FollowAction::isUseful()
{ {
if (bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL) != nullptr) {
return false;
}
Formation* formation = AI_VALUE(Formation*, "formation"); Formation* formation = AI_VALUE(Formation*, "formation");
std::string const target = formation->GetTargetName(); std::string const target = formation->GetTargetName();

View File

@@ -1255,6 +1255,14 @@ bool FleeAction::Execute(Event event)
return MoveAway(AI_VALUE(Unit*, "current target")); return MoveAway(AI_VALUE(Unit*, "current target"));
} }
bool FleeAction::isUseful()
{
if (bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL) != nullptr) {
return false;
}
return true;
}
bool FleeWithPetAction::Execute(Event event) bool FleeWithPetAction::Execute(Event event)
{ {
if (Pet* pet = bot->GetPet()) if (Pet* pet = bot->GetPet())

View File

@@ -48,6 +48,7 @@ class FleeAction : public MovementAction
FleeAction(PlayerbotAI* botAI, float distance = sPlayerbotAIConfig->spellDistance) : MovementAction(botAI, "flee"), distance(distance) { } FleeAction(PlayerbotAI* botAI, float distance = sPlayerbotAIConfig->spellDistance) : MovementAction(botAI, "flee"), distance(distance) { }
bool Execute(Event event) override; bool Execute(Event event) override;
bool isUseful() override;
private: private:
float distance; float distance;

View File

@@ -8,6 +8,10 @@
float ThreatMultiplier::GetValue(Action* action) float ThreatMultiplier::GetValue(Action* action)
{ {
if (AI_VALUE(bool, "neglect threat")) {
return 1.0f;
}
if (!action || action->getThreatType() == Action::ActionThreatType::None) if (!action || action->getThreatType() == Action::ActionThreatType::None)
return 1.0f; return 1.0f;

View File

@@ -53,15 +53,11 @@ void TankPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
"devotion aura", "devotion aura",
NextAction::array(0, new NextAction("devotion aura", 90.0f), NULL))); NextAction::array(0, new NextAction("devotion aura", 90.0f), NULL)));
// triggers.push_back(new TriggerNode("judgement of light", NextAction::array(0, new NextAction("judgement of light", ACTION_HIGH + 6), nullptr))); triggers.push_back(new TriggerNode("light aoe", NextAction::array(0, new NextAction("avenger's shield", ACTION_HIGH + 5), nullptr)));
// triggers.push_back(new TriggerNode("medium mana", NextAction::array(0, new NextAction("judgement of wisdom", ACTION_HIGH + 6), nullptr))); triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("consecration", ACTION_HIGH + 7), new NextAction("avenger's shield", ACTION_HIGH + 6), NULL)));
// triggers.push_back(new TriggerNode("judgement", NextAction::array(0, new NextAction("judgement", ACTION_HIGH + 6), nullptr)));
// triggers.push_back(new TriggerNode("judgement", NextAction::array(0, new NextAction("exorcism", ACTION_HIGH + 6), nullptr)));
triggers.push_back(new TriggerNode("light aoe", NextAction::array(0, new NextAction("hammer of the righteous", ACTION_HIGH + 8), new NextAction("avenger's shield", ACTION_HIGH + 7), nullptr)));
triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("consecration", ACTION_HIGH + 1), new NextAction("avenger's shield", ACTION_HIGH + 3), NULL)));
// triggers.push_back(new TriggerNode("avenger's shield", NextAction::array(0, new NextAction("avenger's shield", ACTION_HIGH + 7), nullptr))); // triggers.push_back(new TriggerNode("avenger's shield", NextAction::array(0, new NextAction("avenger's shield", ACTION_HIGH + 7), nullptr)));
triggers.push_back(new TriggerNode("lose aggro", NextAction::array(0, new NextAction("hand of reckoning", ACTION_HIGH + 7), nullptr))); triggers.push_back(new TriggerNode("lose aggro", NextAction::array(0, new NextAction("hand of reckoning", ACTION_HIGH + 7), nullptr)));
triggers.push_back(new TriggerNode("holy shield", NextAction::array(0, new NextAction("holy shield", ACTION_HIGH + 7), nullptr))); triggers.push_back(new TriggerNode("holy shield", NextAction::array(0, new NextAction("holy shield", ACTION_HIGH + 4), nullptr)));
// triggers.push_back(new TriggerNode("blessing", NextAction::array(0, new NextAction("blessing of sanctuary", ACTION_HIGH + 9), nullptr))); // triggers.push_back(new TriggerNode("blessing", NextAction::array(0, new NextAction("blessing of sanctuary", ACTION_HIGH + 9), nullptr)));
triggers.push_back(new TriggerNode("target critical health", NextAction::array(0, new NextAction("hammer of wrath", ACTION_CRITICAL_HEAL), nullptr))); triggers.push_back(new TriggerNode("target critical health", NextAction::array(0, new NextAction("hammer of wrath", ACTION_CRITICAL_HEAL), nullptr)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(

View File

@@ -25,8 +25,8 @@ class RaidNaxxActionContext : public NamedObjectContext<Action>
// creators["thaddius move to platform"] = &RaidNaxxActionContext::thaddius_move_to_platform; // creators["thaddius move to platform"] = &RaidNaxxActionContext::thaddius_move_to_platform;
// creators["thaddius move polarity"] = &RaidNaxxActionContext::thaddius_move_polarity; // creators["thaddius move polarity"] = &RaidNaxxActionContext::thaddius_move_polarity;
// 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;
@@ -60,8 +60,8 @@ class RaidNaxxActionContext : public NamedObjectContext<Action>
// static Action* thaddius_ranged_to_place(PlayerbotAI* ai) { return new ThaddiusRangedToPlaceAction(ai); } // static Action* thaddius_ranged_to_place(PlayerbotAI* ai) { return new ThaddiusRangedToPlaceAction(ai); }
// static Action* thaddius_move_to_platform(PlayerbotAI* ai) { return new ThaddiusMoveToPlatformAction(ai); } // static Action* thaddius_move_to_platform(PlayerbotAI* ai) { return new ThaddiusMoveToPlatformAction(ai); }
// 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); }

View File

@@ -288,121 +288,129 @@ bool HeiganDanceRangedAction::Execute(Event event) {
// return MoveTo(bot->GetMapId(), position[idx].first, position[idx].second, bot->GetPositionZ()); // return MoveTo(bot->GetMapId(), position[idx].first, position[idx].second, bot->GetPositionZ());
// } // }
// bool RazuviousUseObedienceCrystalAction::Execute(Event event) bool RazuviousUseObedienceCrystalAction::Execute(Event event)
// { {
if (!helper.UpdateBossAI()) {
// if (Unit* charm = bot->GetCharm()) { return false;
// Unit* target = AI_VALUE2(Unit*, "find target", "instructor razuvious"); }
// if (!target) { // bot->GetCharm
// return false; if (Unit* charm = bot->GetCharm()) {
// } Unit* target = AI_VALUE2(Unit*, "find target", "instructor razuvious");
// charm->GetMotionMaster()->MoveChase(target); if (!target) {
// charm->Attack(target, true); return false;
// charm->SetFacingToObject(target); }
// Aura* forceObedience = botAI->GetAura("force obedience", charm); if (charm->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_ACTIVE) == NULL_MOTION_TYPE) {
// uint32 duration_time; charm->GetMotionMaster()->Clear();
// if (!forceObedience) { charm->GetMotionMaster()->MoveChase(target);
// forceObedience = botAI->GetAura("mind control", charm); charm->GetAI()->AttackStart(target);
// duration_time = 60000; }
// } else { Aura* forceObedience = botAI->GetAura("force obedience", charm);
// duration_time = 90000; uint32 duration_time;
// } if (!forceObedience) {
// if (!forceObedience) { forceObedience = botAI->GetAura("mind control", charm);
// return false; duration_time = 60000;
// } } else {
// if (charm->GetDistance(target) <= 0.51f) { duration_time = 90000;
// // taunt }
// bool tauntUseful = true; if (!forceObedience) {
// if (forceObedience->GetDuration() <= (duration_time - 5000)) { return false;
// if (target->GetVictim() && botAI->HasAura(29061, target->GetVictim())) { }
// tauntUseful = false; if (charm->GetDistance(target) <= 0.51f) {
// } // taunt
// if (forceObedience->GetDuration() <= 3000) { bool tauntUseful = true;
// tauntUseful = false; if (forceObedience->GetDuration() <= (duration_time - 5000)) {
// } if (target->GetVictim() && botAI->HasAura(29061, target->GetVictim())) {
// } tauntUseful = false;
// if (forceObedience->GetDuration() >= (duration_time - 500)) { }
// tauntUseful = false; if (forceObedience->GetDuration() <= 3000) {
// } tauntUseful = false;
// if ( tauntUseful && !charm->GetSpellHistory()->HasCooldown(29060) ) { }
// // shield }
// if (!charm->GetSpellHistory()->HasCooldown(29061)) { if (forceObedience->GetDuration() >= (duration_time - 500)) {
// charm->CastSpell(charm, 29061, true); tauntUseful = false;
// charm->GetSpellHistory()->AddCooldown(29061, 0, Seconds(30)); }
// } if ( tauntUseful && !charm->HasSpellCooldown(29060) ) {
// charm->CastSpell(target, 29060, true); // shield
// charm->GetSpellHistory()->AddCooldown(29060, 0, Seconds(20)); if (!charm->HasSpellCooldown(29061)) {
// } charm->CastSpell(charm, 29061, true);
// // strike charm->AddSpellCooldown(29061, 0, 30 * 1000);
// if (!charm->GetSpellHistory()->HasCooldown(61696)) { }
// charm->CastSpell(target, 61696, true); charm->CastSpell(target, 29060, true);
// charm->GetSpellHistory()->AddCooldown(61696, 0, Seconds(4)); charm->AddSpellCooldown(29060, 0, 20 * 1000);
// } }
// } // strike
// } else { if (!charm->HasSpellCooldown(61696)) {
// Difficulty diff = bot->GetRaidDifficulty(); charm->CastSpell(target, 61696, true);
// if (diff == RAID_DIFFICULTY_10MAN_NORMAL) { charm->AddSpellCooldown(61696, 0, 4 * 1000);
// list<ObjectGuid> npcs = AI_VALUE(list<ObjectGuid>, "nearest npcs"); }
// for (list<ObjectGuid>::iterator i = npcs.begin(); i != npcs.end(); i++) }
// { } else {
// Creature* unit = botAI->GetCreature(*i); Difficulty diff = bot->GetRaidDifficulty();
// if (!unit) { if (diff == RAID_DIFFICULTY_10MAN_NORMAL) {
// continue; GuidVector npcs = AI_VALUE(GuidVector, "nearest npcs");
// } for (auto i = npcs.begin(); i != npcs.end(); i++)
// if (botAI->IsMainTank(bot) && unit->GetSpawnId() != 128352) { {
// continue; Creature* unit = botAI->GetCreature(*i);
// } if (!unit) {
// if (!botAI->IsMainTank(bot) && unit->GetSpawnId() != 128353) { continue;
// continue; }
// } if (botAI->IsMainTank(bot) && unit->GetSpawnId() != 128352) {
// if (MoveTo(unit)) { continue;
// return true; }
// } if (!botAI->IsMainTank(bot) && unit->GetSpawnId() != 128353) {
// Creature *creature = bot->GetNPCIfCanInteractWith(*i, UNIT_NPC_FLAG_SPELLCLICK); continue;
// if (!creature) }
// continue; if (MoveTo(unit)) {
// creature->HandleSpellClick(bot); return true;
// return true; }
// } Creature *creature = bot->GetNPCIfCanInteractWith(*i, UNIT_NPC_FLAG_SPELLCLICK);
// } else { if (!creature)
// list<ObjectGuid> attackers = context->GetValue<list<ObjectGuid> >("attackers")->Get(); continue;
// Unit* target = nullptr; creature->HandleSpellClick(bot);
// for (list<ObjectGuid>::iterator i = attackers.begin(); i != attackers.end(); ++i) { return true;
// Unit* unit = botAI->GetUnit(*i); }
// if (!unit) } else {
// continue; GuidVector attackers = context->GetValue<GuidVector>("attackers")->Get();
// if (botAI->EqualLowercaseName(unit->GetName(), "death knight understudy")) { Unit* target = nullptr;
// target = unit; for (auto i = attackers.begin(); i != attackers.end(); ++i) {
// break; Unit* unit = botAI->GetUnit(*i);
// } if (!unit)
// } continue;
// if (target) { if (botAI->EqualLowercaseName(unit->GetName(), "death knight understudy")) {
// if (bot->GetDistance2d(target) > sPlayerbotAIConfig.spellDistance) { target = unit;
// return MoveNear(target, sPlayerbotAIConfig.spellDistance); break;
// } else { }
// return botAI->CastSpell("mind control", target); }
// } if (target) {
// } if (bot->GetDistance2d(target) > sPlayerbotAIConfig->spellDistance) {
// } return MoveNear(target, sPlayerbotAIConfig->spellDistance);
// } } else {
// return false; return botAI->CastSpell("mind control", target);
// } }
}
}
}
return false;
}
// bool RazuviousTargetAction::Execute(Event event) bool RazuviousTargetAction::Execute(Event event)
// { {
// Unit* razuvious = AI_VALUE2(Unit*, "find target", "instructor razuvious"); if (!helper.UpdateBossAI()) {
// Unit* understudy = AI_VALUE2(Unit*, "find target", "death knight understudy"); return false;
// Unit* target = nullptr; }
// if (botAI->IsTank(bot)) { Unit* razuvious = AI_VALUE2(Unit*, "find target", "instructor razuvious");
// target = understudy; Unit* understudy = AI_VALUE2(Unit*, "find target", "death knight understudy");
// } else { Unit* target = nullptr;
// target = razuvious; if (botAI->IsTank(bot)) {
// } target = understudy;
// if (AI_VALUE(Unit*, "current target") == target) { } else {
// return false; target = razuvious;
// } }
// return Attack(target); if (AI_VALUE(Unit*, "current target") == target) {
// } return false;
}
return Attack(target);
}
// bool HorsemanAttractAlternativelyAction::Execute(Event event) // bool HorsemanAttractAlternativelyAction::Execute(Event event)
// { // {

View File

@@ -127,19 +127,23 @@ protected:
// virtual bool isUseful(); // virtual bool isUseful();
// }; // };
// class RazuviousUseObedienceCrystalAction : public MovementAction class RazuviousUseObedienceCrystalAction : public MovementAction
// { {
// public: public:
// RazuviousUseObedienceCrystalAction(PlayerbotAI* ai) : MovementAction(ai, "razuvious use obedience crystal") {} RazuviousUseObedienceCrystalAction(PlayerbotAI* ai) : MovementAction(ai, "razuvious use obedience crystal"), helper(ai) {}
// virtual bool Execute(Event event); bool Execute(Event event) override;
// }; private:
RazuviousBossHelper helper;
};
// class RazuviousTargetAction : public AttackAction class RazuviousTargetAction : public AttackAction
// { {
// public: public:
// RazuviousTargetAction(PlayerbotAI* ai) : AttackAction(ai, "razuvious target") {} RazuviousTargetAction(PlayerbotAI* ai) : AttackAction(ai, "razuvious target"), helper(ai) {}
// virtual bool Execute(Event event); bool Execute(Event event) override;
// }; private:
RazuviousBossHelper helper;
};
// class HorsemanAttractAlternativelyAction : public AttackAction // class HorsemanAttractAlternativelyAction : public AttackAction
// { // {

View File

@@ -18,22 +18,14 @@ const uint32 NAXX_MAP_ID = 533;
template<class BossAiType> template<class BossAiType>
class GenericBossHelper : public AiObject { class GenericBossHelper : public AiObject {
};
class KelthuzadBossHelper: public AiObject {
public: public:
std::pair<float, float> center = {3716.19f, -5106.58f}; GenericBossHelper(PlayerbotAI* botAI, std::string name): AiObject(botAI), name_(name) {}
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() { bool UpdateBossAI() {
Unit* target = AI_VALUE2(Unit*, "find target", "kel'thuzad"); Unit* target = AI_VALUE2(Unit*, "find target", name_);
if (!target) { if (!target) {
return false; return false;
} }
ai_ = dynamic_cast<boss_kelthuzad::boss_kelthuzadAI *>(target->GetAI()); ai_ = dynamic_cast<BossAiType *>(target->GetAI());
if (!ai_) { if (!ai_) {
return false; return false;
} }
@@ -43,6 +35,18 @@ class KelthuzadBossHelper: public AiObject {
} }
return true; return true;
} }
protected:
std::string name_;
BossAiType *ai_;
EventMap* event_map_;
};
class KelthuzadBossHelper: public GenericBossHelper<boss_kelthuzad::boss_kelthuzadAI> {
public:
KelthuzadBossHelper(PlayerbotAI *botAI): GenericBossHelper(botAI, "kel'thuzad") {}
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};
bool IsPhaseOne() { bool IsPhaseOne() {
return event_map_->GetNextEventTime(KELTHUZAD_EVENT_PHASE_2) != 0; return event_map_->GetNextEventTime(KELTHUZAD_EVENT_PHASE_2) != 0;
} }
@@ -63,10 +67,11 @@ class KelthuzadBossHelper: public AiObject {
} }
return shadow_fissure; return shadow_fissure;
} }
private:
boss_kelthuzad::boss_kelthuzadAI *ai_;
EventMap* event_map_;
}; };
class RazuviousBossHelper: public GenericBossHelper<boss_razuvious::boss_razuviousAI> {
public:
RazuviousBossHelper(PlayerbotAI *botAI): GenericBossHelper(botAI, "instructor razuvious") {}
};
#endif #endif

View File

@@ -16,6 +16,7 @@
#include "DruidActions.h" #include "DruidActions.h"
#include "PaladinActions.h" #include "PaladinActions.h"
#include "WarriorActions.h" #include "WarriorActions.h"
#include "DruidBearActions.h"
float HeiganDanceMultiplier::GetValue(Action* action) float HeiganDanceMultiplier::GetValue(Action* action)
{ {
@@ -63,7 +64,7 @@ float HeiganDanceMultiplier::GetValue(Action* action)
// } // }
// context->GetValue<bool>("neglect threat")->Set(true); // context->GetValue<bool>("neglect threat")->Set(true);
// if (botAI->GetCurrentState() == BOT_STATE_COMBAT && // if (botAI->GetCurrentState() == BOT_STATE_COMBAT &&
// (dynamic_cast<AttackLeastHpTargetAction*>(action) || // (dynamic_cast<DpsAssistAction*>(action) ||
// dynamic_cast<TankAssistAction*>(action) || // dynamic_cast<TankAssistAction*>(action) ||
// dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) || // dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) ||
// dynamic_cast<FleeAction*>(action))) { // dynamic_cast<FleeAction*>(action))) {
@@ -91,7 +92,7 @@ float HeiganDanceMultiplier::GetValue(Action* action)
// uint32 curr_phase = eventMap->GetPhaseMask(); // uint32 curr_phase = eventMap->GetPhaseMask();
// // pet phase // // pet phase
// if (curr_phase == 2 && // if (curr_phase == 2 &&
// ( dynamic_cast<AttackLeastHpTargetAction*>(action) || // ( dynamic_cast<DpsAssistAction*>(action) ||
// dynamic_cast<TankAssistAction*>(action) || // dynamic_cast<TankAssistAction*>(action) ||
// dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) || // dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) ||
// dynamic_cast<ReachPartyMemberToHealAction*>(action) || // dynamic_cast<ReachPartyMemberToHealAction*>(action) ||
@@ -148,24 +149,23 @@ float HeiganDanceMultiplier::GetValue(Action* action)
// return 1.0f; // return 1.0f;
// } // }
// float InstructorRazuviousGenericMultiplier::GetValue(Action* action) float InstructorRazuviousGenericMultiplier::GetValue(Action* action)
// { {
// Unit* boss = AI_VALUE2(Unit*, "find target", "instructor razuvious"); if (!helper.UpdateBossAI()) {
// if (!boss) { return 1.0f;
// return 1.0f; }
// } context->GetValue<bool>("neglect threat")->Set(true);
// context->GetValue<bool>("neglect threat")->Set(true); if (botAI->GetState() == BOT_STATE_COMBAT &&
// if (botAI->GetCurrentState() == BOT_STATE_COMBAT && (dynamic_cast<DpsAssistAction*>(action) ||
// (dynamic_cast<AttackLeastHpTargetAction*>(action) || dynamic_cast<TankAssistAction*>(action) ||
// dynamic_cast<TankAssistAction*>(action) || dynamic_cast<CastTauntAction*>(action) ||
// dynamic_cast<CastTauntAction*>(action) || dynamic_cast<CastDarkCommandAction*>(action) ||
// dynamic_cast<CastDarkCommandAction*>(action) || dynamic_cast<CastHandOfReckoningAction*>(action) ||
// dynamic_cast<CastHandOfReckoningAction*>(action) || dynamic_cast<CastGrowlAction*>(action))) {
// dynamic_cast<CastGrowlAction*>(action))) { return 0.0f;
// return 0.0f; }
// } return 1.0f;
// return 1.0f; }
// }
float KelthuzadGenericMultiplier::GetValue(Action* action) float KelthuzadGenericMultiplier::GetValue(Action* action)
{ {
@@ -205,7 +205,7 @@ float AnubrekhanGenericMultiplier::GetValue(Action* action)
return 1.0f; return 1.0f;
} }
if ( if (
// (dynamic_cast<AttackLeastHpTargetAction*>(action) || // (dynamic_cast<DpsAssistAction*>(action) ||
// dynamic_cast<DpsAssistAction*>(action) || // dynamic_cast<DpsAssistAction*>(action) ||
// dynamic_cast<TankAssistAction*>(action) || // dynamic_cast<TankAssistAction*>(action) ||
dynamic_cast<FollowAction*>(action)) { dynamic_cast<FollowAction*>(action)) {
@@ -228,7 +228,7 @@ float AnubrekhanGenericMultiplier::GetValue(Action* action)
// if (!boss) { // if (!boss) {
// return 1.0f; // return 1.0f;
// } // }
// if ((dynamic_cast<AttackLeastHpTargetAction*>(action) || // if ((dynamic_cast<DpsAssistAction*>(action) ||
// dynamic_cast<TankAssistAction*>(action))) { // dynamic_cast<TankAssistAction*>(action))) {
// return 0.0f; // return 0.0f;
// } // }
@@ -262,7 +262,7 @@ float AnubrekhanGenericMultiplier::GetValue(Action* action)
// if (!boss) { // if (!boss) {
// return 1.0f; // return 1.0f;
// } // }
// if ((dynamic_cast<AttackLeastHpTargetAction*>(action) || // if ((dynamic_cast<DpsAssistAction*>(action) ||
// dynamic_cast<TankAssistAction*>(action) || // dynamic_cast<TankAssistAction*>(action) ||
// dynamic_cast<FleeAction*>(action) || // dynamic_cast<FleeAction*>(action) ||
// dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) || // dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) ||

View File

@@ -41,14 +41,14 @@ public:
// virtual float GetValue(Action* action); // virtual float GetValue(Action* action);
// }; // };
// class InstructorRazuviousGenericMultiplier : public Multiplier class InstructorRazuviousGenericMultiplier : public Multiplier
// { {
// public: public:
// InstructorRazuviousGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "instructor razuvious generic") {} InstructorRazuviousGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "instructor razuvious generic"), helper(ai) {}
virtual float GetValue(Action* action);
// public: private:
// virtual float GetValue(Action* action); RazuviousBossHelper helper;
// }; };
class KelthuzadGenericMultiplier : public Multiplier class KelthuzadGenericMultiplier : public Multiplier
{ {

View File

@@ -30,6 +30,22 @@ void RaidNaxxStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
"heigan ranged", "heigan ranged",
NextAction::array(0, new NextAction("heigan dance ranged", ACTION_RAID + 1), NULL))); NextAction::array(0, new NextAction("heigan dance ranged", 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(
"anub'rekhan",
NextAction::array(0,
// new NextAction("anub'rekhan choose target", ACTION_RAID + 1),
new NextAction("anub'rekhan position", ACTION_RAID + 1),
NULL)));
// Thaddius // Thaddius
// triggers.push_back(new TriggerNode( // triggers.push_back(new TriggerNode(
// "thaddius phase pet", // "thaddius phase pet",
@@ -51,14 +67,14 @@ void RaidNaxxStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
// "thaddius phase thaddius", // "thaddius phase thaddius",
// NextAction::array(0, new NextAction("thaddius move polarity", ACTION_RAID + 1), NULL))); // NextAction::array(0, new NextAction("thaddius move polarity", ACTION_RAID + 1), NULL)));
// // Instructor Razuvious // Instructor Razuvious
// triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
// "razuvious tank", "razuvious tank",
// NextAction::array(0, new NextAction("razuvious use obedience crystal", ACTION_RAID + 1), NULL))); NextAction::array(0, new NextAction("razuvious use obedience crystal", ACTION_RAID + 1), NULL)));
// triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
// "razuvious nontank", "razuvious nontank",
// NextAction::array(0, new NextAction("razuvious target", ACTION_RAID + 1), NULL))); NextAction::array(0, new NextAction("razuvious target", ACTION_RAID + 1), NULL)));
// // four horseman // // four horseman
// triggers.push_back(new TriggerNode( // triggers.push_back(new TriggerNode(
@@ -86,21 +102,7 @@ void RaidNaxxStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
// "sapphiron chill", // "sapphiron chill",
// NextAction::array(0, new NextAction("sapphiron avoid chill", ACTION_RAID + 1), NULL))); // 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)));
// Anub'Rekhan
triggers.push_back(new TriggerNode(
"anub'rekhan",
NextAction::array(0,
// new NextAction("anub'rekhan choose target", ACTION_RAID + 1),
new NextAction("anub'rekhan position", ACTION_RAID + 1),
NULL)));
// // Gluth // // Gluth
// triggers.push_back(new TriggerNode( // triggers.push_back(new TriggerNode(
@@ -115,6 +117,7 @@ void RaidNaxxStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
// "gluth main tank mortal wound", // "gluth main tank mortal wound",
// NextAction::array(0, // NextAction::array(0,
// new NextAction("taunt spell", ACTION_RAID + 1), NULL))); // new NextAction("taunt spell", ACTION_RAID + 1), NULL)));
// // Loatheb // // Loatheb
// triggers.push_back(new TriggerNode( // triggers.push_back(new TriggerNode(
// "loatheb", // "loatheb",
@@ -130,7 +133,7 @@ void RaidNaxxStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers)
// multipliers.push_back(new LoathebGenericMultiplier(ai)); // multipliers.push_back(new LoathebGenericMultiplier(ai));
// multipliers.push_back(new ThaddiusGenericMultiplier(ai)); // multipliers.push_back(new ThaddiusGenericMultiplier(ai));
// multipliers.push_back(new SapphironGenericMultiplier(ai)); // multipliers.push_back(new SapphironGenericMultiplier(ai));
// multipliers.push_back(new InstructorRazuviousGenericMultiplier(ai)); 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(ai)); // multipliers.push_back(new FourhorsemanGenericMultiplier(ai));

View File

@@ -25,8 +25,8 @@ class RaidNaxxTriggerContext : public NamedObjectContext<Trigger>
// creators["thaddius phase transition"] = &RaidNaxxTriggerContext::thaddius_phase_transition; // creators["thaddius phase transition"] = &RaidNaxxTriggerContext::thaddius_phase_transition;
// creators["thaddius phase thaddius"] = &RaidNaxxTriggerContext::thaddius_phase_thaddius; // creators["thaddius phase thaddius"] = &RaidNaxxTriggerContext::thaddius_phase_thaddius;
// 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;
@@ -56,8 +56,8 @@ class RaidNaxxTriggerContext : public NamedObjectContext<Trigger>
// static Trigger* thaddius_phase_pet_lose_aggro(PlayerbotAI* ai) { return new ThaddiusPhasePetLoseAggroTrigger(ai); } // static Trigger* thaddius_phase_pet_lose_aggro(PlayerbotAI* ai) { return new ThaddiusPhasePetLoseAggroTrigger(ai); }
// static Trigger* thaddius_phase_transition(PlayerbotAI* ai) { return new ThaddiusPhaseTransitionTrigger(ai); } // static Trigger* thaddius_phase_transition(PlayerbotAI* ai) { return new ThaddiusPhaseTransitionTrigger(ai); }
// static Trigger* thaddius_phase_thaddius(PlayerbotAI* ai) { return new ThaddiusPhaseThaddiusTrigger(ai); } // static Trigger* thaddius_phase_thaddius(PlayerbotAI* ai) { return new ThaddiusPhaseThaddiusTrigger(ai); }
// 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); }

View File

@@ -91,23 +91,23 @@ bool HeiganRangedTrigger::IsActive()
return botAI->IsRanged(bot); return botAI->IsRanged(bot);
} }
// bool RazuviousTankTrigger::IsActive() bool RazuviousTankTrigger::IsActive()
// { {
// Difficulty diff = bot->GetRaidDifficulty(); Difficulty diff = bot->GetRaidDifficulty();
// if (diff == RAID_DIFFICULTY_10MAN_NORMAL) { if (diff == RAID_DIFFICULTY_10MAN_NORMAL) {
// return BossPhaseTrigger::IsActive() && botAI->IsTank(bot); return helper.UpdateBossAI() && botAI->IsTank(bot);
// } }
// return BossPhaseTrigger::IsActive() && bot->getClass() == CLASS_PRIEST; return helper.UpdateBossAI() && bot->getClass() == CLASS_PRIEST;
// } }
// bool RazuviousNontankTrigger::IsActive() bool RazuviousNontankTrigger::IsActive()
// { {
// Difficulty diff = bot->GetRaidDifficulty(); Difficulty diff = bot->GetRaidDifficulty();
// if (diff == RAID_DIFFICULTY_10MAN_NORMAL) { if (diff == RAID_DIFFICULTY_10MAN_NORMAL) {
// return BossPhaseTrigger::IsActive() && !(botAI->IsTank(bot)); return helper.UpdateBossAI() && !(botAI->IsTank(bot));
// } }
// return BossPhaseTrigger::IsActive() && !(bot->getClass() == CLASS_PRIEST); return helper.UpdateBossAI() && !(bot->getClass() == CLASS_PRIEST);
// } }
// bool HorsemanAttractorsTrigger::IsActive() // bool HorsemanAttractorsTrigger::IsActive()
// { // {

View File

@@ -78,10 +78,43 @@ public:
}; };
class HeiganRangedTrigger : public Trigger class HeiganRangedTrigger : public Trigger
{
public:
HeiganRangedTrigger(PlayerbotAI* ai): Trigger(ai, "heigan ranged") {}
bool IsActive() override;
};
class RazuviousTankTrigger : public Trigger
{
public:
RazuviousTankTrigger(PlayerbotAI* ai) : Trigger(ai, "instructor razuvious tank"), helper(ai) {}
bool IsActive() override;
private:
RazuviousBossHelper helper;
};
class RazuviousNontankTrigger : public Trigger
{
public:
RazuviousNontankTrigger(PlayerbotAI* ai) : Trigger(ai, "instructor razuvious non-tank"), helper(ai) {}
bool IsActive() override;
private:
RazuviousBossHelper helper;
};
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>
{ {
public: public:
HeiganRangedTrigger(PlayerbotAI* ai): Trigger(ai, "heigan ranged") {} AnubrekhanTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "anub'rekhan", 0, "anub'rekhan trigger") {}
virtual bool IsActive();
}; };
// class ThaddiusPhasePetTrigger : public BossPhaseTrigger // class ThaddiusPhasePetTrigger : public BossPhaseTrigger
@@ -112,20 +145,6 @@ 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 RazuviousTankTrigger : public BossPhaseTrigger
// {
// public:
// RazuviousTankTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "instructor razuvious", 0, "razuvious tank") {}
// virtual bool IsActive();
// };
// class RazuviousNontankTrigger : public BossPhaseTrigger
// {
// public:
// RazuviousNontankTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "instructor razuvious", 0, "razuvious nontank") {}
// virtual bool IsActive();
// };
// class HorsemanAttractorsTrigger : public BossPhaseTrigger // class HorsemanAttractorsTrigger : public BossPhaseTrigger
// { // {
// public: // public:
@@ -168,20 +187,7 @@ public:
// virtual bool IsActive(); // virtual bool IsActive();
// }; // };
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>
{
public:
AnubrekhanTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "anub'rekhan", 0, "anub'rekhan trigger") {}
};
// class KelthuzadPhaseTwoTrigger : public BossPhaseTrigger // class KelthuzadPhaseTwoTrigger : public BossPhaseTrigger
// { // {

View File

@@ -124,9 +124,7 @@ void GenericShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
// triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("riptide", 26.0f), nullptr))); // triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("riptide", 26.0f), nullptr)));
triggers.push_back(new TriggerNode("heroism", NextAction::array(0, new NextAction("heroism", 31.0f), nullptr))); triggers.push_back(new TriggerNode("heroism", NextAction::array(0, new NextAction("heroism", 31.0f), nullptr)));
triggers.push_back(new TriggerNode("bloodlust", NextAction::array(0, new NextAction("bloodlust", 30.0f), nullptr))); triggers.push_back(new TriggerNode("bloodlust", NextAction::array(0, new NextAction("bloodlust", 30.0f), nullptr)));
triggers.push_back(new TriggerNode(
"medium mana",
NextAction::array(0, new NextAction("mana tide totem", ACTION_EMERGENCY + 5), NULL)));
} }
void ShamanBuffDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void ShamanBuffDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)

View File

@@ -97,5 +97,9 @@ void HealShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
"enemy too close for spell", "enemy too close for spell",
NextAction::array(0, new NextAction("flee", 49.0f), NULL))); NextAction::array(0, new NextAction("flee", 49.0f), NULL)));
triggers.push_back(new TriggerNode(
"medium mana",
NextAction::array(0, new NextAction("mana tide totem", ACTION_HIGH + 5), NULL)));
triggers.push_back(new TriggerNode("party member to heal out of spell range", NextAction::array(0, new NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 1), nullptr))); triggers.push_back(new TriggerNode("party member to heal out of spell range", NextAction::array(0, new NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 1), nullptr)));
} }

View File

@@ -225,19 +225,19 @@ class NoDrinkTrigger : public Trigger
class LightAoeTrigger : public AoeTrigger class LightAoeTrigger : public AoeTrigger
{ {
public: public:
LightAoeTrigger(PlayerbotAI* botAI) : AoeTrigger(botAI, 2, 8.0f) { } LightAoeTrigger(PlayerbotAI* botAI) : AoeTrigger(botAI, 2, 10.0f) { }
}; };
class MediumAoeTrigger : public AoeTrigger class MediumAoeTrigger : public AoeTrigger
{ {
public: public:
MediumAoeTrigger(PlayerbotAI* botAI) : AoeTrigger(botAI, 3, 8.0f) { } MediumAoeTrigger(PlayerbotAI* botAI) : AoeTrigger(botAI, 3, 10.0f) { }
}; };
class HighAoeTrigger : public AoeTrigger class HighAoeTrigger : public AoeTrigger
{ {
public: public:
HighAoeTrigger(PlayerbotAI* botAI) : AoeTrigger(botAI, 4, 8.0f) { } HighAoeTrigger(PlayerbotAI* botAI) : AoeTrigger(botAI, 4, 10.0f) { }
}; };
class BuffTrigger : public SpellTrigger class BuffTrigger : public SpellTrigger

View File

@@ -22,4 +22,16 @@ class ThreatValue : public Uint8CalculatedValue, public Qualified
uint8 Calculate(Unit* target); uint8 Calculate(Unit* target);
}; };
class NeglectThreatResetValue : public ManualSetValue<bool>
{
public:
NeglectThreatResetValue(PlayerbotAI* ai, bool defaultValue = false, std::string name = "neglect threat") :
ManualSetValue<bool>(ai, defaultValue, name) {}
virtual bool Get() {
bool ret = value;
Reset();
return ret;
}
};
#endif #endif

View File

@@ -291,6 +291,7 @@ class ValueContext : public NamedObjectContext<UntypedValue>
creators["find target"] = &ValueContext::find_target; creators["find target"] = &ValueContext::find_target;
creators["boss target"] = &ValueContext::boss_target; creators["boss target"] = &ValueContext::boss_target;
creators["nearest triggers"] = &ValueContext::nearest_triggers; creators["nearest triggers"] = &ValueContext::nearest_triggers;
creators["neglect threat"] = &ValueContext::neglect_threat;
} }
private: private:
@@ -486,6 +487,7 @@ class ValueContext : public NamedObjectContext<UntypedValue>
static UntypedValue* find_target(PlayerbotAI* ai) { return new FindTargetValue(ai); } static UntypedValue* find_target(PlayerbotAI* ai) { return new FindTargetValue(ai); }
static UntypedValue* boss_target(PlayerbotAI* ai) { return new BossTargetValue(ai); } static UntypedValue* boss_target(PlayerbotAI* ai) { return new BossTargetValue(ai); }
static UntypedValue* nearest_triggers(PlayerbotAI* ai) { return new NearestTriggersValue(ai); } static UntypedValue* nearest_triggers(PlayerbotAI* ai) { return new NearestTriggersValue(ai); }
static UntypedValue* neglect_threat(PlayerbotAI* ai) { return new NeglectThreatResetValue(ai); }
}; };
#endif #endif