mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
miscs(raid strategy, distance triggers, etc)
This commit is contained in:
@@ -20,6 +20,7 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
|
|||||||
strategyContexts.Add(new MovementStrategyContext());
|
strategyContexts.Add(new MovementStrategyContext());
|
||||||
strategyContexts.Add(new AssistStrategyContext());
|
strategyContexts.Add(new AssistStrategyContext());
|
||||||
strategyContexts.Add(new QuestStrategyContext());
|
strategyContexts.Add(new QuestStrategyContext());
|
||||||
|
strategyContexts.Add(new RaidStrategyContext());
|
||||||
|
|
||||||
actionContexts.Add(new ActionContext());
|
actionContexts.Add(new ActionContext());
|
||||||
actionContexts.Add(new ChatActionContext());
|
actionContexts.Add(new ChatActionContext());
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
#include "UseFoodStrategy.h"
|
#include "UseFoodStrategy.h"
|
||||||
#include "UsePotionsStrategy.h"
|
#include "UsePotionsStrategy.h"
|
||||||
#include "WorldPacketHandlerStrategy.h"
|
#include "WorldPacketHandlerStrategy.h"
|
||||||
|
#include "RaidStrategy.h"
|
||||||
|
|
||||||
class StrategyContext : public NamedObjectContext<Strategy>
|
class StrategyContext : public NamedObjectContext<Strategy>
|
||||||
{
|
{
|
||||||
@@ -220,4 +221,15 @@ class QuestStrategyContext : public NamedObjectContext<Strategy>
|
|||||||
static Strategy* accept_all_quests(PlayerbotAI* botAI) { return new AcceptAllQuestsStrategy(botAI); }
|
static Strategy* accept_all_quests(PlayerbotAI* botAI) { return new AcceptAllQuestsStrategy(botAI); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RaidStrategyContext : public NamedObjectContext<Strategy>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RaidStrategyContext() : NamedObjectContext<Strategy>(false, true)
|
||||||
|
{
|
||||||
|
creators["naxx"] = &RaidStrategyContext::naxx;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static Strategy* naxx(PlayerbotAI* botAI) { return new RaidNaxxGenericStrategy(botAI); }
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
#include "XpGainAction.h"
|
#include "XpGainAction.h"
|
||||||
#include "VehicleActions.h"
|
#include "VehicleActions.h"
|
||||||
#include "WorldBuffAction.h"
|
#include "WorldBuffAction.h"
|
||||||
|
#include "RaidNaxxAction.h"
|
||||||
|
|
||||||
class PlayerbotAI;
|
class PlayerbotAI;
|
||||||
|
|
||||||
@@ -221,6 +222,42 @@ class ActionContext : public NamedObjectContext<Action>
|
|||||||
creators["rpg mount anim"] = &ActionContext::rpg_mount_anim;
|
creators["rpg mount anim"] = &ActionContext::rpg_mount_anim;
|
||||||
|
|
||||||
creators["toggle pet spell"] = &ActionContext::toggle_pet_spell;
|
creators["toggle pet spell"] = &ActionContext::toggle_pet_spell;
|
||||||
|
|
||||||
|
// creators["rotate grobbulus"] = &ActionContext::rotate_grobbulus;
|
||||||
|
// creators["grobbulus move center"] = &ActionContext::grobbulus_move_center;
|
||||||
|
|
||||||
|
creators["heigan dance melee"] = &ActionContext::heigan_dance_melee;
|
||||||
|
creators["heigan dance ranged"] = &ActionContext::heigan_dance_ranged;
|
||||||
|
|
||||||
|
// creators["thaddius attack nearest pet"] = &ActionContext::thaddius_attack_nearest_pet;
|
||||||
|
// creators["thaddius melee to place"] = &ActionContext::thaddius_tank_to_place;
|
||||||
|
// creators["thaddius ranged to place"] = &ActionContext::thaddius_ranged_to_place;
|
||||||
|
// creators["thaddius move to platform"] = &ActionContext::thaddius_move_to_platform;
|
||||||
|
// creators["thaddius move polarity"] = &ActionContext::thaddius_move_polarity;
|
||||||
|
|
||||||
|
// creators["razuvious use obedience crystal"] = &ActionContext::razuvious_use_obedience_crystal;
|
||||||
|
// creators["razuvious target"] = &ActionContext::razuvious_target;
|
||||||
|
|
||||||
|
// creators["horseman attract alternatively"] = &ActionContext::horseman_attract_alternatively;
|
||||||
|
// creators["horseman attack in order"] = &ActionContext::horseman_attack_in_order;
|
||||||
|
|
||||||
|
// creators["sapphiron ground main tank position"] = &ActionContext::sapphiron_ground_main_tank_position;
|
||||||
|
// creators["sapphiron ground position"] = &ActionContext::sapphiron_ground_position;
|
||||||
|
// creators["sapphiron flight position"] = &ActionContext::sapphiron_flight_position;
|
||||||
|
// creators["sapphiron avoid chill"] = &ActionContext::sapphiron_avoid_chill;
|
||||||
|
|
||||||
|
// creators["kel'thuzad choose target"] = &ActionContext::kelthuzad_choose_target;
|
||||||
|
// creators["kel'thuzad position"] = &ActionContext::kelthuzad_position;
|
||||||
|
|
||||||
|
// creators["anub'rekhan choose target"] = &ActionContext::anubrekhan_choose_target;
|
||||||
|
// creators["anub'rekhan position"] = &ActionContext::anubrekhan_position;
|
||||||
|
|
||||||
|
// creators["gluth choose target"] = &ActionContext::gluth_choose_target;
|
||||||
|
// creators["gluth position"] = &ActionContext::gluth_position;
|
||||||
|
// creators["gluth slowdown"] = &ActionContext::gluth_slowdown;
|
||||||
|
|
||||||
|
// creators["loatheb position"] = &ActionContext::loatheb_position;
|
||||||
|
// creators["loatheb choose target"] = &ActionContext::loatheb_choose_target;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -382,6 +419,33 @@ class ActionContext : public NamedObjectContext<Action>
|
|||||||
static Action* rpg_mount_anim(PlayerbotAI* botAI) { return new RpgMountAnimAction(botAI); }
|
static Action* rpg_mount_anim(PlayerbotAI* botAI) { return new RpgMountAnimAction(botAI); }
|
||||||
|
|
||||||
static Action* toggle_pet_spell(PlayerbotAI* ai) { return new TogglePetSpellAutoCastAction(ai); }
|
static Action* toggle_pet_spell(PlayerbotAI* ai) { return new TogglePetSpellAutoCastAction(ai); }
|
||||||
|
|
||||||
|
// static Action* rotate_grobbulus(PlayerbotAI* ai) { return new RotateGrobbulusAction(ai); }
|
||||||
|
// static Action* grobbulus_move_center(PlayerbotAI* ai) { return new GrobblulusMoveCenterAction(ai); }
|
||||||
|
static Action* heigan_dance_melee(PlayerbotAI* ai) { return new HeiganDanceMeleeAction(ai); }
|
||||||
|
static Action* heigan_dance_ranged(PlayerbotAI* ai) { return new HeiganDanceRangedAction(ai); }
|
||||||
|
// static Action* thaddius_attack_nearest_pet(PlayerbotAI* ai) { return new ThaddiusAttackNearestPetAction(ai); }
|
||||||
|
// static Action* thaddius_tank_to_place(PlayerbotAI* ai) { return new ThaddiusMeleeToPlaceAction(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_polarity(PlayerbotAI* ai) { return new ThaddiusMovePolarityAction(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* horseman_attract_alternatively(PlayerbotAI* ai) { return new HorsemanAttractAlternativelyAction(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_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* 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); }
|
||||||
|
// static Action* gluth_position(PlayerbotAI* ai) { return new GluthPositionAction(ai); }
|
||||||
|
// static Action* gluth_slowdown(PlayerbotAI* ai) { return new GluthSlowdownAction(ai); }
|
||||||
|
// static Action* loatheb_position(PlayerbotAI* ai) { return new LoathebPositionAction(ai); }
|
||||||
|
// static Action* loatheb_choose_target(PlayerbotAI* ai) { return new LoathebChooseTargetAction(ai); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -108,11 +108,11 @@ bool CastSpellAction::isUseful()
|
|||||||
if (!spellTarget->IsInWorld() || spellTarget->GetMapId() != bot->GetMapId())
|
if (!spellTarget->IsInWorld() || spellTarget->GetMapId() != bot->GetMapId())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
float combatReach = bot->GetCombatReach() + spellTarget->GetCombatReach();
|
// float combatReach = bot->GetCombatReach() + spellTarget->GetCombatReach();
|
||||||
if (!botAI->IsRanged(bot))
|
// if (!botAI->IsRanged(bot))
|
||||||
combatReach += 4.0f / 3.0f;
|
// combatReach += 4.0f / 3.0f;
|
||||||
|
|
||||||
return spellTarget && AI_VALUE2(bool, "spell cast useful", spell) && sServerFacade->GetDistance2d(bot, spellTarget) <= (range + combatReach);
|
return spellTarget && AI_VALUE2(bool, "spell cast useful", spell); // && sServerFacade->GetDistance2d(bot, spellTarget) <= (range + combatReach);
|
||||||
}
|
}
|
||||||
|
|
||||||
CastMeleeSpellAction::CastMeleeSpellAction(PlayerbotAI* botAI, std::string const spell) : CastSpellAction(botAI, spell)
|
CastMeleeSpellAction::CastMeleeSpellAction(PlayerbotAI* botAI, std::string const spell) : CastSpellAction(botAI, spell)
|
||||||
|
|||||||
@@ -128,6 +128,43 @@ bool MovementAction::MoveToLOS(WorldObject* target, bool ranged)
|
|||||||
|
|
||||||
bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, bool react)
|
bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, bool react)
|
||||||
{
|
{
|
||||||
|
// if (!IsMovingAllowed(mapId, x, y, z))
|
||||||
|
// return false;
|
||||||
|
// bot->UpdateGroundPositionZ(x, y, z);
|
||||||
|
|
||||||
|
// float distance = bot->GetDistance2d(x, y);
|
||||||
|
// if (distance > sPlayerbotAIConfig->contactDistance)
|
||||||
|
// {
|
||||||
|
// WaitForReach(distance);
|
||||||
|
|
||||||
|
// if (bot->IsSitState())
|
||||||
|
// bot->SetStandState(UNIT_STAND_STATE_STAND);
|
||||||
|
|
||||||
|
// if (bot->IsNonMeleeSpellCast(true))
|
||||||
|
// {
|
||||||
|
// bot->CastStop();
|
||||||
|
// botAI->InterruptSpell();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) &&
|
||||||
|
// !bot->IsFlying() && !bot->IsUnderWater();
|
||||||
|
// MotionMaster &mm = *bot->GetMotionMaster();
|
||||||
|
// mm.Clear();
|
||||||
|
|
||||||
|
// // float botZ = bot->GetPositionZ();
|
||||||
|
// // if (!bot->InBattleground() && z - botZ > 0.5f && bot->GetDistance2d(x, y) <= 5.0f)
|
||||||
|
// // {
|
||||||
|
// // float speed = bot->GetSpeed(MOVE_RUN);
|
||||||
|
// // mm.MoveJump(x, y, botZ + 0.5f, speed, speed, 1);
|
||||||
|
// // }
|
||||||
|
// // else
|
||||||
|
// mm.MovePoint(mapId, x, y, z, generatePath);
|
||||||
|
|
||||||
|
// AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation());
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return false;
|
||||||
UpdateMovementState();
|
UpdateMovementState();
|
||||||
// LOG_DEBUG("playerbots", "IsMovingAllowed {}", IsMovingAllowed());
|
// LOG_DEBUG("playerbots", "IsMovingAllowed {}", IsMovingAllowed());
|
||||||
if (!IsMovingAllowed())
|
if (!IsMovingAllowed())
|
||||||
@@ -507,20 +544,20 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Clean movement if not already moving the same way.
|
// Clean movement if not already moving the same way.
|
||||||
if (mover->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
|
// if (mover->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
|
||||||
{
|
// {
|
||||||
mover->StopMoving();
|
// mover->StopMoving();
|
||||||
mover->GetMotionMaster()->Clear();
|
// mover->GetMotionMaster()->Clear();
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
mover->GetMotionMaster()->GetDestination(x, y, z);
|
// mover->GetMotionMaster()->GetDestination(x, y, z);
|
||||||
if (movePosition.distance(WorldPosition(movePosition.getMapId(), x, y, z, 0)) > minDist)
|
// if (movePosition.distance(WorldPosition(movePosition.getMapId(), x, y, z, 0)) > minDist)
|
||||||
{
|
// {
|
||||||
mover->StopMoving();
|
// mover->StopMoving();
|
||||||
mover->GetMotionMaster()->Clear();
|
// mover->GetMotionMaster()->Clear();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (totalDistance > maxDist && !detailedMove && !botAI->HasPlayerNearby(&movePosition)) // Why walk if you can fly?
|
if (totalDistance > maxDist && !detailedMove && !botAI->HasPlayerNearby(&movePosition)) // Why walk if you can fly?
|
||||||
{
|
{
|
||||||
@@ -549,6 +586,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
|||||||
{
|
{
|
||||||
bot->SetWalk(masterWalking);
|
bot->SetWalk(masterWalking);
|
||||||
bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), generatePath);
|
bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), generatePath);
|
||||||
|
WaitForReach(startPosition.distance(movePosition));
|
||||||
// LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY());
|
// LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -595,6 +633,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), Position(movePosition.getX(), movePosition.getY(), movePosition.getZ(), 0.f));
|
bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), Position(movePosition.getX(), movePosition.getY(), movePosition.getZ(), 0.f));
|
||||||
|
WaitForReach(startPosition.distance(movePosition));
|
||||||
LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY());
|
LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1221,6 +1260,14 @@ bool MovementAction::MoveAway(Unit* target)
|
|||||||
return MoveTo(target->GetMapId(), dx, dy, dz);
|
return MoveTo(target->GetMapId(), dx, dy, dz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MovementAction::MoveInside(uint32 mapId, float x, float y, float z, float distance)
|
||||||
|
{
|
||||||
|
if (bot->GetDistance2d(x, y) <= distance) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return MoveNear(mapId, x, y, z, distance);
|
||||||
|
}
|
||||||
|
|
||||||
bool FleeAction::Execute(Event event)
|
bool FleeAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
// return Flee(AI_VALUE(Unit*, "current target"));
|
// return Flee(AI_VALUE(Unit*, "current target"));
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ class MovementAction : public Action
|
|||||||
void ClearIdleState();
|
void ClearIdleState();
|
||||||
void UpdateMovementState();
|
void UpdateMovementState();
|
||||||
bool MoveAway(Unit* target);
|
bool MoveAway(Unit* target);
|
||||||
|
bool MoveInside(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->followDistance);
|
||||||
void CreateWp(Player* wpOwner, float x, float y, float z, float o, uint32 entry, bool important = false);
|
void CreateWp(Player* wpOwner, float x, float y, float z, float o, uint32 entry, bool important = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
1135
src/strategy/actions/RaidNaxxAction.cpp
Normal file
1135
src/strategy/actions/RaidNaxxAction.cpp
Normal file
File diff suppressed because it is too large
Load Diff
318
src/strategy/actions/RaidNaxxAction.h
Normal file
318
src/strategy/actions/RaidNaxxAction.h
Normal file
@@ -0,0 +1,318 @@
|
|||||||
|
#ifndef _PLAYERBOT_RAIDNAXXACTION_H
|
||||||
|
#define _PLAYERBOT_RAIDNAXXACTION_H
|
||||||
|
|
||||||
|
#include "Action.h"
|
||||||
|
#include "MovementActions.h"
|
||||||
|
#include "AttackAction.h"
|
||||||
|
#include "GenericActions.h"
|
||||||
|
|
||||||
|
// just for test
|
||||||
|
// class TryToGetBossAIAction : public Action
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// TryToGetBossAIAction(PlayerbotAI* ai) : Action(ai, "try to get boss ai") {}
|
||||||
|
|
||||||
|
// public:
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class GoBehindTheBossAction : public MovementAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// GoBehindTheBossAction(PlayerbotAI* ai, float distance = 24.0f, float delta_angle = M_PI / 8) : MovementAction(ai, "grobbulus go behind the boss") {
|
||||||
|
// this->distance = distance;
|
||||||
|
// this->delta_angle = delta_angle;
|
||||||
|
// }
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// protected:
|
||||||
|
// float distance, delta_angle;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class 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
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// MoveInsideAction(PlayerbotAI* ai, float x, float y, float distance = 5.0f) : MovementAction(ai, "move inside") {
|
||||||
|
// this->x = x;
|
||||||
|
// this->y = y;
|
||||||
|
// this->distance = distance;
|
||||||
|
// }
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// protected:
|
||||||
|
// float x, y, distance;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class RotateAroundTheCenterPointAction : public MovementAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// RotateAroundTheCenterPointAction(PlayerbotAI* ai, string name,
|
||||||
|
// float center_x, float center_y, float radius = 40.0f,
|
||||||
|
// uint32 intervals = 16, bool clockwise = true, float start_angle = 0) : MovementAction(ai, name) {
|
||||||
|
// this->center_x = center_x;
|
||||||
|
// this->center_y = center_y;
|
||||||
|
// this->radius = radius;
|
||||||
|
// this->intervals = intervals;
|
||||||
|
// this->clockwise = clockwise;
|
||||||
|
// this->call_counters = 0;
|
||||||
|
// for (int i = 0; i < intervals; i++) {
|
||||||
|
// float angle = start_angle + 2 * M_PI * i / intervals;
|
||||||
|
// waypoints.push_back(std::make_pair(center_x + cos(angle) * radius, center_y + sin(angle) * radius));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// protected:
|
||||||
|
// virtual uint32 GetCurrWaypoint() { return 0; }
|
||||||
|
// uint32 FindNearestWaypoint();
|
||||||
|
// float center_x, center_y, radius;
|
||||||
|
// uint32 intervals, call_counters;
|
||||||
|
// bool clockwise;
|
||||||
|
// std::vector<std::pair<float, float>> waypoints;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class RotateGrobbulusAction : public RotateAroundTheCenterPointAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// RotateGrobbulusAction(PlayerbotAI* ai): RotateAroundTheCenterPointAction(ai, "rotate grobbulus", 3281.23f, -3310.38f, 35.0f, 8, true, M_PI) {}
|
||||||
|
// virtual bool isUseful() {
|
||||||
|
// return RotateAroundTheCenterPointAction::isUseful() && ai->IsMainTank(bot) && AI_VALUE2(bool, "has aggro", "boss target");
|
||||||
|
// }
|
||||||
|
// virtual uint32 GetCurrWaypoint();
|
||||||
|
// protected:
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class GrobblulusMoveCenterAction : public MoveInsideAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// GrobblulusMoveCenterAction(PlayerbotAI* ai) : MoveInsideAction(ai, 3281.23f, -3310.38f, 5.0f) {}
|
||||||
|
// };
|
||||||
|
|
||||||
|
class HeiganDanceAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HeiganDanceAction(PlayerbotAI* ai) : MovementAction(ai, "heigan dance") {
|
||||||
|
this->prev_phase = 0;
|
||||||
|
this->prev_erupt = 0;
|
||||||
|
this->prev_timer = 0;
|
||||||
|
waypoints.push_back(std::make_pair(2793.58f, -3665.93f));
|
||||||
|
waypoints.push_back(std::make_pair(2775.49f, -3674.43f));
|
||||||
|
waypoints.push_back(std::make_pair(2762.30f, -3684.59f));
|
||||||
|
waypoints.push_back(std::make_pair(2755.99f, -3703.96f));
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
bool CalculateSafe();
|
||||||
|
void ResetSafe() { curr_safe = 0; curr_dir = 1; }
|
||||||
|
void NextSafe() { curr_safe += curr_dir; if (curr_safe == 3 || curr_safe == 0) { curr_dir = -curr_dir; } }
|
||||||
|
uint32 prev_phase, prev_erupt, prev_timer;
|
||||||
|
uint32 curr_safe, curr_dir;
|
||||||
|
std::vector<std::pair<float, float>> waypoints;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HeiganDanceMeleeAction : public HeiganDanceAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HeiganDanceMeleeAction(PlayerbotAI* ai) : HeiganDanceAction(ai) {}
|
||||||
|
virtual bool Execute(Event event);
|
||||||
|
};
|
||||||
|
|
||||||
|
class HeiganDanceRangedAction : public HeiganDanceAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HeiganDanceRangedAction(PlayerbotAI* ai) : HeiganDanceAction(ai) {
|
||||||
|
platform = std::make_pair(2794.26f, -3706.67f);
|
||||||
|
}
|
||||||
|
virtual bool Execute(Event event);
|
||||||
|
protected:
|
||||||
|
std::pair<float, float> platform;
|
||||||
|
};
|
||||||
|
|
||||||
|
// class ThaddiusAttackNearestPetAction : public AttackAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// ThaddiusAttackNearestPetAction(PlayerbotAI* ai) : AttackAction(ai, "thaddius attack nearest pet") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// virtual bool isUseful();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class ThaddiusMeleeToPlaceAction : public MovementAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// ThaddiusMeleeToPlaceAction(PlayerbotAI* ai) : MovementAction(ai, "thaddius melee to place") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// virtual bool isUseful();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class ThaddiusRangedToPlaceAction : public MovementAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// ThaddiusRangedToPlaceAction(PlayerbotAI* ai) : MovementAction(ai, "thaddius ranged to place") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// virtual bool isUseful();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class ThaddiusMoveToPlatformAction : public MovementAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// ThaddiusMoveToPlatformAction(PlayerbotAI* ai) : MovementAction(ai, "thaddius move to platform") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// virtual bool isUseful();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class ThaddiusMovePolarityAction : public MovementAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// ThaddiusMovePolarityAction(PlayerbotAI* ai) : MovementAction(ai, "thaddius move polarity") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// virtual bool isUseful();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class RazuviousUseObedienceCrystalAction : public MovementAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// RazuviousUseObedienceCrystalAction(PlayerbotAI* ai) : MovementAction(ai, "razuvious use obedience crystal") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class RazuviousTargetAction : public AttackAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// RazuviousTargetAction(PlayerbotAI* ai) : AttackAction(ai, "razuvious target") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class HorsemanAttractAlternativelyAction : public AttackAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// HorsemanAttractAlternativelyAction(PlayerbotAI* ai) : AttackAction(ai, "horseman attract alternatively") {
|
||||||
|
// this->last_voidzone = 0;
|
||||||
|
// this->voidzone_counter = 0;
|
||||||
|
// }
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// protected:
|
||||||
|
// uint32 last_voidzone, voidzone_counter;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class HorsemanAttactInOrderAction : public AttackAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// HorsemanAttactInOrderAction(PlayerbotAI* ai) : AttackAction(ai, "horseman attact in order") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class SapphironGroundMainTankPositionAction : public MovementAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// SapphironGroundMainTankPositionAction(PlayerbotAI* ai) : MovementAction(ai, "sapphiron ground main tank position") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class SapphironGroundPositionAction : public MovementAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// SapphironGroundPositionAction(PlayerbotAI* ai) : MovementAction(ai, "sapphiron ground position") {
|
||||||
|
// this->reset = 1;
|
||||||
|
// this->last_flight = 0;
|
||||||
|
// this->reset_timer = 0;
|
||||||
|
// }
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// protected:
|
||||||
|
// bool reset;
|
||||||
|
// uint32 last_flight, reset_timer;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class SapphironFlightPositionAction : public MovementAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// SapphironFlightPositionAction(PlayerbotAI* ai) : MovementAction(ai, "sapphiron flight position") {
|
||||||
|
// this->last_explosion = 0;
|
||||||
|
// this->move_ice_bolt = 0;
|
||||||
|
// }
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// protected:
|
||||||
|
// uint32 last_explosion;
|
||||||
|
// bool move_ice_bolt;
|
||||||
|
// bool MoveToNearestIcebolt();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class SapphironAvoidChillAction : public MovementAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// SapphironAvoidChillAction(PlayerbotAI* ai) : MovementAction(ai, "sapphiron avoid chill") {}
|
||||||
|
// 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 KelthuzadPositionAction : public MovementAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// KelthuzadPositionAction(PlayerbotAI* ai) : MovementAction(ai, "kel'thuzad position") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class AnubrekhanChooseTargetAction : public AttackAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// AnubrekhanChooseTargetAction(PlayerbotAI* ai) : AttackAction(ai, "anub'rekhan choose target") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class AnubrekhanPositionAction : public RotateAroundTheCenterPointAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// AnubrekhanPositionAction(PlayerbotAI* ai) : RotateAroundTheCenterPointAction(ai, "anub'rekhan position", 3272.49f, -3476.27f, 45.0f, 16) {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class GluthChooseTargetAction : public AttackAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// GluthChooseTargetAction(PlayerbotAI* ai) : AttackAction(ai, "gluth choose target") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class GluthPositionAction : public RotateAroundTheCenterPointAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// GluthPositionAction(PlayerbotAI* ai) : RotateAroundTheCenterPointAction(ai, "gluth position", 3293.61f, -3149.01f, 12.0f, 12) {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class GluthSlowdownAction : public Action
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// GluthSlowdownAction(PlayerbotAI* ai) : Action(ai, "slowdown") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class LoathebPositionAction : public MovementAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// LoathebPositionAction(PlayerbotAI* ai) : MovementAction(ai, "loatheb position") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class LoathebChooseTargetAction : public AttackAction
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// LoathebChooseTargetAction(PlayerbotAI* ai) : AttackAction(ai, "loatheb choose target") {}
|
||||||
|
// virtual bool Execute(Event event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -36,7 +36,7 @@ ReachSpellAction::ReachSpellAction(PlayerbotAI* botAI) : ReachTargetAction(botAI
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ReachPartyMemberToHealAction::ReachPartyMemberToHealAction(PlayerbotAI* botAI) : ReachTargetAction(botAI, "reach party member to heal", botAI->GetRange("spell"))
|
ReachPartyMemberToHealAction::ReachPartyMemberToHealAction(PlayerbotAI* botAI) : ReachTargetAction(botAI, "reach party member to heal", botAI->GetRange("heal"))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class RTSCStrategy : public Strategy
|
|||||||
RTSCStrategy(PlayerbotAI* botAI);
|
RTSCStrategy(PlayerbotAI* botAI);
|
||||||
|
|
||||||
std::string const getName() override { return "RTSC"; }
|
std::string const getName() override { return "RTSC"; }
|
||||||
void InitTriggers(std::vector<TriggerNode*>& triggers);
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
427
src/strategy/generic/RaidStrategy.cpp
Normal file
427
src/strategy/generic/RaidStrategy.cpp
Normal file
@@ -0,0 +1,427 @@
|
|||||||
|
#include "RaidStrategy.h"
|
||||||
|
#include "MovementActions.h"
|
||||||
|
#include "ScriptedCreature.h"
|
||||||
|
#include "RaidNaxxAction.h"
|
||||||
|
#include "GenericSpellActions.h"
|
||||||
|
#include "ChooseTargetActions.h"
|
||||||
|
#include "ReachTargetActions.h"
|
||||||
|
#include "UseMeetingStoneAction.h"
|
||||||
|
#include "FollowActions.h"
|
||||||
|
#include "ShamanActions.h"
|
||||||
|
#include "PriestActions.h"
|
||||||
|
#include "DKActions.h"
|
||||||
|
#include "HunterActions.h"
|
||||||
|
#include "MageActions.h"
|
||||||
|
#include "RogueActions.h"
|
||||||
|
#include "DruidActions.h"
|
||||||
|
#include "PaladinActions.h"
|
||||||
|
#include "WarriorActions.h"
|
||||||
|
#include <string>
|
||||||
|
#include "../../../../src/server/scripts/Northrend/Naxxramas/boss_heigan.h"
|
||||||
|
|
||||||
|
float HeiganDanceMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "heigan the unclean");
|
||||||
|
if (!boss) {
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
boss_heigan::boss_heiganAI* boss_ai = dynamic_cast<boss_heigan::boss_heiganAI*>(boss->GetAI());
|
||||||
|
EventMap* eventMap = &boss_ai->events;
|
||||||
|
uint32 curr_phase = boss_ai->currentPhase;
|
||||||
|
uint32 curr_dance = eventMap->GetNextEventTime(4);
|
||||||
|
uint32 curr_timer = eventMap->GetTimer();
|
||||||
|
uint32 curr_erupt = eventMap->GetNextEventTime(3);
|
||||||
|
if (dynamic_cast<SetBehindTargetAction*>(action)) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
if (curr_phase != PHASE_FAST_DANCE && (int32)curr_dance - curr_timer >= 3000) {
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
if (dynamic_cast<HeiganDanceAction*>(action) || dynamic_cast<CurePartyMemberAction*>(action)) {
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
if (dynamic_cast<CastSpellAction*>(action))
|
||||||
|
{
|
||||||
|
uint32 spellId = AI_VALUE2(uint32, "spell id", action->getName());
|
||||||
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||||
|
if (!spellInfo) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
uint32 castTime = spellInfo->CalcCastTime();
|
||||||
|
if (castTime == 0) {
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// float LoathebGenericMultiplier::GetValue(Action* action)
|
||||||
|
// {
|
||||||
|
// Unit* boss = AI_VALUE2(Unit*, "find target", "loatheb");
|
||||||
|
// if (!boss) {
|
||||||
|
// // bot->Yell("Can\'t find Loatheb...", LANG_UNIVERSAL);
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
// context->GetValue<bool>("neglect threat")->Set(true);
|
||||||
|
// if (botAI->GetCurrentState() == BOT_STATE_COMBAT &&
|
||||||
|
// (dynamic_cast<AttackLeastHpTargetAction*>(action) ||
|
||||||
|
// dynamic_cast<TankAssistAction*>(action) ||
|
||||||
|
// dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) ||
|
||||||
|
// dynamic_cast<FleeAction*>(action))) {
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
// if (!dynamic_cast<CastHealingSpellAction*>(action)) {
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
// // bot->Yell("It\'s a healing spell!", LANG_UNIVERSAL);
|
||||||
|
// Aura* aura = botAI->GetAura("necrotic aura", bot);
|
||||||
|
// if (!aura || aura->GetDuration() <= 1500) {
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// float ThaddiusGenericMultiplier::GetValue(Action* action)
|
||||||
|
// {
|
||||||
|
// Unit* boss = AI_VALUE2(Unit*, "find target", "thaddius");
|
||||||
|
// if (!boss) {
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
// BossAI* boss_ai = dynamic_cast<BossAI*>(boss->GetAI());
|
||||||
|
// EventMap* eventMap = boss_botAI->GetEvents();
|
||||||
|
// uint32 curr_phase = eventMap->GetPhaseMask();
|
||||||
|
// // pet phase
|
||||||
|
// if (curr_phase == 2 &&
|
||||||
|
// ( dynamic_cast<AttackLeastHpTargetAction*>(action) ||
|
||||||
|
// dynamic_cast<TankAssistAction*>(action) ||
|
||||||
|
// dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) ||
|
||||||
|
// dynamic_cast<ReachPartyMemberToHealAction*>(action) ||
|
||||||
|
// dynamic_cast<BuffOnMainTankAction*>(action) )) {
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
// // die at the same time
|
||||||
|
// Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
// Unit* feugen = AI_VALUE2(Unit*, "find target", "feugen");
|
||||||
|
// Unit* stalagg = AI_VALUE2(Unit*, "find target", "stalagg");
|
||||||
|
// if (curr_phase == 2 && target && feugen && stalagg &&
|
||||||
|
// target->GetHealthPct() <= 40 &&
|
||||||
|
// (feugen->GetHealthPct() >= target->GetHealthPct() + 3 || stalagg->GetHealthPct() >= target->GetHealthPct() + 3)) {
|
||||||
|
// if (dynamic_cast<CastSpellAction*>(action) && !dynamic_cast<CastHealingSpellAction*>(action)) {
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // magnetic pull
|
||||||
|
// // uint32 curr_timer = eventMap->GetTimer();
|
||||||
|
// // // if (curr_phase == 2 && bot->GetPositionZ() > 312.5f && dynamic_cast<MovementAction*>(action)) {
|
||||||
|
// // if (curr_phase == 2 && (curr_timer % 20000 >= 18000 || curr_timer % 20000 <= 2000) && dynamic_cast<MovementAction*>(action)) {
|
||||||
|
// // // MotionMaster *mm = bot->GetMotionMaster();
|
||||||
|
// // // mm->Clear();
|
||||||
|
// // return 0.0f;
|
||||||
|
// // }
|
||||||
|
// // thaddius phase
|
||||||
|
// if (curr_phase == 8 && dynamic_cast<FleeAction*>(action)) {
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// float SapphironGenericMultiplier::GetValue(Action* action)
|
||||||
|
// {
|
||||||
|
// Unit* boss = AI_VALUE2(Unit*, "find target", "sapphiron");
|
||||||
|
// if (!boss) {
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
// if (dynamic_cast<FollowAction*>(action) ||
|
||||||
|
// dynamic_cast<CastDeathGripAction*>(action)) {
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
// BossAI* boss_ai = dynamic_cast<BossAI*>(boss->GetAI());
|
||||||
|
// EventMap* eventMap = boss_botAI->GetEvents();
|
||||||
|
// uint32 curr_phase = eventMap->GetPhaseMask();
|
||||||
|
// uint32 timer = eventMap->GetTimer();
|
||||||
|
// uint32 explosion = eventMap->GetNextEventTime(10);
|
||||||
|
// if (curr_phase == 4 && explosion > timer &&
|
||||||
|
// (dynamic_cast<MovementAction*>(action) &&
|
||||||
|
// !dynamic_cast<SapphironFlightPositionAction*>(action) &&
|
||||||
|
// !dynamic_cast<SummonAction*>(action))) {
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// float InstructorRazuviousGenericMultiplier::GetValue(Action* action)
|
||||||
|
// {
|
||||||
|
// Unit* boss = AI_VALUE2(Unit*, "find target", "instructor razuvious");
|
||||||
|
// if (!boss) {
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
// context->GetValue<bool>("neglect threat")->Set(true);
|
||||||
|
// if (botAI->GetCurrentState() == BOT_STATE_COMBAT &&
|
||||||
|
// (dynamic_cast<AttackLeastHpTargetAction*>(action) ||
|
||||||
|
// dynamic_cast<TankAssistAction*>(action) ||
|
||||||
|
// dynamic_cast<CastTauntAction*>(action) ||
|
||||||
|
// dynamic_cast<CastDarkCommandAction*>(action) ||
|
||||||
|
// dynamic_cast<CastHandOfReckoningAction*>(action) ||
|
||||||
|
// dynamic_cast<CastGrowlAction*>(action))) {
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
// 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 AnubrekhanGenericMultiplier::GetValue(Action* action)
|
||||||
|
// {
|
||||||
|
// Unit* boss = AI_VALUE2(Unit*, "find target", "anub'rekhan");
|
||||||
|
// if (!boss) {
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
// if ((dynamic_cast<AttackLeastHpTargetAction*>(action) ||
|
||||||
|
// dynamic_cast<TankAssistAction*>(action) ||
|
||||||
|
// dynamic_cast<FollowAction*>(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 == 2) {
|
||||||
|
// if (dynamic_cast<FleeAction*>(action)) {
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// float FourhorsemanGenericMultiplier::GetValue(Action* action)
|
||||||
|
// {
|
||||||
|
// Unit* boss = AI_VALUE2(Unit*, "find target", "sir zeliek");
|
||||||
|
// if (!boss) {
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
// if ((dynamic_cast<AttackLeastHpTargetAction*>(action) ||
|
||||||
|
// dynamic_cast<TankAssistAction*>(action))) {
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// float GothikGenericMultiplier::GetValue(Action* action)
|
||||||
|
// {
|
||||||
|
// Unit* boss = AI_VALUE2(Unit*, "find target", "gothik the harvester");
|
||||||
|
// if (!boss) {
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
// BossAI* boss_ai = dynamic_cast<BossAI*>(boss->GetAI());
|
||||||
|
// EventMap* eventMap = boss_botAI->GetEvents();
|
||||||
|
// uint32 curr_phase = eventMap->GetPhaseMask();
|
||||||
|
// if (curr_phase == 1 && (dynamic_cast<FollowAction*>(action))) {
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
// if (curr_phase == 1 && (dynamic_cast<AttackAction*>(action))) {
|
||||||
|
// Unit* target = action->GetTarget();
|
||||||
|
// if (target == boss) {
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// float GluthGenericMultiplier::GetValue(Action* action)
|
||||||
|
// {
|
||||||
|
// Unit* boss = AI_VALUE2(Unit*, "find target", "gluth");
|
||||||
|
// if (!boss) {
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
// if ((dynamic_cast<AttackLeastHpTargetAction*>(action) ||
|
||||||
|
// dynamic_cast<TankAssistAction*>(action) ||
|
||||||
|
// dynamic_cast<FleeAction*>(action) ||
|
||||||
|
// dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) ||
|
||||||
|
// dynamic_cast<CastStarfallAction*>(action))) {
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (botAI->IsMainTank(bot)) {
|
||||||
|
// Aura* aura = botAI->GetAuraWithDuration("mortal wound", bot);
|
||||||
|
// if (aura && aura->GetStackAmount() >= 5) {
|
||||||
|
// if (dynamic_cast<CastTauntAction*>(action) ||
|
||||||
|
// dynamic_cast<CastDarkCommandAction*>(action) ||
|
||||||
|
// dynamic_cast<CastHandOfReckoningAction*>(action) ||
|
||||||
|
// dynamic_cast<CastGrowlAction*>(action)) {
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return 1.0f;
|
||||||
|
// }
|
||||||
|
|
||||||
|
void RaidNaxxGenericStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||||
|
{
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "often",
|
||||||
|
// NextAction::array(0, new NextAction("try to get boss ai", ACTION_RAID), NULL)));
|
||||||
|
|
||||||
|
// Grobbulus
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "mutating injection",
|
||||||
|
// NextAction::array(0, new NextAction("grobbulus go behind the boss", ACTION_RAID + 2), NULL)));
|
||||||
|
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "mutating injection removed",
|
||||||
|
// NextAction::array(0, new NextAction("grobbulus move center", ACTION_RAID + 1), NULL)));
|
||||||
|
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "grobbulus cloud",
|
||||||
|
// NextAction::array(0, new NextAction("rotate grobbulus", ACTION_RAID + 1), NULL)));
|
||||||
|
|
||||||
|
// Heigan the Unclean
|
||||||
|
triggers.push_back(new TriggerNode(
|
||||||
|
"heigan melee",
|
||||||
|
NextAction::array(0, new NextAction("heigan dance melee", ACTION_RAID + 1), NULL)));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode(
|
||||||
|
"heigan ranged",
|
||||||
|
NextAction::array(0, new NextAction("heigan dance ranged", ACTION_RAID + 1), NULL)));
|
||||||
|
|
||||||
|
// Thaddius
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "thaddius phase pet",
|
||||||
|
// NextAction::array(0,
|
||||||
|
// new NextAction("thaddius attack nearest pet", ACTION_RAID + 1),
|
||||||
|
// new NextAction("thaddius melee to place", ACTION_RAID),
|
||||||
|
// new NextAction("thaddius ranged to place", ACTION_RAID),
|
||||||
|
// NULL)));
|
||||||
|
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "thaddius phase pet lose aggro",
|
||||||
|
// NextAction::array(0, new NextAction("taunt spell", ACTION_RAID + 2), NULL)));
|
||||||
|
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "thaddius phase transition",
|
||||||
|
// NextAction::array(0, new NextAction("thaddius move to platform", ACTION_RAID + 1), NULL)));
|
||||||
|
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "thaddius phase thaddius",
|
||||||
|
// NextAction::array(0, new NextAction("thaddius move polarity", ACTION_RAID + 1), NULL)));
|
||||||
|
|
||||||
|
// // Instructor Razuvious
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "razuvious tank",
|
||||||
|
// NextAction::array(0, new NextAction("razuvious use obedience crystal", ACTION_RAID + 1), NULL)));
|
||||||
|
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "razuvious nontank",
|
||||||
|
// NextAction::array(0, new NextAction("razuvious target", ACTION_RAID + 1), NULL)));
|
||||||
|
|
||||||
|
// // four horseman
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "horseman attractors",
|
||||||
|
// NextAction::array(0, new NextAction("horseman attract alternatively", ACTION_RAID + 1), NULL)));
|
||||||
|
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "horseman except attractors",
|
||||||
|
// NextAction::array(0, new NextAction("horseman attack in order", ACTION_RAID + 1), NULL)));
|
||||||
|
|
||||||
|
// // sapphiron
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "sapphiron ground main tank",
|
||||||
|
// NextAction::array(0, new NextAction("sapphiron ground main tank position", ACTION_RAID + 1), NULL)));
|
||||||
|
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "sapphiron ground except main tank",
|
||||||
|
// NextAction::array(0, new NextAction("sapphiron ground position", ACTION_RAID + 1), NULL)));
|
||||||
|
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "sapphiron flight",
|
||||||
|
// NextAction::array(0, new NextAction("sapphiron flight position", ACTION_RAID + 1), NULL)));
|
||||||
|
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "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)));
|
||||||
|
|
||||||
|
// // 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
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "gluth",
|
||||||
|
// NextAction::array(0,
|
||||||
|
// new NextAction("gluth choose target", ACTION_RAID + 1),
|
||||||
|
// new NextAction("gluth position", ACTION_RAID + 1),
|
||||||
|
// new NextAction("gluth slowdown", ACTION_RAID),
|
||||||
|
// NULL)));
|
||||||
|
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "gluth main tank mortal wound",
|
||||||
|
// NextAction::array(0,
|
||||||
|
// new NextAction("taunt spell", ACTION_RAID + 1), NULL)));
|
||||||
|
// // Loatheb
|
||||||
|
// triggers.push_back(new TriggerNode(
|
||||||
|
// "loatheb",
|
||||||
|
// NextAction::array(0,
|
||||||
|
// new NextAction("loatheb position", ACTION_RAID + 1),
|
||||||
|
// new NextAction("loatheb choose target", ACTION_RAID + 1),
|
||||||
|
// NULL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaidNaxxGenericStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers)
|
||||||
|
{
|
||||||
|
multipliers.push_back(new HeiganDanceMultiplier(botAI));
|
||||||
|
// multipliers.push_back(new LoathebGenericMultiplier(ai));
|
||||||
|
// 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 AnubrekhanGenericMultiplier(ai));
|
||||||
|
// multipliers.push_back(new FourhorsemanGenericMultiplier(ai));
|
||||||
|
// multipliers.push_back(new GothikGenericMultiplier(ai));
|
||||||
|
// multipliers.push_back(new GluthGenericMultiplier(ai));
|
||||||
|
}
|
||||||
108
src/strategy/generic/RaidStrategy.h
Normal file
108
src/strategy/generic/RaidStrategy.h
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
|
||||||
|
#ifndef _PLAYERBOT_RAIDSTRATEGY_H
|
||||||
|
#define _PLAYERBOT_RAIDSTRATEGY_H
|
||||||
|
|
||||||
|
#include "Multiplier.h"
|
||||||
|
#include "Strategy.h"
|
||||||
|
|
||||||
|
class HeiganDanceMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HeiganDanceMultiplier(PlayerbotAI* ai) : Multiplier(ai, "helgan dance") {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
// class LoathebGenericMultiplier : public Multiplier
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// LoathebGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "loatheb generic") {}
|
||||||
|
|
||||||
|
// public:
|
||||||
|
// virtual float GetValue(Action* action);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class ThaddiusGenericMultiplier : public Multiplier
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// ThaddiusGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "thaddius generic") {}
|
||||||
|
|
||||||
|
// public:
|
||||||
|
// virtual float GetValue(Action* action);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class SapphironGenericMultiplier : public Multiplier
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// SapphironGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "sapphiron generic") {}
|
||||||
|
|
||||||
|
// public:
|
||||||
|
// virtual float GetValue(Action* action);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class InstructorRazuviousGenericMultiplier : public Multiplier
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// InstructorRazuviousGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "instructor razuvious generic") {}
|
||||||
|
|
||||||
|
// 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 AnubrekhanGenericMultiplier : public Multiplier
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// AnubrekhanGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "anubrekhan generic") {}
|
||||||
|
|
||||||
|
// public:
|
||||||
|
// virtual float GetValue(Action* action);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class FourhorsemanGenericMultiplier : public Multiplier
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// FourhorsemanGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "fourhorseman generic") {}
|
||||||
|
|
||||||
|
// public:
|
||||||
|
// virtual float GetValue(Action* action);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class GothikGenericMultiplier : public Multiplier
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// GothikGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "gothik generic") {}
|
||||||
|
|
||||||
|
// public:
|
||||||
|
// virtual float GetValue(Action* action);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class GluthGenericMultiplier : public Multiplier
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// GluthGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "gluth generic") {}
|
||||||
|
|
||||||
|
// public:
|
||||||
|
// virtual float GetValue(Action* action);
|
||||||
|
// };
|
||||||
|
|
||||||
|
class RaidNaxxGenericStrategy : public Strategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RaidNaxxGenericStrategy(PlayerbotAI* ai) : Strategy(ai) {}
|
||||||
|
virtual std::string const getName() override { return "naxx"; }
|
||||||
|
virtual void InitTriggers(std::vector<TriggerNode*> &triggers) override;
|
||||||
|
virtual void InitMultipliers(std::vector<Multiplier*> &multipliers) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -76,6 +76,9 @@ void GenericHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
// triggers.push_back(new TriggerNode("no ammo", NextAction::array(0, new NextAction("switch to melee", ACTION_HIGH + 1), new NextAction("say::no ammo", ACTION_HIGH), nullptr)));
|
// triggers.push_back(new TriggerNode("no ammo", NextAction::array(0, new NextAction("switch to melee", ACTION_HIGH + 1), new NextAction("say::no ammo", ACTION_HIGH), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("aspect of the viper", NextAction::array(0, new NextAction("aspect of the viper", ACTION_HIGH), NULL)));
|
triggers.push_back(new TriggerNode("aspect of the viper", NextAction::array(0, new NextAction("aspect of the viper", ACTION_HIGH), NULL)));
|
||||||
triggers.push_back(new TriggerNode("enemy too close for shoot", NextAction::array(0, new NextAction("flee", ACTION_HIGH + 3), NULL)));
|
triggers.push_back(new TriggerNode("enemy too close for shoot", NextAction::array(0, new NextAction("flee", ACTION_HIGH + 3), NULL)));
|
||||||
|
triggers.push_back(new TriggerNode("misdirection on main tank", NextAction::array(0, new NextAction("misdirection on main tank", ACTION_HIGH + 7), NULL)));
|
||||||
|
triggers.push_back(new TriggerNode("tranquilizing shot", NextAction::array(0, new NextAction("tranquilizing shot", 61.0f), NULL)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NextAction** HunterBoostStrategy::getDefaultActions()
|
NextAction** HunterBoostStrategy::getDefaultActions()
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ END_SPELL_ACTION()
|
|||||||
BEGIN_RANGED_SPELL_ACTION(CastKillShotAction, "kill shot")
|
BEGIN_RANGED_SPELL_ACTION(CastKillShotAction, "kill shot")
|
||||||
END_SPELL_ACTION()
|
END_SPELL_ACTION()
|
||||||
|
|
||||||
BEGIN_RANGED_SPELL_ACTION(CastTranquilizingShortAction, "tranquilizing shot")
|
BEGIN_RANGED_SPELL_ACTION(CastTranquilizingShotAction, "tranquilizing shot")
|
||||||
END_SPELL_ACTION()
|
END_SPELL_ACTION()
|
||||||
|
|
||||||
class CastAspectOfTheHawkAction : public CastBuffSpellAction
|
class CastAspectOfTheHawkAction : public CastBuffSpellAction
|
||||||
@@ -218,4 +218,9 @@ class CastScareBeastCcAction : public CastSpellAction
|
|||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CastMisdirectionOnMainTankAction : public BuffOnMainTankAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastMisdirectionOnMainTankAction(PlayerbotAI* ai) : BuffOnMainTankAction(ai, "misdirection", true) {}
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ class HunterTriggerFactoryInternal : public NamedObjectContext<Trigger>
|
|||||||
creators["has ammo"] = &HunterTriggerFactoryInternal::has_ammo;
|
creators["has ammo"] = &HunterTriggerFactoryInternal::has_ammo;
|
||||||
creators["switch to melee"] = &HunterTriggerFactoryInternal::switch_to_melee;
|
creators["switch to melee"] = &HunterTriggerFactoryInternal::switch_to_melee;
|
||||||
creators["switch to ranged"] = &HunterTriggerFactoryInternal::switch_to_ranged;
|
creators["switch to ranged"] = &HunterTriggerFactoryInternal::switch_to_ranged;
|
||||||
|
creators["misdirection on main tank"] = &HunterTriggerFactoryInternal::misdirection_on_main_tank;
|
||||||
|
creators["tranquilizing shot"] = &HunterTriggerFactoryInternal::remove_enrage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -105,6 +107,8 @@ class HunterTriggerFactoryInternal : public NamedObjectContext<Trigger>
|
|||||||
static Trigger* has_ammo(PlayerbotAI* botAI) { return new HunterHasAmmoTrigger(botAI); }
|
static Trigger* has_ammo(PlayerbotAI* botAI) { return new HunterHasAmmoTrigger(botAI); }
|
||||||
static Trigger* switch_to_melee(PlayerbotAI* botAI) { return new SwitchToMeleeTrigger(botAI); }
|
static Trigger* switch_to_melee(PlayerbotAI* botAI) { return new SwitchToMeleeTrigger(botAI); }
|
||||||
static Trigger* switch_to_ranged(PlayerbotAI* botAI) { return new SwitchToRangedTrigger(botAI); }
|
static Trigger* switch_to_ranged(PlayerbotAI* botAI) { return new SwitchToRangedTrigger(botAI); }
|
||||||
|
static Trigger* misdirection_on_main_tank(PlayerbotAI* ai) { return new MisdirectionOnMainTankTrigger(ai); }
|
||||||
|
static Trigger* remove_enrage(PlayerbotAI* ai) { return new TargetRemoveEnrageTrigger(ai); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class HunterAiObjectContextInternal : public NamedObjectContext<Action>
|
class HunterAiObjectContextInternal : public NamedObjectContext<Action>
|
||||||
@@ -152,6 +156,7 @@ class HunterAiObjectContextInternal : public NamedObjectContext<Action>
|
|||||||
creators["tranquilizing shot"] = &HunterAiObjectContextInternal::tranquilizing_shot;
|
creators["tranquilizing shot"] = &HunterAiObjectContextInternal::tranquilizing_shot;
|
||||||
creators["steady shot"] = &HunterAiObjectContextInternal::steady_shot;
|
creators["steady shot"] = &HunterAiObjectContextInternal::steady_shot;
|
||||||
creators["kill shot"] = &HunterAiObjectContextInternal::kill_shot;
|
creators["kill shot"] = &HunterAiObjectContextInternal::kill_shot;
|
||||||
|
creators["misdirection on main tank"] = &HunterAiObjectContextInternal::misdirection_on_main_tank;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -191,9 +196,10 @@ class HunterAiObjectContextInternal : public NamedObjectContext<Action>
|
|||||||
static Action* wing_clip(PlayerbotAI* botAI) { return new CastWingClipAction(botAI); }
|
static Action* wing_clip(PlayerbotAI* botAI) { return new CastWingClipAction(botAI); }
|
||||||
static Action* raptor_strike(PlayerbotAI* botAI) { return new CastRaptorStrikeAction(botAI); }
|
static Action* raptor_strike(PlayerbotAI* botAI) { return new CastRaptorStrikeAction(botAI); }
|
||||||
static Action* aspect_of_the_dragonhawk(PlayerbotAI* ai) { return new CastAspectOfTheDragonhawkAction(ai); }
|
static Action* aspect_of_the_dragonhawk(PlayerbotAI* ai) { return new CastAspectOfTheDragonhawkAction(ai); }
|
||||||
static Action* tranquilizing_shot(PlayerbotAI* ai) { return new CastTranquilizingShortAction(ai); }
|
static Action* tranquilizing_shot(PlayerbotAI* ai) { return new CastTranquilizingShotAction(ai); }
|
||||||
static Action* steady_shot(PlayerbotAI* ai) { return new CastSteadyShotAction(ai); }
|
static Action* steady_shot(PlayerbotAI* ai) { return new CastSteadyShotAction(ai); }
|
||||||
static Action* kill_shot(PlayerbotAI* ai) { return new CastKillShotAction(ai); }
|
static Action* kill_shot(PlayerbotAI* ai) { return new CastKillShotAction(ai); }
|
||||||
|
static Action* misdirection_on_main_tank(PlayerbotAI* ai) { return new CastMisdirectionOnMainTankAction(ai); }
|
||||||
};
|
};
|
||||||
|
|
||||||
HunterAiObjectContext::HunterAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
|
HunterAiObjectContext::HunterAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "GenericTriggers.h"
|
#include "GenericTriggers.h"
|
||||||
#include "Trigger.h"
|
#include "Trigger.h"
|
||||||
|
#include "CureTriggers.h"
|
||||||
|
|
||||||
class PlayerbotAI;
|
class PlayerbotAI;
|
||||||
|
|
||||||
@@ -149,4 +150,15 @@ class SwitchToMeleeTrigger : public Trigger
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MisdirectionOnMainTankTrigger : public BuffOnMainTankTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MisdirectionOnMainTankTrigger(PlayerbotAI* ai) : BuffOnMainTankTrigger(ai, "misdirection", true) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TargetRemoveEnrageTrigger : public TargetAuraDispelTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TargetRemoveEnrageTrigger(PlayerbotAI* ai) : TargetAuraDispelTrigger(ai, "tranquilizing shot", DISPEL_ENRAGE) {}
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ void GenericMageNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& trigg
|
|||||||
NonCombatStrategy::InitTriggers(triggers);
|
NonCombatStrategy::InitTriggers(triggers);
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("arcane intellect", NextAction::array(0, new NextAction("arcane intellect", 21.0f), nullptr)));
|
triggers.push_back(new TriggerNode("arcane intellect", NextAction::array(0, new NextAction("arcane intellect", 21.0f), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("no drink", NextAction::array(0, new NextAction("conjure water", 16.0f), nullptr)));
|
// triggers.push_back(new TriggerNode("no drink", NextAction::array(0, new NextAction("conjure water", 16.0f), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("no food", NextAction::array(0, new NextAction("conjure food", 15.0f), nullptr)));
|
// triggers.push_back(new TriggerNode("no food", NextAction::array(0, new NextAction("conjure food", 15.0f), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("apply oil", 1.0f), nullptr)));
|
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("apply oil", 1.0f), nullptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +69,6 @@ void MageBuffDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
void MageBuffStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void MageBuffStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
triggers.push_back(new TriggerNode("arcane intellect on party", NextAction::array(0, new NextAction("arcane intellect on party", 20.0f), nullptr)));
|
triggers.push_back(new TriggerNode("arcane intellect on party", NextAction::array(0, new NextAction("arcane intellect on party", 20.0f), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("give water", NextAction::array(0, new NextAction("give water", 14.0f), nullptr)));
|
// triggers.push_back(new TriggerNode("give water", NextAction::array(0, new NextAction("give water", 14.0f), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("give food", NextAction::array(0, new NextAction("give food", 13.0f), nullptr)));
|
// triggers.push_back(new TriggerNode("give food", NextAction::array(0, new NextAction("give food", 13.0f), nullptr)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ HealPaladinStrategy::HealPaladinStrategy(PlayerbotAI* botAI) : GenericPaladinStr
|
|||||||
|
|
||||||
NextAction** HealPaladinStrategy::getDefaultActions()
|
NextAction** HealPaladinStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(0, new NextAction("judgement of light", ACTION_NORMAL + 2),
|
return NextAction::array(0, new NextAction("judgement of light", ACTION_NORMAL + 2), nullptr);
|
||||||
new NextAction("reach party member to heal", ACTION_NORMAL + 1), nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HealPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void HealPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
|||||||
@@ -54,9 +54,7 @@ void TankPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
// 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("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("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("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(
|
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)));
|
||||||
"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 + 7), nullptr)));
|
||||||
|
|||||||
@@ -342,30 +342,30 @@ class CastWindShearOnEnemyHealerAction : public CastSpellOnEnemyHealerAction
|
|||||||
CastWindShearOnEnemyHealerAction(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, "wind shear") { }
|
CastWindShearOnEnemyHealerAction(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, "wind shear") { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastCurePoisonAction : public CastCureSpellAction
|
// class CastCurePoisonAction : public CastCureSpellAction
|
||||||
{
|
// {
|
||||||
public:
|
// public:
|
||||||
CastCurePoisonAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cure poison") { }
|
// CastCurePoisonAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cure poison") { }
|
||||||
};
|
// };
|
||||||
|
|
||||||
class CastCurePoisonOnPartyAction : public CurePartyMemberAction
|
// class CastCurePoisonOnPartyAction : public CurePartyMemberAction
|
||||||
{
|
// {
|
||||||
public:
|
// public:
|
||||||
CastCurePoisonOnPartyAction(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "cure poison", DISPEL_POISON) { }
|
// CastCurePoisonOnPartyAction(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "cure poison", DISPEL_POISON) { }
|
||||||
};
|
// };
|
||||||
|
|
||||||
class CastCureDiseaseAction : public CastCureSpellAction
|
// class CastCureDiseaseAction : public CastCureSpellAction
|
||||||
{
|
// {
|
||||||
public:
|
// public:
|
||||||
CastCureDiseaseAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cure disease") { }
|
// CastCureDiseaseAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cure disease") { }
|
||||||
};
|
// };
|
||||||
|
|
||||||
class CastCureDiseaseOnPartyAction : public CurePartyMemberAction
|
// class CastCureDiseaseOnPartyAction : public CurePartyMemberAction
|
||||||
{
|
// {
|
||||||
public:
|
// public:
|
||||||
CastCureDiseaseOnPartyAction(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "cure disease", DISPEL_DISEASE) { }
|
// CastCureDiseaseOnPartyAction(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "cure disease", DISPEL_DISEASE) { }
|
||||||
|
|
||||||
std::string const getName() override { return "cure disease on party"; }
|
// std::string const getName() override { return "cure disease on party"; }
|
||||||
};
|
// };
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ class ShamanATriggerFactoryInternal : public NamedObjectContext<Trigger>
|
|||||||
creators["wind shear on enemy healer"] = &ShamanATriggerFactoryInternal::wind_shear_on_enemy_healer;
|
creators["wind shear on enemy healer"] = &ShamanATriggerFactoryInternal::wind_shear_on_enemy_healer;
|
||||||
creators["cure poison"] = &ShamanATriggerFactoryInternal::cure_poison;
|
creators["cure poison"] = &ShamanATriggerFactoryInternal::cure_poison;
|
||||||
creators["party member cure poison"] = &ShamanATriggerFactoryInternal::party_member_cure_poison;
|
creators["party member cure poison"] = &ShamanATriggerFactoryInternal::party_member_cure_poison;
|
||||||
creators["cure disease"] = &ShamanATriggerFactoryInternal::cure_disease;
|
// creators["cure disease"] = &ShamanATriggerFactoryInternal::cure_disease;
|
||||||
creators["party member cure disease"] = &ShamanATriggerFactoryInternal::party_member_cure_disease;
|
creators["party member cure disease"] = &ShamanATriggerFactoryInternal::party_member_cure_disease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,10 +192,10 @@ class ShamanAiObjectContextInternal : public NamedObjectContext<Action>
|
|||||||
creators["thunderstorm"] = &ShamanAiObjectContextInternal::thunderstorm;
|
creators["thunderstorm"] = &ShamanAiObjectContextInternal::thunderstorm;
|
||||||
creators["heroism"] = &ShamanAiObjectContextInternal::heroism;
|
creators["heroism"] = &ShamanAiObjectContextInternal::heroism;
|
||||||
creators["bloodlust"] = &ShamanAiObjectContextInternal::bloodlust;
|
creators["bloodlust"] = &ShamanAiObjectContextInternal::bloodlust;
|
||||||
creators["cure disease"] = &ShamanAiObjectContextInternal::cure_disease;
|
// creators["cure disease"] = &ShamanAiObjectContextInternal::cure_disease;
|
||||||
creators["cure disease on party"] = &ShamanAiObjectContextInternal::cure_disease_on_party;
|
// creators["cure disease on party"] = &ShamanAiObjectContextInternal::cure_disease_on_party;
|
||||||
creators["cure poison"] = &ShamanAiObjectContextInternal::cure_poison;
|
// creators["cure poison"] = &ShamanAiObjectContextInternal::cure_poison;
|
||||||
creators["cure poison on party"] = &ShamanAiObjectContextInternal::cure_poison_on_party;
|
// creators["cure poison on party"] = &ShamanAiObjectContextInternal::cure_poison_on_party;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -248,10 +248,10 @@ class ShamanAiObjectContextInternal : public NamedObjectContext<Action>
|
|||||||
static Action* lava_lash(PlayerbotAI* botAI) { return new CastLavaLashAction(botAI); }
|
static Action* lava_lash(PlayerbotAI* botAI) { return new CastLavaLashAction(botAI); }
|
||||||
static Action* ancestral_spirit(PlayerbotAI* botAI) { return new CastAncestralSpiritAction(botAI); }
|
static Action* ancestral_spirit(PlayerbotAI* botAI) { return new CastAncestralSpiritAction(botAI); }
|
||||||
static Action* wind_shear_on_enemy_healer(PlayerbotAI* botAI) { return new CastWindShearOnEnemyHealerAction(botAI); }
|
static Action* wind_shear_on_enemy_healer(PlayerbotAI* botAI) { return new CastWindShearOnEnemyHealerAction(botAI); }
|
||||||
static Action* cure_poison(PlayerbotAI* botAI) { return new CastCurePoisonAction(botAI); }
|
// static Action* cure_poison(PlayerbotAI* botAI) { return new CastCurePoisonAction(botAI); }
|
||||||
static Action* cure_poison_on_party(PlayerbotAI* botAI) { return new CastCurePoisonOnPartyAction(botAI); }
|
// static Action* cure_poison_on_party(PlayerbotAI* botAI) { return new CastCurePoisonOnPartyAction(botAI); }
|
||||||
static Action* cure_disease(PlayerbotAI* botAI) { return new CastCureDiseaseAction(botAI); }
|
// static Action* cure_disease(PlayerbotAI* botAI) { return new CastCureDiseaseAction(botAI); }
|
||||||
static Action* cure_disease_on_party(PlayerbotAI* botAI) { return new CastCureDiseaseOnPartyAction(botAI); }
|
// static Action* cure_disease_on_party(PlayerbotAI* botAI) { return new CastCureDiseaseOnPartyAction(botAI); }
|
||||||
};
|
};
|
||||||
|
|
||||||
ShamanAiObjectContext::ShamanAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
|
ShamanAiObjectContext::ShamanAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ class AmmoCountTrigger : public ItemCountTrigger
|
|||||||
class HasAuraTrigger : public Trigger
|
class HasAuraTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HasAuraTrigger(PlayerbotAI* botAI, std::string const spell) : Trigger(botAI, spell) { }
|
HasAuraTrigger(PlayerbotAI* botAI, std::string const spell, int32 checkInterval = 1) : Trigger(botAI, spell, checkInterval) { }
|
||||||
|
|
||||||
std::string const GetTargetName() override { return "self target"; }
|
std::string const GetTargetName() override { return "self target"; }
|
||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
|
|||||||
151
src/strategy/triggers/RaidNaxxTrigger.cpp
Normal file
151
src/strategy/triggers/RaidNaxxTrigger.cpp
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#include "Playerbots.h"
|
||||||
|
#include "RaidNaxxTrigger.h"
|
||||||
|
#include "ScriptedCreature.h"
|
||||||
|
|
||||||
|
// bool MutatingInjectionRemovedTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// Unit* boss = AI_VALUE2(Unit*, "find target", "grobbulus");
|
||||||
|
// if (!boss) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// return HasNotAuraTrigger::IsActive() && botAI->GetCurrentState() == BOT_STATE_COMBAT && botAI->IsRanged(bot);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool BossEventTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// Unit* boss = AI_VALUE(Unit*, "boss target");
|
||||||
|
// if (!boss || boss->GetEntry() != boss_entry) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// BossAI* boss_ai = dynamic_cast<BossAI*>(boss->GetAI());
|
||||||
|
// EventMap* eventMap = boss_botAI->GetEvents();
|
||||||
|
// const uint32 event_time = eventMap->GetNextEventTime(event_id);
|
||||||
|
// if (event_time != last_event_time) {
|
||||||
|
// last_event_time = event_time;
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool BossPhaseTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// Unit* boss = AI_VALUE2(Unit*, "find target", boss_name);
|
||||||
|
// if (!boss) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// if (this->phase_mask == 0) {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// BossAI* boss_ai = dynamic_cast<BossAI*>(boss->GetAI());
|
||||||
|
// EventMap* eventMap = boss_botAI->GetEvents();
|
||||||
|
// uint8 phase_mask = eventMap->GetPhaseMask();
|
||||||
|
// // bot->Yell("phase mask detected: " + to_string(phase_mask) + " compare with " + to_string(this->phase_mask), LANG_UNIVERSAL);
|
||||||
|
// return phase_mask == this->phase_mask;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool GrobbulusCloudTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// Unit* boss = AI_VALUE(Unit*, "boss target");
|
||||||
|
// if (!boss || boss->GetEntry() != boss_entry) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// if (!botAI->IsMainTank(bot)) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// // bot->Yell("has aggro on " + boss->GetName() + " : " + to_string(AI_VALUE2(bool, "has aggro", "boss target")), LANG_UNIVERSAL);
|
||||||
|
// return AI_VALUE2(bool, "has aggro", "boss target");
|
||||||
|
// }
|
||||||
|
|
||||||
|
bool HeiganMeleeTrigger::IsActive()
|
||||||
|
{
|
||||||
|
|
||||||
|
Unit* heigan = AI_VALUE2(Unit*, "find target", "heigan the unclean");
|
||||||
|
if (!heigan) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !botAI->IsRanged(bot);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HeiganRangedTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* heigan = AI_VALUE2(Unit*, "find target", "heigan the unclean");
|
||||||
|
if (!heigan) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return botAI->IsRanged(bot);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bool RazuviousTankTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// Difficulty diff = bot->GetRaidDifficulty();
|
||||||
|
// if (diff == RAID_DIFFICULTY_10MAN_NORMAL) {
|
||||||
|
// return BossPhaseTrigger::IsActive() && botAI->IsTank(bot);
|
||||||
|
// }
|
||||||
|
// return BossPhaseTrigger::IsActive() && bot->getClass() == CLASS_PRIEST;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool RazuviousNontankTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// Difficulty diff = bot->GetRaidDifficulty();
|
||||||
|
// if (diff == RAID_DIFFICULTY_10MAN_NORMAL) {
|
||||||
|
// return BossPhaseTrigger::IsActive() && !(botAI->IsTank(bot));
|
||||||
|
// }
|
||||||
|
// return BossPhaseTrigger::IsActive() && !(bot->getClass() == CLASS_PRIEST);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool HorsemanAttractorsTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// Difficulty diff = bot->GetRaidDifficulty();
|
||||||
|
// if (diff == RAID_DIFFICULTY_25MAN_NORMAL) {
|
||||||
|
// return BossPhaseTrigger::IsActive() && (botAI->IsRangedDpsAssistantOfIndex(bot, 0) || botAI->IsHealAssistantOfIndex(bot, 0) ||
|
||||||
|
// botAI->IsHealAssistantOfIndex(bot, 1) || botAI->IsHealAssistantOfIndex(bot, 2));
|
||||||
|
// }
|
||||||
|
// return BossPhaseTrigger::IsActive() && (botAI->IsRangedDpsAssistantOfIndex(bot, 0) || botAI->IsHealAssistantOfIndex(bot, 0));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool HorsemanExceptAttractorsTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// return BossPhaseTrigger::IsActive() &&
|
||||||
|
// !(botAI->IsRangedDpsAssistantOfIndex(bot, 0) || botAI->IsHealAssistantOfIndex(bot, 0) ||
|
||||||
|
// botAI->IsHealAssistantOfIndex(bot, 1) || botAI->IsHealAssistantOfIndex(bot, 2));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool SapphironGroundMainTankTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// return BossPhaseTrigger::IsActive() && botAI->IsMainTank(bot) && AI_VALUE2(bool, "has aggro", "boss target");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool SapphironGroundExceptMainTankTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// return BossPhaseTrigger::IsActive() && !botAI->IsMainTank(bot);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool SapphironFlightTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// return BossPhaseTrigger::IsActive();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool SapphironGroundChillTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// return BossPhaseTrigger::IsActive() && !botAI->IsMainTank(bot) && botAI->HasAura("chill", bot);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool GluthMainTankMortalWoundTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// if (!BossPhaseTrigger::IsActive()) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// if (!botAI->IsAssistTankOfIndex(bot, 0)) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// Unit* mt = AI_VALUE(Unit*, "main tank");
|
||||||
|
// if (!mt) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// Aura* aura = botAI->GetAuraWithDuration("mortal wound", mt);
|
||||||
|
// if (!aura || aura->GetStackAmount() < 5) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// // bot->Yell("Time to taunt!", LANG_UNIVERSAL);
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
212
src/strategy/triggers/RaidNaxxTrigger.h
Normal file
212
src/strategy/triggers/RaidNaxxTrigger.h
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
|
||||||
|
#ifndef _PLAYERBOT_RAIDNAXXTRIGGER_H
|
||||||
|
#define _PLAYERBOT_RAIDNAXXTRIGGER_H
|
||||||
|
|
||||||
|
#include "Trigger.h"
|
||||||
|
#include "PlayerbotAIConfig.h"
|
||||||
|
#include "GenericTriggers.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
// class MutatingInjectionTrigger : public HasAuraTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// MutatingInjectionTrigger(PlayerbotAI* ai): HasAuraTrigger(ai, "mutating injection", 1) {}
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class AuraRemovedTrigger : public Trigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// AuraRemovedTrigger(PlayerbotAI* ai, string name): Trigger(ai, name, 1) {
|
||||||
|
// this->prev_check = false;
|
||||||
|
// }
|
||||||
|
// virtual bool IsActive() {
|
||||||
|
// bool check = ai->HasAuraWithDuration(name, bot);
|
||||||
|
// bool ret = false;
|
||||||
|
// // bot->Yell(to_string(prev_check) + to_string(check), LANG_UNIVERSAL);
|
||||||
|
// if (prev_check && !check) {
|
||||||
|
// ret = true;
|
||||||
|
// }
|
||||||
|
// prev_check = check;
|
||||||
|
// return ret;
|
||||||
|
// }
|
||||||
|
// protected:
|
||||||
|
// bool prev_check;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class MutatingInjectionRemovedTrigger : public HasNotAuraTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// MutatingInjectionRemovedTrigger(PlayerbotAI* ai): HasNotAuraTrigger(ai, "mutating injection", 1) {}
|
||||||
|
// virtual bool IsActive();
|
||||||
|
// };
|
||||||
|
|
||||||
|
class BossEventTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BossEventTrigger(PlayerbotAI* ai, uint32 boss_entry, uint32 event_id, string name = "boss event"): Trigger(ai, name, 1) {
|
||||||
|
this->boss_entry = boss_entry;
|
||||||
|
this->event_id = event_id;
|
||||||
|
this->last_event_time = -1;
|
||||||
|
}
|
||||||
|
virtual bool IsActive();
|
||||||
|
protected:
|
||||||
|
uint32 boss_entry, event_id, last_event_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BossPhaseTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BossPhaseTrigger(PlayerbotAI* ai, string boss_name, uint32 phase_mask, string name = "boss event"): Trigger(ai, name, 1) {
|
||||||
|
this->boss_name = boss_name;
|
||||||
|
this->phase_mask = phase_mask;
|
||||||
|
}
|
||||||
|
virtual bool IsActive();
|
||||||
|
protected:
|
||||||
|
string boss_name;
|
||||||
|
uint32 phase_mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
// class GrobbulusCloudTrigger : public BossEventTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// GrobbulusCloudTrigger(PlayerbotAI* ai): BossEventTrigger(ai, 15931, 2, "grobbulus cloud event") {}
|
||||||
|
// virtual bool IsActive();
|
||||||
|
// };
|
||||||
|
|
||||||
|
class HeiganMeleeTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HeiganMeleeTrigger(PlayerbotAI* ai): Trigger(ai, "heigan melee") {}
|
||||||
|
virtual bool IsActive();
|
||||||
|
};
|
||||||
|
|
||||||
|
class HeiganRangedTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HeiganRangedTrigger(PlayerbotAI* ai): Trigger(ai, "heigan ranged") {}
|
||||||
|
virtual bool IsActive();
|
||||||
|
};
|
||||||
|
|
||||||
|
// class ThaddiusPhasePetTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// ThaddiusPhasePetTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "thaddius", 1 << (2 - 1), "thaddius phase pet") {}
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class ThaddiusPhasePetLoseAggroTrigger : public ThaddiusPhasePetTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// ThaddiusPhasePetLoseAggroTrigger(PlayerbotAI* ai) : ThaddiusPhasePetTrigger(ai) {}
|
||||||
|
// virtual bool IsActive() {
|
||||||
|
// Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
// return ThaddiusPhasePetTrigger::IsActive() && ai->IsTank(bot) && target && target->GetVictim() != bot;
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class ThaddiusPhaseTransitionTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// ThaddiusPhaseTransitionTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "thaddius", 1 << (3 - 1), "thaddius phase transition") {}
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class ThaddiusPhaseThaddiusTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// 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
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// HorsemanAttractorsTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "sir zeliek", 0, "horseman attractors") {}
|
||||||
|
// virtual bool IsActive();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class HorsemanExceptAttractorsTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// HorsemanExceptAttractorsTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "sir zeliek", 0, "horseman except attractors") {}
|
||||||
|
// virtual bool IsActive();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class SapphironGroundMainTankTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// SapphironGroundMainTankTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "sapphiron", (1 << (2 - 1)), "sapphiron ground main tank") {}
|
||||||
|
// virtual bool IsActive();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class SapphironGroundExceptMainTankTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// SapphironGroundExceptMainTankTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "sapphiron", (1 << (2 - 1)), "sapphiron ground except main tank") {}
|
||||||
|
// virtual bool IsActive();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class SapphironFlightTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// SapphironFlightTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "sapphiron", (1 << (3 - 1)), "sapphiron flight") {}
|
||||||
|
// virtual bool IsActive();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class SapphironGroundChillTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// SapphironGroundChillTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "sapphiron", 0, "sapphiron chill") {}
|
||||||
|
// virtual bool IsActive();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class KelthuzadTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// KelthuzadTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "kel'thuzad", 0, "kel'thuzad trigger") {}
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class AnubrekhanTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// AnubrekhanTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "anub'rekhan", 0, "anub'rekhan trigger") {}
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class KelthuzadPhaseTwoTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// KelthuzadPhaseTwoTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "kel'thuzad", 1 << (2 - 1), "kel'thuzad trigger") {}
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class GluthTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// GluthTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "gluth", 0, "gluth trigger") {}
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class GluthMainTankMortalWoundTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// GluthMainTankMortalWoundTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "gluth", 0, "gluth main tank mortal wound trigger") {}
|
||||||
|
// virtual bool IsActive();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class LoathebTrigger : public BossPhaseTrigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// LoathebTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "loatheb", 0, "loatheb trigger") {}
|
||||||
|
// };
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -145,15 +145,15 @@ bool EnemyOutOfSpellRangeTrigger::IsActive()
|
|||||||
return target && (sServerFacade->GetDistance2d(bot, target) > (distance + combatReach + sPlayerbotAIConfig->contactDistance) || !bot->IsWithinLOSInMap(target));
|
return target && (sServerFacade->GetDistance2d(bot, target) > (distance + combatReach + sPlayerbotAIConfig->contactDistance) || !bot->IsWithinLOSInMap(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EnemyOutOfMeleeTrigger::IsActive()
|
// bool EnemyOutOfMeleeTrigger::IsActive()
|
||||||
{
|
// {
|
||||||
Unit* target = AI_VALUE(Unit*, GetTargetName());
|
// Unit* target = AI_VALUE(Unit*, GetTargetName());
|
||||||
if (!target)
|
// if (!target)
|
||||||
return false;
|
// return false;
|
||||||
|
|
||||||
float targetDistance = sServerFacade->GetDistance2d(bot, target);
|
// float targetDistance = sServerFacade->GetDistance2d(bot, target);
|
||||||
return target && (targetDistance > std::max(5.0f, bot->GetCombatReach() + target->GetCombatReach()) || (!bot->IsWithinLOSInMap(target) && targetDistance > 5.0f));
|
// return target && (targetDistance > std::max(5.0f, bot->GetCombatReach() + target->GetCombatReach()) || (!bot->IsWithinLOSInMap(target) && targetDistance > 5.0f));
|
||||||
}
|
// }
|
||||||
|
|
||||||
bool PartyMemberToHealOutOfSpellRangeTrigger::IsActive()
|
bool PartyMemberToHealOutOfSpellRangeTrigger::IsActive()
|
||||||
{
|
{
|
||||||
@@ -166,7 +166,7 @@ bool PartyMemberToHealOutOfSpellRangeTrigger::IsActive()
|
|||||||
}
|
}
|
||||||
|
|
||||||
PartyMemberToHealOutOfSpellRangeTrigger::PartyMemberToHealOutOfSpellRangeTrigger(PlayerbotAI* botAI) :
|
PartyMemberToHealOutOfSpellRangeTrigger::PartyMemberToHealOutOfSpellRangeTrigger(PlayerbotAI* botAI) :
|
||||||
OutOfRangeTrigger(botAI, "party member to heal out of spell range", botAI->GetRange("spell"))
|
OutOfRangeTrigger(botAI, "party member to heal out of spell range", botAI->GetRange("heal") + 1.0f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class EnemyOutOfMeleeTrigger : public OutOfRangeTrigger
|
|||||||
public:
|
public:
|
||||||
EnemyOutOfMeleeTrigger(PlayerbotAI* botAI) : OutOfRangeTrigger(botAI, "enemy out of melee range", sPlayerbotAIConfig->meleeDistance) { }
|
EnemyOutOfMeleeTrigger(PlayerbotAI* botAI) : OutOfRangeTrigger(botAI, "enemy out of melee range", sPlayerbotAIConfig->meleeDistance) { }
|
||||||
|
|
||||||
bool IsActive() override;
|
// bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EnemyOutOfSpellRangeTrigger : public OutOfRangeTrigger
|
class EnemyOutOfSpellRangeTrigger : public OutOfRangeTrigger
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "StuckTriggers.h"
|
#include "StuckTriggers.h"
|
||||||
#include "TravelTriggers.h"
|
#include "TravelTriggers.h"
|
||||||
#include "NamedObjectContext.h"
|
#include "NamedObjectContext.h"
|
||||||
|
#include "RaidNaxxTrigger.h"
|
||||||
|
|
||||||
class PlayerbotAI;
|
class PlayerbotAI;
|
||||||
|
|
||||||
@@ -191,6 +192,38 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
|||||||
creators["rpg craft"] = &TriggerContext::rpg_craft;
|
creators["rpg craft"] = &TriggerContext::rpg_craft;
|
||||||
creators["rpg trade useful"] = &TriggerContext::rpg_trade_useful;
|
creators["rpg trade useful"] = &TriggerContext::rpg_trade_useful;
|
||||||
creators["rpg duel"] = &TriggerContext::rpg_duel;
|
creators["rpg duel"] = &TriggerContext::rpg_duel;
|
||||||
|
|
||||||
|
// creators["mutating injection"] = &TriggerContext::mutating_injection;
|
||||||
|
// creators["mutating injection removed"] = &TriggerContext::mutating_injection_removed;
|
||||||
|
// creators["grobbulus cloud"] = &TriggerContext::grobbulus_cloud;
|
||||||
|
creators["heigan melee"] = &TriggerContext::heigan_melee;
|
||||||
|
creators["heigan ranged"] = &TriggerContext::heigan_ranged;
|
||||||
|
|
||||||
|
// creators["thaddius phase pet"] = &TriggerContext::thaddius_phase_pet;
|
||||||
|
// creators["thaddius phase pet lose aggro"] = &TriggerContext::thaddius_phase_pet_lose_aggro;
|
||||||
|
// creators["thaddius phase transition"] = &TriggerContext::thaddius_phase_transition;
|
||||||
|
// creators["thaddius phase thaddius"] = &TriggerContext::thaddius_phase_thaddius;
|
||||||
|
|
||||||
|
// creators["razuvious tank"] = &TriggerContext::razuvious_tank;
|
||||||
|
// creators["razuvious nontank"] = &TriggerContext::razuvious_nontank;
|
||||||
|
|
||||||
|
// creators["horseman attractors"] = &TriggerContext::horseman_attractors;
|
||||||
|
// creators["horseman except attractors"] = &TriggerContext::horseman_except_attractors;
|
||||||
|
|
||||||
|
// creators["sapphiron ground main tank"] = &TriggerContext::sapphiron_ground_main_tank;
|
||||||
|
// creators["sapphiron ground except main tank"] = &TriggerContext::sapphiron_ground_except_main_tank;
|
||||||
|
// creators["sapphiron flight"] = &TriggerContext::sapphiron_flight;
|
||||||
|
// creators["sapphiron chill"] = &TriggerContext::sapphiron_ground_chill;
|
||||||
|
|
||||||
|
// creators["kel'thuzad"] = &TriggerContext::kelthuzad;
|
||||||
|
// creators["kel'thuzad phase two"] = &TriggerContext::kelthuzad_phase_two;
|
||||||
|
|
||||||
|
// creators["anub'rekhan"] = &TriggerContext::anubrekhan;
|
||||||
|
|
||||||
|
// creators["gluth"] = &TriggerContext::gluth;
|
||||||
|
// creators["gluth main tank mortal wound"] = &TriggerContext::gluth_main_tank_mortal_wound;
|
||||||
|
|
||||||
|
// creators["loatheb"] = &TriggerContext::loatheb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -330,6 +363,31 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
|||||||
static Trigger* rpg_craft(PlayerbotAI* botAI) { return new RpgCraftTrigger(botAI); }
|
static Trigger* rpg_craft(PlayerbotAI* botAI) { return new RpgCraftTrigger(botAI); }
|
||||||
static Trigger* rpg_trade_useful(PlayerbotAI* botAI) { return new RpgTradeUsefulTrigger(botAI); }
|
static Trigger* rpg_trade_useful(PlayerbotAI* botAI) { return new RpgTradeUsefulTrigger(botAI); }
|
||||||
static Trigger* rpg_duel(PlayerbotAI* botAI) { return new RpgDuelTrigger(botAI); }
|
static Trigger* rpg_duel(PlayerbotAI* botAI) { return new RpgDuelTrigger(botAI); }
|
||||||
|
|
||||||
|
// static Trigger* mutating_injection(PlayerbotAI* ai) { return new MutatingInjectionTrigger(ai); }
|
||||||
|
// static Trigger* mutating_injection_removed(PlayerbotAI* ai) { return new MutatingInjectionRemovedTrigger(ai); }
|
||||||
|
// static Trigger* grobbulus_cloud(PlayerbotAI* ai) { return new GrobbulusCloudTrigger(ai); }
|
||||||
|
static Trigger* heigan_melee(PlayerbotAI* ai) { return new HeiganMeleeTrigger(ai); }
|
||||||
|
static Trigger* heigan_ranged(PlayerbotAI* ai) { return new HeiganRangedTrigger(ai); }
|
||||||
|
// static Trigger* thaddius_phase_pet(PlayerbotAI* ai) { return new ThaddiusPhasePetTrigger(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_thaddius(PlayerbotAI* ai) { return new ThaddiusPhaseThaddiusTrigger(ai); }
|
||||||
|
// static Trigger* razuvious_tank(PlayerbotAI* ai) { return new RazuviousTankTrigger(ai); }
|
||||||
|
// static Trigger* razuvious_nontank(PlayerbotAI* ai) { return new RazuviousNontankTrigger(ai); }
|
||||||
|
|
||||||
|
// static Trigger* horseman_attractors(PlayerbotAI* ai) { return new HorsemanAttractorsTrigger(ai); }
|
||||||
|
// static Trigger* horseman_except_attractors(PlayerbotAI* ai) { return new HorsemanExceptAttractorsTrigger(ai); }
|
||||||
|
// static Trigger* sapphiron_ground_main_tank(PlayerbotAI* ai) { return new SapphironGroundMainTankTrigger(ai); }
|
||||||
|
// 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_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); }
|
||||||
|
// static Trigger* gluth_main_tank_mortal_wound(PlayerbotAI* ai) { return new GluthMainTankMortalWoundTrigger(ai); }
|
||||||
|
// static Trigger* loatheb(PlayerbotAI* ai) { return new LoathebTrigger(ai); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ bool HasAggroValue::Calculate()
|
|||||||
{
|
{
|
||||||
if (Player* pl = victim->ToPlayer())
|
if (Player* pl = victim->ToPlayer())
|
||||||
{
|
{
|
||||||
if (botAI->IsTank(pl))
|
if (botAI->IsMainTank(pl))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ Unit* PartyMemberToHeal::Calculate()
|
|||||||
if (player && Check(player) && player->IsAlive()) {
|
if (player && Check(player) && player->IsAlive()) {
|
||||||
uint8 health = player->GetHealthPct();
|
uint8 health = player->GetHealthPct();
|
||||||
if (isRaid || health < sPlayerbotAIConfig->mediumHealth || !IsTargetOfSpellCast(player, predicate)) {
|
if (isRaid || health < sPlayerbotAIConfig->mediumHealth || !IsTargetOfSpellCast(player, predicate)) {
|
||||||
if (player->GetDistance2d(bot) > sPlayerbotAIConfig->spellDistance) {
|
if (player->GetDistance2d(bot) > sPlayerbotAIConfig->healDistance) {
|
||||||
calc.probe(health + 30, player);
|
calc.probe(health + 30, player);
|
||||||
} else {
|
} else {
|
||||||
calc.probe(health + player->GetDistance2d(bot) / 10, player);
|
calc.probe(health + player->GetDistance2d(bot) / 10, player);
|
||||||
@@ -75,7 +75,7 @@ bool PartyMemberToHeal::Check(Unit* player)
|
|||||||
// return player && player != bot && player->GetMapId() == bot->GetMapId() && player->IsInWorld() &&
|
// return player && player != bot && player->GetMapId() == bot->GetMapId() && player->IsInWorld() &&
|
||||||
// sServerFacade->GetDistance2d(bot, player) < (player->IsPlayer() && botAI->IsTank((Player*)player) ? 50.0f : 40.0f);
|
// sServerFacade->GetDistance2d(bot, player) < (player->IsPlayer() && botAI->IsTank((Player*)player) ? 50.0f : 40.0f);
|
||||||
return player && player->GetMapId() == bot->GetMapId() &&
|
return player && player->GetMapId() == bot->GetMapId() &&
|
||||||
bot->GetDistance2d(player) < sPlayerbotAIConfig->spellDistance * 2 &&
|
bot->GetDistance2d(player) < sPlayerbotAIConfig->healDistance * 2 &&
|
||||||
bot->IsWithinLOS(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
|
bot->IsWithinLOS(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include "LastMovementValue.h"
|
#include "LastMovementValue.h"
|
||||||
#include "RtiTargetValue.h"
|
#include "RtiTargetValue.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
#include "ScriptedCreature.h"
|
||||||
|
#include "ThreatMgr.h"
|
||||||
|
|
||||||
Unit* FindTargetStrategy::GetResult()
|
Unit* FindTargetStrategy::GetResult()
|
||||||
{
|
{
|
||||||
@@ -111,3 +113,50 @@ WorldPosition HomeBindValue::Calculate()
|
|||||||
{
|
{
|
||||||
return WorldPosition(bot->m_homebindMapId, bot->m_homebindX, bot->m_homebindY, bot->m_homebindZ, 0.f);
|
return WorldPosition(bot->m_homebindMapId, bot->m_homebindX, bot->m_homebindY, bot->m_homebindZ, 0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Unit* FindTargetValue::Calculate()
|
||||||
|
{
|
||||||
|
if (qualifier == "") {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (GroupReference *gref = group->GetFirstMember(); gref; gref = gref->next()) {
|
||||||
|
Player* member = gref->GetSource();
|
||||||
|
if (!member) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
HostileReference *ref = member->getHostileRefMgr().getFirst();
|
||||||
|
while (ref)
|
||||||
|
{
|
||||||
|
ThreatMgr *threatManager = ref->GetSource();
|
||||||
|
Unit *unit = threatManager->GetOwner();
|
||||||
|
std::wstring wnamepart;
|
||||||
|
Utf8toWStr(unit->GetName(), wnamepart);
|
||||||
|
wstrToLower(wnamepart);
|
||||||
|
if (!qualifier.empty() && qualifier.length() == wnamepart.length() && Utf8FitTo(qualifier, wnamepart)) {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
assert(ref);
|
||||||
|
ref = ref->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindBossTargetStrategy::CheckAttacker(Unit* attacker, ThreatMgr* threatManager)
|
||||||
|
{
|
||||||
|
UnitAI* unitAI = attacker->GetAI();
|
||||||
|
BossAI* bossAI = dynamic_cast<BossAI*>(unitAI);
|
||||||
|
if (bossAI) {
|
||||||
|
result = attacker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* BossTargetValue::Calculate()
|
||||||
|
{
|
||||||
|
FindBossTargetStrategy strategy(botAI);
|
||||||
|
return FindTarget(&strategy);
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "TravelMgr.h"
|
#include "TravelMgr.h"
|
||||||
#include "Value.h"
|
#include "Value.h"
|
||||||
|
#include "NamedObjectContext.h"
|
||||||
|
|
||||||
class PlayerbotAI;
|
class PlayerbotAI;
|
||||||
class ThreatMgr;
|
class ThreatMgr;
|
||||||
@@ -97,4 +98,28 @@ class PullTargetValue : public ManualSetValue<ObjectGuid>
|
|||||||
PullTargetValue(PlayerbotAI* botAI, std::string const name = "pull target") : ManualSetValue<ObjectGuid>(botAI, ObjectGuid::Empty, name) { }
|
PullTargetValue(PlayerbotAI* botAI, std::string const name = "pull target") : ManualSetValue<ObjectGuid>(botAI, ObjectGuid::Empty, name) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FindTargetValue : public UnitCalculatedValue, public Qualified
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FindTargetValue(PlayerbotAI* ai) : UnitCalculatedValue(ai) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Unit* Calculate();
|
||||||
|
};
|
||||||
|
|
||||||
|
class FindBossTargetStrategy : public FindTargetStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FindBossTargetStrategy(PlayerbotAI* ai) : FindTargetStrategy(ai) {}
|
||||||
|
virtual void CheckAttacker(Unit* attacker, ThreatMgr* threatManager);
|
||||||
|
};
|
||||||
|
|
||||||
|
class BossTargetValue : public TargetValue, public Qualified
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BossTargetValue(PlayerbotAI* ai) : TargetValue(ai) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Unit* Calculate();
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -287,6 +287,8 @@ class ValueContext : public NamedObjectContext<UntypedValue>
|
|||||||
creators["has area debuff"] = &ValueContext::has_area_debuff;
|
creators["has area debuff"] = &ValueContext::has_area_debuff;
|
||||||
|
|
||||||
creators["main tank"] = &ValueContext::main_tank;
|
creators["main tank"] = &ValueContext::main_tank;
|
||||||
|
creators["find target"] = &ValueContext::find_target;
|
||||||
|
creators["boss target"] = &ValueContext::boss_target;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -479,6 +481,8 @@ class ValueContext : public NamedObjectContext<UntypedValue>
|
|||||||
static UntypedValue* has_area_debuff(PlayerbotAI* botAI) { return new HasAreaDebuffValue(botAI); }
|
static UntypedValue* has_area_debuff(PlayerbotAI* botAI) { return new HasAreaDebuffValue(botAI); }
|
||||||
|
|
||||||
static UntypedValue* main_tank(PlayerbotAI* ai) { return new PartyMemberMainTankValue(ai); }
|
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); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user