mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
- Added generic boss aura triggers and actions (#1242)
- Added Freya strategy - Added or updated aura resistance strategies for ulduar
This commit is contained in:
52
src/strategy/actions/BossAuraActions.cpp
Normal file
52
src/strategy/actions/BossAuraActions.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||||
|
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <HunterBuffStrategies.h>
|
||||||
|
#include <PaladinBuffStrategies.h>
|
||||||
|
#include <PlayerbotAI.h>
|
||||||
|
|
||||||
|
#include "BossAuraActions.h"
|
||||||
|
#include "BossAuraTriggers.h"
|
||||||
|
|
||||||
|
const std::string ADD_STRATEGY_CHAR = "+";
|
||||||
|
|
||||||
|
bool BossFireResistanceAction::isUseful()
|
||||||
|
{
|
||||||
|
BossFireResistanceTrigger bossFireResistanceTrigger(botAI, bossName);
|
||||||
|
return bossFireResistanceTrigger.IsActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BossFireResistanceAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
PaladinFireResistanceStrategy paladinFireResistanceStrategy(botAI);
|
||||||
|
botAI->ChangeStrategy(ADD_STRATEGY_CHAR + paladinFireResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BossFrostResistanceAction::isUseful()
|
||||||
|
{
|
||||||
|
BossFrostResistanceTrigger bossFrostResistanceTrigger(botAI, bossName);
|
||||||
|
return bossFrostResistanceTrigger.IsActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BossFrostResistanceAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
PaladinFrostResistanceStrategy paladinFrostResistanceStrategy(botAI);
|
||||||
|
botAI->ChangeStrategy(ADD_STRATEGY_CHAR + paladinFrostResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BossNatureResistanceAction::isUseful()
|
||||||
|
{
|
||||||
|
BossNatureResistanceTrigger bossNatureResistanceTrigger(botAI, bossName);
|
||||||
|
return bossNatureResistanceTrigger.IsActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BossNatureResistanceAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
HunterNatureResistanceStrategy hunterNatureResistanceStrategy(botAI);
|
||||||
|
botAI->ChangeStrategy(ADD_STRATEGY_CHAR + hunterNatureResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
57
src/strategy/actions/BossAuraActions.h
Normal file
57
src/strategy/actions/BossAuraActions.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||||
|
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PLAYERBOT_BOSSAURAACTION_H
|
||||||
|
#define _PLAYERBOT_BOSSAURAACTION_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Action.h"
|
||||||
|
|
||||||
|
class PlayerbotAI;
|
||||||
|
|
||||||
|
class BossFireResistanceAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BossFireResistanceAction(PlayerbotAI* botAI, std::string const bossName)
|
||||||
|
: Action(botAI, bossName + " fire resistance action"), bossName(bossName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
bool isUseful() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string bossName;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BossFrostResistanceAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BossFrostResistanceAction(PlayerbotAI* botAI, std::string const bossName)
|
||||||
|
: Action(botAI, bossName + " frost resistance action"), bossName(bossName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
bool isUseful() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string bossName;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BossNatureResistanceAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BossNatureResistanceAction(PlayerbotAI* botAI, std::string const bossName)
|
||||||
|
: Action(botAI, bossName + " nature resistance action"), bossName(bossName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
bool isUseful() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string bossName;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "Action.h"
|
#include "Action.h"
|
||||||
#include "NamedObjectContext.h"
|
#include "NamedObjectContext.h"
|
||||||
#include "RaidUlduarActions.h"
|
#include "RaidUlduarActions.h"
|
||||||
|
#include "BossAuraActions.h"
|
||||||
|
|
||||||
class RaidUlduarActionContext : public NamedObjectContext<Action>
|
class RaidUlduarActionContext : public NamedObjectContext<Action>
|
||||||
{
|
{
|
||||||
@@ -36,7 +37,12 @@ public:
|
|||||||
creators["hodir biting cold jump"] = &RaidUlduarActionContext::hodir_biting_cold_jump;
|
creators["hodir biting cold jump"] = &RaidUlduarActionContext::hodir_biting_cold_jump;
|
||||||
creators["hodir frost resistance action"] = &RaidUlduarActionContext::hodir_frost_resistance_action;
|
creators["hodir frost resistance action"] = &RaidUlduarActionContext::hodir_frost_resistance_action;
|
||||||
creators["freya move away nature bomb"] = &RaidUlduarActionContext::freya_move_away_nature_bomb;
|
creators["freya move away nature bomb"] = &RaidUlduarActionContext::freya_move_away_nature_bomb;
|
||||||
creators["freya mark eonars gift"] = &RaidUlduarActionContext::freya_mark_eonars_gift;
|
creators["freya fire resistance action"] = &RaidUlduarActionContext::freya_fire_resistance_action;
|
||||||
|
creators["freya nature resistance action"] = &RaidUlduarActionContext::freya_nature_resistance_action;
|
||||||
|
creators["freya mark dps target action"] = &RaidUlduarActionContext::freya_mark_dps_target_action;
|
||||||
|
creators["freya move to healing spore action"] = &RaidUlduarActionContext::freya_move_to_healing_spore_action;
|
||||||
|
creators["thorim nature resistance action"] = &RaidUlduarActionContext::thorim_nature_resistance_action;
|
||||||
|
creators["mimiron fire resistance action"] = &RaidUlduarActionContext::mimiron_fire_resistance_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -49,19 +55,24 @@ private:
|
|||||||
static Action* razorscale_grounded(PlayerbotAI* ai) { return new RazorscaleGroundedAction(ai); }
|
static Action* razorscale_grounded(PlayerbotAI* ai) { return new RazorscaleGroundedAction(ai); }
|
||||||
static Action* razorscale_harpoon_action(PlayerbotAI* ai) { return new RazorscaleHarpoonAction(ai); }
|
static Action* razorscale_harpoon_action(PlayerbotAI* ai) { return new RazorscaleHarpoonAction(ai); }
|
||||||
static Action* razorscale_fuse_armor_action(PlayerbotAI* ai) { return new RazorscaleFuseArmorAction(ai); }
|
static Action* razorscale_fuse_armor_action(PlayerbotAI* ai) { return new RazorscaleFuseArmorAction(ai); }
|
||||||
static Action* razorscale_fire_resistance_action(PlayerbotAI* ai) { return new RazorscaleFireResistanceAction(ai); }
|
static Action* razorscale_fire_resistance_action(PlayerbotAI* ai) { return new BossFireResistanceAction(ai, "razorscale"); }
|
||||||
static Action* ignis_fire_resistance_action(PlayerbotAI* ai) { return new IgnisFireResistanceAction(ai); }
|
static Action* ignis_fire_resistance_action(PlayerbotAI* ai) { return new BossFireResistanceAction(ai, "ignis the furnace master"); }
|
||||||
static Action* iron_assembly_lightning_tendrils_action(PlayerbotAI* ai) { return new IronAssemblyLightningTendrilsAction(ai); }
|
static Action* iron_assembly_lightning_tendrils_action(PlayerbotAI* ai) { return new IronAssemblyLightningTendrilsAction(ai); }
|
||||||
static Action* iron_assembly_overload_action(PlayerbotAI* ai) { return new IronAssemblyOverloadAction(ai); }
|
static Action* iron_assembly_overload_action(PlayerbotAI* ai) { return new IronAssemblyOverloadAction(ai); }
|
||||||
static Action* kologarn_mark_dps_target_action(PlayerbotAI* ai) { return new KologarnMarkDpsTargetAction(ai); }
|
static Action* kologarn_mark_dps_target_action(PlayerbotAI* ai) { return new KologarnMarkDpsTargetAction(ai); }
|
||||||
static Action* kologarn_fall_from_floor_action(PlayerbotAI* ai) { return new KologarnFallFromFloorAction(ai); }
|
static Action* kologarn_fall_from_floor_action(PlayerbotAI* ai) { return new KologarnFallFromFloorAction(ai); }
|
||||||
static Action* kologarn_nature_resistance_action(PlayerbotAI* ai) { return new KologarnNatureResistanceAction(ai); }
|
static Action* kologarn_nature_resistance_action(PlayerbotAI* ai) { return new BossNatureResistanceAction(ai, "kologarn"); }
|
||||||
static Action* kologarn_rubble_slowdown_action(PlayerbotAI* ai) { return new KologarnRubbleSlowdownAction(ai); }
|
static Action* kologarn_rubble_slowdown_action(PlayerbotAI* ai) { return new KologarnRubbleSlowdownAction(ai); }
|
||||||
static Action* hodir_move_snowpacked_icicle(PlayerbotAI* ai) { return new HodirMoveSnowpackedIcicleAction(ai); }
|
static Action* hodir_move_snowpacked_icicle(PlayerbotAI* ai) { return new HodirMoveSnowpackedIcicleAction(ai); }
|
||||||
static Action* hodir_biting_cold_jump(PlayerbotAI* ai) { return new HodirBitingColdJumpAction(ai); }
|
static Action* hodir_biting_cold_jump(PlayerbotAI* ai) { return new HodirBitingColdJumpAction(ai); }
|
||||||
static Action* hodir_frost_resistance_action(PlayerbotAI* ai) { return new HodirFrostResistanceAction(ai); }
|
static Action* hodir_frost_resistance_action(PlayerbotAI* ai) { return new BossFrostResistanceAction(ai, "hodir"); }
|
||||||
static Action* freya_move_away_nature_bomb(PlayerbotAI* ai) { return new FreyaMoveAwayNatureBombAction(ai); }
|
static Action* freya_move_away_nature_bomb(PlayerbotAI* ai) { return new FreyaMoveAwayNatureBombAction(ai); }
|
||||||
static Action* freya_mark_eonars_gift(PlayerbotAI* ai) { return new FreyaMarkEonarsGiftAction(ai); }
|
static Action* freya_fire_resistance_action(PlayerbotAI* ai) { return new BossFireResistanceAction(ai, "freya"); }
|
||||||
|
static Action* freya_nature_resistance_action(PlayerbotAI* ai) { return new BossNatureResistanceAction(ai, "freya"); }
|
||||||
|
static Action* freya_mark_dps_target_action(PlayerbotAI* ai) { return new FreyaMarkDpsTargetAction(ai); }
|
||||||
|
static Action* freya_move_to_healing_spore_action(PlayerbotAI* ai) { return new FreyaMoveToHealingSporeAction(ai); }
|
||||||
|
static Action* thorim_nature_resistance_action(PlayerbotAI* ai) { return new BossNatureResistanceAction(ai, "thorim"); }
|
||||||
|
static Action* mimiron_fire_resistance_action(PlayerbotAI* ai) { return new BossFireResistanceAction(ai, "mimiron"); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,8 +24,6 @@
|
|||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
#include "Vehicle.h"
|
#include "Vehicle.h"
|
||||||
#include <HunterBuffStrategies.h>
|
|
||||||
#include <PaladinBuffStrategies.h>
|
|
||||||
|
|
||||||
const std::vector<uint32> availableVehicles = {NPC_VEHICLE_CHOPPER, NPC_SALVAGED_DEMOLISHER,
|
const std::vector<uint32> availableVehicles = {NPC_VEHICLE_CHOPPER, NPC_SALVAGED_DEMOLISHER,
|
||||||
NPC_SALVAGED_DEMOLISHER_TURRET, NPC_SALVAGED_SIEGE_ENGINE,
|
NPC_SALVAGED_DEMOLISHER_TURRET, NPC_SALVAGED_SIEGE_ENGINE,
|
||||||
@@ -1168,32 +1166,6 @@ bool RazorscaleFuseArmorAction::Execute(Event event)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RazorscaleFireResistanceAction::isUseful()
|
|
||||||
{
|
|
||||||
RazorscaleFireResistanceTrigger razorscaleFireResistanceTrigger(botAI);
|
|
||||||
return razorscaleFireResistanceTrigger.IsActive();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RazorscaleFireResistanceAction::Execute(Event event)
|
|
||||||
{
|
|
||||||
PaladinFireResistanceStrategy paladinFireResistanceStrategy(botAI);
|
|
||||||
botAI->ChangeStrategy(std::string("+") + paladinFireResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IgnisFireResistanceAction::isUseful()
|
|
||||||
{
|
|
||||||
IgnisFireResistanceTrigger ignisFireResistanceTrigger(botAI);
|
|
||||||
return ignisFireResistanceTrigger.IsActive();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IgnisFireResistanceAction::Execute(Event event)
|
|
||||||
{
|
|
||||||
PaladinFireResistanceStrategy paladinFireResistanceStrategy(botAI);
|
|
||||||
botAI->ChangeStrategy(std::string("+") + paladinFireResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IronAssemblyLightningTendrilsAction::isUseful()
|
bool IronAssemblyLightningTendrilsAction::isUseful()
|
||||||
{
|
{
|
||||||
IronAssemblyLightningTendrilsTrigger ironAssemblyLightningTendrilsTrigger(botAI);
|
IronAssemblyLightningTendrilsTrigger ironAssemblyLightningTendrilsTrigger(botAI);
|
||||||
@@ -1377,19 +1349,6 @@ bool KologarnFallFromFloorAction::isUseful()
|
|||||||
return kologarnFallFromFloorTrigger.IsActive();
|
return kologarnFallFromFloorTrigger.IsActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KologarnNatureResistanceAction::Execute(Event event)
|
|
||||||
{
|
|
||||||
HunterNatureResistanceStrategy hunterNatureResistanceStrategy(botAI);
|
|
||||||
botAI->ChangeStrategy(std::string("+") + hunterNatureResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KologarnNatureResistanceAction::isUseful()
|
|
||||||
{
|
|
||||||
KologarnNatureResistanceTrigger kologarnNatureResistanceTrigger(botAI);
|
|
||||||
return kologarnNatureResistanceTrigger.IsActive();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KologarnRubbleSlowdownAction::Execute(Event event)
|
bool KologarnRubbleSlowdownAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
Group* group = bot->GetGroup();
|
Group* group = bot->GetGroup();
|
||||||
@@ -1478,19 +1437,6 @@ bool HodirBitingColdJumpAction::Execute(Event event)
|
|||||||
// return true;
|
// return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HodirFrostResistanceAction::isUseful()
|
|
||||||
{
|
|
||||||
HodirFrostResistanceTrigger hodirFrostResistanceTrigger(botAI);
|
|
||||||
return hodirFrostResistanceTrigger.IsActive();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HodirFrostResistanceAction::Execute(Event event)
|
|
||||||
{
|
|
||||||
PaladinFrostResistanceStrategy paladinFrostResistanceStrategy(botAI);
|
|
||||||
botAI->ChangeStrategy(std::string("+") + paladinFrostResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FreyaMoveAwayNatureBombAction::isUseful()
|
bool FreyaMoveAwayNatureBombAction::isUseful()
|
||||||
{
|
{
|
||||||
// Check boss and it is alive
|
// Check boss and it is alive
|
||||||
@@ -1517,79 +1463,118 @@ bool FreyaMoveAwayNatureBombAction::Execute(Event event)
|
|||||||
return FleePosition(target->GetPosition(), 13.0f);
|
return FleePosition(target->GetPosition(), 13.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FreyaMarkEonarsGiftAction::isUseful()
|
bool FreyaMarkDpsTargetAction::isUseful()
|
||||||
{
|
{
|
||||||
// Only tank bot can mark target
|
FreyaMarkDpsTargetTrigger freyaMarkDpsTargetTrigger(botAI);
|
||||||
if (!botAI->IsTank(bot))
|
return freyaMarkDpsTargetTrigger.IsActive();
|
||||||
{
|
}
|
||||||
|
|
||||||
|
bool FreyaMarkDpsTargetAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "freya");
|
||||||
|
if (!boss || !boss->IsAlive())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// Check Eonar's gift and it is alive
|
Unit* targetToMark = nullptr;
|
||||||
|
|
||||||
|
// Check which adds is up
|
||||||
|
Unit* eonarsGift = nullptr;
|
||||||
|
Unit* ancientConservator = nullptr;
|
||||||
|
Unit* snaplasher = nullptr;
|
||||||
|
Unit* ancientWaterSpirit = nullptr;
|
||||||
|
Unit* stormLasher = nullptr;
|
||||||
|
Unit* firstDetonatingLasher = nullptr;
|
||||||
|
|
||||||
// Target is not findable from threat table using AI_VALUE2(),
|
|
||||||
// therefore need to search manually for the unit id
|
|
||||||
GuidVector targets = AI_VALUE(GuidVector, "possible targets");
|
GuidVector targets = AI_VALUE(GuidVector, "possible targets");
|
||||||
Unit* target = nullptr;
|
Unit* target = nullptr;
|
||||||
for (auto i = targets.begin(); i != targets.end(); ++i)
|
for (auto i = targets.begin(); i != targets.end(); ++i)
|
||||||
{
|
{
|
||||||
target = botAI->GetUnit(*i);
|
target = botAI->GetUnit(*i);
|
||||||
if (!target)
|
if (!target || !target->IsAlive())
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
uint32 creatureId = target->GetEntry();
|
if (target->GetEntry() == NPC_EONARS_GIFT)
|
||||||
if (creatureId == NPC_EONARS_GIFT && target->IsAlive())
|
|
||||||
{
|
{
|
||||||
break;
|
eonarsGift = target;
|
||||||
|
}
|
||||||
|
else if (target->GetEntry() == NPC_ANCIENT_CONSERVATOR)
|
||||||
|
{
|
||||||
|
ancientConservator = target;
|
||||||
|
}
|
||||||
|
else if (target->GetEntry() == NPC_SNAPLASHER)
|
||||||
|
{
|
||||||
|
snaplasher = target;
|
||||||
|
}
|
||||||
|
else if (target->GetEntry() == NPC_ANCIENT_WATER_SPIRIT)
|
||||||
|
{
|
||||||
|
ancientWaterSpirit = target;
|
||||||
|
}
|
||||||
|
else if (target->GetEntry() == NPC_STORM_LASHER)
|
||||||
|
{
|
||||||
|
stormLasher = target;
|
||||||
|
}
|
||||||
|
else if (target->GetEntry() == NPC_DETONATING_LASHER && !firstDetonatingLasher)
|
||||||
|
{
|
||||||
|
firstDetonatingLasher = target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if Eonar's Gift is already set as the skull marker
|
// Check that eonars gift is need to be mark
|
||||||
Group* group = bot->GetGroup();
|
if (eonarsGift)
|
||||||
if (!group)
|
|
||||||
{
|
{
|
||||||
return false;
|
targetToMark = eonarsGift;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8 skullIndex = 7;
|
// Check that ancient conservator is need to be mark
|
||||||
ObjectGuid currentSkullTarget = group->GetTargetIcon(skullIndex);
|
if (ancientConservator && !targetToMark)
|
||||||
if (!target || currentSkullTarget == target->GetGUID())
|
|
||||||
{
|
{
|
||||||
return false; // Skull marker is already correctly set or no Eonar's Gift found
|
targetToMark = ancientConservator;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
// Check that trio of adds is need to be mark
|
||||||
}
|
if ((snaplasher || ancientWaterSpirit || stormLasher) && !targetToMark)
|
||||||
|
{
|
||||||
|
Unit* highestHealthUnit = nullptr;
|
||||||
|
uint32 highestHealth = 0;
|
||||||
|
|
||||||
|
if (snaplasher && snaplasher->GetHealth() > highestHealth)
|
||||||
|
{
|
||||||
|
highestHealth = snaplasher->GetHealth();
|
||||||
|
highestHealthUnit = snaplasher;
|
||||||
|
}
|
||||||
|
if (ancientWaterSpirit && ancientWaterSpirit->GetHealth() > highestHealth)
|
||||||
|
{
|
||||||
|
highestHealth = ancientWaterSpirit->GetHealth();
|
||||||
|
highestHealthUnit = ancientWaterSpirit;
|
||||||
|
}
|
||||||
|
if (stormLasher && stormLasher->GetHealth() > highestHealth)
|
||||||
|
{
|
||||||
|
highestHealthUnit = stormLasher;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the highest health unit is not already marked, mark it
|
||||||
|
if (highestHealthUnit)
|
||||||
|
{
|
||||||
|
targetToMark = highestHealthUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that detonating lasher is need to be mark
|
||||||
|
if (firstDetonatingLasher && !targetToMark)
|
||||||
|
{
|
||||||
|
targetToMark = firstDetonatingLasher;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!targetToMark)
|
||||||
|
{
|
||||||
|
return false; // No target to mark
|
||||||
|
}
|
||||||
|
|
||||||
bool FreyaMarkEonarsGiftAction::Execute(Event event)
|
|
||||||
{
|
|
||||||
bool isMainTank = botAI->IsMainTank(bot);
|
bool isMainTank = botAI->IsMainTank(bot);
|
||||||
Unit* mainTankUnit = AI_VALUE(Unit*, "main tank");
|
Unit* mainTankUnit = AI_VALUE(Unit*, "main tank");
|
||||||
Player* mainTank = mainTankUnit ? mainTankUnit->ToPlayer() : nullptr;
|
Player* mainTank = mainTankUnit ? mainTankUnit->ToPlayer() : nullptr;
|
||||||
|
int8 squareIndex = 5; // Square
|
||||||
GuidVector targets = AI_VALUE(GuidVector, "possible targets");
|
int8 skullIndex = 7; // Skull
|
||||||
Unit* target = nullptr;
|
|
||||||
for (auto i = targets.begin(); i != targets.end(); ++i)
|
|
||||||
{
|
|
||||||
Unit* unit = botAI->GetUnit(*i);
|
|
||||||
if (!unit)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 creatureId = unit->GetEntry();
|
|
||||||
if (creatureId == NPC_EONARS_GIFT && unit->IsAlive())
|
|
||||||
{
|
|
||||||
target = unit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mainTank && !GET_PLAYERBOT_AI(mainTank)) // Main tank is a real player
|
if (mainTank && !GET_PLAYERBOT_AI(mainTank)) // Main tank is a real player
|
||||||
{
|
{
|
||||||
@@ -1599,19 +1584,18 @@ bool FreyaMarkEonarsGiftAction::Execute(Event event)
|
|||||||
if (botAI->IsAssistTankOfIndex(bot, i) && GET_PLAYERBOT_AI(bot)) // Bot is a valid tank
|
if (botAI->IsAssistTankOfIndex(bot, i) && GET_PLAYERBOT_AI(bot)) // Bot is a valid tank
|
||||||
{
|
{
|
||||||
Group* group = bot->GetGroup();
|
Group* group = bot->GetGroup();
|
||||||
if (group && target)
|
if (group)
|
||||||
{
|
{
|
||||||
int8 skullIndex = 7; // Skull
|
|
||||||
ObjectGuid currentSkullTarget = group->GetTargetIcon(skullIndex);
|
ObjectGuid currentSkullTarget = group->GetTargetIcon(skullIndex);
|
||||||
|
|
||||||
// If there's no skull set yet, or the skull is on a different target, set the Eonar's Gift
|
if (!currentSkullTarget || (targetToMark->GetGUID() != currentSkullTarget))
|
||||||
if (!currentSkullTarget || (target->GetGUID() != currentSkullTarget))
|
|
||||||
{
|
{
|
||||||
group->SetTargetIcon(skullIndex, bot->GetGUID(), target->GetGUID());
|
group->SetTargetIcon(skullIndex, bot->GetGUID(), targetToMark->GetGUID());
|
||||||
|
group->SetTargetIcon(squareIndex, bot->GetGUID(), boss->GetGUID());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break; // Stop after finding the first valid bot tank
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1620,13 +1604,13 @@ bool FreyaMarkEonarsGiftAction::Execute(Event event)
|
|||||||
Group* group = bot->GetGroup();
|
Group* group = bot->GetGroup();
|
||||||
if (group)
|
if (group)
|
||||||
{
|
{
|
||||||
int8 skullIndex = 7; // Skull
|
|
||||||
ObjectGuid currentSkullTarget = group->GetTargetIcon(skullIndex);
|
ObjectGuid currentSkullTarget = group->GetTargetIcon(skullIndex);
|
||||||
|
|
||||||
// If there's no skull set yet, or the skull is on a different target, set the Eonar's Gift
|
if (!currentSkullTarget || (targetToMark->GetGUID() != currentSkullTarget))
|
||||||
if (!currentSkullTarget || (target->GetGUID() != currentSkullTarget))
|
|
||||||
{
|
{
|
||||||
group->SetTargetIcon(skullIndex, bot->GetGUID(), target->GetGUID());
|
group->SetTargetIcon(skullIndex, bot->GetGUID(), targetToMark->GetGUID());
|
||||||
|
group->SetTargetIcon(squareIndex, bot->GetGUID(), boss->GetGUID());
|
||||||
|
botAI->GetAiObjectContext()->GetValue<std::string>("rti")->Set("square");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1634,3 +1618,40 @@ bool FreyaMarkEonarsGiftAction::Execute(Event event)
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FreyaMoveToHealingSporeAction::isUseful()
|
||||||
|
{
|
||||||
|
FreyaMoveToHealingSporeTrigger freyaMoveToHealingSporeTrigger(botAI);
|
||||||
|
return freyaMoveToHealingSporeTrigger.IsActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FreyaMoveToHealingSporeAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
GuidVector targets = AI_VALUE(GuidVector, "nearest npcs");
|
||||||
|
Creature* nearestSpore = nullptr;
|
||||||
|
float nearestDistance = std::numeric_limits<float>::max();
|
||||||
|
|
||||||
|
for (auto guid : targets)
|
||||||
|
{
|
||||||
|
Unit* unit = botAI->GetUnit(guid);
|
||||||
|
if (!unit)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check if this unit is a healthy spore and alive
|
||||||
|
if (unit->GetEntry() != NPC_HEALTHY_SPORE || !unit->IsAlive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float distance = bot->GetDistance2d(unit);
|
||||||
|
if (distance < nearestDistance)
|
||||||
|
{
|
||||||
|
nearestDistance = distance;
|
||||||
|
nearestSpore = static_cast<Creature*>(unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nearestSpore)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return MoveTo(nearestSpore->GetMapId(), nearestSpore->GetPositionX(), nearestSpore->GetPositionY(),
|
||||||
|
nearestSpore->GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
|
||||||
|
}
|
||||||
|
|||||||
@@ -106,25 +106,6 @@ public:
|
|||||||
bool isUseful() override;
|
bool isUseful() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RazorscaleFireResistanceAction : public Action
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RazorscaleFireResistanceAction(PlayerbotAI* botAI) : Action(botAI, "razorscale fire resistance action") {}
|
|
||||||
bool Execute(Event event) override;
|
|
||||||
bool isUseful() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Ignis
|
|
||||||
//
|
|
||||||
class IgnisFireResistanceAction : public Action
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IgnisFireResistanceAction(PlayerbotAI* botAI) : Action(botAI, "ignis fire resistance action") {}
|
|
||||||
bool Execute(Event event) override;
|
|
||||||
bool isUseful() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class HodirMoveSnowpackedIcicleAction : public MovementAction
|
class HodirMoveSnowpackedIcicleAction : public MovementAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -133,14 +114,6 @@ public:
|
|||||||
bool isUseful() override;
|
bool isUseful() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HodirFrostResistanceAction : public Action
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
HodirFrostResistanceAction(PlayerbotAI* botAI) : Action(botAI, "hodir frost resistance action") {}
|
|
||||||
bool Execute(Event event) override;
|
|
||||||
bool isUseful() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IronAssemblyLightningTendrilsAction : public MovementAction
|
class IronAssemblyLightningTendrilsAction : public MovementAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -173,14 +146,6 @@ public:
|
|||||||
bool isUseful() override;
|
bool isUseful() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class KologarnNatureResistanceAction : public Action
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
KologarnNatureResistanceAction(PlayerbotAI* botAI) : Action(botAI, "kologarn nature resistance action") {}
|
|
||||||
bool Execute(Event event) override;
|
|
||||||
bool isUseful() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class KologarnRubbleSlowdownAction : public Action
|
class KologarnRubbleSlowdownAction : public Action
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -203,10 +168,19 @@ public:
|
|||||||
bool isUseful() override;
|
bool isUseful() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FreyaMarkEonarsGiftAction : public MovementAction
|
class FreyaMarkDpsTargetAction : public MovementAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FreyaMarkEonarsGiftAction(PlayerbotAI* botAI) : MovementAction(botAI, "freya mark eonars gift") {}
|
FreyaMarkDpsTargetAction(PlayerbotAI* botAI) : MovementAction(botAI, "freya mark dps target action") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
bool isUseful() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FreyaMoveToHealingSporeAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FreyaMoveToHealingSporeAction(PlayerbotAI* ai) : MovementAction(ai, "freya move to healing spore action") {}
|
||||||
|
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
bool isUseful() override;
|
bool isUseful() override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -105,13 +105,39 @@ void RaidUlduarStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
//
|
//
|
||||||
// Freya
|
// Freya
|
||||||
//
|
//
|
||||||
triggers.push_back(new TriggerNode(
|
|
||||||
"freya tank near eonars gift",
|
|
||||||
NextAction::array(0, new NextAction("freya mark eonars gift", ACTION_RAID + 1), nullptr)));
|
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"freya near nature bomb",
|
"freya near nature bomb",
|
||||||
NextAction::array(0, new NextAction("freya move away nature bomb", ACTION_RAID), nullptr)));
|
NextAction::array(0, new NextAction("freya move away nature bomb", ACTION_RAID), nullptr)));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode(
|
||||||
|
"freya nature resistance trigger",
|
||||||
|
NextAction::array(0, new NextAction("freya nature resistance action", ACTION_RAID), nullptr)));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode(
|
||||||
|
"freya fire resistance trigger",
|
||||||
|
NextAction::array(0, new NextAction("freya fire resistance action", ACTION_RAID), nullptr)));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode(
|
||||||
|
"freya mark dps target trigger",
|
||||||
|
NextAction::array(0, new NextAction("freya mark dps target action", ACTION_RAID), nullptr)));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode(
|
||||||
|
"freya move to healing spore trigger",
|
||||||
|
NextAction::array(0, new NextAction("freya move to healing spore action", ACTION_RAID), nullptr)));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Thorim
|
||||||
|
//
|
||||||
|
triggers.push_back(new TriggerNode(
|
||||||
|
"thorim nature resistance trigger",
|
||||||
|
NextAction::array(0, new NextAction("thorim nature resistance action", ACTION_RAID), nullptr)));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mimiron
|
||||||
|
//
|
||||||
|
triggers.push_back(new TriggerNode(
|
||||||
|
"mimiron fire resistance trigger",
|
||||||
|
NextAction::array(0, new NextAction("mimiron fire resistance action", ACTION_RAID), nullptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RaidUlduarStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
|
void RaidUlduarStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "AiObjectContext.h"
|
#include "AiObjectContext.h"
|
||||||
#include "NamedObjectContext.h"
|
#include "NamedObjectContext.h"
|
||||||
#include "RaidUlduarTriggers.h"
|
#include "RaidUlduarTriggers.h"
|
||||||
|
#include "BossAuraTriggers.h"
|
||||||
|
|
||||||
class RaidUlduarTriggerContext : public NamedObjectContext<Trigger>
|
class RaidUlduarTriggerContext : public NamedObjectContext<Trigger>
|
||||||
{
|
{
|
||||||
@@ -36,7 +37,12 @@ public:
|
|||||||
creators["hodir near snowpacked icicle"] = &RaidUlduarTriggerContext::hodir_near_snowpacked_icicle;
|
creators["hodir near snowpacked icicle"] = &RaidUlduarTriggerContext::hodir_near_snowpacked_icicle;
|
||||||
creators["hodir frost resistance trigger"] = &RaidUlduarTriggerContext::hodir_frost_resistance_trigger;
|
creators["hodir frost resistance trigger"] = &RaidUlduarTriggerContext::hodir_frost_resistance_trigger;
|
||||||
creators["freya near nature bomb"] = &RaidUlduarTriggerContext::freya_near_nature_bomb;
|
creators["freya near nature bomb"] = &RaidUlduarTriggerContext::freya_near_nature_bomb;
|
||||||
creators["freya tank near eonars gift"] = &RaidUlduarTriggerContext::freya_tank_near_eonars_gift;
|
creators["freya fire resistance trigger"] = &RaidUlduarTriggerContext::freya_fire_resistance_trigger;
|
||||||
|
creators["freya nature resistance trigger"] = &RaidUlduarTriggerContext::freya_nature_resistance_trigger;
|
||||||
|
creators["freya mark dps target trigger"] = &RaidUlduarTriggerContext::freya_mark_dps_target_trigger;
|
||||||
|
creators["freya move to healing spore trigger"] = &RaidUlduarTriggerContext::freya_move_to_healing_spore_trigger;
|
||||||
|
creators["thorim nature resistance trigger"] = &RaidUlduarTriggerContext::thorim_nature_resistance_trigger;
|
||||||
|
creators["mimiron fire resistance trigger"] = &RaidUlduarTriggerContext::mimiron_fire_resistance_trigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -49,19 +55,24 @@ private:
|
|||||||
static Trigger* razorscale_grounded(PlayerbotAI* ai) { return new RazorscaleGroundedTrigger(ai); }
|
static Trigger* razorscale_grounded(PlayerbotAI* ai) { return new RazorscaleGroundedTrigger(ai); }
|
||||||
static Trigger* razorscale_harpoon_trigger(PlayerbotAI* ai) { return new RazorscaleHarpoonAvailableTrigger(ai); }
|
static Trigger* razorscale_harpoon_trigger(PlayerbotAI* ai) { return new RazorscaleHarpoonAvailableTrigger(ai); }
|
||||||
static Trigger* razorscale_fuse_armor_trigger(PlayerbotAI* ai) { return new RazorscaleFuseArmorTrigger(ai); }
|
static Trigger* razorscale_fuse_armor_trigger(PlayerbotAI* ai) { return new RazorscaleFuseArmorTrigger(ai); }
|
||||||
static Trigger* razorscale_fire_resistance_trigger(PlayerbotAI* ai) { return new RazorscaleFireResistanceTrigger(ai); }
|
static Trigger* razorscale_fire_resistance_trigger(PlayerbotAI* ai) { return new BossFireResistanceTrigger(ai, "razorscale"); }
|
||||||
static Trigger* ignis_fire_resistance_trigger(PlayerbotAI* ai) { return new IgnisFireResistanceTrigger(ai); }
|
static Trigger* ignis_fire_resistance_trigger(PlayerbotAI* ai) { return new BossFireResistanceTrigger(ai, "ignis the furnace master"); }
|
||||||
static Trigger* iron_assembly_lightning_tendrils_trigger(PlayerbotAI* ai) { return new IronAssemblyLightningTendrilsTrigger(ai); }
|
static Trigger* iron_assembly_lightning_tendrils_trigger(PlayerbotAI* ai) { return new IronAssemblyLightningTendrilsTrigger(ai); }
|
||||||
static Trigger* iron_assembly_overload_trigger(PlayerbotAI* ai) { return new IronAssemblyOverloadTrigger(ai); }
|
static Trigger* iron_assembly_overload_trigger(PlayerbotAI* ai) { return new IronAssemblyOverloadTrigger(ai); }
|
||||||
static Trigger* kologarn_mark_dps_target_trigger(PlayerbotAI* ai) { return new KologarnMarkDpsTargetTrigger(ai); }
|
static Trigger* kologarn_mark_dps_target_trigger(PlayerbotAI* ai) { return new KologarnMarkDpsTargetTrigger(ai); }
|
||||||
static Trigger* kologarn_fall_from_floor_trigger(PlayerbotAI* ai) { return new KologarnFallFromFloorTrigger(ai); }
|
static Trigger* kologarn_fall_from_floor_trigger(PlayerbotAI* ai) { return new KologarnFallFromFloorTrigger(ai); }
|
||||||
static Trigger* kologarn_nature_resistance_trigger(PlayerbotAI* ai) { return new KologarnNatureResistanceTrigger(ai); }
|
static Trigger* kologarn_nature_resistance_trigger(PlayerbotAI* ai) { return new BossNatureResistanceTrigger(ai, "kologarn"); }
|
||||||
static Trigger* kologarn_rubble_slowdown_trigger(PlayerbotAI* ai) { return new KologarnRubbleSlowdownTrigger(ai); }
|
static Trigger* kologarn_rubble_slowdown_trigger(PlayerbotAI* ai) { return new KologarnRubbleSlowdownTrigger(ai); }
|
||||||
static Trigger* hodir_biting_cold(PlayerbotAI* ai) { return new HodirBitingColdTrigger(ai); }
|
static Trigger* hodir_biting_cold(PlayerbotAI* ai) { return new HodirBitingColdTrigger(ai); }
|
||||||
static Trigger* hodir_near_snowpacked_icicle(PlayerbotAI* ai) { return new HodirNearSnowpackedIcicleTrigger(ai); }
|
static Trigger* hodir_near_snowpacked_icicle(PlayerbotAI* ai) { return new HodirNearSnowpackedIcicleTrigger(ai); }
|
||||||
static Trigger* hodir_frost_resistance_trigger(PlayerbotAI* ai) { return new HodirFrostResistanceTrigger(ai); }
|
static Trigger* hodir_frost_resistance_trigger(PlayerbotAI* ai) { return new BossFrostResistanceTrigger(ai, "hodir"); }
|
||||||
static Trigger* freya_near_nature_bomb(PlayerbotAI* ai) { return new FreyaNearNatureBombTrigger(ai); }
|
static Trigger* freya_near_nature_bomb(PlayerbotAI* ai) { return new FreyaNearNatureBombTrigger(ai); }
|
||||||
static Trigger* freya_tank_near_eonars_gift(PlayerbotAI* ai) { return new FreyaTankNearEonarsGiftTrigger(ai); }
|
static Trigger* freya_fire_resistance_trigger(PlayerbotAI* ai) { return new BossFireResistanceTrigger(ai, "freya"); }
|
||||||
|
static Trigger* freya_nature_resistance_trigger(PlayerbotAI* ai) { return new BossNatureResistanceTrigger(ai, "freya"); }
|
||||||
|
static Trigger* freya_mark_dps_target_trigger(PlayerbotAI* ai) { return new FreyaMarkDpsTargetTrigger(ai); }
|
||||||
|
static Trigger* freya_move_to_healing_spore_trigger(PlayerbotAI* ai) { return new FreyaMoveToHealingSporeTrigger(ai); }
|
||||||
|
static Trigger* thorim_nature_resistance_trigger(PlayerbotAI* ai) { return new BossNatureResistanceTrigger(ai, "thorim"); }
|
||||||
|
static Trigger* mimiron_fire_resistance_trigger(PlayerbotAI* ai) { return new BossFireResistanceTrigger(ai, "mimiron"); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -11,8 +11,6 @@
|
|||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
#include "Trigger.h"
|
#include "Trigger.h"
|
||||||
#include "Vehicle.h"
|
#include "Vehicle.h"
|
||||||
#include <HunterBuffStrategies.h>
|
|
||||||
#include <PaladinBuffStrategies.h>
|
|
||||||
|
|
||||||
const std::vector<uint32> availableVehicles = {NPC_VEHICLE_CHOPPER, NPC_SALVAGED_DEMOLISHER,
|
const std::vector<uint32> availableVehicles = {NPC_VEHICLE_CHOPPER, NPC_SALVAGED_DEMOLISHER,
|
||||||
NPC_SALVAGED_DEMOLISHER_TURRET, NPC_SALVAGED_SIEGE_ENGINE,
|
NPC_SALVAGED_DEMOLISHER_TURRET, NPC_SALVAGED_SIEGE_ENGINE,
|
||||||
@@ -244,100 +242,6 @@ bool RazorscaleFuseArmorTrigger::IsActive()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RazorscaleFireResistanceTrigger::IsActive()
|
|
||||||
{
|
|
||||||
// Check boss and it is alive
|
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "razorscale");
|
|
||||||
if (!boss || !boss->IsAlive())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if bot is paladin
|
|
||||||
if (bot->getClass() != CLASS_PALADIN)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if bot have fire resistance aura
|
|
||||||
if (bot->HasAura(SPELL_FIRE_RESISTANCE_AURA))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if bot dont have already have fire resistance strategy
|
|
||||||
PaladinFireResistanceStrategy paladinFireResistanceStrategy(botAI);
|
|
||||||
if (botAI->HasStrategy(paladinFireResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check that the bot actually knows the spell
|
|
||||||
if (!bot->HasActiveSpell(SPELL_FIRE_RESISTANCE_AURA))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Get the group and ensure it's a raid group
|
|
||||||
Group* group = bot->GetGroup();
|
|
||||||
if (!group || !group->isRaidGroup())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Iterate through group members to find the first alive paladin
|
|
||||||
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
|
||||||
{
|
|
||||||
Player* member = gref->GetSource();
|
|
||||||
if (!member || !member->IsAlive())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Check if the member is a hunter
|
|
||||||
if (member->getClass() == CLASS_PALADIN)
|
|
||||||
{
|
|
||||||
// Return true only if the current bot is the first alive paladin
|
|
||||||
return member == bot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IgnisFireResistanceTrigger::IsActive()
|
|
||||||
{
|
|
||||||
// Check boss and it is alive
|
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "ignis the furnace master");
|
|
||||||
if (!boss || !boss->IsAlive())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if bot is paladin
|
|
||||||
if (bot->getClass() != CLASS_PALADIN)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if bot have fire resistance aura
|
|
||||||
if (bot->HasAura(SPELL_FIRE_RESISTANCE_AURA))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if bot dont have already have fire resistance strategy
|
|
||||||
PaladinFireResistanceStrategy paladinFireResistanceStrategy(botAI);
|
|
||||||
if (botAI->HasStrategy(paladinFireResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check that the bot actually knows the spell
|
|
||||||
if (!bot->HasActiveSpell(SPELL_FIRE_RESISTANCE_AURA))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Get the group and ensure it's a raid group
|
|
||||||
Group* group = bot->GetGroup();
|
|
||||||
if (!group || !group->isRaidGroup())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Iterate through group members to find the first alive paladin
|
|
||||||
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
|
||||||
{
|
|
||||||
Player* member = gref->GetSource();
|
|
||||||
if (!member || !member->IsAlive())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Check if the member is a hunter
|
|
||||||
if (member->getClass() == CLASS_PALADIN)
|
|
||||||
{
|
|
||||||
// Return true only if the current bot is the first alive paladin
|
|
||||||
return member == bot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IronAssemblyLightningTendrilsTrigger::IsActive()
|
bool IronAssemblyLightningTendrilsTrigger::IsActive()
|
||||||
{
|
{
|
||||||
// Check boss and it is alive
|
// Check boss and it is alive
|
||||||
@@ -451,57 +355,6 @@ bool KologarnFallFromFloorTrigger::IsActive()
|
|||||||
return bot->GetPositionZ() < ULDUAR_KOLOGARN_AXIS_Z_PATHING_ISSUE_DETECT;
|
return bot->GetPositionZ() < ULDUAR_KOLOGARN_AXIS_Z_PATHING_ISSUE_DETECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KologarnNatureResistanceTrigger::IsActive()
|
|
||||||
{
|
|
||||||
// Check boss and it is alive
|
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "kologarn");
|
|
||||||
if (!boss || !boss->IsAlive())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if bot is alive
|
|
||||||
if (!bot->IsAlive())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if bot is hunter
|
|
||||||
if (bot->getClass() != CLASS_HUNTER)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if bot have nature resistance aura
|
|
||||||
if (bot->HasAura(SPELL_ASPECT_OF_THE_WILD))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if bot dont have already setted nature resistance aura
|
|
||||||
HunterNatureResistanceStrategy hunterNatureResistanceStrategy(botAI);
|
|
||||||
if (botAI->HasStrategy(hunterNatureResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check that the bot actually knows Aspect of the Wild
|
|
||||||
if (!bot->HasActiveSpell(SPELL_ASPECT_OF_THE_WILD))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Get the group and ensure it's a raid group
|
|
||||||
Group* group = bot->GetGroup();
|
|
||||||
if (!group || !group->isRaidGroup())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Iterate through group members to find the first alive hunter
|
|
||||||
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
|
||||||
{
|
|
||||||
Player* member = gref->GetSource();
|
|
||||||
if (!member || !member->IsAlive())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Check if the member is a hunter
|
|
||||||
if (member->getClass() == CLASS_HUNTER)
|
|
||||||
{
|
|
||||||
// Return true only if the current bot is the first alive hunter
|
|
||||||
return member == bot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KologarnRubbleSlowdownTrigger::IsActive()
|
bool KologarnRubbleSlowdownTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "kologarn");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "kologarn");
|
||||||
@@ -579,53 +432,6 @@ bool HodirNearSnowpackedIcicleTrigger::IsActive()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HodirFrostResistanceTrigger::IsActive()
|
|
||||||
{
|
|
||||||
// Check boss and it is alive
|
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "hodir");
|
|
||||||
if (!boss || !boss->IsAlive())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if bot is paladin
|
|
||||||
if (bot->getClass() != CLASS_PALADIN)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if bot have frost resistance aura
|
|
||||||
if (bot->HasAura(SPELL_FROST_RESISTANCE_AURA))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if bot dont have already have frost resistance strategy
|
|
||||||
PaladinFrostResistanceStrategy paladinFrostResistanceStrategy(botAI);
|
|
||||||
if (botAI->HasStrategy(paladinFrostResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check that the bot actually knows the spell
|
|
||||||
if (!bot->HasActiveSpell(SPELL_FROST_RESISTANCE_AURA))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Get the group and ensure it's a raid group
|
|
||||||
Group* group = bot->GetGroup();
|
|
||||||
if (!group || !group->isRaidGroup())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Iterate through group members to find the first alive paladin
|
|
||||||
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
|
||||||
{
|
|
||||||
Player* member = gref->GetSource();
|
|
||||||
if (!member || !member->IsAlive())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Check if the member is a hunter
|
|
||||||
if (member->getClass() == CLASS_PALADIN)
|
|
||||||
{
|
|
||||||
// Return true only if the current bot is the first alive paladin
|
|
||||||
return member == bot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FreyaNearNatureBombTrigger::IsActive()
|
bool FreyaNearNatureBombTrigger::IsActive()
|
||||||
{
|
{
|
||||||
// Check boss and it is alive
|
// Check boss and it is alive
|
||||||
@@ -640,34 +446,185 @@ bool FreyaNearNatureBombTrigger::IsActive()
|
|||||||
return target != nullptr;
|
return target != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FreyaTankNearEonarsGiftTrigger::IsActive()
|
bool FreyaMarkDpsTargetTrigger::IsActive()
|
||||||
{
|
{
|
||||||
|
// Check boss and it is alive
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "freya");
|
||||||
|
if (!boss || !boss->IsAlive())
|
||||||
|
return false;
|
||||||
|
|
||||||
// Only tank bot can mark target
|
// Only tank bot can mark target
|
||||||
if (!botAI->IsTank(bot))
|
if (!botAI->IsTank(bot))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Get current raid dps target
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int8 skullIndex = 7;
|
||||||
|
ObjectGuid currentSkullTarget = group->GetTargetIcon(skullIndex);
|
||||||
|
Unit* currentSkullUnit = botAI->GetUnit(currentSkullTarget);
|
||||||
|
|
||||||
|
if (currentSkullUnit && !currentSkullUnit->IsAlive())
|
||||||
|
{
|
||||||
|
currentSkullUnit = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check Eonar's gift and it is alive
|
// Check which adds is up
|
||||||
|
Unit* eonarsGift = nullptr;
|
||||||
|
Unit* ancientConservator = nullptr;
|
||||||
|
Unit* snaplasher = nullptr;
|
||||||
|
Unit* ancientWaterSpirit = nullptr;
|
||||||
|
Unit* stormLasher = nullptr;
|
||||||
|
Unit* firstDetonatingLasher = nullptr;
|
||||||
|
|
||||||
// Target is not findable from threat table using AI_VALUE2(),
|
|
||||||
// therefore need to search manually for the unit id
|
|
||||||
GuidVector targets = AI_VALUE(GuidVector, "possible targets");
|
GuidVector targets = AI_VALUE(GuidVector, "possible targets");
|
||||||
|
Unit* target = nullptr;
|
||||||
for (auto i = targets.begin(); i != targets.end(); ++i)
|
for (auto i = targets.begin(); i != targets.end(); ++i)
|
||||||
{
|
{
|
||||||
Unit* unit = botAI->GetUnit(*i);
|
target = botAI->GetUnit(*i);
|
||||||
if (!unit)
|
if (!target || !target->IsAlive())
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (target->GetEntry() == NPC_EONARS_GIFT)
|
||||||
|
{
|
||||||
|
eonarsGift = target;
|
||||||
|
}
|
||||||
|
else if (target->GetEntry() == NPC_ANCIENT_CONSERVATOR)
|
||||||
|
{
|
||||||
|
ancientConservator = target;
|
||||||
|
}
|
||||||
|
else if (target->GetEntry() == NPC_SNAPLASHER)
|
||||||
|
{
|
||||||
|
snaplasher = target;
|
||||||
|
}
|
||||||
|
else if (target->GetEntry() == NPC_ANCIENT_WATER_SPIRIT)
|
||||||
|
{
|
||||||
|
ancientWaterSpirit = target;
|
||||||
|
}
|
||||||
|
else if (target->GetEntry() == NPC_STORM_LASHER)
|
||||||
|
{
|
||||||
|
stormLasher = target;
|
||||||
|
}
|
||||||
|
else if (target->GetEntry() == NPC_DETONATING_LASHER && !firstDetonatingLasher)
|
||||||
|
{
|
||||||
|
firstDetonatingLasher = target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that eonars gift is need to be mark
|
||||||
|
if (eonarsGift &&
|
||||||
|
(!currentSkullUnit || currentSkullUnit->GetEntry() != eonarsGift->GetEntry()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that ancient conservator is need to be mark
|
||||||
|
if (ancientConservator &&
|
||||||
|
(!currentSkullUnit || currentSkullUnit->GetEntry() != ancientConservator->GetEntry()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that trio of adds is need to be mark
|
||||||
|
if (snaplasher || ancientWaterSpirit || stormLasher)
|
||||||
|
{
|
||||||
|
Unit* highestHealthUnit = nullptr;
|
||||||
|
uint32 highestHealth = 0;
|
||||||
|
|
||||||
|
if (snaplasher && snaplasher->GetHealth() > highestHealth)
|
||||||
|
{
|
||||||
|
highestHealth = snaplasher->GetHealth();
|
||||||
|
highestHealthUnit = snaplasher;
|
||||||
|
}
|
||||||
|
if (ancientWaterSpirit && ancientWaterSpirit->GetHealth() > highestHealth)
|
||||||
|
{
|
||||||
|
highestHealth = ancientWaterSpirit->GetHealth();
|
||||||
|
highestHealthUnit = ancientWaterSpirit;
|
||||||
|
}
|
||||||
|
if (stormLasher && stormLasher->GetHealth() > highestHealth)
|
||||||
|
{
|
||||||
|
highestHealthUnit = stormLasher;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 creatureId = unit->GetEntry();
|
// If the highest health unit is not already marked, mark it
|
||||||
if (creatureId == NPC_EONARS_GIFT && unit->IsAlive())
|
if (highestHealthUnit &&
|
||||||
|
(!currentSkullUnit || currentSkullUnit->GetEntry() != highestHealthUnit->GetEntry()))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that detonating lasher is need to be mark
|
||||||
|
if (firstDetonatingLasher &&
|
||||||
|
(!currentSkullUnit || currentSkullUnit->GetEntry() != firstDetonatingLasher->GetEntry()))
|
||||||
|
{
|
||||||
|
Map* map = bot->GetMap();
|
||||||
|
if (!map || !map->IsRaid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32 healthThreshold = map->Is25ManRaid() ? 7200 : 4900; // Detonate maximum damage
|
||||||
|
|
||||||
|
// Check that detonate lasher dont kill raid members
|
||||||
|
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
||||||
|
{
|
||||||
|
Player* member = gref->GetSource();
|
||||||
|
if (!member || !member->IsAlive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (member->GetHealth() < healthThreshold)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FreyaMoveToHealingSporeTrigger::IsActive()
|
||||||
|
{
|
||||||
|
// Check for the Freya boss
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "freya");
|
||||||
|
if (!boss || !boss->IsAlive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!botAI->IsRanged(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Unit* conservatory = AI_VALUE2(Unit*, "find target", "ancient conservator");
|
||||||
|
if (!conservatory || !conservatory->IsAlive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
GuidVector targets = AI_VALUE(GuidVector, "nearest npcs");
|
||||||
|
float nearestDistance = std::numeric_limits<float>::max();
|
||||||
|
bool foundSpore = false;
|
||||||
|
|
||||||
|
// Iterate through all targets to find healthy spores
|
||||||
|
for (const ObjectGuid& guid : targets)
|
||||||
|
{
|
||||||
|
Unit* unit = botAI->GetUnit(guid);
|
||||||
|
if (!unit || !unit->IsAlive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check if the unit is a healthy spore
|
||||||
|
if (unit->GetEntry() == NPC_HEALTHY_SPORE)
|
||||||
|
{
|
||||||
|
foundSpore = true;
|
||||||
|
float distance = bot->GetDistance(unit);
|
||||||
|
if (distance < nearestDistance)
|
||||||
|
{
|
||||||
|
nearestDistance = distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no healthy spores are found, return false
|
||||||
|
if (!foundSpore)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If the nearest spore is farther than 6 yards, a move is required
|
||||||
|
return nearestDistance > 6.0f;
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,14 +34,17 @@ enum UlduarIDs
|
|||||||
SPELL_BITING_COLD_PLAYER_AURA = 62039,
|
SPELL_BITING_COLD_PLAYER_AURA = 62039,
|
||||||
|
|
||||||
// Freya
|
// Freya
|
||||||
|
NPC_SNAPLASHER = 32916,
|
||||||
|
NPC_STORM_LASHER = 32919,
|
||||||
|
NPC_DETONATING_LASHER = 32918,
|
||||||
|
NPC_ANCIENT_WATER_SPIRIT = 33202,
|
||||||
|
NPC_ANCIENT_CONSERVATOR = 33203,
|
||||||
|
NPC_HEALTHY_SPORE = 33215,
|
||||||
NPC_EONARS_GIFT = 33228,
|
NPC_EONARS_GIFT = 33228,
|
||||||
GOBJECT_NATURE_BOMB = 194902,
|
GOBJECT_NATURE_BOMB = 194902,
|
||||||
|
|
||||||
// Buffs
|
// Buffs
|
||||||
SPELL_FROST_TRAP = 13809,
|
SPELL_FROST_TRAP = 13809
|
||||||
SPELL_FROST_RESISTANCE_AURA = 48945,
|
|
||||||
SPELL_FIRE_RESISTANCE_AURA = 48947,
|
|
||||||
SPELL_ASPECT_OF_THE_WILD = 49071,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const float ULDUAR_KOLOGARN_AXIS_Z_PATHING_ISSUE_DETECT = 420.0f;
|
const float ULDUAR_KOLOGARN_AXIS_Z_PATHING_ISSUE_DETECT = 420.0f;
|
||||||
@@ -115,23 +118,6 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RazorscaleFireResistanceTrigger : public Trigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RazorscaleFireResistanceTrigger(PlayerbotAI* ai) : Trigger(ai, "razorscale fire resistance trigger") {}
|
|
||||||
bool IsActive() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Ignis
|
|
||||||
//
|
|
||||||
class IgnisFireResistanceTrigger : public Trigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IgnisFireResistanceTrigger(PlayerbotAI* ai) : Trigger(ai, "ignis fire resistance trigger") {}
|
|
||||||
bool IsActive() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Iron Assembly
|
// Iron Assembly
|
||||||
//
|
//
|
||||||
@@ -166,13 +152,6 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class KologarnNatureResistanceTrigger : public Trigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
KologarnNatureResistanceTrigger(PlayerbotAI* ai) : Trigger(ai, "kologarn nature resistance trigger") {}
|
|
||||||
bool IsActive() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class KologarnRubbleSlowdownTrigger : public Trigger
|
class KologarnRubbleSlowdownTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -197,13 +176,6 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HodirFrostResistanceTrigger : public Trigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
HodirFrostResistanceTrigger(PlayerbotAI* ai) : Trigger(ai, "hodir frost resistance trigger") {}
|
|
||||||
bool IsActive() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Freya
|
// Freya
|
||||||
//
|
//
|
||||||
@@ -214,10 +186,17 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FreyaTankNearEonarsGiftTrigger : public Trigger
|
class FreyaMarkDpsTargetTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FreyaTankNearEonarsGiftTrigger(PlayerbotAI* ai) : Trigger(ai, "freya tank near eonars gift") {}
|
FreyaMarkDpsTargetTrigger(PlayerbotAI* ai) : Trigger(ai, "freya mark dps target trigger") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FreyaMoveToHealingSporeTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FreyaMoveToHealingSporeTrigger(PlayerbotAI* ai) : Trigger(ai, "freya move to healing spore trigger") {}
|
||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
157
src/strategy/triggers/BossAuraTriggers.cpp
Normal file
157
src/strategy/triggers/BossAuraTriggers.cpp
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||||
|
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "BossAuraTriggers.h"
|
||||||
|
|
||||||
|
#include <HunterBuffStrategies.h>
|
||||||
|
#include <PaladinBuffStrategies.h>
|
||||||
|
#include <Unit.h>
|
||||||
|
|
||||||
|
#include "Playerbots.h"
|
||||||
|
|
||||||
|
bool BossFireResistanceTrigger::IsActive()
|
||||||
|
{
|
||||||
|
// Check boss and it is alive
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", bossName);
|
||||||
|
if (!boss || !boss->IsAlive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if bot is paladin
|
||||||
|
if (bot->getClass() != CLASS_PALADIN)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if bot have fire resistance aura
|
||||||
|
if (bot->HasAura(SPELL_FIRE_RESISTANCE_AURA))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if bot dont have already have fire resistance strategy
|
||||||
|
PaladinFireResistanceStrategy paladinFireResistanceStrategy(botAI);
|
||||||
|
if (botAI->HasStrategy(paladinFireResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check that the bot actually knows the spell
|
||||||
|
if (!bot->HasActiveSpell(SPELL_FIRE_RESISTANCE_AURA))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Get the group and ensure it's a raid group
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group || !group->isRaidGroup())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Iterate through group members to find the first alive paladin
|
||||||
|
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
||||||
|
{
|
||||||
|
Player* member = gref->GetSource();
|
||||||
|
if (!member || !member->IsAlive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check if the member is a hunter
|
||||||
|
if (member->getClass() == CLASS_PALADIN)
|
||||||
|
{
|
||||||
|
// Return true only if the current bot is the first alive paladin
|
||||||
|
return member == bot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BossFrostResistanceTrigger::IsActive()
|
||||||
|
{
|
||||||
|
// Check boss and it is alive
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", bossName);
|
||||||
|
if (!boss || !boss->IsAlive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if bot is paladin
|
||||||
|
if (bot->getClass() != CLASS_PALADIN)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if bot have frost resistance aura
|
||||||
|
if (bot->HasAura(SPELL_FROST_RESISTANCE_AURA))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if bot dont have already have frost resistance strategy
|
||||||
|
PaladinFrostResistanceStrategy paladinFrostResistanceStrategy(botAI);
|
||||||
|
if (botAI->HasStrategy(paladinFrostResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check that the bot actually knows the spell
|
||||||
|
if (!bot->HasActiveSpell(SPELL_FROST_RESISTANCE_AURA))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Get the group and ensure it's a raid group
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group || !group->isRaidGroup())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Iterate through group members to find the first alive paladin
|
||||||
|
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
||||||
|
{
|
||||||
|
Player* member = gref->GetSource();
|
||||||
|
if (!member || !member->IsAlive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check if the member is a hunter
|
||||||
|
if (member->getClass() == CLASS_PALADIN)
|
||||||
|
{
|
||||||
|
// Return true only if the current bot is the first alive paladin
|
||||||
|
return member == bot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BossNatureResistanceTrigger::IsActive()
|
||||||
|
{
|
||||||
|
// Check boss and it is alive
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", bossName);
|
||||||
|
if (!boss || !boss->IsAlive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if bot is alive
|
||||||
|
if (!bot->IsAlive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if bot is hunter
|
||||||
|
if (bot->getClass() != CLASS_HUNTER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if bot have nature resistance aura
|
||||||
|
if (bot->HasAura(SPELL_ASPECT_OF_THE_WILD))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if bot dont have already setted nature resistance aura
|
||||||
|
HunterNatureResistanceStrategy hunterNatureResistanceStrategy(botAI);
|
||||||
|
if (botAI->HasStrategy(hunterNatureResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check that the bot actually knows Aspect of the Wild
|
||||||
|
if (!bot->HasActiveSpell(SPELL_ASPECT_OF_THE_WILD))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Get the group and ensure it's a raid group
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group || !group->isRaidGroup())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Iterate through group members to find the first alive hunter
|
||||||
|
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
||||||
|
{
|
||||||
|
Player* member = gref->GetSource();
|
||||||
|
if (!member || !member->IsAlive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check if the member is a hunter
|
||||||
|
if (member->getClass() == CLASS_HUNTER)
|
||||||
|
{
|
||||||
|
// Return true only if the current bot is the first alive hunter
|
||||||
|
return member == bot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
59
src/strategy/triggers/BossAuraTriggers.h
Normal file
59
src/strategy/triggers/BossAuraTriggers.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||||
|
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PLAYERBOT_BOSSAURATRIGGERS_H
|
||||||
|
#define _PLAYERBOT_BOSSAURATRIGGERS_H
|
||||||
|
|
||||||
|
#include "GenericTriggers.h"
|
||||||
|
|
||||||
|
class PlayerbotAI;
|
||||||
|
|
||||||
|
enum BossAuraIDs
|
||||||
|
{
|
||||||
|
SPELL_FROST_RESISTANCE_AURA = 48945,
|
||||||
|
SPELL_FIRE_RESISTANCE_AURA = 48947,
|
||||||
|
SPELL_ASPECT_OF_THE_WILD = 49071,
|
||||||
|
};
|
||||||
|
|
||||||
|
class BossFireResistanceTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BossFireResistanceTrigger(PlayerbotAI* ai, std::string const bossName)
|
||||||
|
: Trigger(ai, bossName + " fire resistance trigger"), bossName(bossName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool IsActive() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string bossName;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BossFrostResistanceTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BossFrostResistanceTrigger(PlayerbotAI* ai, std::string const bossName)
|
||||||
|
: Trigger(ai, bossName + " frost resistance trigger"), bossName(bossName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool IsActive() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string bossName;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BossNatureResistanceTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BossNatureResistanceTrigger(PlayerbotAI* ai, std::string const bossName)
|
||||||
|
: Trigger(ai, "kologarn nature resistance trigger"), bossName(bossName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool IsActive() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string bossName;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user