mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-13 00:58:33 +00:00
Merge pull request #880 from liyunfan1223/improve_dps
Improve DPS rotation
This commit is contained in:
@@ -23,6 +23,7 @@
|
|||||||
# LEVELS
|
# LEVELS
|
||||||
# GEAR
|
# GEAR
|
||||||
# QUESTS
|
# QUESTS
|
||||||
|
# ACTIVITIES
|
||||||
# SPELLS
|
# SPELLS
|
||||||
# STRATEGIES
|
# STRATEGIES
|
||||||
# TELEPORTS
|
# TELEPORTS
|
||||||
@@ -612,6 +613,50 @@ AiPlayerbot.EquipmentPersistenceLevel = 80
|
|||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
AiPlayerbot.AutoUpgradeEquip = 1
|
AiPlayerbot.AutoUpgradeEquip = 1
|
||||||
|
|
||||||
|
# Only set wolf pets for hunters to have higher damage (0 = disabled, 1 = enabled only for max-level, 2 = enabled)
|
||||||
|
# Default: 0 (disabled)
|
||||||
|
AiPlayerbot.HunterWolfPet = 0
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
####################################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################################################
|
||||||
|
# ACTIVITIES
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Specify percent of active bots
|
||||||
|
# The default is 10. With 10% of all bots going active or inactive each minute. Regardless
|
||||||
|
# This value is only applied to inactive areas where no real-players are detected, when
|
||||||
|
# real-players are nearby, friend, group, guild, bg, instances etc the value is always
|
||||||
|
# enforced to 100%
|
||||||
|
AiPlayerbot.BotActiveAlone = 100
|
||||||
|
|
||||||
|
# Force botActiveAlone when bot is ... of real player
|
||||||
|
AiPlayerbot.BotActiveAloneForceWhenInRadius = 150
|
||||||
|
AiPlayerbot.BotActiveAloneForceWhenInZone = 1
|
||||||
|
AiPlayerbot.BotActiveAloneForceWhenInMap = 0
|
||||||
|
AiPlayerbot.BotActiveAloneForceWhenIsFriend = 1
|
||||||
|
AiPlayerbot.BotActiveAloneForceWhenInGuild = 1
|
||||||
|
|
||||||
|
# SmartScale is enabled or not.
|
||||||
|
# The default is 1. When enabled (smart) scales the 'BotActiveAlone' value.
|
||||||
|
# (The scaling will be overruled by the BotActiveAloneForceWhen...rules)
|
||||||
|
#
|
||||||
|
# Limitfloor - when DIFF (latency) above floor, activity scaling is applied starting with 90%
|
||||||
|
# LimitCeiling - when DIFF (latency) above ceiling, activity is 0%;
|
||||||
|
#
|
||||||
|
# MinLevel - only apply scaling when level is above or equal to min(bot)Level
|
||||||
|
# MaxLevel - only apply scaling when level is lower or equal of max(bot)Level
|
||||||
|
#
|
||||||
|
AiPlayerbot.botActiveAloneSmartScale = 1
|
||||||
|
AiPlayerbot.botActiveAloneSmartScaleDiffLimitfloor = 50
|
||||||
|
AiPlayerbot.botActiveAloneSmartScaleDiffLimitCeiling = 200
|
||||||
|
AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel = 1
|
||||||
|
AiPlayerbot.botActiveAloneSmartScaleWhenMaxLevel = 80
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
@@ -960,7 +1005,7 @@ AiPlayerbot.PremadeSpecGlyph.6.1 = 45805,43673,43547,43544,43672,43543
|
|||||||
AiPlayerbot.PremadeSpecLink.6.1.60 = -32003350332203012300023101351
|
AiPlayerbot.PremadeSpecLink.6.1.60 = -32003350332203012300023101351
|
||||||
AiPlayerbot.PremadeSpecLink.6.1.80 = -32002350352203012300033101351-230200305003
|
AiPlayerbot.PremadeSpecLink.6.1.80 = -32002350352203012300033101351-230200305003
|
||||||
AiPlayerbot.PremadeSpecName.6.2 = unholy pve
|
AiPlayerbot.PremadeSpecName.6.2 = unholy pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.6.2 = 43542,43673,45804,43544,43672,43549
|
AiPlayerbot.PremadeSpecGlyph.6.2 = 43542,43673,43546,43544,43672,43549
|
||||||
AiPlayerbot.PremadeSpecLink.6.2.60 = --2301303050032151000150013131151
|
AiPlayerbot.PremadeSpecLink.6.2.60 = --2301303050032151000150013131151
|
||||||
AiPlayerbot.PremadeSpecLink.6.2.80 = -320033500002-2301303050032151000150013133151
|
AiPlayerbot.PremadeSpecLink.6.2.80 = -320033500002-2301303050032151000150013133151
|
||||||
AiPlayerbot.PremadeSpecName.6.3 = double aura blood pve
|
AiPlayerbot.PremadeSpecName.6.3 = double aura blood pve
|
||||||
@@ -1551,36 +1596,6 @@ AiPlayerbot.RandombotsWalkingRPG = 0
|
|||||||
# Set randombots movement speed to walking only inside buildings
|
# Set randombots movement speed to walking only inside buildings
|
||||||
AiPlayerbot.RandombotsWalkingRPG.InDoors = 0
|
AiPlayerbot.RandombotsWalkingRPG.InDoors = 0
|
||||||
|
|
||||||
# Specify percent of active bots
|
|
||||||
# The default is 10. With 10% of all bots going active or inactive each minute. Regardless
|
|
||||||
# This value is only applied to inactive areas where no real-players are detected, when
|
|
||||||
# real-players are nearby, friend, group, guild, bg, instances etc the value is always
|
|
||||||
# enforced to 100%
|
|
||||||
AiPlayerbot.BotActiveAlone = 100
|
|
||||||
|
|
||||||
# Force botActiveAlone when bot is ... of real player
|
|
||||||
AiPlayerbot.BotActiveAloneForceWhenInRadius = 150
|
|
||||||
AiPlayerbot.BotActiveAloneForceWhenInZone = 1
|
|
||||||
AiPlayerbot.BotActiveAloneForceWhenInMap = 0
|
|
||||||
AiPlayerbot.BotActiveAloneForceWhenIsFriend = 1
|
|
||||||
AiPlayerbot.BotActiveAloneForceWhenInGuild = 1
|
|
||||||
|
|
||||||
# SmartScale is enabled or not.
|
|
||||||
# The default is 1. When enabled (smart) scales the 'BotActiveAlone' value.
|
|
||||||
# (The scaling will be overruled by the BotActiveAloneForceWhen...rules)
|
|
||||||
#
|
|
||||||
# Limitfloor - when DIFF (latency) above floor, activity scaling is applied starting with 90%
|
|
||||||
# LimitCeiling - when DIFF (latency) above ceiling, activity is 0%;
|
|
||||||
#
|
|
||||||
# MinLevel - only apply scaling when level is above or equal to min(bot)Level
|
|
||||||
# MaxLevel - only apply scaling when level is lower or equal of max(bot)Level
|
|
||||||
#
|
|
||||||
AiPlayerbot.botActiveAloneSmartScale = 1
|
|
||||||
AiPlayerbot.botActiveAloneSmartScaleDiffLimitfloor = 50
|
|
||||||
AiPlayerbot.botActiveAloneSmartScaleDiffLimitCeiling = 200
|
|
||||||
AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel = 1
|
|
||||||
AiPlayerbot.botActiveAloneSmartScaleWhenMaxLevel = 80
|
|
||||||
|
|
||||||
# Premade spell to avoid (undetected spells)
|
# Premade spell to avoid (undetected spells)
|
||||||
# spellid-radius, ...
|
# spellid-radius, ...
|
||||||
AiPlayerbot.PremadeAvoidAoe = 62234-4
|
AiPlayerbot.PremadeAvoidAoe = 62234-4
|
||||||
|
|||||||
@@ -2928,7 +2928,10 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Unit* oldSel = bot->GetSelectedUnit();
|
Unit* oldSel = bot->GetSelectedUnit();
|
||||||
Spell* spell = new Spell(bot, spellInfo, TRIGGERED_NONE);
|
// TRIGGERED_IGNORE_POWER_AND_REAGENT_COST flag for not calling CheckPower in check
|
||||||
|
// which avoids buff charge to be ineffectively reduced (e.g. dk freezing fog for howling blast)
|
||||||
|
/// @TODO: Fix all calls to ApplySpellMod
|
||||||
|
Spell* spell = new Spell(bot, spellInfo, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST);
|
||||||
|
|
||||||
spell->m_targets.SetUnitTarget(target);
|
spell->m_targets.SetUnitTarget(target);
|
||||||
spell->m_CastItem = castItem;
|
spell->m_CastItem = castItem;
|
||||||
@@ -2938,7 +2941,6 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell,
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
spell->m_targets.SetItemTarget(itemTarget);
|
spell->m_targets.SetItemTarget(itemTarget);
|
||||||
|
|
||||||
SpellCastResult result = spell->CheckCast(true);
|
SpellCastResult result = spell->CheckCast(true);
|
||||||
delete spell;
|
delete spell;
|
||||||
|
|
||||||
|
|||||||
@@ -511,6 +511,7 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
autoTrainSpells = sConfigMgr->GetOption<std::string>("AiPlayerbot.AutoTrainSpells", "yes");
|
autoTrainSpells = sConfigMgr->GetOption<std::string>("AiPlayerbot.AutoTrainSpells", "yes");
|
||||||
autoPickTalents = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoPickTalents", true);
|
autoPickTalents = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoPickTalents", true);
|
||||||
autoUpgradeEquip = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoUpgradeEquip", false);
|
autoUpgradeEquip = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoUpgradeEquip", false);
|
||||||
|
hunterWolfPet = sConfigMgr->GetOption<int32>("AiPlayerbot.HunterWolfPet", 0);
|
||||||
autoLearnTrainerSpells = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoLearnTrainerSpells", true);
|
autoLearnTrainerSpells = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoLearnTrainerSpells", true);
|
||||||
autoLearnQuestSpells = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoLearnQuestSpells", false);
|
autoLearnQuestSpells = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoLearnQuestSpells", false);
|
||||||
autoTeleportForLevel = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoTeleportForLevel", false);
|
autoTeleportForLevel = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoTeleportForLevel", false);
|
||||||
|
|||||||
@@ -289,6 +289,7 @@ public:
|
|||||||
std::string autoTrainSpells;
|
std::string autoTrainSpells;
|
||||||
bool autoPickTalents;
|
bool autoPickTalents;
|
||||||
bool autoUpgradeEquip;
|
bool autoUpgradeEquip;
|
||||||
|
int32 hunterWolfPet;
|
||||||
bool autoLearnTrainerSpells;
|
bool autoLearnTrainerSpells;
|
||||||
bool autoDoQuests;
|
bool autoDoQuests;
|
||||||
bool enableNewRpgStrategy;
|
bool enableNewRpgStrategy;
|
||||||
|
|||||||
@@ -484,10 +484,11 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
|
|||||||
|
|
||||||
if (!groupValid)
|
if (!groupValid)
|
||||||
{
|
{
|
||||||
WorldPacket p;
|
bot->RemoveFromGroup();
|
||||||
std::string const member = bot->GetName();
|
// WorldPacket p;
|
||||||
p << uint32(PARTY_OP_LEAVE) << member << uint32(0);
|
// std::string const member = bot->GetName();
|
||||||
bot->GetSession()->HandleGroupDisbandOpcode(p);
|
// p << uint32(PARTY_OP_LEAVE) << member << uint32(0);
|
||||||
|
// bot->GetSession()->HandleGroupDisbandOpcode(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
#include "SpellAuraDefines.h"
|
#include "SpellAuraDefines.h"
|
||||||
#include "StatsWeightCalculator.h"
|
#include "StatsWeightCalculator.h"
|
||||||
|
#include "World.h"
|
||||||
|
|
||||||
#define PLAYER_SKILL_INDEX(x) (PLAYER_SKILL_INFO_1_1 + ((x)*3))
|
#define PLAYER_SKILL_INDEX(x) (PLAYER_SKILL_INFO_1_1 + ((x)*3))
|
||||||
|
|
||||||
@@ -786,6 +787,13 @@ void PlayerbotFactory::InitPet()
|
|||||||
if (itr->second.minlevel > bot->GetLevel())
|
if (itr->second.minlevel > bot->GetLevel())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
bool onlyWolf = sPlayerbotAIConfig->hunterWolfPet == 2 ||
|
||||||
|
(sPlayerbotAIConfig->hunterWolfPet == 1 &&
|
||||||
|
bot->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
|
||||||
|
// Wolf only (for higher dps)
|
||||||
|
if (onlyWolf && itr->second.family != CREATURE_FAMILY_WOLF)
|
||||||
|
continue;
|
||||||
|
|
||||||
ids.push_back(itr->first);
|
ids.push_back(itr->first);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2807,11 +2815,11 @@ void PlayerbotFactory::InitAmmo()
|
|||||||
|
|
||||||
uint32 entry = sRandomItemMgr->GetAmmo(level, subClass);
|
uint32 entry = sRandomItemMgr->GetAmmo(level, subClass);
|
||||||
uint32 count = bot->GetItemCount(entry);
|
uint32 count = bot->GetItemCount(entry);
|
||||||
uint32 maxCount = 6000;
|
uint32 maxCount = bot->getClass() == CLASS_HUNTER ? 6000 : 1000;
|
||||||
|
|
||||||
if (count < maxCount / 2)
|
if (count < maxCount)
|
||||||
{
|
{
|
||||||
if (Item* newItem = StoreNewItemInInventorySlot(bot, entry, maxCount / 2))
|
if (Item* newItem = StoreNewItemInInventorySlot(bot, entry, maxCount - count))
|
||||||
{
|
{
|
||||||
newItem->AddToUpdateQueueOf(bot);
|
newItem->AddToUpdateQueueOf(bot);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,9 +84,7 @@ bool LeaveGroupAction::Leave(Player* player)
|
|||||||
bool shouldStay = randomBot && bot->GetGroup() && player == bot;
|
bool shouldStay = randomBot && bot->GetGroup() && player == bot;
|
||||||
if (!shouldStay)
|
if (!shouldStay)
|
||||||
{
|
{
|
||||||
WorldPacket p;
|
bot->RemoveFromGroup();
|
||||||
p << uint32(PARTY_OP_LEAVE) << bot->GetName() << uint32(0);
|
|
||||||
bot->GetSession()->HandleGroupDisbandOpcode(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (randomBot)
|
if (randomBot)
|
||||||
|
|||||||
@@ -74,14 +74,14 @@ public:
|
|||||||
creators["plague strike"] = &DeathKnightTriggerFactoryInternal::plague_strike;
|
creators["plague strike"] = &DeathKnightTriggerFactoryInternal::plague_strike;
|
||||||
creators["plague strike on attacker"] = &DeathKnightTriggerFactoryInternal::plague_strike_on_attacker;
|
creators["plague strike on attacker"] = &DeathKnightTriggerFactoryInternal::plague_strike_on_attacker;
|
||||||
creators["icy touch"] = &DeathKnightTriggerFactoryInternal::icy_touch;
|
creators["icy touch"] = &DeathKnightTriggerFactoryInternal::icy_touch;
|
||||||
creators["icy touch 8s"] = &DeathKnightTriggerFactoryInternal::icy_touch_8s;
|
creators["icy touch 3s"] = &DeathKnightTriggerFactoryInternal::icy_touch_3s;
|
||||||
creators["dd cd and icy touch 8s"] = &DeathKnightTriggerFactoryInternal::dd_cd_and_icy_touch_8s;
|
creators["dd cd and icy touch 3s"] = &DeathKnightTriggerFactoryInternal::dd_cd_and_icy_touch_3s;
|
||||||
creators["death coil"] = &DeathKnightTriggerFactoryInternal::death_coil;
|
creators["death coil"] = &DeathKnightTriggerFactoryInternal::death_coil;
|
||||||
creators["icy touch on attacker"] = &DeathKnightTriggerFactoryInternal::icy_touch_on_attacker;
|
creators["icy touch on attacker"] = &DeathKnightTriggerFactoryInternal::icy_touch_on_attacker;
|
||||||
creators["improved icy talons"] = &DeathKnightTriggerFactoryInternal::improved_icy_talons;
|
creators["improved icy talons"] = &DeathKnightTriggerFactoryInternal::improved_icy_talons;
|
||||||
creators["plague strike"] = &DeathKnightTriggerFactoryInternal::plague_strike;
|
creators["plague strike"] = &DeathKnightTriggerFactoryInternal::plague_strike;
|
||||||
creators["plague strike 8s"] = &DeathKnightTriggerFactoryInternal::plague_strike_8s;
|
creators["plague strike 3s"] = &DeathKnightTriggerFactoryInternal::plague_strike_3s;
|
||||||
creators["dd cd and plague strike 8s"] = &DeathKnightTriggerFactoryInternal::dd_cd_and_plague_strike_8s;
|
creators["dd cd and plague strike 3s"] = &DeathKnightTriggerFactoryInternal::dd_cd_and_plague_strike_3s;
|
||||||
creators["horn of winter"] = &DeathKnightTriggerFactoryInternal::horn_of_winter;
|
creators["horn of winter"] = &DeathKnightTriggerFactoryInternal::horn_of_winter;
|
||||||
creators["mind freeze"] = &DeathKnightTriggerFactoryInternal::mind_freeze;
|
creators["mind freeze"] = &DeathKnightTriggerFactoryInternal::mind_freeze;
|
||||||
creators["mind freeze on enemy healer"] = &DeathKnightTriggerFactoryInternal::mind_freeze_on_enemy_healer;
|
creators["mind freeze on enemy healer"] = &DeathKnightTriggerFactoryInternal::mind_freeze_on_enemy_healer;
|
||||||
@@ -94,6 +94,7 @@ public:
|
|||||||
creators["high blood rune"] = &DeathKnightTriggerFactoryInternal::high_blood_rune;
|
creators["high blood rune"] = &DeathKnightTriggerFactoryInternal::high_blood_rune;
|
||||||
creators["high frost rune"] = &DeathKnightTriggerFactoryInternal::high_frost_rune;
|
creators["high frost rune"] = &DeathKnightTriggerFactoryInternal::high_frost_rune;
|
||||||
creators["high unholy rune"] = &DeathKnightTriggerFactoryInternal::high_unholy_rune;
|
creators["high unholy rune"] = &DeathKnightTriggerFactoryInternal::high_unholy_rune;
|
||||||
|
creators["no rune"] = &DeathKnightTriggerFactoryInternal::no_rune;
|
||||||
creators["freezing fog"] = &DeathKnightTriggerFactoryInternal::freezing_fog;
|
creators["freezing fog"] = &DeathKnightTriggerFactoryInternal::freezing_fog;
|
||||||
creators["no desolation"] = &DeathKnightTriggerFactoryInternal::no_desolation;
|
creators["no desolation"] = &DeathKnightTriggerFactoryInternal::no_desolation;
|
||||||
creators["dd cd and no desolation"] = &DeathKnightTriggerFactoryInternal::dd_cd_and_no_desolation;
|
creators["dd cd and no desolation"] = &DeathKnightTriggerFactoryInternal::dd_cd_and_no_desolation;
|
||||||
@@ -106,15 +107,15 @@ private:
|
|||||||
static Trigger* pestilence_glyph(PlayerbotAI* botAI) { return new PestilenceGlyphTrigger(botAI); }
|
static Trigger* pestilence_glyph(PlayerbotAI* botAI) { return new PestilenceGlyphTrigger(botAI); }
|
||||||
static Trigger* blood_strike(PlayerbotAI* botAI) { return new BloodStrikeTrigger(botAI); }
|
static Trigger* blood_strike(PlayerbotAI* botAI) { return new BloodStrikeTrigger(botAI); }
|
||||||
static Trigger* plague_strike(PlayerbotAI* botAI) { return new PlagueStrikeDebuffTrigger(botAI); }
|
static Trigger* plague_strike(PlayerbotAI* botAI) { return new PlagueStrikeDebuffTrigger(botAI); }
|
||||||
static Trigger* plague_strike_8s(PlayerbotAI* botAI) { return new PlagueStrike8sDebuffTrigger(botAI); }
|
static Trigger* plague_strike_3s(PlayerbotAI* botAI) { return new PlagueStrike3sDebuffTrigger(botAI); }
|
||||||
static Trigger* dd_cd_and_plague_strike_8s(PlayerbotAI* botAI) { return new TwoTriggers(botAI, "death and decay cooldown", "plague strike 8s"); }
|
static Trigger* dd_cd_and_plague_strike_3s(PlayerbotAI* botAI) { return new TwoTriggers(botAI, "death and decay cooldown", "plague strike 3s"); }
|
||||||
static Trigger* plague_strike_on_attacker(PlayerbotAI* botAI)
|
static Trigger* plague_strike_on_attacker(PlayerbotAI* botAI)
|
||||||
{
|
{
|
||||||
return new PlagueStrikeDebuffOnAttackerTrigger(botAI);
|
return new PlagueStrikeDebuffOnAttackerTrigger(botAI);
|
||||||
}
|
}
|
||||||
static Trigger* icy_touch(PlayerbotAI* botAI) { return new IcyTouchDebuffTrigger(botAI); }
|
static Trigger* icy_touch(PlayerbotAI* botAI) { return new IcyTouchDebuffTrigger(botAI); }
|
||||||
static Trigger* icy_touch_8s(PlayerbotAI* botAI) { return new IcyTouch8sDebuffTrigger(botAI); }
|
static Trigger* icy_touch_3s(PlayerbotAI* botAI) { return new IcyTouch3sDebuffTrigger(botAI); }
|
||||||
static Trigger* dd_cd_and_icy_touch_8s(PlayerbotAI* botAI) { return new TwoTriggers(botAI, "death and decay cooldown", "icy touch 8s"); }
|
static Trigger* dd_cd_and_icy_touch_3s(PlayerbotAI* botAI) { return new TwoTriggers(botAI, "death and decay cooldown", "icy touch 3s"); }
|
||||||
static Trigger* death_coil(PlayerbotAI* botAI) { return new DeathCoilTrigger(botAI); }
|
static Trigger* death_coil(PlayerbotAI* botAI) { return new DeathCoilTrigger(botAI); }
|
||||||
static Trigger* icy_touch_on_attacker(PlayerbotAI* botAI) { return new IcyTouchDebuffOnAttackerTrigger(botAI); }
|
static Trigger* icy_touch_on_attacker(PlayerbotAI* botAI) { return new IcyTouchDebuffOnAttackerTrigger(botAI); }
|
||||||
static Trigger* improved_icy_talons(PlayerbotAI* botAI) { return new ImprovedIcyTalonsTrigger(botAI); }
|
static Trigger* improved_icy_talons(PlayerbotAI* botAI) { return new ImprovedIcyTalonsTrigger(botAI); }
|
||||||
@@ -136,6 +137,7 @@ private:
|
|||||||
static Trigger* high_blood_rune(PlayerbotAI* botAI) { return new HighBloodRuneTrigger(botAI); }
|
static Trigger* high_blood_rune(PlayerbotAI* botAI) { return new HighBloodRuneTrigger(botAI); }
|
||||||
static Trigger* high_frost_rune(PlayerbotAI* botAI) { return new HighFrostRuneTrigger(botAI); }
|
static Trigger* high_frost_rune(PlayerbotAI* botAI) { return new HighFrostRuneTrigger(botAI); }
|
||||||
static Trigger* high_unholy_rune(PlayerbotAI* botAI) { return new HighUnholyRuneTrigger(botAI); }
|
static Trigger* high_unholy_rune(PlayerbotAI* botAI) { return new HighUnholyRuneTrigger(botAI); }
|
||||||
|
static Trigger* no_rune(PlayerbotAI* botAI) { return new NoRuneTrigger(botAI); }
|
||||||
static Trigger* freezing_fog(PlayerbotAI* botAI) { return new FreezingFogTrigger(botAI); }
|
static Trigger* freezing_fog(PlayerbotAI* botAI) { return new FreezingFogTrigger(botAI); }
|
||||||
static Trigger* no_desolation(PlayerbotAI* botAI) { return new DesolationTrigger(botAI); }
|
static Trigger* no_desolation(PlayerbotAI* botAI) { return new DesolationTrigger(botAI); }
|
||||||
static Trigger* dd_cd_and_no_desolation(PlayerbotAI* botAI) { return new TwoTriggers(botAI, "death and decay cooldown", "no desolation"); }
|
static Trigger* dd_cd_and_no_desolation(PlayerbotAI* botAI) { return new TwoTriggers(botAI, "death and decay cooldown", "no desolation"); }
|
||||||
|
|||||||
@@ -37,20 +37,32 @@ bool PestilenceGlyphTrigger::IsActive()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Based on runeSlotTypes
|
||||||
bool HighBloodRuneTrigger::IsActive()
|
bool HighBloodRuneTrigger::IsActive()
|
||||||
{
|
{
|
||||||
return !bot->GetRuneCooldown(0) && !bot->GetRuneCooldown(1);
|
return bot->GetRuneCooldown(0) <= 2000 && bot->GetRuneCooldown(1) <= 2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HighFrostRuneTrigger::IsActive()
|
bool HighFrostRuneTrigger::IsActive()
|
||||||
{
|
{
|
||||||
return !bot->GetRuneCooldown(2) && !bot->GetRuneCooldown(3);
|
return bot->GetRuneCooldown(4) <= 2000 && bot->GetRuneCooldown(5) <= 2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HighUnholyRuneTrigger::IsActive()
|
bool HighUnholyRuneTrigger::IsActive()
|
||||||
{
|
{
|
||||||
return !bot->GetRuneCooldown(4) && !bot->GetRuneCooldown(5);
|
return bot->GetRuneCooldown(2) <= 2000 && bot->GetRuneCooldown(3) <= 2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NoRuneTrigger::IsActive()
|
||||||
|
{
|
||||||
|
for (uint32 i = 0; i < MAX_RUNES; ++i)
|
||||||
|
{
|
||||||
|
if (!bot->GetRuneCooldown(i))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool DesolationTrigger::IsActive()
|
bool DesolationTrigger::IsActive()
|
||||||
{
|
{
|
||||||
return bot->HasAura(66817) && BuffTrigger::IsActive();
|
return bot->HasAura(66817) && BuffTrigger::IsActive();
|
||||||
@@ -62,5 +74,5 @@ bool DeathAndDecayCooldownTrigger::IsActive()
|
|||||||
if (!spellId)
|
if (!spellId)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return bot->GetSpellCooldownDelay(spellId) >= 3000;
|
return bot->GetSpellCooldownDelay(spellId) >= 2000;
|
||||||
}
|
}
|
||||||
@@ -20,10 +20,10 @@ public:
|
|||||||
PlagueStrikeDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "blood plague", 1, true, .0f) {}
|
PlagueStrikeDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "blood plague", 1, true, .0f) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlagueStrike8sDebuffTrigger : public DebuffTrigger
|
class PlagueStrike3sDebuffTrigger : public DebuffTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PlagueStrike8sDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "blood plague", 1, true, .0f, 3000) {}
|
PlagueStrike3sDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "blood plague", 1, true, .0f, 3000) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// DEBUFF_CHECKISOWNER_TRIGGER(IcyTouchDebuffTrigger, "frost fever");
|
// DEBUFF_CHECKISOWNER_TRIGGER(IcyTouchDebuffTrigger, "frost fever");
|
||||||
@@ -33,10 +33,10 @@ public:
|
|||||||
IcyTouchDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "frost fever", 1, true, .0f) {}
|
IcyTouchDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "frost fever", 1, true, .0f) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class IcyTouch8sDebuffTrigger : public DebuffTrigger
|
class IcyTouch3sDebuffTrigger : public DebuffTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IcyTouch8sDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "frost fever", 1, true, .0f, 3000) {}
|
IcyTouch3sDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "frost fever", 1, true, .0f, 3000) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
BUFF_TRIGGER(UnbreakableArmorTrigger, "unbreakable armor");
|
BUFF_TRIGGER(UnbreakableArmorTrigger, "unbreakable armor");
|
||||||
@@ -165,6 +165,13 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NoRuneTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NoRuneTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no rune") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
class FreezingFogTrigger : public HasAuraTrigger
|
class FreezingFogTrigger : public HasAuraTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ NextAction** UnholyDKStrategy::getDefaultActions()
|
|||||||
return NextAction::array(
|
return NextAction::array(
|
||||||
0, new NextAction("death and decay", ACTION_HIGH + 5),
|
0, new NextAction("death and decay", ACTION_HIGH + 5),
|
||||||
new NextAction("summon gargoyle", ACTION_DEFAULT + 0.4f),
|
new NextAction("summon gargoyle", ACTION_DEFAULT + 0.4f),
|
||||||
new NextAction("empower rune weapon", ACTION_DEFAULT + 0.3f),
|
// new NextAction("empower rune weapon", ACTION_DEFAULT + 0.3f),
|
||||||
new NextAction("horn of winter", ACTION_DEFAULT + 0.2f),
|
new NextAction("horn of winter", ACTION_DEFAULT + 0.2f),
|
||||||
new NextAction("death coil", ACTION_DEFAULT + 0.1f),
|
new NextAction("death coil", ACTION_DEFAULT + 0.1f),
|
||||||
new NextAction("melee", ACTION_DEFAULT), nullptr);
|
new NextAction("melee", ACTION_DEFAULT), nullptr);
|
||||||
@@ -93,8 +93,8 @@ void UnholyDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
"death and decay cooldown", NextAction::array(0,
|
"death and decay cooldown", NextAction::array(0,
|
||||||
new NextAction("ghoul frenzy", ACTION_DEFAULT + 0.9f),
|
new NextAction("ghoul frenzy", ACTION_DEFAULT + 0.9f),
|
||||||
new NextAction("scourge strike", ACTION_DEFAULT + 0.8f),
|
new NextAction("scourge strike", ACTION_DEFAULT + 0.8f),
|
||||||
new NextAction("blood boil", ACTION_DEFAULT + 0.7f),
|
new NextAction("icy touch", ACTION_DEFAULT + 0.7f),
|
||||||
new NextAction("icy touch", ACTION_DEFAULT + 0.6f),
|
new NextAction("blood strike", ACTION_DEFAULT + 0.6f),
|
||||||
new NextAction("plague strike", ACTION_DEFAULT + 0.5f),
|
new NextAction("plague strike", ACTION_DEFAULT + 0.5f),
|
||||||
nullptr)));
|
nullptr)));
|
||||||
|
|
||||||
@@ -111,24 +111,26 @@ void UnholyDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
new NextAction("icy touch", ACTION_NORMAL + 3), nullptr)));
|
new NextAction("icy touch", ACTION_NORMAL + 3), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"high unholy rune", NextAction::array(0,
|
"high blood rune", NextAction::array(0, new NextAction("blood strike", ACTION_NORMAL + 2), nullptr)));
|
||||||
new NextAction("plague strike", ACTION_NORMAL + 2), nullptr)));
|
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"high blood rune", NextAction::array(0, new NextAction("blood strike", ACTION_NORMAL + 1), nullptr)));
|
"high unholy rune", NextAction::array(0,
|
||||||
|
new NextAction("plague strike", ACTION_NORMAL + 1), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("dd cd and plague strike 8s", NextAction::array(0, new NextAction("plague strike", ACTION_HIGH + 2), nullptr)));
|
new TriggerNode("dd cd and plague strike 3s", NextAction::array(0, new NextAction("plague strike", ACTION_HIGH + 1), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("dd cd and icy touch 8s", NextAction::array(0, new NextAction("icy touch", ACTION_HIGH + 1), nullptr)));
|
new TriggerNode("dd cd and icy touch 3s", NextAction::array(0, new NextAction("icy touch", ACTION_HIGH + 2), nullptr)));
|
||||||
|
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("no rune", NextAction::array(0, new NextAction("empower rune weapon", ACTION_HIGH + 1), nullptr)));
|
||||||
|
|
||||||
// triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction(, ACTION_NORMAL + 2), nullptr)));
|
// triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction(, ACTION_NORMAL + 2), nullptr)));
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"army of the dead", NextAction::array(0, new NextAction("army of the dead", ACTION_HIGH + 6), nullptr)));
|
"army of the dead", NextAction::array(0, new NextAction("army of the dead", ACTION_HIGH + 6), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("bone shield", NextAction::array(0, new NextAction("bone shield", ACTION_HIGH + 1), nullptr)));
|
new TriggerNode("bone shield", NextAction::array(0, new NextAction("bone shield", ACTION_HIGH + 3), nullptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnholyDKAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void UnholyDKAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
|||||||
@@ -41,8 +41,11 @@ DpsHunterStrategy::DpsHunterStrategy(PlayerbotAI* botAI) : GenericHunterStrategy
|
|||||||
NextAction** DpsHunterStrategy::getDefaultActions()
|
NextAction** DpsHunterStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(
|
return NextAction::array(
|
||||||
0, new NextAction("kill shot", ACTION_DEFAULT + 0.8f), new NextAction("chimera shot", ACTION_DEFAULT + 0.7f),
|
0,
|
||||||
new NextAction("explosive shot", ACTION_DEFAULT + 0.6f), new NextAction("aimed shot", ACTION_DEFAULT + 0.5f),
|
new NextAction("explosive shot", ACTION_HIGH + 1.0f),
|
||||||
|
new NextAction("kill shot", ACTION_DEFAULT + 0.8f),
|
||||||
|
new NextAction("chimera shot", ACTION_DEFAULT + 0.6f),
|
||||||
|
new NextAction("aimed shot", ACTION_DEFAULT + 0.5f),
|
||||||
new NextAction("silencing shot", ACTION_DEFAULT + 0.4f),
|
new NextAction("silencing shot", ACTION_DEFAULT + 0.4f),
|
||||||
new NextAction("kill command", ACTION_DEFAULT + 0.3f),
|
new NextAction("kill command", ACTION_DEFAULT + 0.3f),
|
||||||
// new NextAction("arcane shot", ACTION_DEFAULT + 0.2f),
|
// new NextAction("arcane shot", ACTION_DEFAULT + 0.2f),
|
||||||
@@ -55,7 +58,7 @@ void DpsHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
GenericHunterStrategy::InitTriggers(triggers);
|
GenericHunterStrategy::InitTriggers(triggers);
|
||||||
|
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("black arrow", NextAction::array(0, new NextAction("black arrow", 15.0f), nullptr)));
|
new TriggerNode("black arrow", NextAction::array(0, new NextAction("black arrow", 19.0f), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("low mana", NextAction::array(0, new NextAction("viper sting", 23.0f), nullptr)));
|
new TriggerNode("low mana", NextAction::array(0, new NextAction("viper sting", 23.0f), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ void GenericHunterNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& tri
|
|||||||
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)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("low ammo", NextAction::array(0, new NextAction("say::low ammo", ACTION_NORMAL), nullptr)));
|
new TriggerNode("low ammo", NextAction::array(0, new NextAction("say::low ammo", ACTION_NORMAL), nullptr)));
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("no track", NextAction::array(0, new NextAction("track humanoids", ACTION_NORMAL), nullptr)));
|
||||||
// triggers.push_back(new TriggerNode("no ammo", NextAction::array(0, new NextAction("switch to melee",
|
// triggers.push_back(new TriggerNode("no ammo", NextAction::array(0, new NextAction("switch to melee",
|
||||||
// ACTION_NORMAL + 1), new NextAction("say::no ammo", ACTION_NORMAL), nullptr))); triggers.push_back(new
|
// ACTION_NORMAL + 1), new NextAction("say::no ammo", ACTION_NORMAL), nullptr))); triggers.push_back(new
|
||||||
// TriggerNode("has ammo", NextAction::array(0, new NextAction("switch to ranged", ACTION_NORMAL), nullptr)));
|
// TriggerNode("has ammo", NextAction::array(0, new NextAction("switch to ranged", ACTION_NORMAL), nullptr)));
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ public:
|
|||||||
creators["aspect of the wild"] = &HunterTriggerFactoryInternal::aspect_of_the_wild;
|
creators["aspect of the wild"] = &HunterTriggerFactoryInternal::aspect_of_the_wild;
|
||||||
creators["aspect of the viper"] = &HunterTriggerFactoryInternal::aspect_of_the_viper;
|
creators["aspect of the viper"] = &HunterTriggerFactoryInternal::aspect_of_the_viper;
|
||||||
creators["trueshot aura"] = &HunterTriggerFactoryInternal::trueshot_aura;
|
creators["trueshot aura"] = &HunterTriggerFactoryInternal::trueshot_aura;
|
||||||
|
creators["no track"] = &HunterTriggerFactoryInternal::no_track;
|
||||||
creators["serpent sting on attacker"] = &HunterTriggerFactoryInternal::serpent_sting_on_attacker;
|
creators["serpent sting on attacker"] = &HunterTriggerFactoryInternal::serpent_sting_on_attacker;
|
||||||
creators["pet not happy"] = &HunterTriggerFactoryInternal::pet_not_happy;
|
creators["pet not happy"] = &HunterTriggerFactoryInternal::pet_not_happy;
|
||||||
creators["concussive shot on snare target"] = &HunterTriggerFactoryInternal::concussive_shot_on_snare_target;
|
creators["concussive shot on snare target"] = &HunterTriggerFactoryInternal::concussive_shot_on_snare_target;
|
||||||
@@ -99,6 +100,7 @@ private:
|
|||||||
static Trigger* pet_not_happy(PlayerbotAI* botAI) { return new HunterPetNotHappy(botAI); }
|
static Trigger* pet_not_happy(PlayerbotAI* botAI) { return new HunterPetNotHappy(botAI); }
|
||||||
static Trigger* serpent_sting_on_attacker(PlayerbotAI* botAI) { return new SerpentStingOnAttackerTrigger(botAI); }
|
static Trigger* serpent_sting_on_attacker(PlayerbotAI* botAI) { return new SerpentStingOnAttackerTrigger(botAI); }
|
||||||
static Trigger* trueshot_aura(PlayerbotAI* botAI) { return new TrueshotAuraTrigger(botAI); }
|
static Trigger* trueshot_aura(PlayerbotAI* botAI) { return new TrueshotAuraTrigger(botAI); }
|
||||||
|
static Trigger* no_track(PlayerbotAI* botAI) { return new NoTrackTrigger(botAI); }
|
||||||
static Trigger* aspect_of_the_viper(PlayerbotAI* botAI) { return new HunterAspectOfTheViperTrigger(botAI); }
|
static Trigger* aspect_of_the_viper(PlayerbotAI* botAI) { return new HunterAspectOfTheViperTrigger(botAI); }
|
||||||
static Trigger* black_arrow(PlayerbotAI* botAI) { return new BlackArrowTrigger(botAI); }
|
static Trigger* black_arrow(PlayerbotAI* botAI) { return new BlackArrowTrigger(botAI); }
|
||||||
static Trigger* NoStings(PlayerbotAI* botAI) { return new HunterNoStingsActiveTrigger(botAI); }
|
static Trigger* NoStings(PlayerbotAI* botAI) { return new HunterNoStingsActiveTrigger(botAI); }
|
||||||
@@ -159,6 +161,7 @@ public:
|
|||||||
creators["aspect of the pack"] = &HunterAiObjectContextInternal::aspect_of_the_pack;
|
creators["aspect of the pack"] = &HunterAiObjectContextInternal::aspect_of_the_pack;
|
||||||
creators["aspect of the cheetah"] = &HunterAiObjectContextInternal::aspect_of_the_cheetah;
|
creators["aspect of the cheetah"] = &HunterAiObjectContextInternal::aspect_of_the_cheetah;
|
||||||
creators["trueshot aura"] = &HunterAiObjectContextInternal::trueshot_aura;
|
creators["trueshot aura"] = &HunterAiObjectContextInternal::trueshot_aura;
|
||||||
|
creators["track humanoids"] = &HunterAiObjectContextInternal::track_humanoids;
|
||||||
creators["feign death"] = &HunterAiObjectContextInternal::feign_death;
|
creators["feign death"] = &HunterAiObjectContextInternal::feign_death;
|
||||||
creators["wing clip"] = &HunterAiObjectContextInternal::wing_clip;
|
creators["wing clip"] = &HunterAiObjectContextInternal::wing_clip;
|
||||||
creators["raptor strike"] = &HunterAiObjectContextInternal::raptor_strike;
|
creators["raptor strike"] = &HunterAiObjectContextInternal::raptor_strike;
|
||||||
@@ -182,6 +185,7 @@ private:
|
|||||||
static Action* feed_pet(PlayerbotAI* botAI) { return new FeedPetAction(botAI); }
|
static Action* feed_pet(PlayerbotAI* botAI) { return new FeedPetAction(botAI); }
|
||||||
static Action* feign_death(PlayerbotAI* botAI) { return new CastFeignDeathAction(botAI); }
|
static Action* feign_death(PlayerbotAI* botAI) { return new CastFeignDeathAction(botAI); }
|
||||||
static Action* trueshot_aura(PlayerbotAI* botAI) { return new CastTrueshotAuraAction(botAI); }
|
static Action* trueshot_aura(PlayerbotAI* botAI) { return new CastTrueshotAuraAction(botAI); }
|
||||||
|
static Action* track_humanoids(PlayerbotAI* botAI) { return new CastBuffSpellAction(botAI, "track humanoids"); }
|
||||||
static Action* auto_shot(PlayerbotAI* botAI) { return new CastAutoShotAction(botAI); }
|
static Action* auto_shot(PlayerbotAI* botAI) { return new CastAutoShotAction(botAI); }
|
||||||
static Action* aimed_shot(PlayerbotAI* botAI) { return new CastAimedShotAction(botAI); }
|
static Action* aimed_shot(PlayerbotAI* botAI) { return new CastAimedShotAction(botAI); }
|
||||||
static Action* chimera_shot(PlayerbotAI* botAI) { return new CastChimeraShotAction(botAI); }
|
static Action* chimera_shot(PlayerbotAI* botAI) { return new CastChimeraShotAction(botAI); }
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ bool HunterPetNotHappy::IsActive()
|
|||||||
bool HunterAspectOfTheViperTrigger::IsActive()
|
bool HunterAspectOfTheViperTrigger::IsActive()
|
||||||
{
|
{
|
||||||
return SpellTrigger::IsActive() && !botAI->HasAura(spell, GetTarget()) &&
|
return SpellTrigger::IsActive() && !botAI->HasAura(spell, GetTarget()) &&
|
||||||
AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig->lowMana;
|
AI_VALUE2(uint8, "mana", "self target") < (sPlayerbotAIConfig->lowMana / 2);
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,3 +88,36 @@ bool SwitchToMeleeTrigger::IsActive()
|
|||||||
(target->GetVictim() == bot &&
|
(target->GetVictim() == bot &&
|
||||||
sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "current target"), 8.0f));
|
sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "current target"), 8.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NoTrackTrigger::IsActive()
|
||||||
|
{
|
||||||
|
std::vector<std::string> track_list = {
|
||||||
|
"track beasts",
|
||||||
|
"track demons",
|
||||||
|
"track dragonkin",
|
||||||
|
"track elementals",
|
||||||
|
"track giants",
|
||||||
|
"track hidden",
|
||||||
|
"track humanoids"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto &track: track_list)
|
||||||
|
{
|
||||||
|
if (botAI->HasAura(track, bot))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SerpentStingOnAttackerTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!DebuffOnAttackerTrigger::IsActive())
|
||||||
|
return false;
|
||||||
|
Unit* target = GetTarget();
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !botAI->HasAura("scorpid sting", target, false, true) &&
|
||||||
|
!botAI->HasAura("viper sting", target, false, true);
|
||||||
|
}
|
||||||
@@ -101,10 +101,18 @@ public:
|
|||||||
TrueshotAuraTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "trueshot aura") {}
|
TrueshotAuraTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "trueshot aura") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NoTrackTrigger : public BuffTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NoTrackTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "no track") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
class SerpentStingOnAttackerTrigger : public DebuffOnAttackerTrigger
|
class SerpentStingOnAttackerTrigger : public DebuffOnAttackerTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SerpentStingOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "serpent sting", true) {}
|
SerpentStingOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "serpent sting", true) {}
|
||||||
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
BEGIN_TRIGGER(HunterPetNotHappy, Trigger)
|
BEGIN_TRIGGER(HunterPetNotHappy, Trigger)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ private:
|
|||||||
{
|
{
|
||||||
return new ActionNode("arcane barrage",
|
return new ActionNode("arcane barrage",
|
||||||
/*P*/ nullptr,
|
/*P*/ nullptr,
|
||||||
/*A*/ NextAction::array(0, new NextAction("arcane missiles"), nullptr),
|
/*A*/ nullptr,
|
||||||
/*C*/ nullptr);
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,8 +59,10 @@ ArcaneMageStrategy::ArcaneMageStrategy(PlayerbotAI* botAI) : GenericMageStrategy
|
|||||||
|
|
||||||
NextAction** ArcaneMageStrategy::getDefaultActions()
|
NextAction** ArcaneMageStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(0, new NextAction("arcane blast", ACTION_DEFAULT + 0.1f),
|
return NextAction::array(0, new NextAction("arcane blast", ACTION_DEFAULT + 0.3f),
|
||||||
new NextAction("shoot", ACTION_DEFAULT), NULL);
|
// new NextAction("arcane barrage", ACTION_DEFAULT + 0.2f), // cast during movement
|
||||||
|
new NextAction("fire blast", ACTION_DEFAULT + 0.1f), // cast during movement
|
||||||
|
new NextAction("shoot", ACTION_DEFAULT), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArcaneMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void ArcaneMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
NextAction** FireMageStrategy::getDefaultActions()
|
NextAction** FireMageStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(0, new NextAction("fireball", ACTION_DEFAULT + 0.1f),
|
return NextAction::array(0, new NextAction("fireball", ACTION_DEFAULT + 0.2f),
|
||||||
|
new NextAction("fire blast", ACTION_DEFAULT + 0.1f), // cast during movement
|
||||||
new NextAction("shoot", ACTION_DEFAULT), NULL);
|
new NextAction("shoot", ACTION_DEFAULT), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,6 +24,8 @@ void FireMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
new TriggerNode("hot streak", NextAction::array(0, new NextAction("pyroblast", 25.0f), nullptr)));
|
new TriggerNode("hot streak", NextAction::array(0, new NextAction("pyroblast", 25.0f), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("combustion", NextAction::array(0, new NextAction("combustion", 50.0f), nullptr)));
|
new TriggerNode("combustion", NextAction::array(0, new NextAction("combustion", 50.0f), nullptr)));
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("living bomb", NextAction::array(0, new NextAction("living bomb", 19.0f), nullptr)));
|
||||||
// triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("dragon's
|
// triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("dragon's
|
||||||
// breath", 70.0f), nullptr)));
|
// breath", 70.0f), nullptr)));
|
||||||
}
|
}
|
||||||
@@ -30,7 +33,10 @@ void FireMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
void FireMageAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void FireMageAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("medium aoe", NextAction::array(0, new NextAction("flamestrike", 20.0f), nullptr)));
|
new TriggerNode("medium aoe", NextAction::array(0,
|
||||||
triggers.push_back(
|
new NextAction("dragon's breath", 24.0f),
|
||||||
new TriggerNode("living bomb", NextAction::array(0, new NextAction("living bomb", 25.0f), nullptr)));
|
new NextAction("flamestrike", 23.0f),
|
||||||
|
new NextAction("blast wave", 22.0f),
|
||||||
|
new NextAction("living bomb on attackers", 21.0f),
|
||||||
|
new NextAction("blizzard", 20.0f), nullptr)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ void FrostMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("has pet", NextAction::array(0, new NextAction("toggle pet spell", ACTION_HIGH + 1), nullptr)));
|
new TriggerNode("has pet", NextAction::array(0, new NextAction("toggle pet spell", ACTION_HIGH + 1), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("ice barrier", NextAction::array(0, new NextAction("ice barrier", ACTION_NORMAL), nullptr)));
|
new TriggerNode("medium health", NextAction::array(0, new NextAction("ice barrier", ACTION_NORMAL), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"brain freeze", NextAction::array(0, new NextAction("frostfire bolt", ACTION_NORMAL + 3), nullptr)));
|
"brain freeze", NextAction::array(0, new NextAction("frostfire bolt", ACTION_NORMAL + 3), nullptr)));
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ void GenericMageNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& trigg
|
|||||||
|
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("arcane intellect", NextAction::array(0, new NextAction("arcane intellect", 21.0f), nullptr)));
|
new TriggerNode("arcane intellect", NextAction::array(0, new NextAction("arcane intellect", 21.0f), nullptr)));
|
||||||
|
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("no focus magic", NextAction::array(0, new NextAction("focus magic on party", 19.0f), nullptr)));
|
||||||
// triggers.push_back(new TriggerNode("no drink", NextAction::array(0, new NextAction("conjure water", 16.0f),
|
// 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
|
// nullptr))); triggers.push_back(new TriggerNode("no food", NextAction::array(0, new NextAction("conjure
|
||||||
// food", 15.0f), nullptr)));
|
// food", 15.0f), nullptr)));
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ private:
|
|||||||
{
|
{
|
||||||
return new ActionNode("fire blast",
|
return new ActionNode("fire blast",
|
||||||
/*P*/ nullptr,
|
/*P*/ nullptr,
|
||||||
/*A*/ NextAction::array(0, new NextAction("scorch"), nullptr),
|
/*A*/ nullptr,
|
||||||
/*C*/ nullptr);
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,16 +115,16 @@ private:
|
|||||||
{
|
{
|
||||||
return new ActionNode("dragon's breath",
|
return new ActionNode("dragon's breath",
|
||||||
/*P*/ nullptr,
|
/*P*/ nullptr,
|
||||||
/*A*/ NextAction::array(0, new NextAction("blast wave"), nullptr),
|
/*A*/ nullptr,
|
||||||
/*C*/ NextAction::array(0, new NextAction("flamestrike", 71.0f), nullptr));
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ActionNode* blast_wave([[maybe_unused]] PlayerbotAI* botAI)
|
static ActionNode* blast_wave([[maybe_unused]] PlayerbotAI* botAI)
|
||||||
{
|
{
|
||||||
return new ActionNode("blast wave",
|
return new ActionNode("blast wave",
|
||||||
/*P*/ nullptr,
|
/*P*/ nullptr,
|
||||||
/*A*/ NextAction::array(0, new NextAction("frost nova"), nullptr),
|
/*A*/ nullptr,
|
||||||
/*C*/ NextAction::array(0, new NextAction("flamestrike", 71.0f), nullptr));
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ActionNode* remove_curse([[maybe_unused]] PlayerbotAI* botAI)
|
static ActionNode* remove_curse([[maybe_unused]] PlayerbotAI* botAI)
|
||||||
@@ -194,8 +194,7 @@ void MageBoostStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
triggers.push_back(new TriggerNode("icy veins", NextAction::array(0, new NextAction("icy veins", 50.0f), nullptr)));
|
triggers.push_back(new TriggerNode("icy veins", NextAction::array(0, new NextAction("icy veins", 50.0f), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("presence of mind", NextAction::array(0, new NextAction("presence of mind", 42.0f), nullptr)));
|
new TriggerNode("presence of mind", NextAction::array(0, new NextAction("presence of mind", 42.0f), nullptr)));
|
||||||
// triggers.push_back(new TriggerNode("arcane power", NextAction::array(0, new NextAction("arcane power", 41.0f),
|
// triggers.push_back(new TriggerNode("arcane power", NextAction::array(0, new NextAction("arcane power", 41.0f), nullptr)));
|
||||||
// nullptr)));
|
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("mirror image", NextAction::array(0, new NextAction("mirror image", 41.0f), nullptr)));
|
new TriggerNode("mirror image", NextAction::array(0, new NextAction("mirror image", 41.0f), nullptr)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,18 @@
|
|||||||
|
|
||||||
#include "MageActions.h"
|
#include "MageActions.h"
|
||||||
|
|
||||||
|
#include "PlayerbotAIConfig.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
#include "ServerFacade.h"
|
#include "ServerFacade.h"
|
||||||
|
#include "SharedDefines.h"
|
||||||
|
|
||||||
Value<Unit*>* CastPolymorphAction::GetTargetValue() { return context->GetValue<Unit*>("cc target", getName()); }
|
Value<Unit*>* CastPolymorphAction::GetTargetValue() { return context->GetValue<Unit*>("cc target", getName()); }
|
||||||
|
|
||||||
bool CastFrostNovaAction::isUseful()
|
bool CastFrostNovaAction::isUseful()
|
||||||
{
|
{
|
||||||
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
if (target && target->ToCreature() && target->ToCreature()->HasMechanicTemplateImmunity(1 << (MECHANIC_FREEZE - 1)))
|
||||||
|
return false;
|
||||||
return sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", GetTargetName()), 10.f);
|
return sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", GetTargetName()), 10.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,3 +26,65 @@ bool CastConeOfColdAction::isUseful()
|
|||||||
bool targetClose = sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", GetTargetName()), 10.f);
|
bool targetClose = sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", GetTargetName()), 10.f);
|
||||||
return facingTarget && targetClose;
|
return facingTarget && targetClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CastDragonsBreathAction::isUseful()
|
||||||
|
{
|
||||||
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
if (!target)
|
||||||
|
return false;
|
||||||
|
bool facingTarget = AI_VALUE2(bool, "facing", "current target");
|
||||||
|
bool targetClose = bot->IsWithinCombatRange(target, 10.0f);
|
||||||
|
return facingTarget && targetClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CastBlastWaveAction::isUseful()
|
||||||
|
{
|
||||||
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
if (!target)
|
||||||
|
return false;
|
||||||
|
bool targetClose = bot->IsWithinCombatRange(target, 10.0f);
|
||||||
|
return targetClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* CastFocusMagicOnPartyAction::GetTarget()
|
||||||
|
{
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
Unit* casterDps = nullptr;
|
||||||
|
Unit* healer = nullptr;
|
||||||
|
Unit* target = nullptr;
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
|
{
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (!member || member == bot || !member->IsAlive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (member->GetMap() != bot->GetMap() || bot->GetDistance(member) > sPlayerbotAIConfig->spellDistance)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (member->HasAura(54646))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (member->getClass() == CLASS_MAGE)
|
||||||
|
return member;
|
||||||
|
|
||||||
|
if (!casterDps && botAI->IsCaster(member) && botAI->IsDps(member))
|
||||||
|
casterDps = member;
|
||||||
|
|
||||||
|
if (!healer && botAI->IsHeal(member))
|
||||||
|
healer = member;
|
||||||
|
|
||||||
|
if (!target)
|
||||||
|
target = member;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (casterDps)
|
||||||
|
return casterDps;
|
||||||
|
|
||||||
|
if (healer)
|
||||||
|
return healer;
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
@@ -57,10 +57,10 @@ public:
|
|||||||
CastPyroblastAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "pyroblast") {}
|
CastPyroblastAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "pyroblast") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastFlamestrikeAction : public CastSpellAction
|
class CastFlamestrikeAction : public CastDebuffSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastFlamestrikeAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "flamestrike") {}
|
CastFlamestrikeAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "flamestrike", true, 0.0f) {}
|
||||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -243,11 +243,18 @@ public:
|
|||||||
CastLivingBombAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "living bomb", true) {}
|
CastLivingBombAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "living bomb", true) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CastLivingBombOnAttackersAction : public CastDebuffSpellOnAttackerAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastLivingBombOnAttackersAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "living bomb", true) {}
|
||||||
|
};
|
||||||
|
|
||||||
class CastDragonsBreathAction : public CastSpellAction
|
class CastDragonsBreathAction : public CastSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastDragonsBreathAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "dragon's breath") {}
|
CastDragonsBreathAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "dragon's breath") {}
|
||||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||||
|
bool isUseful() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastBlastWaveAction : public CastSpellAction
|
class CastBlastWaveAction : public CastSpellAction
|
||||||
@@ -255,6 +262,7 @@ class CastBlastWaveAction : public CastSpellAction
|
|||||||
public:
|
public:
|
||||||
CastBlastWaveAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "blast wave") {}
|
CastBlastWaveAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "blast wave") {}
|
||||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||||
|
bool isUseful() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastInvisibilityAction : public CastBuffSpellAction
|
class CastInvisibilityAction : public CastBuffSpellAction
|
||||||
@@ -294,4 +302,11 @@ public:
|
|||||||
CastMirrorImageAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "mirror image") {}
|
CastMirrorImageAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "mirror image") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CastFocusMagicOnPartyAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastFocusMagicOnPartyAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "focus magic") {}
|
||||||
|
Unit* GetTarget() override;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ public:
|
|||||||
creators["mirror image"] = &MageTriggerFactoryInternal::mirror_image;
|
creators["mirror image"] = &MageTriggerFactoryInternal::mirror_image;
|
||||||
creators["frost nova on target"] = &MageTriggerFactoryInternal::frost_nova_on_target;
|
creators["frost nova on target"] = &MageTriggerFactoryInternal::frost_nova_on_target;
|
||||||
creators["frostbite on target"] = &MageTriggerFactoryInternal::frostbite_on_target;
|
creators["frostbite on target"] = &MageTriggerFactoryInternal::frostbite_on_target;
|
||||||
|
creators["no focus magic"] = &MageTriggerFactoryInternal::no_focus_magic;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -141,6 +142,7 @@ private:
|
|||||||
static Trigger* mirror_image(PlayerbotAI* botAI) { return new MirrorImageTrigger(botAI); }
|
static Trigger* mirror_image(PlayerbotAI* botAI) { return new MirrorImageTrigger(botAI); }
|
||||||
static Trigger* frost_nova_on_target(PlayerbotAI* botAI) { return new FrostNovaOnTargetTrigger(botAI); }
|
static Trigger* frost_nova_on_target(PlayerbotAI* botAI) { return new FrostNovaOnTargetTrigger(botAI); }
|
||||||
static Trigger* frostbite_on_target(PlayerbotAI* botAI) { return new FrostbiteOnTargetTrigger(botAI); }
|
static Trigger* frostbite_on_target(PlayerbotAI* botAI) { return new FrostbiteOnTargetTrigger(botAI); }
|
||||||
|
static Trigger* no_focus_magic(PlayerbotAI* botAI) { return new NoFocusMagicTrigger(botAI); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class MageAiObjectContextInternal : public NamedObjectContext<Action>
|
class MageAiObjectContextInternal : public NamedObjectContext<Action>
|
||||||
@@ -184,6 +186,7 @@ public:
|
|||||||
creators["polymorph"] = &MageAiObjectContextInternal::polymorph;
|
creators["polymorph"] = &MageAiObjectContextInternal::polymorph;
|
||||||
creators["spellsteal"] = &MageAiObjectContextInternal::spellsteal;
|
creators["spellsteal"] = &MageAiObjectContextInternal::spellsteal;
|
||||||
creators["living bomb"] = &MageAiObjectContextInternal::living_bomb;
|
creators["living bomb"] = &MageAiObjectContextInternal::living_bomb;
|
||||||
|
creators["living bomb on attackers"] = &MageAiObjectContextInternal::living_bomb_on_attackers;
|
||||||
creators["dragon's breath"] = &MageAiObjectContextInternal::dragons_breath;
|
creators["dragon's breath"] = &MageAiObjectContextInternal::dragons_breath;
|
||||||
creators["blast wave"] = &MageAiObjectContextInternal::blast_wave;
|
creators["blast wave"] = &MageAiObjectContextInternal::blast_wave;
|
||||||
creators["invisibility"] = &MageAiObjectContextInternal::invisibility;
|
creators["invisibility"] = &MageAiObjectContextInternal::invisibility;
|
||||||
@@ -195,6 +198,7 @@ public:
|
|||||||
creators["fire ward"] = &MageAiObjectContextInternal::fire_ward;
|
creators["fire ward"] = &MageAiObjectContextInternal::fire_ward;
|
||||||
creators["frost ward"] = &MageAiObjectContextInternal::frost_ward;
|
creators["frost ward"] = &MageAiObjectContextInternal::frost_ward;
|
||||||
creators["mirror image"] = &MageAiObjectContextInternal::mirror_image;
|
creators["mirror image"] = &MageAiObjectContextInternal::mirror_image;
|
||||||
|
creators["focus magic on party"] = &MageAiObjectContextInternal::focus_magic_on_party;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -242,6 +246,7 @@ private:
|
|||||||
static Action* polymorph(PlayerbotAI* botAI) { return new CastPolymorphAction(botAI); }
|
static Action* polymorph(PlayerbotAI* botAI) { return new CastPolymorphAction(botAI); }
|
||||||
static Action* spellsteal(PlayerbotAI* botAI) { return new CastSpellstealAction(botAI); }
|
static Action* spellsteal(PlayerbotAI* botAI) { return new CastSpellstealAction(botAI); }
|
||||||
static Action* living_bomb(PlayerbotAI* botAI) { return new CastLivingBombAction(botAI); }
|
static Action* living_bomb(PlayerbotAI* botAI) { return new CastLivingBombAction(botAI); }
|
||||||
|
static Action* living_bomb_on_attackers(PlayerbotAI* botAI) { return new CastLivingBombOnAttackersAction(botAI); }
|
||||||
static Action* dragons_breath(PlayerbotAI* botAI) { return new CastDragonsBreathAction(botAI); }
|
static Action* dragons_breath(PlayerbotAI* botAI) { return new CastDragonsBreathAction(botAI); }
|
||||||
static Action* blast_wave(PlayerbotAI* botAI) { return new CastBlastWaveAction(botAI); }
|
static Action* blast_wave(PlayerbotAI* botAI) { return new CastBlastWaveAction(botAI); }
|
||||||
static Action* invisibility(PlayerbotAI* botAI) { return new CastInvisibilityAction(botAI); }
|
static Action* invisibility(PlayerbotAI* botAI) { return new CastInvisibilityAction(botAI); }
|
||||||
@@ -251,6 +256,7 @@ private:
|
|||||||
return new CastCounterspellOnEnemyHealerAction(botAI);
|
return new CastCounterspellOnEnemyHealerAction(botAI);
|
||||||
}
|
}
|
||||||
static Action* mirror_image(PlayerbotAI* botAI) { return new CastMirrorImageAction(botAI); }
|
static Action* mirror_image(PlayerbotAI* botAI) { return new CastMirrorImageAction(botAI); }
|
||||||
|
static Action* focus_magic_on_party(PlayerbotAI* botAI) { return new CastFocusMagicOnPartyAction(botAI); }
|
||||||
};
|
};
|
||||||
|
|
||||||
MageAiObjectContext::MageAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
|
MageAiObjectContext::MageAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
|
||||||
|
|||||||
@@ -33,6 +33,17 @@ bool FingersOfFrostSingleTrigger::IsActive()
|
|||||||
return (aura && aura->GetCharges() == 1);
|
return (aura && aura->GetCharges() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ArcaneBlastStackTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Aura* aura = botAI->GetAura(getName(), GetTarget(), false, true, 3);
|
||||||
|
if (!aura)
|
||||||
|
return false;
|
||||||
|
if (aura->GetStackAmount() >= 4)
|
||||||
|
return true;
|
||||||
|
bool hasMissileBarrage = botAI->HasAura(44401, bot);
|
||||||
|
return hasMissileBarrage;
|
||||||
|
}
|
||||||
|
|
||||||
bool FrostNovaOnTargetTrigger::IsActive()
|
bool FrostNovaOnTargetTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Unit* target = GetTarget();
|
Unit* target = GetTarget();
|
||||||
@@ -52,3 +63,24 @@ bool FrostbiteOnTargetTrigger::IsActive()
|
|||||||
}
|
}
|
||||||
return botAI->HasAura(spell, target);
|
return botAI->HasAura(spell, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NoFocusMagicTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!bot->HasSpell(54646))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
|
{
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (!member || member == bot || !member->IsAlive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (member->HasAura(54646, bot->GetGUID()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ class ArcaneBlastStackTrigger : public HasAuraStackTrigger
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ArcaneBlastStackTrigger(PlayerbotAI* botAI) : HasAuraStackTrigger(botAI, "arcane blast", 3, 1) {}
|
ArcaneBlastStackTrigger(PlayerbotAI* botAI) : HasAuraStackTrigger(botAI, "arcane blast", 3, 1) {}
|
||||||
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MirrorImageTrigger : public BoostTrigger
|
class MirrorImageTrigger : public BoostTrigger
|
||||||
@@ -193,4 +194,11 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NoFocusMagicTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NoFocusMagicTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no focus magic") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ ShadowPriestStrategy::ShadowPriestStrategy(PlayerbotAI* botAI) : GenericPriestSt
|
|||||||
|
|
||||||
NextAction** ShadowPriestStrategy::getDefaultActions()
|
NextAction** ShadowPriestStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(0, new NextAction("mind blast", ACTION_DEFAULT + 0.2f),
|
return NextAction::array(0, new NextAction("mind blast", ACTION_DEFAULT + 0.3f),
|
||||||
// new NextAction("shadow word: death", 12.0f),
|
new NextAction("mind flay", ACTION_DEFAULT + 0.2f),
|
||||||
new NextAction("mind flay", ACTION_DEFAULT + 0.1f),
|
new NextAction("shadow word: death", ACTION_DEFAULT + 0.1f), // cast during movement
|
||||||
new NextAction("shoot", ACTION_DEFAULT), NULL);
|
new NextAction("shoot", ACTION_DEFAULT), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowPriestStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void ShadowPriestStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ CasterShamanStrategy::CasterShamanStrategy(PlayerbotAI* botAI) : GenericShamanSt
|
|||||||
NextAction** CasterShamanStrategy::getDefaultActions()
|
NextAction** CasterShamanStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(0, new NextAction("lava burst", ACTION_DEFAULT + 0.2f),
|
return NextAction::array(0, new NextAction("lava burst", ACTION_DEFAULT + 0.2f),
|
||||||
new NextAction("lightning bolt", ACTION_DEFAULT), NULL);
|
new NextAction("lightning bolt", ACTION_DEFAULT + 0.1f),
|
||||||
|
// new NextAction("earth shock", ACTION_DEFAULT), // cast during movement
|
||||||
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CasterShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void CasterShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "ShamanTriggers.h"
|
#include "ShamanTriggers.h"
|
||||||
|
|
||||||
|
#include "ItemTemplate.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -46,8 +47,12 @@ bool MainHandWeaponNoImbueTrigger::IsActive()
|
|||||||
bool OffHandWeaponNoImbueTrigger::IsActive()
|
bool OffHandWeaponNoImbueTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Item* const itemForSpell = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
|
Item* const itemForSpell = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
|
||||||
if (!itemForSpell || itemForSpell->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) ||
|
if (!itemForSpell)
|
||||||
itemForSpell->GetTemplate()->InventoryType != INVTYPE_WEAPON)
|
return false;
|
||||||
|
uint32 invType = itemForSpell->GetTemplate()->InventoryType;
|
||||||
|
bool allowedType = (invType == INVTYPE_WEAPON) || (invType == INVTYPE_WEAPONOFFHAND);
|
||||||
|
if (itemForSpell->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) ||
|
||||||
|
!allowedType)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ public:
|
|||||||
class FlameShockTrigger : public DebuffTrigger
|
class FlameShockTrigger : public DebuffTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FlameShockTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "flame shock", 1, true) {}
|
FlameShockTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "flame shock", 1, true, 6.0f) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class WrathOfAirTotemTrigger : public TotemTrigger
|
class WrathOfAirTotemTrigger : public TotemTrigger
|
||||||
|
|||||||
@@ -618,8 +618,8 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const GetTargetName() { return "self target"; }
|
std::string const GetTargetName() override { return "self target"; }
|
||||||
virtual bool IsActive();
|
bool IsActive() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int stack;
|
int stack;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ float EstimatedGroupDpsValue::Calculate()
|
|||||||
if (member == bot) // calculated
|
if (member == bot) // calculated
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!member || !member->IsInWorld())
|
if (!member || !member->IsInWorld() || !member->IsAlive())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (member->GetMapId() != bot->GetMapId())
|
if (member->GetMapId() != bot->GetMapId())
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ DpsWarlockStrategy::DpsWarlockStrategy(PlayerbotAI* botAI) : GenericWarlockStrat
|
|||||||
NextAction** DpsWarlockStrategy::getDefaultActions()
|
NextAction** DpsWarlockStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(
|
return NextAction::array(
|
||||||
0, new NextAction("haunt", ACTION_DEFAULT + 0.3f), new NextAction("demonic empowerment", ACTION_DEFAULT + 0.2f),
|
0, new NextAction("haunt", ACTION_DEFAULT + 0.4f), new NextAction("demonic empowerment", ACTION_DEFAULT + 0.3f),
|
||||||
new NextAction("shadow bolt", ACTION_DEFAULT + 0.1f), new NextAction("shoot", ACTION_DEFAULT), nullptr);
|
new NextAction("shadow bolt", ACTION_DEFAULT + 0.2f), new NextAction("shoot", ACTION_DEFAULT), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DpsWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void DpsWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
@@ -71,6 +71,12 @@ void DpsWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
|
|
||||||
triggers.push_back(new TriggerNode("decimation", NextAction::array(0, new NextAction("soul fire", 16.0f), NULL)));
|
triggers.push_back(new TriggerNode("decimation", NextAction::array(0, new NextAction("soul fire", 16.0f), NULL)));
|
||||||
|
|
||||||
|
// cast during movement
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("high mana", NextAction::array(0, new NextAction("life tap", ACTION_DEFAULT + 0.1f), nullptr)));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("life tap glyph buff", NextAction::array(0, new NextAction("life tap", 28.0f), NULL)));
|
||||||
|
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("metamorphosis", NextAction::array(0, new NextAction("metamorphosis", 20.0f), NULL)));
|
new TriggerNode("metamorphosis", NextAction::array(0, new NextAction("metamorphosis", 20.0f), NULL)));
|
||||||
}
|
}
|
||||||
@@ -78,9 +84,9 @@ void DpsWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
void DpsAoeWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void DpsAoeWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("medium aoe", NextAction::array(0, new NextAction("seed of corruption", 39.0f),
|
new TriggerNode("medium aoe", NextAction::array(0, new NextAction("seed of corruption", 33.0f),
|
||||||
new NextAction("seed of corruption on attacker", 38.0f),
|
new NextAction("seed of corruption on attacker", 32.0f),
|
||||||
new NextAction("rain of fire", 37.0f), nullptr)));
|
new NextAction("rain of fire", 31.0f), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("corruption on attacker",
|
triggers.push_back(new TriggerNode("corruption on attacker",
|
||||||
NextAction::array(0, new NextAction("corruption on attacker", 27.0f), nullptr)));
|
NextAction::array(0, new NextAction("corruption on attacker", 27.0f), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Value<Unit*>* CastFearOnCcAction::GetTargetValue() { return context->GetValue<Un
|
|||||||
|
|
||||||
bool CastFearOnCcAction::Execute(Event event) { return botAI->CastSpell("fear", GetTarget()); }
|
bool CastFearOnCcAction::Execute(Event event) { return botAI->CastSpell("fear", GetTarget()); }
|
||||||
|
|
||||||
bool CastFearOnCcAction::isPossible() { return botAI->CanCastSpell("fear", GetTarget()); }
|
bool CastFearOnCcAction::isPossible() { return true; }
|
||||||
|
|
||||||
bool CastFearOnCcAction::isUseful() { return true; }
|
bool CastFearOnCcAction::isUseful() { return true; }
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "WarlockAiObjectContext.h"
|
#include "WarlockAiObjectContext.h"
|
||||||
|
|
||||||
#include "DpsWarlockStrategy.h"
|
#include "DpsWarlockStrategy.h"
|
||||||
|
#include "GenericTriggers.h"
|
||||||
#include "GenericWarlockNonCombatStrategy.h"
|
#include "GenericWarlockNonCombatStrategy.h"
|
||||||
#include "NamedObjectContext.h"
|
#include "NamedObjectContext.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
@@ -98,6 +99,7 @@ public:
|
|||||||
creators["unstable affliction on attacker"] = &WarlockTriggerFactoryInternal::unstable_affliction_on_attacker;
|
creators["unstable affliction on attacker"] = &WarlockTriggerFactoryInternal::unstable_affliction_on_attacker;
|
||||||
creators["haunt"] = &WarlockTriggerFactoryInternal::haunt;
|
creators["haunt"] = &WarlockTriggerFactoryInternal::haunt;
|
||||||
creators["decimation"] = &WarlockTriggerFactoryInternal::decimation;
|
creators["decimation"] = &WarlockTriggerFactoryInternal::decimation;
|
||||||
|
creators["life tap glyph buff"] = &WarlockTriggerFactoryInternal::life_tap_glyph_buff;
|
||||||
creators["molten core"] = &WarlockTriggerFactoryInternal::molten_core;
|
creators["molten core"] = &WarlockTriggerFactoryInternal::molten_core;
|
||||||
creators["metamorphosis"] = &WarlockTriggerFactoryInternal::metamorphosis;
|
creators["metamorphosis"] = &WarlockTriggerFactoryInternal::metamorphosis;
|
||||||
}
|
}
|
||||||
@@ -131,6 +133,7 @@ private:
|
|||||||
}
|
}
|
||||||
static Trigger* haunt(PlayerbotAI* ai) { return new HauntTrigger(ai); }
|
static Trigger* haunt(PlayerbotAI* ai) { return new HauntTrigger(ai); }
|
||||||
static Trigger* decimation(PlayerbotAI* ai) { return new DecimationTrigger(ai); }
|
static Trigger* decimation(PlayerbotAI* ai) { return new DecimationTrigger(ai); }
|
||||||
|
static Trigger* life_tap_glyph_buff(PlayerbotAI* ai) { return new LifeTapGlyphBuffTrigger(ai); }
|
||||||
static Trigger* molten_core(PlayerbotAI* ai) { return new MoltenCoreTrigger(ai); }
|
static Trigger* molten_core(PlayerbotAI* ai) { return new MoltenCoreTrigger(ai); }
|
||||||
static Trigger* metamorphosis(PlayerbotAI* ai) { return new MetamorphosisTrigger(ai); }
|
static Trigger* metamorphosis(PlayerbotAI* ai) { return new MetamorphosisTrigger(ai); }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "WarlockTriggers.h"
|
#include "WarlockTriggers.h"
|
||||||
|
|
||||||
|
#include "GenericTriggers.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
|
||||||
bool DemonArmorTrigger::IsActive()
|
bool DemonArmorTrigger::IsActive()
|
||||||
@@ -45,3 +46,12 @@ bool DecimationTrigger::IsActive()
|
|||||||
Aura* aura = botAI->GetAura(getName(), GetTarget(), false, true);
|
Aura* aura = botAI->GetAura(getName(), GetTarget(), false, true);
|
||||||
return aura && aura->GetDuration() > 3000;
|
return aura && aura->GetDuration() > 3000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LifeTapGlyphBuffTrigger::IsActive()
|
||||||
|
{
|
||||||
|
// Check life tap glyph first
|
||||||
|
if (!botAI->HasAura(63320, bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return BuffTrigger::IsActive();
|
||||||
|
}
|
||||||
@@ -163,6 +163,13 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LifeTapGlyphBuffTrigger : public BuffTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LifeTapGlyphBuffTrigger(PlayerbotAI* ai) : BuffTrigger(ai, "life tap") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
class MoltenCoreTrigger : public HasAuraTrigger
|
class MoltenCoreTrigger : public HasAuraTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ bool CastSunderArmorAction::isUseful()
|
|||||||
return !aura || aura->GetStackAmount() < 5 || aura->GetDuration() <= 6000;
|
return !aura || aura->GetStackAmount() < 5 || aura->GetDuration() <= 6000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value<Unit*>* CastVigilanceAction::GetTargetValue()
|
Unit* CastVigilanceAction::GetTarget()
|
||||||
{
|
{
|
||||||
Group* group = bot->GetGroup();
|
Group* group = bot->GetGroup();
|
||||||
if (!group)
|
if (!group)
|
||||||
{
|
{
|
||||||
return new ManualSetValue<Unit*>(botAI, nullptr);
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player* currentVigilanceTarget = nullptr;
|
Player* currentVigilanceTarget = nullptr;
|
||||||
@@ -74,23 +74,23 @@ Value<Unit*>* CastVigilanceAction::GetTargetValue()
|
|||||||
// If no valid target, return nullptr
|
// If no valid target, return nullptr
|
||||||
if (!highestPriorityTarget)
|
if (!highestPriorityTarget)
|
||||||
{
|
{
|
||||||
return new ManualSetValue<Unit*>(botAI, nullptr);
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the current target is already the highest-priority target, do nothing
|
// If the current target is already the highest-priority target, do nothing
|
||||||
if (currentVigilanceTarget == highestPriorityTarget)
|
if (currentVigilanceTarget == highestPriorityTarget)
|
||||||
{
|
{
|
||||||
return new ManualSetValue<Unit*>(botAI, nullptr);
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign the new target
|
// Assign the new target
|
||||||
Unit* targetUnit = highestPriorityTarget->ToUnit();
|
Unit* targetUnit = highestPriorityTarget->ToUnit();
|
||||||
if (targetUnit)
|
if (targetUnit)
|
||||||
{
|
{
|
||||||
return new ManualSetValue<Unit*>(botAI, targetUnit);
|
return targetUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ManualSetValue<Unit*>(botAI, nullptr);
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CastVigilanceAction::Execute(Event event)
|
bool CastVigilanceAction::Execute(Event event)
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ class CastVigilanceAction : public BuffOnPartyAction
|
|||||||
public:
|
public:
|
||||||
CastVigilanceAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "vigilance") {}
|
CastVigilanceAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "vigilance") {}
|
||||||
|
|
||||||
Value<Unit*>* GetTargetValue() override;
|
Unit* GetTarget() override;
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user