mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Compare commits
14 Commits
revert-136
...
hermensbas
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
284e8c17b5 | ||
|
|
57a2c9a742 | ||
|
|
3dd0f11453 | ||
|
|
00cc2468f1 | ||
|
|
cf8253579e | ||
|
|
2000c06167 | ||
|
|
453925153f | ||
|
|
9a10f07c74 | ||
|
|
7d6f44ab09 | ||
|
|
bb004825aa | ||
|
|
097bd00f38 | ||
|
|
290bf50faf | ||
|
|
e739f7820b | ||
|
|
6fbaf6510b |
@@ -483,8 +483,8 @@ AiPlayerbot.AutoGearQualityLimit = 3
|
|||||||
|
|
||||||
# Equipment item level (not gearscore) limitation for autogear command (0 = no limit)
|
# Equipment item level (not gearscore) limitation for autogear command (0 = no limit)
|
||||||
# Classic
|
# Classic
|
||||||
# Max iLVL Tier 1 = 66 | Tier 2 = 76 | Tier 2.5 = 81 | Tier 3 = 99
|
# Max iLVL Tier 1 = 66 | Tier 2 = 76 | Tier 2.5 = 88 | Tier 3 = 92
|
||||||
# Max iLVL Phase 1 = 71(MC, ONY, ZG) | Phase 2(BWL) = 77 | Phase 2.5(AQ) = 88 | Phase 3(NAXX) = 100 (NOT RECOMMENDED SINCE ILVL OVERLAPS BETWEEN TIERS)
|
# Max iLVL Phase 1(MC, Ony, ZG) = 78 | Phase 2(BWL) = 83 | Phase 2.5(AQ40) = 88 | Phase 3(Naxx40) = 92
|
||||||
# TBC
|
# TBC
|
||||||
# Max iLVL Tier 4 = 120 | Tier 5 = 133 | Tier 6 = 164
|
# Max iLVL Tier 4 = 120 | Tier 5 = 133 | Tier 6 = 164
|
||||||
# Max iLVL Phase 1(Kara, Gruul, Mag) = 125 | Phase 1.5(ZA) = 138 | Phase 2(SC, TK) = 141 | Phase 3(Hyjal, BT) = 156 | Phase 4(Sunwell) = 164
|
# Max iLVL Phase 1(Kara, Gruul, Mag) = 125 | Phase 1.5(ZA) = 138 | Phase 2(SC, TK) = 141 | Phase 3(Hyjal, BT) = 156 | Phase 4(Sunwell) = 164
|
||||||
@@ -642,8 +642,8 @@ AiPlayerbot.RandomGearQualityLimit = 3
|
|||||||
|
|
||||||
# Equipment item level (not gearscore) limitation for randombots (0 = no limit)
|
# Equipment item level (not gearscore) limitation for randombots (0 = no limit)
|
||||||
# Classic
|
# Classic
|
||||||
# Max iLVL Tier 1 = 66 | Tier 2 = 76 | Tier 2.5 = 81 | Tier 3 = 99
|
# Max iLVL Tier 1 = 66 | Tier 2 = 76 | Tier 2.5 = 88 | Tier 3 = 92
|
||||||
# Max iLVL Phase 1 = 71(MC, ONY, ZG) | Phase 2(BWL) = 77 | Phase 2.5(AQ) = 88 | Phase 3(NAXX) = 100 (NOT RECOMMENDED SINCE ILVL OVERLAPS BETWEEN TIERS)
|
# Max iLVL Phase 1(MC, Ony, ZG) = 78 | Phase 2(BWL) = 83 | Phase 2.5(AQ40) = 88 | Phase 3(Naxx40) = 92
|
||||||
# TBC
|
# TBC
|
||||||
# Max iLVL Tier 4 = 120 | Tier 5 = 133 | Tier 6 = 164
|
# Max iLVL Tier 4 = 120 | Tier 5 = 133 | Tier 6 = 164
|
||||||
# Max iLVL Phase 1(Kara, Gruul, Mag) = 125 | Phase 1.5(ZA) = 138 | Phase 2(SC, TK) = 141 | Phase 3(Hyjal, BT) = 156 | Phase 4(Sunwell) = 164
|
# Max iLVL Phase 1(Kara, Gruul, Mag) = 125 | Phase 1.5(ZA) = 138 | Phase 2(SC, TK) = 141 | Phase 3(Hyjal, BT) = 156 | Phase 4(Sunwell) = 164
|
||||||
@@ -717,8 +717,8 @@ AiPlayerbot.BotActiveAloneForceWhenInGuild = 1
|
|||||||
# The default is 1. When enabled (smart) scales the 'BotActiveAlone' value.
|
# The default is 1. When enabled (smart) scales the 'BotActiveAlone' value.
|
||||||
# (The scaling will be overruled by the BotActiveAloneForceWhen...rules)
|
# (The scaling will be overruled by the BotActiveAloneForceWhen...rules)
|
||||||
#
|
#
|
||||||
# Limitfloor - when DIFF (latency) above floor, activity scaling is applied starting with 90%
|
# Limitfloor - when DIFF (latency) is above floor, activity scaling begins
|
||||||
# LimitCeiling - when DIFF (latency) above ceiling, activity is 0%;
|
# LimitCeiling - when DIFF (latency) is above ceiling, activity is 0%
|
||||||
#
|
#
|
||||||
# MinLevel - only apply scaling when level is above or equal to min(bot)Level
|
# 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
|
# MaxLevel - only apply scaling when level is lower or equal of max(bot)Level
|
||||||
@@ -1062,7 +1062,7 @@ AiPlayerbot.DeleteRandomBotArenaTeams = 0
|
|||||||
AiPlayerbot.PvpProhibitedZoneIds = "2255,656,2361,2362,2363,976,35,2268,3425,392,541,1446,3828,3712,3738,3565,3539,3623,4152,3988,4658,4284,4418,4436,4275,4323,4395,3703,4298,139"
|
AiPlayerbot.PvpProhibitedZoneIds = "2255,656,2361,2362,2363,976,35,2268,3425,392,541,1446,3828,3712,3738,3565,3539,3623,4152,3988,4658,4284,4418,4436,4275,4323,4395,3703,4298,139"
|
||||||
|
|
||||||
# PvP Restricted Areas (bots don't pvp)
|
# PvP Restricted Areas (bots don't pvp)
|
||||||
AiPlayerbot.PvpProhibitedAreaIds = "976,35,392,2268,4161,4010,4317,4312"
|
AiPlayerbot.PvpProhibitedAreaIds = "976,35,392,2268,4161,4010,4317,4312,3649,3887,3958,3724,4080"
|
||||||
|
|
||||||
# Improve reaction speeds in battlegrounds and arenas (may cause lag)
|
# Improve reaction speeds in battlegrounds and arenas (may cause lag)
|
||||||
AiPlayerbot.FastReactInBG = 1
|
AiPlayerbot.FastReactInBG = 1
|
||||||
@@ -1341,8 +1341,8 @@ AiPlayerbot.PremadeSpecLink.9.1.70 = -003203301135112530135201051-55
|
|||||||
AiPlayerbot.PremadeSpecLink.9.1.80 = -003203301135112530135221351-55000005
|
AiPlayerbot.PremadeSpecLink.9.1.80 = -003203301135112530135221351-55000005
|
||||||
AiPlayerbot.PremadeSpecName.9.2 = destro pve
|
AiPlayerbot.PremadeSpecName.9.2 = destro pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.9.2 = 45785,43390,50077,43394,43393,42454
|
AiPlayerbot.PremadeSpecGlyph.9.2 = 45785,43390,50077,43394,43393,42454
|
||||||
AiPlayerbot.PremadeSpecLink.9.2.60 = --05203205210131051313230341
|
AiPlayerbot.PremadeSpecLink.9.2.60 = --05203215200231051305031151
|
||||||
AiPlayerbot.PremadeSpecLink.9.2.80 = -03310030003-05203205210331051335230351
|
AiPlayerbot.PremadeSpecLink.9.2.80 = 23-0302-05203215220331051335231351
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
@@ -1590,11 +1590,11 @@ AiPlayerbot.RandomClassSpecIndex.8.2 = 2
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
AiPlayerbot.RandomClassSpecProb.9.0 = 45
|
AiPlayerbot.RandomClassSpecProb.9.0 = 33
|
||||||
AiPlayerbot.RandomClassSpecIndex.9.0 = 0
|
AiPlayerbot.RandomClassSpecIndex.9.0 = 0
|
||||||
AiPlayerbot.RandomClassSpecProb.9.1 = 45
|
AiPlayerbot.RandomClassSpecProb.9.1 = 34
|
||||||
AiPlayerbot.RandomClassSpecIndex.9.1 = 1
|
AiPlayerbot.RandomClassSpecIndex.9.1 = 1
|
||||||
AiPlayerbot.RandomClassSpecProb.9.2 = 10
|
AiPlayerbot.RandomClassSpecProb.9.2 = 33
|
||||||
AiPlayerbot.RandomClassSpecIndex.9.2 = 2
|
AiPlayerbot.RandomClassSpecIndex.9.2 = 2
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1888,3 +1888,9 @@ AiPlayerbot.TargetPosRecalcDistance = 0.1
|
|||||||
|
|
||||||
# Allow bots to be summoned near innkeepers
|
# Allow bots to be summoned near innkeepers
|
||||||
AiPlayerbot.SummonAtInnkeepersEnabled = 1
|
AiPlayerbot.SummonAtInnkeepersEnabled = 1
|
||||||
|
|
||||||
|
# Enable buffs in ICC to make Heroic easier and more casual.
|
||||||
|
# 30% more damage, 40% damage reduction (tank bots), increased all resistances, reduced threat for non tank bots, increased threat for tank bots.
|
||||||
|
# Buffs will be applied on PP, Sindragosa and Lich King
|
||||||
|
|
||||||
|
AiPlayerbot.EnableICCBuffs = 1
|
||||||
|
|||||||
@@ -385,8 +385,16 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLASS_WARLOCK:
|
case CLASS_WARLOCK:
|
||||||
engine->addStrategiesNoInit("dps assist", "dps", "dps debuff", "aoe", nullptr);
|
if (tab == 0) // Affliction
|
||||||
|
engine->addStrategiesNoInit("affli", "affli aoe", nullptr);
|
||||||
|
else if (tab == 1) // Demonology
|
||||||
|
engine->addStrategiesNoInit("demo", "demo aoe", "meta melee", nullptr);
|
||||||
|
else if (tab == 2) // Destruction
|
||||||
|
engine->addStrategiesNoInit("destro", "destro aoe", "curse of elements", nullptr);
|
||||||
|
|
||||||
|
engine->addStrategiesNoInit("cc", "dps assist", nullptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLASS_DEATH_KNIGHT:
|
case CLASS_DEATH_KNIGHT:
|
||||||
if (tab == 0)
|
if (tab == 0)
|
||||||
engine->addStrategiesNoInit("blood", "tank assist", nullptr);
|
engine->addStrategiesNoInit("blood", "tank assist", nullptr);
|
||||||
@@ -588,15 +596,15 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
|||||||
case CLASS_WARLOCK:
|
case CLASS_WARLOCK:
|
||||||
if (tab == WARLOCK_TAB_AFFLICATION)
|
if (tab == WARLOCK_TAB_AFFLICATION)
|
||||||
{
|
{
|
||||||
nonCombatEngine->addStrategiesNoInit("bmana", nullptr);
|
nonCombatEngine->addStrategiesNoInit("felhunter", nullptr);
|
||||||
}
|
}
|
||||||
else if (tab == WARLOCK_TAB_DEMONOLOGY)
|
else if (tab == WARLOCK_TAB_DEMONOLOGY)
|
||||||
{
|
{
|
||||||
nonCombatEngine->addStrategiesNoInit("bdps", nullptr);
|
nonCombatEngine->addStrategiesNoInit("felguard", nullptr);
|
||||||
}
|
}
|
||||||
else if (tab == WARLOCK_TAB_DESTRUCTION)
|
else if (tab == WARLOCK_TAB_DESTRUCTION)
|
||||||
{
|
{
|
||||||
nonCombatEngine->addStrategiesNoInit("bhealth", nullptr);
|
nonCombatEngine->addStrategiesNoInit("imp", nullptr);
|
||||||
}
|
}
|
||||||
nonCombatEngine->addStrategiesNoInit("dps assist", nullptr);
|
nonCombatEngine->addStrategiesNoInit("dps assist", nullptr);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -525,6 +525,11 @@ uint32 GuildTaskMgr::GetMaxItemTaskCount(uint32 itemId)
|
|||||||
|
|
||||||
bool GuildTaskMgr::IsGuildTaskItem(uint32 itemId, uint32 guildId)
|
bool GuildTaskMgr::IsGuildTaskItem(uint32 itemId, uint32 guildId)
|
||||||
{
|
{
|
||||||
|
if (!sPlayerbotAIConfig->guildTaskEnabled)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 value = 0;
|
uint32 value = 0;
|
||||||
|
|
||||||
PlayerbotsDatabasePreparedStatement* stmt =
|
PlayerbotsDatabasePreparedStatement* stmt =
|
||||||
@@ -548,6 +553,11 @@ bool GuildTaskMgr::IsGuildTaskItem(uint32 itemId, uint32 guildId)
|
|||||||
std::map<uint32, uint32> GuildTaskMgr::GetTaskValues(uint32 owner, std::string const type,
|
std::map<uint32, uint32> GuildTaskMgr::GetTaskValues(uint32 owner, std::string const type,
|
||||||
[[maybe_unused]] uint32* validIn /* = nullptr */)
|
[[maybe_unused]] uint32* validIn /* = nullptr */)
|
||||||
{
|
{
|
||||||
|
if (!sPlayerbotAIConfig->guildTaskEnabled)
|
||||||
|
{
|
||||||
|
return std::map<uint32, uint32>();
|
||||||
|
}
|
||||||
|
|
||||||
std::map<uint32, uint32> results;
|
std::map<uint32, uint32> results;
|
||||||
|
|
||||||
PlayerbotsDatabasePreparedStatement* stmt =
|
PlayerbotsDatabasePreparedStatement* stmt =
|
||||||
@@ -576,6 +586,11 @@ std::map<uint32, uint32> GuildTaskMgr::GetTaskValues(uint32 owner, std::string c
|
|||||||
|
|
||||||
uint32 GuildTaskMgr::GetTaskValue(uint32 owner, uint32 guildId, std::string const type, [[maybe_unused]] uint32* validIn /* = nullptr */)
|
uint32 GuildTaskMgr::GetTaskValue(uint32 owner, uint32 guildId, std::string const type, [[maybe_unused]] uint32* validIn /* = nullptr */)
|
||||||
{
|
{
|
||||||
|
if (!sPlayerbotAIConfig->guildTaskEnabled)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 value = 0;
|
uint32 value = 0;
|
||||||
|
|
||||||
PlayerbotsDatabasePreparedStatement* stmt =
|
PlayerbotsDatabasePreparedStatement* stmt =
|
||||||
|
|||||||
@@ -3154,22 +3154,41 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget)
|
|||||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||||
if (pet && pet->HasSpell(spellId))
|
if (pet && pet->HasSpell(spellId))
|
||||||
{
|
{
|
||||||
bool autocast = false;
|
// List of spell IDs for which we do NOT want to toggle auto-cast or send message
|
||||||
for (unsigned int& m_autospell : pet->m_autospells)
|
// We are excluding Spell Lock and Devour Magic because they are casted in the GenericWarlockStrategy
|
||||||
|
// Without this exclusion, the skill would be togged for auto-cast and the player would
|
||||||
|
// be spammed with messages about enabling/disabling auto-cast
|
||||||
|
switch (spellId)
|
||||||
{
|
{
|
||||||
if (m_autospell == spellId)
|
case 19244: // Spell Lock rank 1
|
||||||
{
|
case 19647: // Spell Lock rank 2
|
||||||
autocast = true;
|
case 19505: // Devour Magic rank 1
|
||||||
|
case 19731: // Devour Magic rank 2
|
||||||
|
case 19734: // Devour Magic rank 3
|
||||||
|
case 19736: // Devour Magic rank 4
|
||||||
|
case 27276: // Devour Magic rank 5
|
||||||
|
case 27277: // Devour Magic rank 6
|
||||||
|
case 48011: // Devour Magic rank 7
|
||||||
|
// No message - just break out of the switch and let normal cast logic continue
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
}
|
bool autocast = false;
|
||||||
|
for (unsigned int& m_autospell : pet->m_autospells)
|
||||||
|
{
|
||||||
|
if (m_autospell == spellId)
|
||||||
|
{
|
||||||
|
autocast = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pet->ToggleAutocast(spellInfo, !autocast);
|
pet->ToggleAutocast(spellInfo, !autocast);
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << (autocast ? "|cffff0000|Disabling" : "|cFF00ff00|Enabling") << " pet auto-cast for ";
|
out << (autocast ? "|cffff0000|Disabling" : "|cFF00ff00|Enabling") << " pet auto-cast for ";
|
||||||
out << chatHelper.FormatSpell(spellInfo);
|
out << chatHelper.FormatSpell(spellInfo);
|
||||||
TellMaster(out);
|
TellMaster(out);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// aiObjectContext->GetValue<LastMovement&>("last movement")->Get().Set(nullptr);
|
// aiObjectContext->GetValue<LastMovement&>("last movement")->Get().Set(nullptr);
|
||||||
@@ -4365,26 +4384,28 @@ bool PlayerbotAI::AllowActivity(ActivityType activityType, bool checkNow)
|
|||||||
|
|
||||||
uint32 PlayerbotAI::AutoScaleActivity(uint32 mod)
|
uint32 PlayerbotAI::AutoScaleActivity(uint32 mod)
|
||||||
{
|
{
|
||||||
|
// Current max server update time (ms), and the configured floor/ceiling values for bot scaling
|
||||||
uint32 maxDiff = sWorldUpdateTime.GetMaxUpdateTimeOfCurrentTable();
|
uint32 maxDiff = sWorldUpdateTime.GetMaxUpdateTimeOfCurrentTable();
|
||||||
uint32 diffLimitFloor = sPlayerbotAIConfig->botActiveAloneSmartScaleDiffLimitfloor;
|
uint32 diffLimitFloor = sPlayerbotAIConfig->botActiveAloneSmartScaleDiffLimitfloor;
|
||||||
uint32 diffLimitCeiling = sPlayerbotAIConfig->botActiveAloneSmartScaleDiffLimitCeiling;
|
uint32 diffLimitCeiling = sPlayerbotAIConfig->botActiveAloneSmartScaleDiffLimitCeiling;
|
||||||
double spreadSize = (double)(diffLimitCeiling - diffLimitFloor) / 6;
|
|
||||||
|
|
||||||
// apply scaling
|
if (diffLimitCeiling <= diffLimitFloor)
|
||||||
|
{
|
||||||
|
// Perfrom binary decision if ceiling <= floor: Either all bots are active or none are
|
||||||
|
return (maxDiff > diffLimitCeiling) ? 0 : mod;
|
||||||
|
}
|
||||||
|
|
||||||
if (maxDiff > diffLimitCeiling)
|
if (maxDiff > diffLimitCeiling)
|
||||||
return 0;
|
return 0;
|
||||||
if (maxDiff > diffLimitFloor + (4 * spreadSize))
|
|
||||||
return (mod * 1) / 10;
|
if (maxDiff <= diffLimitFloor)
|
||||||
if (maxDiff > diffLimitFloor + (3 * spreadSize))
|
return mod;
|
||||||
return (mod * 3) / 10;
|
|
||||||
if (maxDiff > diffLimitFloor + (2 * spreadSize))
|
// Calculate lag progress from floor to ceiling (0 to 1)
|
||||||
return (mod * 5) / 10;
|
double lagProgress = (maxDiff - diffLimitFloor) / (double)(diffLimitCeiling - diffLimitFloor);
|
||||||
if (maxDiff > diffLimitFloor + (1 * spreadSize))
|
|
||||||
return (mod * 7) / 10;
|
// Apply the percentage of active bots (the complement of lag progress) to the mod value
|
||||||
if (maxDiff > diffLimitFloor)
|
return static_cast<uint32>(mod * (1 - lagProgress));
|
||||||
return (mod * 9) / 10;
|
|
||||||
|
|
||||||
return mod;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlayerbotAI::IsOpposing(Player* player) { return IsOpposing(player->getRace(), bot->getRace()); }
|
bool PlayerbotAI::IsOpposing(Player* player) { return IsOpposing(player->getRace(), bot->getRace()); }
|
||||||
@@ -6300,4 +6321,4 @@ void PlayerbotAI::AddTimedEvent(std::function<void()> callback, uint32 delayMs)
|
|||||||
bot->m_Events.AddEvent(
|
bot->m_Events.AddEvent(
|
||||||
new LambdaEvent(std::move(callback)),
|
new LambdaEvent(std::move(callback)),
|
||||||
bot->m_Events.CalculateTime(delayMs));
|
bot->m_Events.CalculateTime(delayMs));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,6 +189,10 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
maxRandomBotsPriceChangeInterval =
|
maxRandomBotsPriceChangeInterval =
|
||||||
sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotsPriceChangeInterval", 48 * HOUR);
|
sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotsPriceChangeInterval", 48 * HOUR);
|
||||||
randomBotJoinLfg = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotJoinLfg", true);
|
randomBotJoinLfg = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotJoinLfg", true);
|
||||||
|
|
||||||
|
//////////////////////////// ICC
|
||||||
|
|
||||||
|
EnableICCBuffs = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableICCBuffs", true);
|
||||||
|
|
||||||
//////////////////////////// CHAT
|
//////////////////////////// CHAT
|
||||||
enableBroadcasts = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableBroadcasts", true);
|
enableBroadcasts = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableBroadcasts", true);
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ public:
|
|||||||
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
bool disabledWithoutRealPlayer;
|
bool disabledWithoutRealPlayer;
|
||||||
|
bool EnableICCBuffs;
|
||||||
bool allowAccountBots, allowGuildBots, allowTrustedAccountBots;
|
bool allowAccountBots, allowGuildBots, allowTrustedAccountBots;
|
||||||
bool randomBotGuildNearby, randomBotInvitePlayer, inviteChat;
|
bool randomBotGuildNearby, randomBotInvitePlayer, inviteChat;
|
||||||
uint32 globalCoolDown, reactDelay, maxWaitForMove, disableMoveSplinePath, maxMovementSearchTime, expireActionTime,
|
uint32 globalCoolDown, reactDelay, maxWaitForMove, disableMoveSplinePath, maxMovementSearchTime, expireActionTime,
|
||||||
|
|||||||
@@ -83,7 +83,14 @@ bool DropTargetAction::Execute(Event event)
|
|||||||
bot->SetTarget(ObjectGuid::Empty);
|
bot->SetTarget(ObjectGuid::Empty);
|
||||||
bot->SetSelection(ObjectGuid());
|
bot->SetSelection(ObjectGuid());
|
||||||
botAI->ChangeEngine(BOT_STATE_NON_COMBAT);
|
botAI->ChangeEngine(BOT_STATE_NON_COMBAT);
|
||||||
// botAI->InterruptSpell();
|
if (bot->getClass() == CLASS_HUNTER) // Check for Hunter Class
|
||||||
|
{
|
||||||
|
Spell const* spell = bot->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL); // Get the current spell being cast by the bot
|
||||||
|
if (spell && spell->m_spellInfo->Id == 75) //Check spell is not nullptr before accessing m_spellInfo
|
||||||
|
{
|
||||||
|
bot->InterruptSpell(CURRENT_AUTOREPEAT_SPELL); // Interrupt Auto Shot
|
||||||
|
}
|
||||||
|
}
|
||||||
bot->AttackStop();
|
bot->AttackStop();
|
||||||
|
|
||||||
// if (Pet* pet = bot->GetPet())
|
// if (Pet* pet = bot->GetPet())
|
||||||
|
|||||||
@@ -14,10 +14,25 @@ enum PetSpells
|
|||||||
PET_PROWL_2 = 24452,
|
PET_PROWL_2 = 24452,
|
||||||
PET_PROWL_3 = 24453,
|
PET_PROWL_3 = 24453,
|
||||||
PET_COWER = 1742,
|
PET_COWER = 1742,
|
||||||
PET_LEAP = 47482
|
PET_LEAP = 47482,
|
||||||
|
PET_SPELL_LOCK_1 = 19244,
|
||||||
|
PET_SPELL_LOCK_2 = 19647,
|
||||||
|
PET_DEVOUR_MAGIC_1 = 19505,
|
||||||
|
PET_DEVOUR_MAGIC_2 = 19731,
|
||||||
|
PET_DEVOUR_MAGIC_3 = 19734,
|
||||||
|
PET_DEVOUR_MAGIC_4 = 19736,
|
||||||
|
PET_DEVOUR_MAGIC_5 = 27276,
|
||||||
|
PET_DEVOUR_MAGIC_6 = 27277,
|
||||||
|
PET_DEVOUR_MAGIC_7 = 48011
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<uint32> disabledPetSpells = {PET_PROWL_1, PET_PROWL_2, PET_PROWL_3, PET_COWER, PET_LEAP};
|
static std::vector<uint32> disabledPetSpells = {
|
||||||
|
PET_PROWL_1, PET_PROWL_2, PET_PROWL_3,
|
||||||
|
PET_COWER, PET_LEAP,
|
||||||
|
PET_SPELL_LOCK_1, PET_SPELL_LOCK_2,
|
||||||
|
PET_DEVOUR_MAGIC_1, PET_DEVOUR_MAGIC_2, PET_DEVOUR_MAGIC_3,
|
||||||
|
PET_DEVOUR_MAGIC_4, PET_DEVOUR_MAGIC_5, PET_DEVOUR_MAGIC_6, PET_DEVOUR_MAGIC_7
|
||||||
|
};
|
||||||
|
|
||||||
bool MeleeAction::isUseful()
|
bool MeleeAction::isUseful()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -304,7 +304,6 @@ bool UseTrinketAction::Execute(Event event)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
Item* trinket2 = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_TRINKET2);
|
Item* trinket2 = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_TRINKET2);
|
||||||
|
|
||||||
if (trinket2 && UseTrinket(trinket2))
|
if (trinket2 && UseTrinket(trinket2))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -333,6 +332,15 @@ bool UseTrinketAction::UseTrinket(Item* item)
|
|||||||
if (item->GetTemplate()->Spells[i].SpellId > 0 && item->GetTemplate()->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_USE)
|
if (item->GetTemplate()->Spells[i].SpellId > 0 && item->GetTemplate()->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_USE)
|
||||||
{
|
{
|
||||||
spellId = item->GetTemplate()->Spells[i].SpellId;
|
spellId = item->GetTemplate()->Spells[i].SpellId;
|
||||||
|
uint32 spellProcFlag = sSpellMgr->GetSpellInfo(spellId)->ProcFlags;
|
||||||
|
|
||||||
|
// Handle items with procflag "if you kill a target that grants honor or experience"
|
||||||
|
// Bots will "learn" the trinket proc, so CanCastSpell() will be true
|
||||||
|
// e.g. on Item https://www.wowhead.com/wotlk/item=44074/oracle-talisman-of-ablution leading to
|
||||||
|
// constant casting of the proc spell onto themselfes https://www.wowhead.com/wotlk/spell=59787/oracle-ablutions
|
||||||
|
// This will lead to multiple hundreds of entries in m_appliedAuras -> Once killing an enemy -> Big diff time spikes
|
||||||
|
if (spellProcFlag != 0) return false;
|
||||||
|
|
||||||
if (!botAI->CanCastSpell(spellId, bot, false))
|
if (!botAI->CanCastSpell(spellId, bot, false))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ReleaseSpiritAction.h"
|
#include "ReleaseSpiritAction.h"
|
||||||
|
#include "ServerFacade.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "GameGraveyard.h"
|
#include "GameGraveyard.h"
|
||||||
#include "NearestNpcsValue.h"
|
#include "NearestNpcsValue.h"
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
#include "ServerFacade.h"
|
#include "ServerFacade.h"
|
||||||
#include "Corpse.h"
|
#include "Corpse.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
// ReleaseSpiritAction implementation
|
// ReleaseSpiritAction implementation
|
||||||
bool ReleaseSpiritAction::Execute(Event event)
|
bool ReleaseSpiritAction::Execute(Event event)
|
||||||
@@ -247,3 +248,19 @@ void RepopAction::PerformGraveyardTeleport(const GraveyardStruct* graveyard) con
|
|||||||
RESET_AI_VALUE(bool, "combat::self target");
|
RESET_AI_VALUE(bool, "combat::self target");
|
||||||
RESET_AI_VALUE(WorldPosition, "current position");
|
RESET_AI_VALUE(WorldPosition, "current position");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SelfResurrectAction implementation for Warlock's Soulstone Resurrection/Shaman's Reincarnation
|
||||||
|
bool SelfResurrectAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
if (!bot->IsAlive() && bot->GetUInt32Value(PLAYER_SELF_RES_SPELL))
|
||||||
|
{
|
||||||
|
WorldPacket packet(CMSG_SELF_RES);
|
||||||
|
bot->GetSession()->HandleSelfResOpcode(packet);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool SelfResurrectAction::isUseful()
|
||||||
|
{
|
||||||
|
return !bot->IsAlive() && bot->GetUInt32Value(PLAYER_SELF_RES_SPELL);
|
||||||
|
}
|
||||||
|
|||||||
@@ -56,4 +56,13 @@ private:
|
|||||||
void PerformGraveyardTeleport(const GraveyardStruct* graveyard) const;
|
void PerformGraveyardTeleport(const GraveyardStruct* graveyard) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// SelfResurrectAction action registration
|
||||||
|
class SelfResurrectAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SelfResurrectAction(PlayerbotAI* ai) : Action(ai, "self resurrect") {}
|
||||||
|
virtual bool Execute(Event event) override;
|
||||||
|
bool isUseful() override;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -238,9 +238,24 @@ bool UseItemAction::UseItem(Item* item, ObjectGuid goGuid, Item* itemTarget, Uni
|
|||||||
{
|
{
|
||||||
targetFlag = TARGET_FLAG_NONE;
|
targetFlag = TARGET_FLAG_NONE;
|
||||||
packet << targetFlag;
|
packet << targetFlag;
|
||||||
packet << bot->GetPackGUID();
|
|
||||||
targetSelected = true;
|
// Use the actual target if provided
|
||||||
out << " on self";
|
if (unitTarget)
|
||||||
|
{
|
||||||
|
packet << unitTarget->GetGUID();
|
||||||
|
targetSelected = true;
|
||||||
|
// If the target is bot or is an enemy, say "on self"
|
||||||
|
if (unitTarget == bot || (unitTarget->IsHostileTo(bot)))
|
||||||
|
out << " on self";
|
||||||
|
else
|
||||||
|
out << " on " << unitTarget->GetName();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet << bot->GetPackGUID();
|
||||||
|
targetSelected = true;
|
||||||
|
out << " on self";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemTemplate const* proto = item->GetTemplate();
|
ItemTemplate const* proto = item->GetTemplate();
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include "TradeStatusExtendedAction.h"
|
#include "TradeStatusExtendedAction.h"
|
||||||
#include "UseMeetingStoneAction.h"
|
#include "UseMeetingStoneAction.h"
|
||||||
#include "NamedObjectContext.h"
|
#include "NamedObjectContext.h"
|
||||||
|
#include "ReleaseSpiritAction.h"
|
||||||
|
|
||||||
class PlayerbotAI;
|
class PlayerbotAI;
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@ public:
|
|||||||
creators["accept trade"] = &WorldPacketActionContext::accept_trade;
|
creators["accept trade"] = &WorldPacketActionContext::accept_trade;
|
||||||
creators["trade status extended"] = &WorldPacketActionContext::trade_status_extended;
|
creators["trade status extended"] = &WorldPacketActionContext::trade_status_extended;
|
||||||
creators["store loot"] = &WorldPacketActionContext::store_loot;
|
creators["store loot"] = &WorldPacketActionContext::store_loot;
|
||||||
|
creators["self resurrect"] = &WorldPacketActionContext::self_resurrect;
|
||||||
|
|
||||||
// quest
|
// quest
|
||||||
creators["talk to quest giver"] = &WorldPacketActionContext::turn_in_quest;
|
creators["talk to quest giver"] = &WorldPacketActionContext::turn_in_quest;
|
||||||
@@ -136,6 +138,7 @@ private:
|
|||||||
static Action* tell_not_enough_money(PlayerbotAI* botAI) { return new TellMasterAction(botAI, "Not enough money"); }
|
static Action* tell_not_enough_money(PlayerbotAI* botAI) { return new TellMasterAction(botAI, "Not enough money"); }
|
||||||
static Action* tell_not_enough_reputation(PlayerbotAI* botAI) { return new TellMasterAction(botAI, "Not enough reputation"); }
|
static Action* tell_not_enough_reputation(PlayerbotAI* botAI) { return new TellMasterAction(botAI, "Not enough reputation"); }
|
||||||
static Action* tell_cannot_equip(PlayerbotAI* botAI) { return new InventoryChangeFailureAction(botAI); }
|
static Action* tell_cannot_equip(PlayerbotAI* botAI) { return new InventoryChangeFailureAction(botAI); }
|
||||||
|
static Action* self_resurrect(PlayerbotAI* botAI) { return new SelfResurrectAction(botAI); }
|
||||||
|
|
||||||
// quest
|
// quest
|
||||||
static Action* quest_update_add_kill(PlayerbotAI* ai) { return new QuestUpdateAddKillAction(ai); }
|
static Action* quest_update_add_kill(PlayerbotAI* ai) { return new QuestUpdateAddKillAction(ai); }
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ void DeadStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
new TriggerNode("falling far", NextAction::array(0, new NextAction("repop", relevance + 1.f), nullptr)));
|
new TriggerNode("falling far", NextAction::array(0, new NextAction("repop", relevance + 1.f), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("location stuck", NextAction::array(0, new NextAction("repop", relevance + 1), nullptr)));
|
new TriggerNode("location stuck", NextAction::array(0, new NextAction("repop", relevance + 1), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode(
|
||||||
|
"can self resurrect", NextAction::array(0, new NextAction("self resurrect", relevance + 2.0f), nullptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
DeadStrategy::DeadStrategy(PlayerbotAI* botAI) : PassTroughStrategy(botAI) {}
|
DeadStrategy::DeadStrategy(PlayerbotAI* botAI) : PassTroughStrategy(botAI) {}
|
||||||
|
|||||||
@@ -12,40 +12,52 @@ public:
|
|||||||
{
|
{
|
||||||
creators["icc lm tank position"] = &RaidIccActionContext::icc_lm_tank_position;
|
creators["icc lm tank position"] = &RaidIccActionContext::icc_lm_tank_position;
|
||||||
creators["icc spike"] = &RaidIccActionContext::icc_spike;
|
creators["icc spike"] = &RaidIccActionContext::icc_spike;
|
||||||
|
|
||||||
creators["icc dark reckoning"] = &RaidIccActionContext::icc_dark_reckoning;
|
creators["icc dark reckoning"] = &RaidIccActionContext::icc_dark_reckoning;
|
||||||
creators["icc ranged position lady deathwhisper"] = &RaidIccActionContext::icc_ranged_position_lady_deathwhisper;
|
creators["icc ranged position lady deathwhisper"] = &RaidIccActionContext::icc_ranged_position_lady_deathwhisper;
|
||||||
creators["icc adds lady deathwhisper"] = &RaidIccActionContext::icc_adds_lady_deathwhisper;
|
creators["icc adds lady deathwhisper"] = &RaidIccActionContext::icc_adds_lady_deathwhisper;
|
||||||
creators["icc shade lady deathwhisper"] = &RaidIccActionContext::icc_shade_lady_deathwhisper;
|
creators["icc shade lady deathwhisper"] = &RaidIccActionContext::icc_shade_lady_deathwhisper;
|
||||||
|
|
||||||
creators["icc rotting frost giant tank position"] = &RaidIccActionContext::icc_rotting_frost_giant_tank_position;
|
creators["icc rotting frost giant tank position"] = &RaidIccActionContext::icc_rotting_frost_giant_tank_position;
|
||||||
creators["icc cannon fire"] = &RaidIccActionContext::icc_cannon_fire;
|
creators["icc cannon fire"] = &RaidIccActionContext::icc_cannon_fire;
|
||||||
creators["icc gunship enter cannon"] = &RaidIccActionContext::icc_gunship_enter_cannon;
|
creators["icc gunship enter cannon"] = &RaidIccActionContext::icc_gunship_enter_cannon;
|
||||||
creators["icc gunship teleport ally"] = &RaidIccActionContext::icc_gunship_teleport_ally;
|
creators["icc gunship teleport ally"] = &RaidIccActionContext::icc_gunship_teleport_ally;
|
||||||
creators["icc gunship teleport horde"] = &RaidIccActionContext::icc_gunship_teleport_horde;
|
creators["icc gunship teleport horde"] = &RaidIccActionContext::icc_gunship_teleport_horde;
|
||||||
|
|
||||||
creators["icc dbs tank position"] = &RaidIccActionContext::icc_dbs_tank_position;
|
creators["icc dbs tank position"] = &RaidIccActionContext::icc_dbs_tank_position;
|
||||||
creators["icc adds dbs"] = &RaidIccActionContext::icc_adds_dbs;
|
creators["icc adds dbs"] = &RaidIccActionContext::icc_adds_dbs;
|
||||||
creators["icc festergut tank position"] = &RaidIccActionContext::icc_festergut_tank_position;
|
|
||||||
|
creators["icc festergut group position"] = &RaidIccActionContext::icc_festergut_group_position;
|
||||||
creators["icc festergut spore"] = &RaidIccActionContext::icc_festergut_spore;
|
creators["icc festergut spore"] = &RaidIccActionContext::icc_festergut_spore;
|
||||||
|
|
||||||
creators["icc rotface tank position"] = &RaidIccActionContext::icc_rotface_tank_position;
|
creators["icc rotface tank position"] = &RaidIccActionContext::icc_rotface_tank_position;
|
||||||
creators["icc rotface group position"] = &RaidIccActionContext::icc_rotface_group_position;
|
creators["icc rotface group position"] = &RaidIccActionContext::icc_rotface_group_position;
|
||||||
creators["icc rotface move away from explosion"] = &RaidIccActionContext::icc_rotface_move_away_from_explosion;
|
creators["icc rotface move away from explosion"] = &RaidIccActionContext::icc_rotface_move_away_from_explosion;
|
||||||
|
|
||||||
creators["icc putricide volatile ooze"] = &RaidIccActionContext::icc_putricide_volatile_ooze;
|
creators["icc putricide volatile ooze"] = &RaidIccActionContext::icc_putricide_volatile_ooze;
|
||||||
creators["icc putricide gas cloud"] = &RaidIccActionContext::icc_putricide_gas_cloud;
|
creators["icc putricide gas cloud"] = &RaidIccActionContext::icc_putricide_gas_cloud;
|
||||||
creators["icc putricide growing ooze puddle"] = &RaidIccActionContext::icc_putricide_growing_ooze_puddle;
|
creators["icc putricide growing ooze puddle"] = &RaidIccActionContext::icc_putricide_growing_ooze_puddle;
|
||||||
creators["avoid malleable goo"] = &RaidIccActionContext::avoid_malleable_goo;
|
creators["icc putricide avoid malleable goo"] = &RaidIccActionContext::icc_putricide_avoid_malleable_goo;
|
||||||
|
|
||||||
creators["icc bpc keleseth tank"] = &RaidIccActionContext::icc_bpc_keleseth_tank;
|
creators["icc bpc keleseth tank"] = &RaidIccActionContext::icc_bpc_keleseth_tank;
|
||||||
creators["icc bpc nucleus"] = &RaidIccActionContext::icc_bpc_nucleus;
|
|
||||||
creators["icc bpc main tank"] = &RaidIccActionContext::icc_bpc_main_tank;
|
creators["icc bpc main tank"] = &RaidIccActionContext::icc_bpc_main_tank;
|
||||||
creators["icc bpc empowered vortex"] = &RaidIccActionContext::icc_bpc_empowered_vortex;
|
creators["icc bpc empowered vortex"] = &RaidIccActionContext::icc_bpc_empowered_vortex;
|
||||||
creators["icc bpc kinetic bomb"] = &RaidIccActionContext::icc_bpc_kinetic_bomb;
|
creators["icc bpc kinetic bomb"] = &RaidIccActionContext::icc_bpc_kinetic_bomb;
|
||||||
creators["icc bql tank position"] = &RaidIccActionContext::icc_bql_tank_position;
|
creators["icc bpc ball of flame"] = &RaidIccActionContext::icc_bpc_ball_of_flame;
|
||||||
|
|
||||||
|
creators["icc bql group position"] = &RaidIccActionContext::icc_bql_group_position;
|
||||||
creators["icc bql pact of darkfallen"] = &RaidIccActionContext::icc_bql_pact_of_darkfallen;
|
creators["icc bql pact of darkfallen"] = &RaidIccActionContext::icc_bql_pact_of_darkfallen;
|
||||||
creators["icc bql vampiric bite"] = &RaidIccActionContext::icc_bql_vampiric_bite;
|
creators["icc bql vampiric bite"] = &RaidIccActionContext::icc_bql_vampiric_bite;
|
||||||
|
|
||||||
creators["icc valkyre spear"] = &RaidIccActionContext::icc_valkyre_spear;
|
creators["icc valkyre spear"] = &RaidIccActionContext::icc_valkyre_spear;
|
||||||
creators["icc sister svalna"] = &RaidIccActionContext::icc_sister_svalna;
|
creators["icc sister svalna"] = &RaidIccActionContext::icc_sister_svalna;
|
||||||
|
|
||||||
|
creators["icc valithria group"] = &RaidIccActionContext::icc_valithria_group;
|
||||||
creators["icc valithria portal"] = &RaidIccActionContext::icc_valithria_portal;
|
creators["icc valithria portal"] = &RaidIccActionContext::icc_valithria_portal;
|
||||||
creators["icc valithria heal"] = &RaidIccActionContext::icc_valithria_heal;
|
creators["icc valithria heal"] = &RaidIccActionContext::icc_valithria_heal;
|
||||||
creators["icc valithria dream cloud"] = &RaidIccActionContext::icc_valithria_dream_cloud;
|
creators["icc valithria dream cloud"] = &RaidIccActionContext::icc_valithria_dream_cloud;
|
||||||
creators["icc sindragosa tank position"] = &RaidIccActionContext::icc_sindragosa_tank_position;
|
|
||||||
|
creators["icc sindragosa group position"] = &RaidIccActionContext::icc_sindragosa_group_position;
|
||||||
creators["icc sindragosa frost beacon"] = &RaidIccActionContext::icc_sindragosa_frost_beacon;
|
creators["icc sindragosa frost beacon"] = &RaidIccActionContext::icc_sindragosa_frost_beacon;
|
||||||
creators["icc sindragosa blistering cold"] = &RaidIccActionContext::icc_sindragosa_blistering_cold;
|
creators["icc sindragosa blistering cold"] = &RaidIccActionContext::icc_sindragosa_blistering_cold;
|
||||||
creators["icc sindragosa unchained magic"] = &RaidIccActionContext::icc_sindragosa_unchained_magic;
|
creators["icc sindragosa unchained magic"] = &RaidIccActionContext::icc_sindragosa_unchained_magic;
|
||||||
@@ -53,6 +65,7 @@ public:
|
|||||||
creators["icc sindragosa mystic buffet"] = &RaidIccActionContext::icc_sindragosa_mystic_buffet;
|
creators["icc sindragosa mystic buffet"] = &RaidIccActionContext::icc_sindragosa_mystic_buffet;
|
||||||
creators["icc sindragosa frost bomb"] = &RaidIccActionContext::icc_sindragosa_frost_bomb;
|
creators["icc sindragosa frost bomb"] = &RaidIccActionContext::icc_sindragosa_frost_bomb;
|
||||||
creators["icc sindragosa tank swap position"] = &RaidIccActionContext::icc_sindragosa_tank_swap_position;
|
creators["icc sindragosa tank swap position"] = &RaidIccActionContext::icc_sindragosa_tank_swap_position;
|
||||||
|
|
||||||
creators["icc lich king shadow trap"] = &RaidIccActionContext::icc_lich_king_shadow_trap;
|
creators["icc lich king shadow trap"] = &RaidIccActionContext::icc_lich_king_shadow_trap;
|
||||||
creators["icc lich king necrotic plague"] = &RaidIccActionContext::icc_lich_king_necrotic_plague;
|
creators["icc lich king necrotic plague"] = &RaidIccActionContext::icc_lich_king_necrotic_plague;
|
||||||
creators["icc lich king winter"] = &RaidIccActionContext::icc_lich_king_winter;
|
creators["icc lich king winter"] = &RaidIccActionContext::icc_lich_king_winter;
|
||||||
@@ -62,40 +75,52 @@ public:
|
|||||||
private:
|
private:
|
||||||
static Action* icc_lm_tank_position(PlayerbotAI* ai) { return new IccLmTankPositionAction(ai); }
|
static Action* icc_lm_tank_position(PlayerbotAI* ai) { return new IccLmTankPositionAction(ai); }
|
||||||
static Action* icc_spike(PlayerbotAI* ai) { return new IccSpikeAction(ai); }
|
static Action* icc_spike(PlayerbotAI* ai) { return new IccSpikeAction(ai); }
|
||||||
|
|
||||||
static Action* icc_dark_reckoning(PlayerbotAI* ai) { return new IccDarkReckoningAction(ai); }
|
static Action* icc_dark_reckoning(PlayerbotAI* ai) { return new IccDarkReckoningAction(ai); }
|
||||||
static Action* icc_ranged_position_lady_deathwhisper(PlayerbotAI* ai) { return new IccRangedPositionLadyDeathwhisperAction(ai); }
|
static Action* icc_ranged_position_lady_deathwhisper(PlayerbotAI* ai) { return new IccRangedPositionLadyDeathwhisperAction(ai); }
|
||||||
static Action* icc_adds_lady_deathwhisper(PlayerbotAI* ai) { return new IccAddsLadyDeathwhisperAction(ai); }
|
static Action* icc_adds_lady_deathwhisper(PlayerbotAI* ai) { return new IccAddsLadyDeathwhisperAction(ai); }
|
||||||
static Action* icc_shade_lady_deathwhisper(PlayerbotAI* ai) { return new IccShadeLadyDeathwhisperAction(ai); }
|
static Action* icc_shade_lady_deathwhisper(PlayerbotAI* ai) { return new IccShadeLadyDeathwhisperAction(ai); }
|
||||||
|
|
||||||
static Action* icc_rotting_frost_giant_tank_position(PlayerbotAI* ai) { return new IccRottingFrostGiantTankPositionAction(ai); }
|
static Action* icc_rotting_frost_giant_tank_position(PlayerbotAI* ai) { return new IccRottingFrostGiantTankPositionAction(ai); }
|
||||||
static Action* icc_cannon_fire(PlayerbotAI* ai) { return new IccCannonFireAction(ai); }
|
static Action* icc_cannon_fire(PlayerbotAI* ai) { return new IccCannonFireAction(ai); }
|
||||||
static Action* icc_gunship_enter_cannon(PlayerbotAI* ai) { return new IccGunshipEnterCannonAction(ai); }
|
static Action* icc_gunship_enter_cannon(PlayerbotAI* ai) { return new IccGunshipEnterCannonAction(ai); }
|
||||||
static Action* icc_gunship_teleport_ally(PlayerbotAI* ai) { return new IccGunshipTeleportAllyAction(ai); }
|
static Action* icc_gunship_teleport_ally(PlayerbotAI* ai) { return new IccGunshipTeleportAllyAction(ai); }
|
||||||
static Action* icc_gunship_teleport_horde(PlayerbotAI* ai) { return new IccGunshipTeleportHordeAction(ai); }
|
static Action* icc_gunship_teleport_horde(PlayerbotAI* ai) { return new IccGunshipTeleportHordeAction(ai); }
|
||||||
|
|
||||||
static Action* icc_dbs_tank_position(PlayerbotAI* ai) { return new IccDbsTankPositionAction(ai); }
|
static Action* icc_dbs_tank_position(PlayerbotAI* ai) { return new IccDbsTankPositionAction(ai); }
|
||||||
static Action* icc_adds_dbs(PlayerbotAI* ai) { return new IccAddsDbsAction(ai); }
|
static Action* icc_adds_dbs(PlayerbotAI* ai) { return new IccAddsDbsAction(ai); }
|
||||||
static Action* icc_festergut_tank_position(PlayerbotAI* ai) { return new IccFestergutTankPositionAction(ai); }
|
|
||||||
|
static Action* icc_festergut_group_position(PlayerbotAI* ai) { return new IccFestergutGroupPositionAction(ai); }
|
||||||
static Action* icc_festergut_spore(PlayerbotAI* ai) { return new IccFestergutSporeAction(ai); }
|
static Action* icc_festergut_spore(PlayerbotAI* ai) { return new IccFestergutSporeAction(ai); }
|
||||||
|
|
||||||
static Action* icc_rotface_tank_position(PlayerbotAI* ai) { return new IccRotfaceTankPositionAction(ai); }
|
static Action* icc_rotface_tank_position(PlayerbotAI* ai) { return new IccRotfaceTankPositionAction(ai); }
|
||||||
static Action* icc_rotface_group_position(PlayerbotAI* ai) { return new IccRotfaceGroupPositionAction(ai); }
|
static Action* icc_rotface_group_position(PlayerbotAI* ai) { return new IccRotfaceGroupPositionAction(ai); }
|
||||||
static Action* icc_rotface_move_away_from_explosion(PlayerbotAI* ai) { return new IccRotfaceMoveAwayFromExplosionAction(ai); }
|
static Action* icc_rotface_move_away_from_explosion(PlayerbotAI* ai) { return new IccRotfaceMoveAwayFromExplosionAction(ai); }
|
||||||
|
|
||||||
static Action* icc_putricide_volatile_ooze(PlayerbotAI* ai) { return new IccPutricideVolatileOozeAction(ai); }
|
static Action* icc_putricide_volatile_ooze(PlayerbotAI* ai) { return new IccPutricideVolatileOozeAction(ai); }
|
||||||
static Action* icc_putricide_gas_cloud(PlayerbotAI* ai) { return new IccPutricideGasCloudAction(ai); }
|
static Action* icc_putricide_gas_cloud(PlayerbotAI* ai) { return new IccPutricideGasCloudAction(ai); }
|
||||||
static Action* icc_putricide_growing_ooze_puddle(PlayerbotAI* ai) { return new IccPutricideGrowingOozePuddleAction(ai); }
|
static Action* icc_putricide_growing_ooze_puddle(PlayerbotAI* ai) { return new IccPutricideGrowingOozePuddleAction(ai); }
|
||||||
static Action* avoid_malleable_goo(PlayerbotAI* ai) { return new AvoidMalleableGooAction(ai); }
|
static Action* icc_putricide_avoid_malleable_goo(PlayerbotAI* ai) { return new IccPutricideAvoidMalleableGooAction(ai); }
|
||||||
|
|
||||||
static Action* icc_bpc_keleseth_tank(PlayerbotAI* ai) { return new IccBpcKelesethTankAction(ai); }
|
static Action* icc_bpc_keleseth_tank(PlayerbotAI* ai) { return new IccBpcKelesethTankAction(ai); }
|
||||||
static Action* icc_bpc_nucleus(PlayerbotAI* ai) { return new IccBpcNucleusAction(ai); }
|
|
||||||
static Action* icc_bpc_main_tank(PlayerbotAI* ai) { return new IccBpcMainTankAction(ai); }
|
static Action* icc_bpc_main_tank(PlayerbotAI* ai) { return new IccBpcMainTankAction(ai); }
|
||||||
static Action* icc_bpc_empowered_vortex(PlayerbotAI* ai) { return new IccBpcEmpoweredVortexAction(ai); }
|
static Action* icc_bpc_empowered_vortex(PlayerbotAI* ai) { return new IccBpcEmpoweredVortexAction(ai); }
|
||||||
static Action* icc_bpc_kinetic_bomb(PlayerbotAI* ai) { return new IccBpcKineticBombAction(ai); }
|
static Action* icc_bpc_kinetic_bomb(PlayerbotAI* ai) { return new IccBpcKineticBombAction(ai); }
|
||||||
static Action* icc_bql_tank_position(PlayerbotAI* ai) { return new IccBqlTankPositionAction(ai); }
|
static Action* icc_bpc_ball_of_flame(PlayerbotAI* ai) { return new IccBpcBallOfFlameAction(ai); }
|
||||||
|
|
||||||
|
static Action* icc_bql_group_position(PlayerbotAI* ai) { return new IccBqlGroupPositionAction(ai); }
|
||||||
static Action* icc_bql_pact_of_darkfallen(PlayerbotAI* ai) { return new IccBqlPactOfDarkfallenAction(ai); }
|
static Action* icc_bql_pact_of_darkfallen(PlayerbotAI* ai) { return new IccBqlPactOfDarkfallenAction(ai); }
|
||||||
static Action* icc_bql_vampiric_bite(PlayerbotAI* ai) { return new IccBqlVampiricBiteAction(ai); }
|
static Action* icc_bql_vampiric_bite(PlayerbotAI* ai) { return new IccBqlVampiricBiteAction(ai); }
|
||||||
|
|
||||||
static Action* icc_valkyre_spear(PlayerbotAI* ai) { return new IccValkyreSpearAction(ai); }
|
static Action* icc_valkyre_spear(PlayerbotAI* ai) { return new IccValkyreSpearAction(ai); }
|
||||||
static Action* icc_sister_svalna(PlayerbotAI* ai) { return new IccSisterSvalnaAction(ai); }
|
static Action* icc_sister_svalna(PlayerbotAI* ai) { return new IccSisterSvalnaAction(ai); }
|
||||||
|
|
||||||
|
static Action* icc_valithria_group(PlayerbotAI* ai) { return new IccValithriaGroupAction(ai); }
|
||||||
static Action* icc_valithria_portal(PlayerbotAI* ai) { return new IccValithriaPortalAction(ai); }
|
static Action* icc_valithria_portal(PlayerbotAI* ai) { return new IccValithriaPortalAction(ai); }
|
||||||
static Action* icc_valithria_heal(PlayerbotAI* ai) { return new IccValithriaHealAction(ai); }
|
static Action* icc_valithria_heal(PlayerbotAI* ai) { return new IccValithriaHealAction(ai); }
|
||||||
static Action* icc_valithria_dream_cloud(PlayerbotAI* ai) { return new IccValithriaDreamCloudAction(ai); }
|
static Action* icc_valithria_dream_cloud(PlayerbotAI* ai) { return new IccValithriaDreamCloudAction(ai); }
|
||||||
static Action* icc_sindragosa_tank_position(PlayerbotAI* ai) { return new IccSindragosaTankPositionAction(ai); }
|
|
||||||
|
static Action* icc_sindragosa_group_position(PlayerbotAI* ai) { return new IccSindragosaGroupPositionAction(ai); }
|
||||||
static Action* icc_sindragosa_frost_beacon(PlayerbotAI* ai) { return new IccSindragosaFrostBeaconAction(ai); }
|
static Action* icc_sindragosa_frost_beacon(PlayerbotAI* ai) { return new IccSindragosaFrostBeaconAction(ai); }
|
||||||
static Action* icc_sindragosa_blistering_cold(PlayerbotAI* ai) { return new IccSindragosaBlisteringColdAction(ai); }
|
static Action* icc_sindragosa_blistering_cold(PlayerbotAI* ai) { return new IccSindragosaBlisteringColdAction(ai); }
|
||||||
static Action* icc_sindragosa_unchained_magic(PlayerbotAI* ai) { return new IccSindragosaUnchainedMagicAction(ai); }
|
static Action* icc_sindragosa_unchained_magic(PlayerbotAI* ai) { return new IccSindragosaUnchainedMagicAction(ai); }
|
||||||
@@ -103,6 +128,7 @@ private:
|
|||||||
static Action* icc_sindragosa_mystic_buffet(PlayerbotAI* ai) { return new IccSindragosaMysticBuffetAction(ai); }
|
static Action* icc_sindragosa_mystic_buffet(PlayerbotAI* ai) { return new IccSindragosaMysticBuffetAction(ai); }
|
||||||
static Action* icc_sindragosa_frost_bomb(PlayerbotAI* ai) { return new IccSindragosaFrostBombAction(ai); }
|
static Action* icc_sindragosa_frost_bomb(PlayerbotAI* ai) { return new IccSindragosaFrostBombAction(ai); }
|
||||||
static Action* icc_sindragosa_tank_swap_position(PlayerbotAI* ai) { return new IccSindragosaTankSwapPositionAction(ai); }
|
static Action* icc_sindragosa_tank_swap_position(PlayerbotAI* ai) { return new IccSindragosaTankSwapPositionAction(ai); }
|
||||||
|
|
||||||
static Action* icc_lich_king_shadow_trap(PlayerbotAI* ai) { return new IccLichKingShadowTrapAction(ai); }
|
static Action* icc_lich_king_shadow_trap(PlayerbotAI* ai) { return new IccLichKingShadowTrapAction(ai); }
|
||||||
static Action* icc_lich_king_necrotic_plague(PlayerbotAI* ai) { return new IccLichKingNecroticPlagueAction(ai); }
|
static Action* icc_lich_king_necrotic_plague(PlayerbotAI* ai) { return new IccLichKingNecroticPlagueAction(ai); }
|
||||||
static Action* icc_lich_king_winter(PlayerbotAI* ai) { return new IccLichKingWinterAction(ai); }
|
static Action* icc_lich_king_winter(PlayerbotAI* ai) { return new IccLichKingWinterAction(ai); }
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -12,12 +12,17 @@
|
|||||||
#include "RaidIccStrategy.h"
|
#include "RaidIccStrategy.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
|
#include "Trigger.h"
|
||||||
|
#include "CellImpl.h"
|
||||||
|
#include "GridNotifiers.h"
|
||||||
|
#include "GridNotifiersImpl.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
|
#include "RaidIccTriggers.h"
|
||||||
|
|
||||||
const Position ICC_LM_TANK_POSITION = Position(-391.0f, 2259.0f, 42.0f);
|
const Position ICC_LM_TANK_POSITION = Position(-391.0f, 2259.0f, 42.0f);
|
||||||
const Position ICC_DARK_RECKONING_SAFE_POSITION = Position(-523.33386f, 2211.2031f, 62.823116f);
|
const Position ICC_DARK_RECKONING_SAFE_POSITION = Position(-523.33386f, 2211.2031f, 62.823116f);
|
||||||
const Position ICC_LDW_TANK_POSTION = Position(-570.1f, 2211.2456f, 49.476616f); //-590.0f
|
const Position ICC_LDW_TANK_POSTION = Position(-570.1f, 2211.2456f, 49.476616f); //-590.0f
|
||||||
const Position ICC_ROTTING_FROST_GIANT_TANK_POSITION = Position(-265.90125f, 2209.0605f, 199.97006f);
|
const Position ICC_ROTTING_FROST_GIANT_TANK_POSITION = Position(-328.5085f, 2225.5142f, 199.97298f);
|
||||||
const Position ICC_GUNSHIP_TELEPORT_ALLY = Position (-370.04645f, 1993.3536f, 466.65656f);
|
const Position ICC_GUNSHIP_TELEPORT_ALLY = Position (-370.04645f, 1993.3536f, 466.65656f);
|
||||||
const Position ICC_GUNSHIP_TELEPORT_ALLY2 = Position (-392.66208f, 2064.893f, 466.5672f, 5.058196f);
|
const Position ICC_GUNSHIP_TELEPORT_ALLY2 = Position (-392.66208f, 2064.893f, 466.5672f, 5.058196f);
|
||||||
const Position ICC_GUNSHIP_TELEPORT_HORDE = Position (-449.5343f, 2477.2024f, 470.17648f);
|
const Position ICC_GUNSHIP_TELEPORT_HORDE = Position (-449.5343f, 2477.2024f, 470.17648f);
|
||||||
@@ -29,33 +34,49 @@ const Position ICC_FESTERGUT_MELEE_SPORE = Position(4269.1772f, 3144.7673f, 360.
|
|||||||
const Position ICC_ROTFACE_TANK_POSITION = Position(4447.061f, 3150.9758f, 360.38568f);
|
const Position ICC_ROTFACE_TANK_POSITION = Position(4447.061f, 3150.9758f, 360.38568f);
|
||||||
const Position ICC_ROTFACE_BIG_OOZE_POSITION = Position(4432.687f, 3142.3035f, 360.38623f);
|
const Position ICC_ROTFACE_BIG_OOZE_POSITION = Position(4432.687f, 3142.3035f, 360.38623f);
|
||||||
const Position ICC_ROTFACE_SAFE_POSITION = Position(4446.557f, 3065.6594f, 360.51843f);
|
const Position ICC_ROTFACE_SAFE_POSITION = Position(4446.557f, 3065.6594f, 360.51843f);
|
||||||
const Position ICC_PUTRICIDE_TANK_POSITION = Position(4393.7676f, 3214.9375f, 389.3997f);
|
const Position ICC_ROTFACE_CENTER_POSITION = Position(4446.0547f, 3144.8677f, 360.38593f); //actual center 4.74089 4445.6616f, 3137.1526f, 360.38608
|
||||||
//const Position ICC_PUTRICIDE_GAS1_POSITION = Position(4350.772f, 3249.9773f, 389.39508f);
|
const Position ICC_PUTRICIDE_TANK_POSITION = Position(4373.227f, 3222.058f, 389.4029f);
|
||||||
//const Position ICC_PUTRICIDE_GAS2_POSITION = Position(4390.002f, 3204.8855f, 389.39938f);
|
const Position ICC_PUTRICIDE_GREEN_POSITION = Position(4423.4126f, 3194.2715f, 389.37683f);
|
||||||
|
const Position ICC_PUTRICIDE_BAD_POSITION = Position(4356.1724f, 3261.5232f, 389.3985f);
|
||||||
//const Position ICC_PUTRICIDE_GAS3_POSITION = Position(4367.753f, 3177.5894f, 389.39575f);
|
//const Position ICC_PUTRICIDE_GAS3_POSITION = Position(4367.753f, 3177.5894f, 389.39575f);
|
||||||
//const Position ICC_PUTRICIDE_GAS4_POSITION = Position(4321.8486f, 3206.464f, 389.3982f);
|
//const Position ICC_PUTRICIDE_GAS4_POSITION = Position(4321.8486f, 3206.464f, 389.3982f);
|
||||||
const Position ICC_BPC_OT_POSITION = Position(4649.2236f, 2796.0972f, 361.1815f);
|
const Position ICC_BPC_OT_POSITION = Position(4649.2236f, 2796.0972f, 361.1815f);
|
||||||
const Position ICC_BPC_MT_POSITION = Position(4648.5674f, 2744.847f, 361.18222f);
|
const Position ICC_BPC_MT_POSITION = Position(4648.5674f, 2744.847f, 361.18222f);
|
||||||
const Position ICC_BQL_CENTER_POSITION = Position(4595.0f, 2769.0f, 400.0f);
|
const Position ICC_BQL_CENTER_POSITION = Position(4595.0f, 2769.0f, 400.0f);
|
||||||
const Position ICC_BQL_TANK_POSITION = Position(4616.102f, 2768.9167f, 400.13797f);
|
const Position ICC_BQL_LWALL1_POSITION = Position(4624.685f, 2789.4895f, 400.13834f);
|
||||||
const Position ICC_VDW_GROUP_POSITION = Position(4204.839f, 2484.9338f, 364.87f);
|
const Position ICC_BQL_LWALL2_POSITION = Position(4600.749f, 2805.7568f, 400.1374f);
|
||||||
|
const Position ICC_BQL_LWALL3_POSITION = Position(4572.857f, 2797.3872f, 400.1374f);
|
||||||
|
const Position ICC_BQL_RWALL1_POSITION = Position(4625.724f, 2748.9917f, 400.13693f);
|
||||||
|
const Position ICC_BQL_RWALL2_POSITION = Position(4608.3774f, 2735.7466f, 400.13693f);
|
||||||
|
const Position ICC_BQL_RWALL3_POSITION = Position(4576.813f, 2739.6067f, 400.13693f);
|
||||||
|
const Position ICC_BQL_LRWALL4_POSITION = Position(4539.345f, 2769.3853f, 403.7267f);
|
||||||
|
const Position ICC_BQL_TANK_POSITION = Position(4629.746f, 2769.6396f, 401.7479f); //old just in front of stairs 4616.102f, 2768.9167f, 400.13797f
|
||||||
|
const Position ICC_VDW_HEAL_POSITION = Position(4203.752f, 2483.4343f, 364.87274f);
|
||||||
|
const Position ICC_VDW_GROUP1_POSITION = Position(4203.585f, 2464.422f, 364.86887f);
|
||||||
|
const Position ICC_VDW_GROUP2_POSITION = Position(4203.5806f, 2505.2383f, 364.87677f);
|
||||||
|
const Position ICC_VDW_PORTALSTART_POSITION = Position(4202.637f, 2488.171f, 375.00256f);
|
||||||
const Position ICC_SINDRAGOSA_TANK_POSITION = Position(4408.016f, 2508.0647f, 203.37955f);
|
const Position ICC_SINDRAGOSA_TANK_POSITION = Position(4408.016f, 2508.0647f, 203.37955f);
|
||||||
const Position ICC_SINDRAGOSA_RANGED_POSITION = Position(4373.7686f, 2498.0042f, 203.38176f);
|
const Position ICC_SINDRAGOSA_FLYING_POSITION = Position(4525.6f, 2485.15f, 245.082f);
|
||||||
const Position ICC_SINDRAGOSA_MELEE_POSITION = Position(4389.22f, 2499.5237f, 203.38033f);
|
const Position ICC_SINDRAGOSA_RANGED_POSITION = Position(4441.572f, 2484.482f, 203.37836f);
|
||||||
const Position ICC_SINDRAGOSA_BLISTERING_COLD_POSITION = Position(4345.922f, 2484.708f, 206.22516f);
|
const Position ICC_SINDRAGOSA_MELEE_POSITION = Position(4423.4546f, 2491.7175f, 203.37686f);
|
||||||
const Position ICC_SINDRAGOSA_THOMB1_POSITION = Position(4381.819f, 2471.1448f, 203.37704f); // Westmost position
|
const Position ICC_SINDRAGOSA_BLISTERING_COLD_POSITION = Position(4473.6616f, 2484.8489f, 203.38258f);
|
||||||
const Position ICC_SINDRAGOSA_THOMB2_POSITION = Position(4381.819f, 2483.1448f, 203.37704f); // 12y east from pos1
|
const Position ICC_SINDRAGOSA_THOMB1_POSITION = Position(4433.6484f, 2469.4133f, 203.3806f);
|
||||||
const Position ICC_SINDRAGOSA_THOMB3_POSITION = Position(4381.819f, 2471.1448f, 203.37704f); // Same as pos1
|
const Position ICC_SINDRAGOSA_THOMB2_POSITION = Position(4434.143f, 2486.201f, 203.37473f);
|
||||||
const Position ICC_SINDRAGOSA_THOMB4_POSITION = Position(4381.819f, 2483.1448f, 203.37704f); // Same as pos2
|
const Position ICC_SINDRAGOSA_THOMB3_POSITION = Position(4436.1147f, 2501.464f, 203.38266f);
|
||||||
const Position ICC_SINDRAGOSA_THOMB5_POSITION = Position(4381.819f, 2495.1448f, 203.37704f); // 12y east from pos2/4
|
const Position ICC_SINDRAGOSA_UNCHAINEDMAGIC1_POSITION = Position(4444.9707f, 2455.7322f, 203.38701f);
|
||||||
|
const Position ICC_SINDRAGOSA_UNCHAINEDMAGIC2_POSITION = Position(4461.3945f, 2463.5513f, 203.38727f);
|
||||||
|
const Position ICC_SINDRAGOSA_UNCHAINEDMAGIC3_POSITION = Position(4473.6616f, 2484.8489f, 203.38258f);
|
||||||
|
const Position ICC_SINDRAGOSA_UNCHAINEDMAGIC4_POSITION = Position(4459.9336f, 2507.409f, 203.38606f);
|
||||||
|
const Position ICC_SINDRAGOSA_UNCHAINEDMAGIC5_POSITION = Position(4442.3096f, 2512.4688f, 203.38647f);
|
||||||
const Position ICC_SINDRAGOSA_CENTER_POSITION = Position(4408.0464f, 2484.478f, 203.37529f);
|
const Position ICC_SINDRAGOSA_CENTER_POSITION = Position(4408.0464f, 2484.478f, 203.37529f);
|
||||||
const Position ICC_SINDRAGOSA_THOMBMB2_POSITION = Position(4382.6113f, 2505.4922f, 203.38197f);
|
const Position ICC_SINDRAGOSA_THOMBMB2_POSITION = Position(4436.895f, 2498.1401f, 203.38133f);
|
||||||
const Position ICC_SINDRAGOSA_FBOMB_POSITION = Position(4400.031f, 2507.0295f, 203.37929f); //old 4400.031f, 2507.0295f, 203.37929f //alternate for 10 man 4366.0225f, 2501.569f, 203.38226f
|
const Position ICC_SINDRAGOSA_FBOMB_POSITION = Position(4449.3647f, 2486.4524f, 203.379f);
|
||||||
const Position ICC_SINDRAGOSA_FBOMB10_POSITION = Position(4366.0225f, 2501.569f, 203.38226f);
|
const Position ICC_SINDRAGOSA_FBOMB10_POSITION = Position(4449.3647f, 2486.4524f, 203.379f);
|
||||||
const Position ICC_SINDRAGOSA_LOS2_POSITION = Position(4376.0938f, 2511.103f, 203.38303f);
|
const Position ICC_SINDRAGOSA_LOS2_POSITION = Position(4441.8286f, 2501.946f, 203.38435f);
|
||||||
const Position ICC_LICH_KING_ADDS_POSITION = Position(476.7332f, -2095.3894f, 840.857f); // old 486.63647f, -2095.7915f, 840.857f
|
const Position ICC_LICH_KING_ADDS_POSITION = Position(476.7332f, -2095.3894f, 840.857f); // old 486.63647f, -2095.7915f, 840.857f
|
||||||
const Position ICC_LICH_KING_MELEE_POSITION = Position(503.5546f, -2106.8213f, 840.857f);
|
const Position ICC_LICH_KING_MELEE_POSITION = Position(503.5546f, -2106.8213f, 840.857f);
|
||||||
const Position ICC_LICH_KING_RANGED_POSITION = Position(501.3563f, -2085.1816f, 840.857f);
|
const Position ICC_LICH_KING_RANGED_POSITION = Position(501.3563f, -2085.1816f, 840.857f);
|
||||||
|
const Position ICC_LICH_KING_ASSISTHC_POSITION = Position(517.2145f, -2125.0674f, 840.857f);
|
||||||
const Position ICC_LK_FROST1_POSITION = Position(503.96548f, -2183.216f, 840.857f);
|
const Position ICC_LK_FROST1_POSITION = Position(503.96548f, -2183.216f, 840.857f);
|
||||||
const Position ICC_LK_FROST2_POSITION = Position(563.07166f, -2125.7578f, 840.857f);
|
const Position ICC_LK_FROST2_POSITION = Position(563.07166f, -2125.7578f, 840.857f);
|
||||||
const Position ICC_LK_FROST3_POSITION = Position(503.40182f, -2067.3435f, 840.857f);
|
const Position ICC_LK_FROST3_POSITION = Position(503.40182f, -2067.3435f, 840.857f);
|
||||||
@@ -70,6 +91,8 @@ public:
|
|||||||
IccLmTankPositionAction(PlayerbotAI* botAI, std::string const name = "icc lm tank position")
|
IccLmTankPositionAction(PlayerbotAI* botAI, std::string const name = "icc lm tank position")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool MoveTowardPosition(const Position& position, float incrementSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccSpikeAction : public AttackAction
|
class IccSpikeAction : public AttackAction
|
||||||
@@ -77,6 +100,10 @@ class IccSpikeAction : public AttackAction
|
|||||||
public:
|
public:
|
||||||
IccSpikeAction(PlayerbotAI* botAI) : AttackAction(botAI, "icc spike") {}
|
IccSpikeAction(PlayerbotAI* botAI) : AttackAction(botAI, "icc spike") {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool HandleSpikeTargeting(Unit* boss);
|
||||||
|
bool MoveTowardPosition(const Position& position, float incrementSize);
|
||||||
|
void UpdateRaidTargetIcon(Unit* target);
|
||||||
};
|
};
|
||||||
|
|
||||||
//Lady Deathwhisper
|
//Lady Deathwhisper
|
||||||
@@ -94,6 +121,8 @@ public:
|
|||||||
IccRangedPositionLadyDeathwhisperAction(PlayerbotAI* botAI, std::string const name = "icc ranged position lady deathwhisper")
|
IccRangedPositionLadyDeathwhisperAction(PlayerbotAI* botAI, std::string const name = "icc ranged position lady deathwhisper")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool MaintainRangedSpacing();
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccAddsLadyDeathwhisperAction : public AttackAction
|
class IccAddsLadyDeathwhisperAction : public AttackAction
|
||||||
@@ -102,6 +131,12 @@ public:
|
|||||||
IccAddsLadyDeathwhisperAction(PlayerbotAI* botAI, std::string const name = "icc adds lady deathwhisper")
|
IccAddsLadyDeathwhisperAction(PlayerbotAI* botAI, std::string const name = "icc adds lady deathwhisper")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool IsTargetedByShade(uint32 shadeEntry);
|
||||||
|
bool MoveTowardPosition(const Position& position, float incrementSize);
|
||||||
|
bool HandleAddTargeting(Unit* boss);
|
||||||
|
void UpdateRaidTargetIcon(Unit* target);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccShadeLadyDeathwhisperAction : public MovementAction
|
class IccShadeLadyDeathwhisperAction : public MovementAction
|
||||||
@@ -127,6 +162,9 @@ public:
|
|||||||
IccCannonFireAction(PlayerbotAI* botAI, std::string const name = "icc cannon fire")
|
IccCannonFireAction(PlayerbotAI* botAI, std::string const name = "icc cannon fire")
|
||||||
: Action(botAI, name) {}
|
: Action(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
Unit* FindValidCannonTarget();
|
||||||
|
bool TryCastCannonSpell(uint32 spellId, Unit* target, Unit* vehicleBase);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccGunshipEnterCannonAction : public MovementAction
|
class IccGunshipEnterCannonAction : public MovementAction
|
||||||
@@ -135,7 +173,10 @@ public:
|
|||||||
IccGunshipEnterCannonAction(PlayerbotAI* botAI, std::string const name = "icc gunship enter cannon")
|
IccGunshipEnterCannonAction(PlayerbotAI* botAI, std::string const name = "icc gunship enter cannon")
|
||||||
: MovementAction(botAI, name) {}
|
: MovementAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
bool EnterVehicle(Unit* vehicleBase, bool moveIfFar);
|
bool EnterVehicle(Unit* vehicleBase, bool moveIfFar);
|
||||||
|
Unit* FindBestAvailableCannon();
|
||||||
|
bool IsValidCannon(Unit* vehicle, const uint32 validEntries[]);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccGunshipTeleportAllyAction : public AttackAction
|
class IccGunshipTeleportAllyAction : public AttackAction
|
||||||
@@ -144,6 +185,10 @@ public:
|
|||||||
IccGunshipTeleportAllyAction(PlayerbotAI* botAI, std::string const name = "icc gunship teleport ally")
|
IccGunshipTeleportAllyAction(PlayerbotAI* botAI, std::string const name = "icc gunship teleport ally")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool TeleportTo(const Position& position);
|
||||||
|
void CleanupSkullIcon(uint8_t SKULL_ICON_INDEX);
|
||||||
|
void UpdateBossSkullIcon(Unit* boss, uint8_t SKULL_ICON_INDEX);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccGunshipTeleportHordeAction : public AttackAction
|
class IccGunshipTeleportHordeAction : public AttackAction
|
||||||
@@ -152,6 +197,10 @@ public:
|
|||||||
IccGunshipTeleportHordeAction(PlayerbotAI* botAI, std::string const name = "icc gunship teleport horde")
|
IccGunshipTeleportHordeAction(PlayerbotAI* botAI, std::string const name = "icc gunship teleport horde")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool TeleportTo(const Position& position);
|
||||||
|
void CleanupSkullIcon(uint8_t SKULL_ICON_INDEX);
|
||||||
|
void UpdateBossSkullIcon(Unit* boss, uint8_t SKULL_ICON_INDEX);
|
||||||
};
|
};
|
||||||
|
|
||||||
//DBS
|
//DBS
|
||||||
@@ -161,6 +210,10 @@ public:
|
|||||||
IccDbsTankPositionAction(PlayerbotAI* botAI, std::string const name = "icc dbs tank position")
|
IccDbsTankPositionAction(PlayerbotAI* botAI, std::string const name = "icc dbs tank position")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool CrowdControlBloodBeasts();
|
||||||
|
bool EvadeBloodBeasts();
|
||||||
|
bool PositionInRangedFormation();
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccAddsDbsAction : public AttackAction
|
class IccAddsDbsAction : public AttackAction
|
||||||
@@ -169,15 +222,22 @@ public:
|
|||||||
IccAddsDbsAction(PlayerbotAI* botAI, std::string const name = "icc adds dbs")
|
IccAddsDbsAction(PlayerbotAI* botAI, std::string const name = "icc adds dbs")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
Unit* FindPriorityTarget(Unit* boss);
|
||||||
|
void UpdateSkullMarker(Unit* priorityTarget);
|
||||||
};
|
};
|
||||||
|
|
||||||
//FESTERGUT
|
//FESTERGUT
|
||||||
class IccFestergutTankPositionAction : public AttackAction
|
class IccFestergutGroupPositionAction : public AttackAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccFestergutTankPositionAction(PlayerbotAI* botAI, std::string const name = "icc festergut tank position")
|
IccFestergutGroupPositionAction(PlayerbotAI* botAI, std::string const name = "icc festergut group position")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool HasSporesInGroup();
|
||||||
|
bool PositionNonTankMembers();
|
||||||
|
int CalculatePositionIndex(Group* group);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccFestergutSporeAction : public AttackAction
|
class IccFestergutSporeAction : public AttackAction
|
||||||
@@ -186,6 +246,17 @@ public:
|
|||||||
IccFestergutSporeAction(PlayerbotAI* botAI, std::string const name = "icc festergut spore")
|
IccFestergutSporeAction(PlayerbotAI* botAI, std::string const name = "icc festergut spore")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
Position CalculateSpreadPosition();
|
||||||
|
struct SporeInfo
|
||||||
|
{
|
||||||
|
std::vector<Unit*> sporedPlayers;
|
||||||
|
ObjectGuid lowestGuid;
|
||||||
|
bool hasLowestGuid = false;
|
||||||
|
};
|
||||||
|
SporeInfo FindSporedPlayers();
|
||||||
|
Position DetermineTargetPosition(bool hasSpore, const SporeInfo& sporeInfo, const Position& spreadRangedPos);
|
||||||
|
bool CheckMainTankSpore();
|
||||||
};
|
};
|
||||||
|
|
||||||
//Rotface
|
//Rotface
|
||||||
@@ -195,6 +266,11 @@ public:
|
|||||||
IccRotfaceTankPositionAction(PlayerbotAI* botAI, std::string const name = "icc rotface tank position")
|
IccRotfaceTankPositionAction(PlayerbotAI* botAI, std::string const name = "icc rotface tank position")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
void MarkBossWithSkull(Unit* boss);
|
||||||
|
bool PositionMainTankAndMelee(Unit *boss);
|
||||||
|
bool HandleAssistTankPositioning(Unit* boss);
|
||||||
|
bool HandleBigOozePositioning(Unit* boss);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccRotfaceGroupPositionAction : public AttackAction
|
class IccRotfaceGroupPositionAction : public AttackAction
|
||||||
@@ -203,25 +279,40 @@ public:
|
|||||||
IccRotfaceGroupPositionAction(PlayerbotAI* botAI, std::string const name = "icc rotface group position")
|
IccRotfaceGroupPositionAction(PlayerbotAI* botAI, std::string const name = "icc rotface group position")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
//bool MoveAwayFromBigOoze(Unit* bigOoze);
|
||||||
|
bool HandlePuddleAvoidance(Unit* boss);
|
||||||
|
bool MoveAwayFromPuddle(Unit* boss, Unit* puddle, float puddleDistance);
|
||||||
|
bool HandleOozeTargeting();
|
||||||
|
bool HandleOozeMemberPositioning();
|
||||||
|
bool PositionRangedAndHealers(Unit* boss,Unit* smallOoze);
|
||||||
|
bool FindAndMoveFromClosestMember(Unit* boss, Unit* smallOoze);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccRotfaceMoveAwayFromExplosionAction : public MovementAction
|
class IccRotfaceMoveAwayFromExplosionAction : public MovementAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccRotfaceMoveAwayFromExplosionAction(PlayerbotAI* botAI, std::string const name = "icc rotface move away from explosion")
|
IccRotfaceMoveAwayFromExplosionAction(PlayerbotAI* botAI, std::string const name = "icc rotface move away from explosion")
|
||||||
: MovementAction(botAI, name) {}
|
: MovementAction(botAI, name) {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
bool Execute(Event event) override;
|
|
||||||
|
bool MoveToRandomSafeLocation();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//PP
|
//PP
|
||||||
|
|
||||||
class IccPutricideGrowingOozePuddleAction : public AttackAction
|
class IccPutricideGrowingOozePuddleAction : public AttackAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccPutricideGrowingOozePuddleAction(PlayerbotAI* botAI, std::string const name = "icc putricide growing ooze puddle")
|
IccPutricideGrowingOozePuddleAction(PlayerbotAI* botAI, std::string const name = "icc putricide growing ooze puddle")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
Unit* FindClosestThreateningPuddle();
|
||||||
|
Position CalculateSafeMovePosition(Unit* closestPuddle);
|
||||||
|
bool IsPositionTooCloseToOtherPuddles(float x, float y, Unit* ignorePuddle);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccPutricideVolatileOozeAction : public AttackAction
|
class IccPutricideVolatileOozeAction : public AttackAction
|
||||||
@@ -230,22 +321,41 @@ public:
|
|||||||
IccPutricideVolatileOozeAction(PlayerbotAI* botAI, std::string const name = "icc putricide volatile ooze")
|
IccPutricideVolatileOozeAction(PlayerbotAI* botAI, std::string const name = "icc putricide volatile ooze")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
void MarkOozeWithSkull(Unit* ooze);
|
||||||
|
Unit* FindAuraTarget();
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccPutricideGasCloudAction : public AttackAction
|
class IccPutricideGasCloudAction : public AttackAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccPutricideGasCloudAction(PlayerbotAI* botAI, std::string const name = "icc putricide gas cloud")
|
IccPutricideGasCloudAction(PlayerbotAI* botAI, std::string const name = "icc putricide gas cloud")
|
||||||
: AttackAction(botAI, name) {}
|
: AttackAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool HandleGaseousBloatMovement(Unit* gasCloud);
|
||||||
|
Position CalculateEmergencyPosition(const Position& botPos, float dx, float dy);
|
||||||
|
bool FindSafeMovementPosition(const Position& botPos, const Position& cloudPos, float dx, float dy, int numAngles,
|
||||||
|
Position& resultPos);
|
||||||
|
bool HandleGroupAuraSituation(Unit* gasCloud);
|
||||||
|
bool GroupHasGaseousBloat(Group* group);
|
||||||
};
|
};
|
||||||
|
|
||||||
class AvoidMalleableGooAction : public MovementAction
|
class IccPutricideAvoidMalleableGooAction : public MovementAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AvoidMalleableGooAction(PlayerbotAI* botAI, std::string const name = "avoid malleable goo" )
|
IccPutricideAvoidMalleableGooAction(PlayerbotAI* botAI, std::string const name = "icc putricide avoid malleable goo")
|
||||||
: MovementAction(botAI, name) {}
|
: MovementAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool HandleTankPositioning(Unit* boss);
|
||||||
|
bool HandleUnboundPlague(Unit* boss);
|
||||||
|
bool HandleBossPositioning(Unit* boss);
|
||||||
|
Position CalculateBossPosition(Unit* boss, float distance);
|
||||||
|
bool HasObstacleBetween(const Position& from, const Position& to);
|
||||||
|
bool IsOnPath(const Position& from, const Position& to, const Position& point, float threshold);
|
||||||
|
Position CalculateArcPoint(const Position& current, const Position& target, const Position& center);
|
||||||
|
Position CalculateIncrementalMove(const Position& current, const Position& target, float maxDistance);
|
||||||
};
|
};
|
||||||
|
|
||||||
//BPC
|
//BPC
|
||||||
@@ -257,20 +367,14 @@ public:
|
|||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccBpcNucleusAction : public AttackAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IccBpcNucleusAction(PlayerbotAI* botAI)
|
|
||||||
: AttackAction(botAI, "icc bpc nucleus") {}
|
|
||||||
bool Execute(Event event) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IccBpcMainTankAction : public AttackAction
|
class IccBpcMainTankAction : public AttackAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccBpcMainTankAction(PlayerbotAI* botAI)
|
IccBpcMainTankAction(PlayerbotAI* botAI)
|
||||||
: AttackAction(botAI, "icc bpc main tank") {}
|
: AttackAction(botAI, "icc bpc main tank") {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
void MarkEmpoweredPrince();
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccBpcEmpoweredVortexAction : public MovementAction
|
class IccBpcEmpoweredVortexAction : public MovementAction
|
||||||
@@ -279,6 +383,9 @@ public:
|
|||||||
IccBpcEmpoweredVortexAction(PlayerbotAI* botAI)
|
IccBpcEmpoweredVortexAction(PlayerbotAI* botAI)
|
||||||
: MovementAction(botAI, "icc bpc empowered vortex") {}
|
: MovementAction(botAI, "icc bpc empowered vortex") {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool MaintainRangedSpacing();
|
||||||
|
bool HandleEmpoweredVortexSpread();
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccBpcKineticBombAction : public AttackAction
|
class IccBpcKineticBombAction : public AttackAction
|
||||||
@@ -287,15 +394,45 @@ public:
|
|||||||
IccBpcKineticBombAction(PlayerbotAI* botAI)
|
IccBpcKineticBombAction(PlayerbotAI* botAI)
|
||||||
: AttackAction(botAI, "icc bpc kinetic bomb") {}
|
: AttackAction(botAI, "icc bpc kinetic bomb") {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
Unit* FindOptimalKineticBomb();
|
||||||
|
bool IsBombAlreadyHandled(Unit* bomb, Group* group);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IccBpcBallOfFlameAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IccBpcBallOfFlameAction(PlayerbotAI* botAI)
|
||||||
|
: MovementAction(botAI, "icc bpc ball of flame") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Blood Queen Lana'thel
|
//Blood Queen Lana'thel
|
||||||
class IccBqlTankPositionAction : public AttackAction
|
class IccBqlGroupPositionAction : public AttackAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccBqlTankPositionAction(PlayerbotAI* botAI)
|
IccBqlGroupPositionAction(PlayerbotAI* botAI)
|
||||||
: AttackAction(botAI, "icc bql tank position") {}
|
: AttackAction(botAI, "icc group tank position") {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool HandleTankPosition(Unit* boss, Aura* frenzyAura, Aura* shadowAura);
|
||||||
|
bool HandleShadowsMovement();
|
||||||
|
Position AdjustControlPoint(const Position& wall, const Position& center, float factor);
|
||||||
|
Position CalculateBezierPoint(float t, const Position path[4]);
|
||||||
|
bool HandleGroupPosition(Unit* boss, Aura* frenzyAura, Aura* shadowAura);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Evaluate curves
|
||||||
|
struct CurveInfo
|
||||||
|
{
|
||||||
|
Position moveTarget;
|
||||||
|
int curveIdx = 0;
|
||||||
|
bool foundSafe = false;
|
||||||
|
float minDist = 0.0f;
|
||||||
|
float score = 0.0f;
|
||||||
|
Position closestPoint;
|
||||||
|
float t_closest = 0.0f;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccBqlPactOfDarkfallenAction : public MovementAction
|
class IccBqlPactOfDarkfallenAction : public MovementAction
|
||||||
@@ -304,6 +441,9 @@ public:
|
|||||||
IccBqlPactOfDarkfallenAction(PlayerbotAI* botAI)
|
IccBqlPactOfDarkfallenAction(PlayerbotAI* botAI)
|
||||||
: MovementAction(botAI, "icc bql pact of darkfallen") {}
|
: MovementAction(botAI, "icc bql pact of darkfallen") {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
void CalculateCenterPosition(Position& targetPos, const std::vector<Player*>& playersWithAura);
|
||||||
|
bool MoveToTargetPosition(const Position& targetPos, int auraCount);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccBqlVampiricBiteAction : public AttackAction
|
class IccBqlVampiricBiteAction : public AttackAction
|
||||||
@@ -312,9 +452,14 @@ public:
|
|||||||
IccBqlVampiricBiteAction(PlayerbotAI* botAI)
|
IccBqlVampiricBiteAction(PlayerbotAI* botAI)
|
||||||
: AttackAction(botAI, "icc bql vampiric bite") {}
|
: AttackAction(botAI, "icc bql vampiric bite") {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
Player* FindBestBiteTarget(Group* group);
|
||||||
|
bool IsInvalidTarget(Player* player);
|
||||||
|
bool MoveTowardsTarget(Player* target);
|
||||||
|
bool CastVampiricBite(Player* target);
|
||||||
};
|
};
|
||||||
|
|
||||||
//VDW
|
// Sister Svalna
|
||||||
class IccValkyreSpearAction : public AttackAction
|
class IccValkyreSpearAction : public AttackAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -331,6 +476,21 @@ public:
|
|||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Valithria Dreamwalker
|
||||||
|
|
||||||
|
class IccValithriaGroupAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IccValithriaGroupAction(PlayerbotAI* botAI)
|
||||||
|
: AttackAction(botAI, "icc valithria group") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool MoveTowardsPosition(const Position& pos, float increment);
|
||||||
|
bool Handle25ManGroupLogic();
|
||||||
|
bool HandleMarkingLogic(bool inGroup1, bool inGroup2, const Position& group1Pos, const Position& group2Pos);
|
||||||
|
bool Handle10ManGroupLogic();
|
||||||
|
};
|
||||||
|
|
||||||
class IccValithriaPortalAction : public MovementAction
|
class IccValithriaPortalAction : public MovementAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -356,12 +516,16 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//Sindragosa
|
//Sindragosa
|
||||||
class IccSindragosaTankPositionAction : public AttackAction
|
class IccSindragosaGroupPositionAction : public AttackAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccSindragosaTankPositionAction(PlayerbotAI* botAI)
|
IccSindragosaGroupPositionAction(PlayerbotAI* botAI)
|
||||||
: AttackAction(botAI, "icc sindragosa tank position") {}
|
: AttackAction(botAI, "icc sindragosa group position") {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
bool HandleTankPositioning(Unit* boss);
|
||||||
|
bool HandleNonTankPositioning();
|
||||||
|
bool MoveIncrementallyToPosition(const Position& targetPos, float maxStep);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccSindragosaFrostBeaconAction : public MovementAction
|
class IccSindragosaFrostBeaconAction : public MovementAction
|
||||||
@@ -370,6 +534,21 @@ public:
|
|||||||
IccSindragosaFrostBeaconAction(PlayerbotAI* botAI)
|
IccSindragosaFrostBeaconAction(PlayerbotAI* botAI)
|
||||||
: MovementAction(botAI, "icc sindragosa frost beacon") {}
|
: MovementAction(botAI, "icc sindragosa frost beacon") {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
void HandleSupportActions();
|
||||||
|
bool HandleBeaconedPlayer(const Unit* boss);
|
||||||
|
bool HandleNonBeaconedPlayer(const Unit* boss);
|
||||||
|
bool MoveToPositionIfNeeded(const Position& position, float tolerance);
|
||||||
|
bool MoveToPosition(const Position& position);
|
||||||
|
bool IsBossFlying(const Unit* boss);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr uint32 FROST_BEACON_AURA_ID = SPELL_FROST_BEACON;
|
||||||
|
static constexpr uint32 HAND_OF_FREEDOM_SPELL_ID = 1044;
|
||||||
|
static constexpr float POSITION_TOLERANCE = 1.0f;
|
||||||
|
static constexpr float TOMB_POSITION_TOLERANCE = 0.5f;
|
||||||
|
static constexpr float MIN_SAFE_DISTANCE = 13.0f;
|
||||||
|
static constexpr float MOVE_TOLERANCE = 2.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccSindragosaBlisteringColdAction : public MovementAction
|
class IccSindragosaBlisteringColdAction : public MovementAction
|
||||||
@@ -396,11 +575,11 @@ public:
|
|||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccSindragosaMysticBuffetAction : public AttackAction
|
class IccSindragosaMysticBuffetAction : public MovementAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccSindragosaMysticBuffetAction(PlayerbotAI* botAI)
|
IccSindragosaMysticBuffetAction(PlayerbotAI* botAI)
|
||||||
: AttackAction(botAI, "icc sindragosa mystic buffet") {}
|
: MovementAction(botAI, "icc sindragosa mystic buffet") {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -444,6 +623,21 @@ class IccLichKingWinterAction : public AttackAction
|
|||||||
IccLichKingWinterAction(PlayerbotAI* botAI)
|
IccLichKingWinterAction(PlayerbotAI* botAI)
|
||||||
: AttackAction(botAI, "icc lich king winter") {}
|
: AttackAction(botAI, "icc lich king winter") {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
void HandlePositionCorrection();
|
||||||
|
bool IsValidCollectibleAdd(Unit* unit);
|
||||||
|
bool IsPositionSafeFromDefile(float x, float y, float z, float minSafeDistance);
|
||||||
|
void HandleTankPositioning();
|
||||||
|
void HandleMeleePositioning();
|
||||||
|
void HandleRangedPositioning();
|
||||||
|
void HandleMainTankAddManagement(Unit* boss, const Position* tankPos);
|
||||||
|
void HandleAssistTankAddManagement(Unit* boss, const Position* tankPos);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Position* GetMainTankPosition();
|
||||||
|
const Position* GetMainTankRangedPosition();
|
||||||
|
bool TryMoveToPosition(float targetX, float targetY, float targetZ, bool isForced = true);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccLichKingAddsAction : public AttackAction
|
class IccLichKingAddsAction : public AttackAction
|
||||||
@@ -452,6 +646,28 @@ class IccLichKingAddsAction : public AttackAction
|
|||||||
IccLichKingAddsAction(PlayerbotAI* botAI)
|
IccLichKingAddsAction(PlayerbotAI* botAI)
|
||||||
: AttackAction(botAI, "icc lich king adds") {}
|
: AttackAction(botAI, "icc lich king adds") {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
void HandleTeleportationFixes(Difficulty diff, Unit* terenasMenethilHC);
|
||||||
|
bool HandleSpiritBombAvoidance(Difficulty diff, Unit* terenasMenethilHC);
|
||||||
|
void HandleHeroicNonTankPositioning(Difficulty diff, Unit* terenasMenethilHC);
|
||||||
|
void HandleSpiritMarkingAndTargeting(Difficulty diff, Unit* terenasMenethilHC);
|
||||||
|
bool HandleQuakeMechanics(Unit* boss);
|
||||||
|
void HandleShamblingHorrors(Unit* boss, bool hasPlague);
|
||||||
|
bool HandleAssistTankAddManagement(Unit* boss, Difficulty diff);
|
||||||
|
void HandleMeleePositioning(Unit* boss, bool hasPlague, Difficulty diff);
|
||||||
|
void HandleMainTankTargeting(Unit* boss, Difficulty diff);
|
||||||
|
void HandleNonTankHeroicPositioning(Unit* boss, Difficulty diff, bool hasPlague);
|
||||||
|
void HandleRangedPositioning(Unit* boss, bool hasPlague, Difficulty diff);
|
||||||
|
void HandleDefileMechanics(Unit* boss, Difficulty diff);
|
||||||
|
void HandleValkyrMechanics(Difficulty diff);
|
||||||
|
std::vector<size_t> CalculateBalancedGroupSizes(size_t totalAssist, size_t numValkyrs);
|
||||||
|
size_t GetAssignedValkyrIndex(size_t assistIndex, const std::vector<size_t>& groupSizes);
|
||||||
|
std::string GetRTIValueForValkyr(size_t valkyrIndex);
|
||||||
|
void HandleValkyrMarking(const std::vector<Unit*>& grabbingValkyrs, Difficulty diff);
|
||||||
|
void HandleValkyrAssignment(const std::vector<Unit*>& grabbingValkyrs);
|
||||||
|
void ApplyCCToValkyr(Unit* valkyr);
|
||||||
|
bool IsValkyr(Unit* unit);
|
||||||
|
void HandleVileSpiritMechanics();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -68,20 +68,13 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//BQL
|
//BQL
|
||||||
class IccBqlPactOfDarkfallenMultiplier : public Multiplier
|
class IccBqlMultiplier : public Multiplier
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccBqlPactOfDarkfallenMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "icc bql pact of darkfallen multiplier") {}
|
IccBqlMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "icc bql multiplier") {}
|
||||||
virtual float GetValue(Action* action) override;
|
virtual float GetValue(Action* action) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccBqlVampiricBiteMultiplier : public Multiplier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IccBqlVampiricBiteMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc bql vampiric bite") {}
|
|
||||||
virtual float GetValue(Action* action);
|
|
||||||
};
|
|
||||||
|
|
||||||
//VDW
|
//VDW
|
||||||
class IccValithriaDreamCloudMultiplier : public Multiplier
|
class IccValithriaDreamCloudMultiplier : public Multiplier
|
||||||
{
|
{
|
||||||
@@ -91,56 +84,14 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//SINDRAGOSA
|
//SINDRAGOSA
|
||||||
class IccSindragosaTankPositionMultiplier : public Multiplier
|
class IccSindragosaMultiplier : public Multiplier
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccSindragosaTankPositionMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc sindragosa tank position") {}
|
IccSindragosaMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc sindragosa") {}
|
||||||
virtual float GetValue(Action* action);
|
|
||||||
};
|
|
||||||
|
|
||||||
class IccSindragosaFrostBeaconMultiplier : public Multiplier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IccSindragosaFrostBeaconMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc sindragosa frost beacon") {}
|
|
||||||
virtual float GetValue(Action* action);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*class IccSindragosaFlyingMultiplier : public Multiplier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IccSindragosaFlyingMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc sindragosa flying") {}
|
|
||||||
virtual float GetValue(Action* action);
|
|
||||||
};*/
|
|
||||||
|
|
||||||
class IccSindragosaMysticBuffetMultiplier : public Multiplier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IccSindragosaMysticBuffetMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc sindragosa mystic buffet") {}
|
|
||||||
virtual float GetValue(Action* action);
|
|
||||||
};
|
|
||||||
|
|
||||||
class IccSindragosaBlisteringColdPriorityMultiplier : public Multiplier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IccSindragosaBlisteringColdPriorityMultiplier(PlayerbotAI* ai) : Multiplier(ai, "sindragosa blistering cold priority") {}
|
|
||||||
|
|
||||||
virtual float GetValue(Action* action) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IccSindragosaFrostBombMultiplier : public Multiplier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IccSindragosaFrostBombMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc sindragosa frost bomb") {}
|
|
||||||
virtual float GetValue(Action* action);
|
|
||||||
};
|
|
||||||
|
|
||||||
class IccLichKingNecroticPlagueMultiplier : public Multiplier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IccLichKingNecroticPlagueMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc lich king necrotic plague") {}
|
|
||||||
virtual float GetValue(Action* action);
|
virtual float GetValue(Action* action);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//LK
|
||||||
class IccLichKingAddsMultiplier : public Multiplier
|
class IccLichKingAddsMultiplier : public Multiplier
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -149,4 +100,4 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -5,25 +5,19 @@
|
|||||||
void RaidIccStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void RaidIccStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
//Lord Marrogwar
|
//Lord Marrogwar
|
||||||
triggers.push_back(new TriggerNode("icc lm tank position",
|
triggers.push_back(new TriggerNode("icc lm",
|
||||||
NextAction::array(0, new NextAction("icc lm tank position", ACTION_RAID + 5), nullptr)));
|
NextAction::array(0, new NextAction("icc lm tank position", ACTION_RAID + 5),
|
||||||
|
new NextAction("icc spike", ACTION_RAID + 3), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("icc spike near",
|
|
||||||
NextAction::array(0, new NextAction("icc spike", ACTION_RAID + 3), nullptr)));
|
|
||||||
|
|
||||||
//Lady Deathwhisper
|
//Lady Deathwhisper
|
||||||
triggers.push_back(new TriggerNode("icc dark reckoning",
|
triggers.push_back(new TriggerNode("icc dark reckoning",
|
||||||
NextAction::array(0, new NextAction("icc dark reckoning", ACTION_MOVE + 5), nullptr)));
|
NextAction::array(0, new NextAction("icc dark reckoning", ACTION_MOVE + 5), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc ranged position lady deathwhisper",
|
triggers.push_back(new TriggerNode("icc lady deathwhisper",
|
||||||
NextAction::array(0, new NextAction("icc ranged position lady deathwhisper", ACTION_MOVE + 2), nullptr)));
|
NextAction::array(0, new NextAction("icc ranged position lady deathwhisper", ACTION_MOVE + 2),
|
||||||
|
new NextAction("icc adds lady deathwhisper", ACTION_RAID + 3),
|
||||||
|
new NextAction("icc shade lady deathwhisper", ACTION_RAID + 4), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc adds lady deathwhisper",
|
|
||||||
NextAction::array(0, new NextAction("icc adds lady deathwhisper", ACTION_RAID + 3), nullptr)));
|
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc shade lady deathwhisper",
|
|
||||||
NextAction::array(0, new NextAction("icc shade lady deathwhisper", ACTION_MOVE + 5), nullptr)));
|
|
||||||
|
|
||||||
//Gunship Battle
|
//Gunship Battle
|
||||||
triggers.push_back(new TriggerNode("icc rotting frost giant tank position",
|
triggers.push_back(new TriggerNode("icc rotting frost giant tank position",
|
||||||
NextAction::array(0, new NextAction("icc rotting frost giant tank position", ACTION_RAID + 5), nullptr)));
|
NextAction::array(0, new NextAction("icc rotting frost giant tank position", ACTION_RAID + 5), nullptr)));
|
||||||
@@ -41,22 +35,20 @@ void RaidIccStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
NextAction::array(0, new NextAction("icc gunship teleport horde", ACTION_RAID + 4), nullptr)));
|
NextAction::array(0, new NextAction("icc gunship teleport horde", ACTION_RAID + 4), nullptr)));
|
||||||
|
|
||||||
//DBS
|
//DBS
|
||||||
triggers.push_back(new TriggerNode("icc dbs tank position",
|
triggers.push_back(new TriggerNode("icc dbs",
|
||||||
NextAction::array(0, new NextAction("icc dbs tank position", ACTION_RAID + 3), nullptr)));
|
NextAction::array(0, new NextAction("icc dbs tank position", ACTION_RAID + 3),
|
||||||
|
new NextAction("icc adds dbs", ACTION_RAID + 5), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc dbs main tank rune of blood",
|
triggers.push_back(new TriggerNode("icc dbs main tank rune of blood",
|
||||||
NextAction::array(0, new NextAction("taunt spell", ACTION_EMERGENCY + 4), nullptr)));
|
NextAction::array(0, new NextAction("taunt spell", ACTION_EMERGENCY + 4), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc adds dbs",
|
|
||||||
NextAction::array(0, new NextAction("icc adds dbs", ACTION_RAID + 5), nullptr)));
|
|
||||||
|
|
||||||
//DOGS
|
//DOGS
|
||||||
triggers.push_back(new TriggerNode("icc stinky precious main tank mortal wound",
|
triggers.push_back(new TriggerNode("icc stinky precious main tank mortal wound",
|
||||||
NextAction::array(0, new NextAction("taunt spell", ACTION_EMERGENCY + 4), nullptr)));
|
NextAction::array(0, new NextAction("taunt spell", ACTION_EMERGENCY + 4), nullptr)));
|
||||||
|
|
||||||
//FESTERGUT
|
//FESTERGUT
|
||||||
triggers.push_back(new TriggerNode("icc festergut tank position",
|
triggers.push_back(new TriggerNode("icc festergut group position",
|
||||||
NextAction::array(0, new NextAction("icc festergut tank position", ACTION_MOVE + 4), nullptr)));
|
NextAction::array(0, new NextAction("icc festergut group position", ACTION_MOVE + 4), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc festergut main tank gastric bloat",
|
triggers.push_back(new TriggerNode("icc festergut main tank gastric bloat",
|
||||||
NextAction::array(0, new NextAction("taunt spell", ACTION_EMERGENCY + 6), nullptr)));
|
NextAction::array(0, new NextAction("taunt spell", ACTION_EMERGENCY + 6), nullptr)));
|
||||||
@@ -85,18 +77,15 @@ void RaidIccStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
NextAction::array(0, new NextAction("icc putricide growing ooze puddle", ACTION_RAID + 3), nullptr)));
|
NextAction::array(0, new NextAction("icc putricide growing ooze puddle", ACTION_RAID + 3), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc putricide main tank mutated plague",
|
triggers.push_back(new TriggerNode("icc putricide main tank mutated plague",
|
||||||
NextAction::array(0, new NextAction("taunt spell", ACTION_RAID + 6), nullptr)));
|
NextAction::array(0, new NextAction("taunt spell", ACTION_RAID + 10), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc putricide malleable goo",
|
triggers.push_back(new TriggerNode("icc putricide malleable goo",
|
||||||
NextAction::array(0, new NextAction("avoid malleable goo", ACTION_RAID + 2), nullptr)));
|
NextAction::array(0, new NextAction("icc putricide avoid malleable goo", ACTION_RAID + 2), nullptr)));
|
||||||
|
|
||||||
//BPC
|
//BPC
|
||||||
triggers.push_back(new TriggerNode("icc bpc keleseth tank",
|
triggers.push_back(new TriggerNode("icc bpc keleseth tank",
|
||||||
NextAction::array(0, new NextAction("icc bpc keleseth tank", ACTION_RAID + 1), nullptr)));
|
NextAction::array(0, new NextAction("icc bpc keleseth tank", ACTION_RAID + 1), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc bpc nucleus",
|
|
||||||
NextAction::array(0, new NextAction("icc bpc nucleus", ACTION_RAID + 2), nullptr)));
|
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc bpc main tank",
|
triggers.push_back(new TriggerNode("icc bpc main tank",
|
||||||
NextAction::array(0, new NextAction("icc bpc main tank", ACTION_RAID + 3), nullptr)));
|
NextAction::array(0, new NextAction("icc bpc main tank", ACTION_RAID + 3), nullptr)));
|
||||||
|
|
||||||
@@ -105,10 +94,13 @@ void RaidIccStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc bpc kinetic bomb",
|
triggers.push_back(new TriggerNode("icc bpc kinetic bomb",
|
||||||
NextAction::array(0, new NextAction("icc bpc kinetic bomb", ACTION_RAID + 6), nullptr)));
|
NextAction::array(0, new NextAction("icc bpc kinetic bomb", ACTION_RAID + 6), nullptr)));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("icc bpc ball of flame",
|
||||||
|
NextAction::array(0, new NextAction("icc bpc ball of flame", ACTION_RAID + 7), nullptr)));
|
||||||
|
|
||||||
//BQL
|
//BQL
|
||||||
triggers.push_back(new TriggerNode("icc bql tank position",
|
triggers.push_back(new TriggerNode("icc bql group position",
|
||||||
NextAction::array(0, new NextAction("icc bql tank position", ACTION_RAID), nullptr)));
|
NextAction::array(0, new NextAction("icc bql group position", ACTION_RAID), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc bql pact of darkfallen",
|
triggers.push_back(new TriggerNode("icc bql pact of darkfallen",
|
||||||
NextAction::array(0, new NextAction("icc bql pact of darkfallen", ACTION_RAID +1), nullptr)));
|
NextAction::array(0, new NextAction("icc bql pact of darkfallen", ACTION_RAID +1), nullptr)));
|
||||||
@@ -116,25 +108,30 @@ void RaidIccStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
triggers.push_back(new TriggerNode("icc bql vampiric bite",
|
triggers.push_back(new TriggerNode("icc bql vampiric bite",
|
||||||
NextAction::array(0, new NextAction("icc bql vampiric bite", ACTION_EMERGENCY + 5), nullptr)));
|
NextAction::array(0, new NextAction("icc bql vampiric bite", ACTION_EMERGENCY + 5), nullptr)));
|
||||||
|
|
||||||
//VDW
|
//Sister Svalna
|
||||||
triggers.push_back(new TriggerNode("icc valkyre spear",
|
triggers.push_back(new TriggerNode("icc valkyre spear",
|
||||||
NextAction::array(0, new NextAction("icc valkyre spear", ACTION_EMERGENCY + 5), nullptr)));
|
NextAction::array(0, new NextAction("icc valkyre spear", ACTION_EMERGENCY + 5), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc sister svalna",
|
triggers.push_back(new TriggerNode("icc sister svalna",
|
||||||
NextAction::array(0, new NextAction("icc sister svalna", ACTION_RAID + 5), nullptr)));
|
NextAction::array(0, new NextAction("icc sister svalna", ACTION_RAID + 5), nullptr)));
|
||||||
|
|
||||||
|
|
||||||
|
//VDW
|
||||||
|
triggers.push_back(new TriggerNode("icc valithria group",
|
||||||
|
NextAction::array(0, new NextAction("icc valithria group", ACTION_RAID + 1), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc valithria portal",
|
triggers.push_back(new TriggerNode("icc valithria portal",
|
||||||
NextAction::array(0, new NextAction("icc valithria portal", ACTION_RAID + 5), nullptr)));
|
NextAction::array(0, new NextAction("icc valithria portal", ACTION_RAID + 5), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc valithria heal",
|
triggers.push_back(new TriggerNode("icc valithria heal",
|
||||||
NextAction::array(0, new NextAction("icc valithria heal", ACTION_RAID+1), nullptr)));
|
NextAction::array(0, new NextAction("icc valithria heal", ACTION_RAID+2), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc valithria dream cloud",
|
triggers.push_back(new TriggerNode("icc valithria dream cloud",
|
||||||
NextAction::array(0, new NextAction("icc valithria dream cloud", ACTION_RAID + 4), nullptr)));
|
NextAction::array(0, new NextAction("icc valithria dream cloud", ACTION_RAID + 4), nullptr)));
|
||||||
|
|
||||||
//SINDRAGOSA
|
//SINDRAGOSA
|
||||||
triggers.push_back(new TriggerNode("icc sindragosa tank position",
|
triggers.push_back(new TriggerNode("icc sindragosa group position",
|
||||||
NextAction::array(0, new NextAction("icc sindragosa tank position", ACTION_RAID + 1), nullptr)));
|
NextAction::array(0, new NextAction("icc sindragosa group position", ACTION_RAID + 1), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("icc sindragosa frost beacon",
|
triggers.push_back(new TriggerNode("icc sindragosa frost beacon",
|
||||||
NextAction::array(0, new NextAction("icc sindragosa frost beacon", ACTION_RAID + 5), nullptr)));
|
NextAction::array(0, new NextAction("icc sindragosa frost beacon", ACTION_RAID + 5), nullptr)));
|
||||||
@@ -181,18 +178,10 @@ void RaidIccStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
|
|||||||
multipliers.push_back(new IccDogsMultiplier(botAI));
|
multipliers.push_back(new IccDogsMultiplier(botAI));
|
||||||
multipliers.push_back(new IccFestergutMultiplier(botAI));
|
multipliers.push_back(new IccFestergutMultiplier(botAI));
|
||||||
multipliers.push_back(new IccRotfaceMultiplier(botAI));
|
multipliers.push_back(new IccRotfaceMultiplier(botAI));
|
||||||
//multipliers.push_back(new IccRotfaceGroupPositionMultiplier(botAI));
|
|
||||||
multipliers.push_back(new IccAddsPutricideMultiplier(botAI));
|
multipliers.push_back(new IccAddsPutricideMultiplier(botAI));
|
||||||
multipliers.push_back(new IccBpcAssistMultiplier(botAI));
|
multipliers.push_back(new IccBpcAssistMultiplier(botAI));
|
||||||
multipliers.push_back(new IccBqlPactOfDarkfallenMultiplier(botAI));
|
multipliers.push_back(new IccBqlMultiplier(botAI));
|
||||||
multipliers.push_back(new IccBqlVampiricBiteMultiplier(botAI));
|
|
||||||
multipliers.push_back(new IccValithriaDreamCloudMultiplier(botAI));
|
multipliers.push_back(new IccValithriaDreamCloudMultiplier(botAI));
|
||||||
multipliers.push_back(new IccSindragosaTankPositionMultiplier(botAI));
|
multipliers.push_back(new IccSindragosaMultiplier(botAI));
|
||||||
multipliers.push_back(new IccSindragosaFrostBeaconMultiplier(botAI));
|
|
||||||
//multipliers.push_back(new IccSindragosaFlyingMultiplier(botAI));
|
|
||||||
multipliers.push_back(new IccSindragosaMysticBuffetMultiplier(botAI));
|
|
||||||
multipliers.push_back(new IccSindragosaBlisteringColdPriorityMultiplier(botAI));
|
|
||||||
multipliers.push_back(new IccSindragosaFrostBombMultiplier(botAI));
|
|
||||||
multipliers.push_back(new IccLichKingNecroticPlagueMultiplier(botAI));
|
|
||||||
multipliers.push_back(new IccLichKingAddsMultiplier(botAI));
|
multipliers.push_back(new IccLichKingAddsMultiplier(botAI));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,46 +10,55 @@ class RaidIccTriggerContext : public NamedObjectContext<Trigger>
|
|||||||
public:
|
public:
|
||||||
RaidIccTriggerContext()
|
RaidIccTriggerContext()
|
||||||
{
|
{
|
||||||
creators["icc lm tank position"] = &RaidIccTriggerContext::icc_lm_tank_position;
|
creators["icc lm"] = &RaidIccTriggerContext::icc_lm;
|
||||||
creators["icc spike near"] = &RaidIccTriggerContext::icc_spike_near;
|
|
||||||
creators["icc dark reckoning"] = &RaidIccTriggerContext::icc_dark_reckoning;
|
creators["icc dark reckoning"] = &RaidIccTriggerContext::icc_dark_reckoning;
|
||||||
creators["icc ranged position lady deathwhisper"] = &RaidIccTriggerContext::icc_ranged_position_lady_deathwhisper;
|
creators["icc lady deathwhisper"] = &RaidIccTriggerContext::icc_lady_deathwhisper;
|
||||||
creators["icc adds lady deathwhisper"] = &RaidIccTriggerContext::icc_adds_lady_deathwhisper;
|
|
||||||
creators["icc shade lady deathwhisper"] = &RaidIccTriggerContext::icc_shade_lady_deathwhisper;
|
|
||||||
creators["icc rotting frost giant tank position"] = &RaidIccTriggerContext::icc_rotting_frost_giant_tank_position;
|
creators["icc rotting frost giant tank position"] = &RaidIccTriggerContext::icc_rotting_frost_giant_tank_position;
|
||||||
creators["icc in cannon"] = &RaidIccTriggerContext::icc_in_cannon;
|
creators["icc in cannon"] = &RaidIccTriggerContext::icc_in_cannon;
|
||||||
creators["icc gunship cannon near"] = &RaidIccTriggerContext::icc_gunship_cannon_near;
|
creators["icc gunship cannon near"] = &RaidIccTriggerContext::icc_gunship_cannon_near;
|
||||||
creators["icc gunship teleport ally"] = &RaidIccTriggerContext::icc_gunship_teleport_ally;
|
creators["icc gunship teleport ally"] = &RaidIccTriggerContext::icc_gunship_teleport_ally;
|
||||||
creators["icc gunship teleport horde"] = &RaidIccTriggerContext::icc_gunship_teleport_horde;
|
creators["icc gunship teleport horde"] = &RaidIccTriggerContext::icc_gunship_teleport_horde;
|
||||||
creators["icc dbs tank position"] = &RaidIccTriggerContext::icc_dbs_tank_position;
|
|
||||||
|
creators["icc dbs"] = &RaidIccTriggerContext::icc_dbs;
|
||||||
creators["icc dbs main tank rune of blood"] = &RaidIccTriggerContext::icc_dbs_main_tank_rune_of_blood;
|
creators["icc dbs main tank rune of blood"] = &RaidIccTriggerContext::icc_dbs_main_tank_rune_of_blood;
|
||||||
creators["icc adds dbs"] = &RaidIccTriggerContext::icc_adds_dbs;
|
|
||||||
creators["icc stinky precious main tank mortal wound"] = &RaidIccTriggerContext::icc_stinky_precious_main_tank_mortal_wound;
|
creators["icc stinky precious main tank mortal wound"] = &RaidIccTriggerContext::icc_stinky_precious_main_tank_mortal_wound;
|
||||||
creators["icc festergut tank position"] = &RaidIccTriggerContext::icc_festergut_tank_position;
|
|
||||||
|
creators["icc festergut group position"] = &RaidIccTriggerContext::icc_festergut_group_position;
|
||||||
creators["icc festergut main tank gastric bloat"] = &RaidIccTriggerContext::icc_festergut_main_tank_gastric_bloat;
|
creators["icc festergut main tank gastric bloat"] = &RaidIccTriggerContext::icc_festergut_main_tank_gastric_bloat;
|
||||||
creators["icc festergut spore"] = &RaidIccTriggerContext::icc_festergut_spore;
|
creators["icc festergut spore"] = &RaidIccTriggerContext::icc_festergut_spore;
|
||||||
|
|
||||||
creators["icc rotface tank position"] = &RaidIccTriggerContext::icc_rotface_tank_position;
|
creators["icc rotface tank position"] = &RaidIccTriggerContext::icc_rotface_tank_position;
|
||||||
creators["icc rotface group position"] = &RaidIccTriggerContext::icc_rotface_group_position;
|
creators["icc rotface group position"] = &RaidIccTriggerContext::icc_rotface_group_position;
|
||||||
creators["icc rotface move away from explosion"] = &RaidIccTriggerContext::icc_rotface_move_away_from_explosion;
|
creators["icc rotface move away from explosion"] = &RaidIccTriggerContext::icc_rotface_move_away_from_explosion;
|
||||||
|
|
||||||
creators["icc putricide volatile ooze"] = &RaidIccTriggerContext::icc_putricide_volatile_ooze;
|
creators["icc putricide volatile ooze"] = &RaidIccTriggerContext::icc_putricide_volatile_ooze;
|
||||||
creators["icc putricide gas cloud"] = &RaidIccTriggerContext::icc_putricide_gas_cloud;
|
creators["icc putricide gas cloud"] = &RaidIccTriggerContext::icc_putricide_gas_cloud;
|
||||||
creators["icc putricide growing ooze puddle"] = &RaidIccTriggerContext::icc_putricide_growing_ooze_puddle;
|
creators["icc putricide growing ooze puddle"] = &RaidIccTriggerContext::icc_putricide_growing_ooze_puddle;
|
||||||
creators["icc putricide main tank mutated plague"] = &RaidIccTriggerContext::icc_putricide_main_tank_mutated_plague;
|
creators["icc putricide main tank mutated plague"] = &RaidIccTriggerContext::icc_putricide_main_tank_mutated_plague;
|
||||||
creators["icc putricide malleable goo"] = &RaidIccTriggerContext::icc_putricide_malleable_goo;
|
creators["icc putricide malleable goo"] = &RaidIccTriggerContext::icc_putricide_malleable_goo;
|
||||||
|
|
||||||
creators["icc bpc keleseth tank"] = &RaidIccTriggerContext::icc_bpc_keleseth_tank;
|
creators["icc bpc keleseth tank"] = &RaidIccTriggerContext::icc_bpc_keleseth_tank;
|
||||||
creators["icc bpc nucleus"] = &RaidIccTriggerContext::icc_bpc_nucleus;
|
|
||||||
creators["icc bpc main tank"] = &RaidIccTriggerContext::icc_bpc_main_tank;
|
creators["icc bpc main tank"] = &RaidIccTriggerContext::icc_bpc_main_tank;
|
||||||
creators["icc bpc empowered vortex"] = &RaidIccTriggerContext::icc_bpc_empowered_vortex;
|
creators["icc bpc empowered vortex"] = &RaidIccTriggerContext::icc_bpc_empowered_vortex;
|
||||||
creators["icc bpc kinetic bomb"] = &RaidIccTriggerContext::icc_bpc_kinetic_bomb;
|
creators["icc bpc kinetic bomb"] = &RaidIccTriggerContext::icc_bpc_kinetic_bomb;
|
||||||
creators["icc bql tank position"] = &RaidIccTriggerContext::icc_bql_tank_position;
|
creators["icc bpc ball of flame"] = &RaidIccTriggerContext::icc_bpc_ball_of_flame;
|
||||||
|
|
||||||
|
creators["icc bql group position"] = &RaidIccTriggerContext::icc_bql_group_position;
|
||||||
creators["icc bql pact of darkfallen"] = &RaidIccTriggerContext::icc_bql_pact_of_darkfallen;
|
creators["icc bql pact of darkfallen"] = &RaidIccTriggerContext::icc_bql_pact_of_darkfallen;
|
||||||
creators["icc bql vampiric bite"] = &RaidIccTriggerContext::icc_bql_vampiric_bite;
|
creators["icc bql vampiric bite"] = &RaidIccTriggerContext::icc_bql_vampiric_bite;
|
||||||
|
|
||||||
creators["icc valkyre spear"] = &RaidIccTriggerContext::icc_valkyre_spear;
|
creators["icc valkyre spear"] = &RaidIccTriggerContext::icc_valkyre_spear;
|
||||||
creators["icc sister svalna"] = &RaidIccTriggerContext::icc_sister_svalna;
|
creators["icc sister svalna"] = &RaidIccTriggerContext::icc_sister_svalna;
|
||||||
|
|
||||||
|
creators["icc valithria group"] = &RaidIccTriggerContext::icc_valithria_group;
|
||||||
creators["icc valithria portal"] = &RaidIccTriggerContext::icc_valithria_portal;
|
creators["icc valithria portal"] = &RaidIccTriggerContext::icc_valithria_portal;
|
||||||
creators["icc valithria heal"] = &RaidIccTriggerContext::icc_valithria_heal;
|
creators["icc valithria heal"] = &RaidIccTriggerContext::icc_valithria_heal;
|
||||||
creators["icc valithria dream cloud"] = &RaidIccTriggerContext::icc_valithria_dream_cloud;
|
creators["icc valithria dream cloud"] = &RaidIccTriggerContext::icc_valithria_dream_cloud;
|
||||||
creators["icc sindragosa tank position"] = &RaidIccTriggerContext::icc_sindragosa_tank_position;
|
|
||||||
|
creators["icc sindragosa group position"] = &RaidIccTriggerContext::icc_sindragosa_group_position;
|
||||||
creators["icc sindragosa frost beacon"] = &RaidIccTriggerContext::icc_sindragosa_frost_beacon;
|
creators["icc sindragosa frost beacon"] = &RaidIccTriggerContext::icc_sindragosa_frost_beacon;
|
||||||
creators["icc sindragosa blistering cold"] = &RaidIccTriggerContext::icc_sindragosa_blistering_cold;
|
creators["icc sindragosa blistering cold"] = &RaidIccTriggerContext::icc_sindragosa_blistering_cold;
|
||||||
creators["icc sindragosa unchained magic"] = &RaidIccTriggerContext::icc_sindragosa_unchained_magic;
|
creators["icc sindragosa unchained magic"] = &RaidIccTriggerContext::icc_sindragosa_unchained_magic;
|
||||||
@@ -58,6 +67,7 @@ public:
|
|||||||
creators["icc sindragosa main tank mystic buffet"] = &RaidIccTriggerContext::icc_sindragosa_main_tank_mystic_buffet;
|
creators["icc sindragosa main tank mystic buffet"] = &RaidIccTriggerContext::icc_sindragosa_main_tank_mystic_buffet;
|
||||||
creators["icc sindragosa frost bomb"] = &RaidIccTriggerContext::icc_sindragosa_frost_bomb;
|
creators["icc sindragosa frost bomb"] = &RaidIccTriggerContext::icc_sindragosa_frost_bomb;
|
||||||
creators["icc sindragosa tank swap position"] = &RaidIccTriggerContext::icc_sindragosa_tank_swap_position;
|
creators["icc sindragosa tank swap position"] = &RaidIccTriggerContext::icc_sindragosa_tank_swap_position;
|
||||||
|
|
||||||
creators["icc lich king shadow trap"] = &RaidIccTriggerContext::icc_lich_king_shadow_trap;
|
creators["icc lich king shadow trap"] = &RaidIccTriggerContext::icc_lich_king_shadow_trap;
|
||||||
creators["icc lich king necrotic plague"] = &RaidIccTriggerContext::icc_lich_king_necrotic_plague;
|
creators["icc lich king necrotic plague"] = &RaidIccTriggerContext::icc_lich_king_necrotic_plague;
|
||||||
creators["icc lich king winter"] = &RaidIccTriggerContext::icc_lich_king_winter;
|
creators["icc lich king winter"] = &RaidIccTriggerContext::icc_lich_king_winter;
|
||||||
@@ -65,46 +75,55 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Trigger* icc_lm_tank_position(PlayerbotAI* ai) { return new IccLmTankPositionTrigger(ai); }
|
static Trigger* icc_lm(PlayerbotAI* ai) { return new IccLmTrigger(ai); }
|
||||||
static Trigger* icc_spike_near(PlayerbotAI* ai) { return new IccSpikeNearTrigger(ai); }
|
|
||||||
static Trigger* icc_dark_reckoning(PlayerbotAI* ai) { return new IccDarkReckoningTrigger(ai); }
|
static Trigger* icc_dark_reckoning(PlayerbotAI* ai) { return new IccDarkReckoningTrigger(ai); }
|
||||||
static Trigger* icc_ranged_position_lady_deathwhisper(PlayerbotAI* ai) { return new IccRangedPositionLadyDeathwhisperTrigger(ai); }
|
static Trigger* icc_lady_deathwhisper(PlayerbotAI* ai) { return new IccLadyDeathwhisperTrigger(ai); }
|
||||||
static Trigger* icc_adds_lady_deathwhisper(PlayerbotAI* ai) { return new IccAddsLadyDeathwhisperTrigger(ai); }
|
|
||||||
static Trigger* icc_shade_lady_deathwhisper(PlayerbotAI* ai) { return new IccShadeLadyDeathwhisperTrigger(ai); }
|
|
||||||
static Trigger* icc_rotting_frost_giant_tank_position(PlayerbotAI* ai) { return new IccRottingFrostGiantTankPositionTrigger(ai); }
|
static Trigger* icc_rotting_frost_giant_tank_position(PlayerbotAI* ai) { return new IccRottingFrostGiantTankPositionTrigger(ai); }
|
||||||
static Trigger* icc_in_cannon(PlayerbotAI* ai) { return new IccInCannonTrigger(ai); }
|
static Trigger* icc_in_cannon(PlayerbotAI* ai) { return new IccInCannonTrigger(ai); }
|
||||||
static Trigger* icc_gunship_cannon_near(PlayerbotAI* ai) { return new IccGunshipCannonNearTrigger(ai); }
|
static Trigger* icc_gunship_cannon_near(PlayerbotAI* ai) { return new IccGunshipCannonNearTrigger(ai); }
|
||||||
static Trigger* icc_gunship_teleport_ally(PlayerbotAI* ai) { return new IccGunshipTeleportAllyTrigger(ai); }
|
static Trigger* icc_gunship_teleport_ally(PlayerbotAI* ai) { return new IccGunshipTeleportAllyTrigger(ai); }
|
||||||
static Trigger* icc_gunship_teleport_horde(PlayerbotAI* ai) { return new IccGunshipTeleportHordeTrigger(ai); }
|
static Trigger* icc_gunship_teleport_horde(PlayerbotAI* ai) { return new IccGunshipTeleportHordeTrigger(ai); }
|
||||||
static Trigger* icc_dbs_tank_position(PlayerbotAI* ai) { return new IccDbsTankPositionTrigger(ai); }
|
|
||||||
|
static Trigger* icc_dbs(PlayerbotAI* ai) { return new IccDbsTrigger(ai); }
|
||||||
static Trigger* icc_dbs_main_tank_rune_of_blood(PlayerbotAI* ai) { return new IccDbsMainTankRuneOfBloodTrigger(ai); }
|
static Trigger* icc_dbs_main_tank_rune_of_blood(PlayerbotAI* ai) { return new IccDbsMainTankRuneOfBloodTrigger(ai); }
|
||||||
static Trigger* icc_adds_dbs(PlayerbotAI* ai) { return new IccAddsDbsTrigger(ai); }
|
|
||||||
static Trigger* icc_stinky_precious_main_tank_mortal_wound(PlayerbotAI* ai) { return new IccStinkyPreciousMainTankMortalWoundTrigger(ai); }
|
static Trigger* icc_stinky_precious_main_tank_mortal_wound(PlayerbotAI* ai) { return new IccStinkyPreciousMainTankMortalWoundTrigger(ai); }
|
||||||
static Trigger* icc_festergut_tank_position(PlayerbotAI* ai) { return new IccFestergutTankPositionTrigger(ai); }
|
|
||||||
|
static Trigger* icc_festergut_group_position(PlayerbotAI* ai) { return new IccFestergutGroupPositionTrigger(ai); }
|
||||||
static Trigger* icc_festergut_main_tank_gastric_bloat(PlayerbotAI* ai) { return new IccFestergutMainTankGastricBloatTrigger(ai); }
|
static Trigger* icc_festergut_main_tank_gastric_bloat(PlayerbotAI* ai) { return new IccFestergutMainTankGastricBloatTrigger(ai); }
|
||||||
static Trigger* icc_festergut_spore(PlayerbotAI* ai) { return new IccFestergutSporeTrigger(ai); }
|
static Trigger* icc_festergut_spore(PlayerbotAI* ai) { return new IccFestergutSporeTrigger(ai); }
|
||||||
|
|
||||||
static Trigger* icc_rotface_tank_position(PlayerbotAI* ai) { return new IccRotfaceTankPositionTrigger(ai); }
|
static Trigger* icc_rotface_tank_position(PlayerbotAI* ai) { return new IccRotfaceTankPositionTrigger(ai); }
|
||||||
static Trigger* icc_rotface_group_position(PlayerbotAI* ai) { return new IccRotfaceGroupPositionTrigger(ai); }
|
static Trigger* icc_rotface_group_position(PlayerbotAI* ai) { return new IccRotfaceGroupPositionTrigger(ai); }
|
||||||
static Trigger* icc_rotface_move_away_from_explosion(PlayerbotAI* ai) { return new IccRotfaceMoveAwayFromExplosionTrigger(ai); }
|
static Trigger* icc_rotface_move_away_from_explosion(PlayerbotAI* ai) { return new IccRotfaceMoveAwayFromExplosionTrigger(ai); }
|
||||||
|
|
||||||
static Trigger* icc_putricide_volatile_ooze(PlayerbotAI* ai) { return new IccPutricideVolatileOozeTrigger(ai); }
|
static Trigger* icc_putricide_volatile_ooze(PlayerbotAI* ai) { return new IccPutricideVolatileOozeTrigger(ai); }
|
||||||
static Trigger* icc_putricide_gas_cloud(PlayerbotAI* ai) { return new IccPutricideGasCloudTrigger(ai); }
|
static Trigger* icc_putricide_gas_cloud(PlayerbotAI* ai) { return new IccPutricideGasCloudTrigger(ai); }
|
||||||
static Trigger* icc_putricide_growing_ooze_puddle(PlayerbotAI* ai) { return new IccPutricideGrowingOozePuddleTrigger(ai); }
|
static Trigger* icc_putricide_growing_ooze_puddle(PlayerbotAI* ai) { return new IccPutricideGrowingOozePuddleTrigger(ai); }
|
||||||
static Trigger* icc_putricide_main_tank_mutated_plague(PlayerbotAI* ai) { return new IccPutricideMainTankMutatedPlagueTrigger(ai); }
|
static Trigger* icc_putricide_main_tank_mutated_plague(PlayerbotAI* ai) { return new IccPutricideMainTankMutatedPlagueTrigger(ai); }
|
||||||
static Trigger* icc_putricide_malleable_goo(PlayerbotAI* ai) { return new IccPutricideMalleableGooTrigger(ai); }
|
static Trigger* icc_putricide_malleable_goo(PlayerbotAI* ai) { return new IccPutricideMalleableGooTrigger(ai); }
|
||||||
|
|
||||||
static Trigger* icc_bpc_keleseth_tank(PlayerbotAI* ai) { return new IccBpcKelesethTankTrigger(ai); }
|
static Trigger* icc_bpc_keleseth_tank(PlayerbotAI* ai) { return new IccBpcKelesethTankTrigger(ai); }
|
||||||
static Trigger* icc_bpc_nucleus(PlayerbotAI* ai) { return new IccBpcNucleusTrigger(ai); }
|
|
||||||
static Trigger* icc_bpc_main_tank(PlayerbotAI* ai) { return new IccBpcMainTankTrigger(ai); }
|
static Trigger* icc_bpc_main_tank(PlayerbotAI* ai) { return new IccBpcMainTankTrigger(ai); }
|
||||||
static Trigger* icc_bpc_empowered_vortex(PlayerbotAI* ai) { return new IccBpcEmpoweredVortexTrigger(ai); }
|
static Trigger* icc_bpc_empowered_vortex(PlayerbotAI* ai) { return new IccBpcEmpoweredVortexTrigger(ai); }
|
||||||
static Trigger* icc_bpc_kinetic_bomb(PlayerbotAI* ai) { return new IccBpcKineticBombTrigger(ai); }
|
static Trigger* icc_bpc_kinetic_bomb(PlayerbotAI* ai) { return new IccBpcKineticBombTrigger(ai); }
|
||||||
static Trigger* icc_bql_tank_position(PlayerbotAI* ai) { return new IccBqlTankPositionTrigger(ai); }
|
static Trigger* icc_bpc_ball_of_flame(PlayerbotAI* ai) { return new IccBpcBallOfFlameTrigger(ai); }
|
||||||
|
|
||||||
|
static Trigger* icc_bql_group_position(PlayerbotAI* ai) { return new IccBqlGroupPositionTrigger(ai); }
|
||||||
static Trigger* icc_bql_pact_of_darkfallen(PlayerbotAI* ai) { return new IccBqlPactOfDarkfallenTrigger(ai); }
|
static Trigger* icc_bql_pact_of_darkfallen(PlayerbotAI* ai) { return new IccBqlPactOfDarkfallenTrigger(ai); }
|
||||||
static Trigger* icc_bql_vampiric_bite(PlayerbotAI* ai) { return new IccBqlVampiricBiteTrigger(ai); }
|
static Trigger* icc_bql_vampiric_bite(PlayerbotAI* ai) { return new IccBqlVampiricBiteTrigger(ai); }
|
||||||
|
|
||||||
static Trigger* icc_valkyre_spear(PlayerbotAI* ai) { return new IccValkyreSpearTrigger(ai); }
|
static Trigger* icc_valkyre_spear(PlayerbotAI* ai) { return new IccValkyreSpearTrigger(ai); }
|
||||||
static Trigger* icc_sister_svalna(PlayerbotAI* ai) { return new IccSisterSvalnaTrigger(ai); }
|
static Trigger* icc_sister_svalna(PlayerbotAI* ai) { return new IccSisterSvalnaTrigger(ai); }
|
||||||
|
|
||||||
|
static Trigger* icc_valithria_group(PlayerbotAI* ai) { return new IccValithriaGroupTrigger(ai); }
|
||||||
static Trigger* icc_valithria_portal(PlayerbotAI* ai) { return new IccValithriaPortalTrigger(ai); }
|
static Trigger* icc_valithria_portal(PlayerbotAI* ai) { return new IccValithriaPortalTrigger(ai); }
|
||||||
static Trigger* icc_valithria_heal(PlayerbotAI* ai) { return new IccValithriaHealTrigger(ai); }
|
static Trigger* icc_valithria_heal(PlayerbotAI* ai) { return new IccValithriaHealTrigger(ai); }
|
||||||
static Trigger* icc_valithria_dream_cloud(PlayerbotAI* ai) { return new IccValithriaDreamCloudTrigger(ai); }
|
static Trigger* icc_valithria_dream_cloud(PlayerbotAI* ai) { return new IccValithriaDreamCloudTrigger(ai); }
|
||||||
static Trigger* icc_sindragosa_tank_position(PlayerbotAI* ai) { return new IccSindragosaTankPositionTrigger(ai); }
|
|
||||||
|
static Trigger* icc_sindragosa_group_position(PlayerbotAI* ai) { return new IccSindragosaGroupPositionTrigger(ai); }
|
||||||
static Trigger* icc_sindragosa_frost_beacon(PlayerbotAI* ai) { return new IccSindragosaFrostBeaconTrigger(ai); }
|
static Trigger* icc_sindragosa_frost_beacon(PlayerbotAI* ai) { return new IccSindragosaFrostBeaconTrigger(ai); }
|
||||||
static Trigger* icc_sindragosa_blistering_cold(PlayerbotAI* ai) { return new IccSindragosaBlisteringColdTrigger(ai); }
|
static Trigger* icc_sindragosa_blistering_cold(PlayerbotAI* ai) { return new IccSindragosaBlisteringColdTrigger(ai); }
|
||||||
static Trigger* icc_sindragosa_unchained_magic(PlayerbotAI* ai) { return new IccSindragosaUnchainedMagicTrigger(ai); }
|
static Trigger* icc_sindragosa_unchained_magic(PlayerbotAI* ai) { return new IccSindragosaUnchainedMagicTrigger(ai); }
|
||||||
@@ -113,6 +132,7 @@ private:
|
|||||||
static Trigger* icc_sindragosa_main_tank_mystic_buffet(PlayerbotAI* ai) { return new IccSindragosaMainTankMysticBuffetTrigger(ai); }
|
static Trigger* icc_sindragosa_main_tank_mystic_buffet(PlayerbotAI* ai) { return new IccSindragosaMainTankMysticBuffetTrigger(ai); }
|
||||||
static Trigger* icc_sindragosa_frost_bomb(PlayerbotAI* ai) { return new IccSindragosaFrostBombTrigger(ai); }
|
static Trigger* icc_sindragosa_frost_bomb(PlayerbotAI* ai) { return new IccSindragosaFrostBombTrigger(ai); }
|
||||||
static Trigger* icc_sindragosa_tank_swap_position(PlayerbotAI* ai) { return new IccSindragosaTankSwapPositionTrigger(ai); }
|
static Trigger* icc_sindragosa_tank_swap_position(PlayerbotAI* ai) { return new IccSindragosaTankSwapPositionTrigger(ai); }
|
||||||
|
|
||||||
static Trigger* icc_lich_king_shadow_trap(PlayerbotAI* ai) { return new IccLichKingShadowTrapTrigger(ai); }
|
static Trigger* icc_lich_king_shadow_trap(PlayerbotAI* ai) { return new IccLichKingShadowTrapTrigger(ai); }
|
||||||
static Trigger* icc_lich_king_necrotic_plague(PlayerbotAI* ai) { return new IccLichKingNecroticPlagueTrigger(ai); }
|
static Trigger* icc_lich_king_necrotic_plague(PlayerbotAI* ai) { return new IccLichKingNecroticPlagueTrigger(ai); }
|
||||||
static Trigger* icc_lich_king_winter(PlayerbotAI* ai) { return new IccLichKingWinterTrigger(ai); }
|
static Trigger* icc_lich_king_winter(PlayerbotAI* ai) { return new IccLichKingWinterTrigger(ai); }
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,18 +5,223 @@
|
|||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
#include "Trigger.h"
|
#include "Trigger.h"
|
||||||
|
|
||||||
//Lord Marrowgar
|
enum CreatureIdsICC
|
||||||
class IccLmTankPositionTrigger : public Trigger
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
IccLmTankPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc lm tank position") {}
|
// Lord Marrowgar
|
||||||
bool IsActive() override;
|
NPC_SPIKE1 = 36619,
|
||||||
|
NPC_SPIKE2 = 38711,
|
||||||
|
NPC_SPIKE3 = 38712,
|
||||||
|
|
||||||
|
// Lady Deathwhisper
|
||||||
|
NPC_SHADE = 38222,
|
||||||
|
|
||||||
|
// Gunship Battle
|
||||||
|
NPC_KOR_KRON_BATTLE_MAGE = 37117,
|
||||||
|
NPC_KOR_KRON_AXETHROWER = 36968,
|
||||||
|
NPC_KOR_KRON_ROCKETEER = 36982,
|
||||||
|
NPC_SKYBREAKER_SORCERER = 37116,
|
||||||
|
NPC_SKYBREAKER_RIFLEMAN = 36969,
|
||||||
|
NPC_SKYBREAKER_MORTAR_SOLDIER = 36978,
|
||||||
|
NPC_IGB_HIGH_OVERLORD_SAURFANG = 36939,
|
||||||
|
NPC_IGB_MURADIN_BRONZEBEARD = 36948,
|
||||||
|
NPC_CANNONA = 36838,
|
||||||
|
NPC_CANNONH = 36839,
|
||||||
|
NPC_MURADIN_BRONZEBEARD = 36948,
|
||||||
|
NPC_HIGH_OVERLORD_SAURFANG = 36939,
|
||||||
|
|
||||||
|
// Deathbringer Saurfang
|
||||||
|
NPC_BLOOD_BEAST1 = 38508,
|
||||||
|
NPC_BLOOD_BEAST2 = 38596,
|
||||||
|
NPC_BLOOD_BEAST3 = 38597,
|
||||||
|
NPC_BLOOD_BEAST4 = 38598,
|
||||||
|
|
||||||
|
// Rotface
|
||||||
|
NPC_PUDDLE = 37013,
|
||||||
|
NPC_BIG_OOZE = 36899,
|
||||||
|
|
||||||
|
// Putricide
|
||||||
|
NPC_MALLEABLE_OOZE_STALKER = 38556,
|
||||||
|
NPC_GROWING_OOZE_PUDDLE = 37690,
|
||||||
|
NPC_CHOKING_GAS_BOMB = 38159,
|
||||||
|
|
||||||
|
// Blood Prince Council
|
||||||
|
NPC_DARK_NUCLEUS = 38369,
|
||||||
|
NPC_PRINCE_KELESETH = 37972,
|
||||||
|
NPC_PRINCE_TALDARAM = 37973,
|
||||||
|
NPC_PRINCE_VALANAR = 37970,
|
||||||
|
NPC_KINETIC_BOMB1 = 38454,
|
||||||
|
NPC_KINETIC_BOMB2 = 38775,
|
||||||
|
NPC_KINETIC_BOMB3 = 38776,
|
||||||
|
NPC_KINETIC_BOMB4 = 38777,
|
||||||
|
NPC_BALL_OF_FLAME = 38332,
|
||||||
|
NPC_BALL_OF_INFERNO_FLAME = 38451,
|
||||||
|
|
||||||
|
// Blood Queen Lana'thel
|
||||||
|
NPC_SWARMING_SHADOWS = 38163,
|
||||||
|
|
||||||
|
// Sister Svalna
|
||||||
|
NPC_SPEAR = 38248,
|
||||||
|
ITEM_SPEAR = 50307,
|
||||||
|
|
||||||
|
// Valithria Dreamwalker
|
||||||
|
NPC_VALITHRIA_DREAMWALKER = 36789,
|
||||||
|
NPC_DREAM_PORTAL = 37945,
|
||||||
|
NPC_NIGHTMARE_PORTAL = 38430,
|
||||||
|
NPC_DREAM_CLOUD = 37985,
|
||||||
|
NPC_NIGHTMARE_CLOUD = 38421,
|
||||||
|
NPC_RISEN_ARCHMAGE = 37868,
|
||||||
|
NPC_BLAZING_SKELETON = 36791,
|
||||||
|
NPC_SUPPRESSER = 37863,
|
||||||
|
NPC_BLISTERING_ZOMBIE = 37934,
|
||||||
|
NPC_GLUTTONOUS_ABOMINATION = 37886,
|
||||||
|
NPC_ROT_WORM = 37907,
|
||||||
|
NPC_COLUMN_OF_FROST = 37918,
|
||||||
|
NPC_MANA_VOID = 38068,
|
||||||
|
NPC_DREAM_PORTAL_PRE_EFFECT = 38186,
|
||||||
|
NPC_NIGHTMARE_PORTAL_PRE_EFFECT = 38429,
|
||||||
|
|
||||||
|
// Sindragosa
|
||||||
|
NPC_SINDRAGOSA = 36853,
|
||||||
|
NPC_TOMB1 = 36980,
|
||||||
|
NPC_TOMB2 = 38320,
|
||||||
|
NPC_TOMB3 = 38321,
|
||||||
|
NPC_TOMB4 = 38322,
|
||||||
|
|
||||||
|
// Lich King
|
||||||
|
NPC_THE_LICH_KING = 36597,
|
||||||
|
NPC_TERENAS_MENETHIL = 36823,
|
||||||
|
NPC_TERENAS_MENETHIL_HC = 39217,
|
||||||
|
NPC_SPIRIT_BOMB = 39189,
|
||||||
|
NPC_WICKED_SPIRIT1 = 39190,
|
||||||
|
NPC_WICKED_SPIRIT2 = 39287,
|
||||||
|
NPC_WICKED_SPIRIT3 = 39288,
|
||||||
|
NPC_WICKED_SPIRIT4 = 39289,
|
||||||
|
NPC_SHADOW_TRAP = 39137,
|
||||||
|
NPC_SHAMBLING_HORROR1 = 37698,
|
||||||
|
NPC_SHAMBLING_HORROR2 = 39299,
|
||||||
|
NPC_SHAMBLING_HORROR3 = 39300,
|
||||||
|
NPC_SHAMBLING_HORROR4 = 39301,
|
||||||
|
NPC_ICE_SPHERE1 = 36633,
|
||||||
|
NPC_ICE_SPHERE2 = 39305,
|
||||||
|
NPC_ICE_SPHERE3 = 39306,
|
||||||
|
NPC_ICE_SPHERE4 = 39307,
|
||||||
|
NPC_RAGING_SPIRIT1 = 36701,
|
||||||
|
NPC_RAGING_SPIRIT2 = 39302,
|
||||||
|
NPC_RAGING_SPIRIT3 = 39303,
|
||||||
|
NPC_RAGING_SPIRIT4 = 39304,
|
||||||
|
NPC_DRUDGE_GHOUL1 = 37695,
|
||||||
|
NPC_DRUDGE_GHOUL2 = 39309,
|
||||||
|
NPC_DRUDGE_GHOUL3 = 39310,
|
||||||
|
NPC_DRUDGE_GHOUL4 = 39311,
|
||||||
|
NPC_VALKYR_SHADOWGUARD1 = 36609,
|
||||||
|
NPC_VALKYR_SHADOWGUARD2 = 39120,
|
||||||
|
NPC_VALKYR_SHADOWGUARD3 = 39121,
|
||||||
|
NPC_VALKYR_SHADOWGUARD4 = 39122,
|
||||||
|
NPC_VILE_SPIRIT1 = 37799,
|
||||||
|
NPC_VILE_SPIRIT2 = 39284,
|
||||||
|
NPC_VILE_SPIRIT3 = 39285,
|
||||||
|
NPC_VILE_SPIRIT4 = 39286,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccSpikeNearTrigger : public Trigger
|
enum SpellIdsICC
|
||||||
|
{
|
||||||
|
// ICC cheat spells
|
||||||
|
SPELL_EMPOWERED_BLOOD = 70227, //70304 -->50%, 70227 /*100% more dmg, 100% more att speed*/
|
||||||
|
SPELL_EXPERIENCED = 71188, //dmg 30% 20% att speed
|
||||||
|
SPELL_NO_THREAT = 70115, //reduce threat
|
||||||
|
SPELL_SPITEFULL_FURY = 36886, //500% more threat
|
||||||
|
SPELL_NITRO_BOOSTS = 54861, //Speed
|
||||||
|
SPELL_PAIN_SUPPRESION = 69910, //40% dmg reduction
|
||||||
|
SPELL_AGEIS_OF_DALARAN = 71638, //268 all ress
|
||||||
|
SPELL_CYCLONE = 33786,
|
||||||
|
SPELL_HAMMER_OF_JUSTICE = 10308, //stun
|
||||||
|
|
||||||
|
// Lady Deathwhisper
|
||||||
|
SPELL_DARK_RECKONING = 69483,
|
||||||
|
|
||||||
|
// Gunship Battle
|
||||||
|
SPELL_DEATH_PLAGUE = 72865,
|
||||||
|
SPELL_BELOW_ZERO = 69705,
|
||||||
|
|
||||||
|
// Festergut
|
||||||
|
SPELL_GAS_SPORE = 69279,
|
||||||
|
|
||||||
|
// Rotface
|
||||||
|
SPELL_SLIME_SPRAY = 69508,
|
||||||
|
SPELL_OOZE_FLOOD = 71215,
|
||||||
|
SPELL_UNSTABLE_OOZE_EXPLOSION = 69839,
|
||||||
|
SPELL_OOZE_FLOOD_VISUAL = 69785,
|
||||||
|
|
||||||
|
// Putricide
|
||||||
|
SPELL_MALLEABLE_GOO = 70852,
|
||||||
|
SPELL_GROW_AURA = 70347,
|
||||||
|
|
||||||
|
// Blood Prince Council
|
||||||
|
SPELL_EMPOWERED_SHOCK_VORTEX1 = 72039,
|
||||||
|
SPELL_EMPOWERED_SHOCK_VORTEX2 = 73037,
|
||||||
|
SPELL_EMPOWERED_SHOCK_VORTEX3 = 73038,
|
||||||
|
SPELL_EMPOWERED_SHOCK_VORTEX4 = 73039,
|
||||||
|
|
||||||
|
// Blood Queen Lana'thel
|
||||||
|
SPELL_PACT_OF_THE_DARKFALLEN = 71340,
|
||||||
|
|
||||||
|
// Sister Svalna
|
||||||
|
SPELL_AETHER_SHIELD = 71463,
|
||||||
|
|
||||||
|
// Valithria Dreamwalker
|
||||||
|
SPELL_DREAM_STATE = 70766,
|
||||||
|
SPELL_EMERALD_VIGOR = 70873,
|
||||||
|
|
||||||
|
// Sindragosa
|
||||||
|
SPELL_FROST_BEACON = 70126,
|
||||||
|
SPELL_ICE_TOMB = 70157,
|
||||||
|
SPELL_FROST_BOMB_VISUAL = 70022,
|
||||||
|
SPELL_BLISTERING_COLD1 = 70123,
|
||||||
|
SPELL_BLISTERING_COLD2 = 71047,
|
||||||
|
SPELL_BLISTERING_COLD3 = 71048,
|
||||||
|
SPELL_BLISTERING_COLD4 = 71049,
|
||||||
|
|
||||||
|
// The Lich King
|
||||||
|
SPELL_HARVEST_SOUL_VALKYR = 68985,
|
||||||
|
SPELL_QUAKE = 72262,
|
||||||
|
SPELL_REMORSELESS_WINTER1 = 72259,
|
||||||
|
SPELL_REMORSELESS_WINTER2 = 74273,
|
||||||
|
SPELL_REMORSELESS_WINTER3 = 74274,
|
||||||
|
SPELL_REMORSELESS_WINTER4 = 74275,
|
||||||
|
SPELL_REMORSELESS_WINTER5 = 68981,
|
||||||
|
SPELL_REMORSELESS_WINTER6 = 74270,
|
||||||
|
SPELL_REMORSELESS_WINTER7 = 74271,
|
||||||
|
SPELL_REMORSELESS_WINTER8 = 74272,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint32 DEFILE_AURAS[] = {72756, 74162, 74163, 74164};
|
||||||
|
const uint32 DEFILE_CAST_ID = 72762;
|
||||||
|
const uint32 DEFILE_NPC_ID = 38757;
|
||||||
|
const size_t DEFILE_AURA_COUNT = 4;
|
||||||
|
|
||||||
|
// All fanatics and adherents entry ids Lady Deathwhisper
|
||||||
|
static const std::array<uint32, 23> addEntriesLady = {
|
||||||
|
37949, 38394, 38625, 38626, 38010, 38397, 39000, 39001,
|
||||||
|
38136, 38396, 38632, 38633, 37890, 38393, 38628, 38629,
|
||||||
|
38135, 38395, 38634, 38009, 38398, 38630, 38631};
|
||||||
|
|
||||||
|
const std::vector<uint32> spellEntriesFlood = {
|
||||||
|
69782, 69783, 69796, 69797, 69798,
|
||||||
|
69799, 69801, 69802, 69795};
|
||||||
|
|
||||||
|
const std::vector<uint32> availableTargetsGS = {
|
||||||
|
NPC_KOR_KRON_AXETHROWER, NPC_KOR_KRON_ROCKETEER, NPC_KOR_KRON_BATTLE_MAGE, NPC_IGB_HIGH_OVERLORD_SAURFANG,
|
||||||
|
NPC_SKYBREAKER_RIFLEMAN, NPC_SKYBREAKER_MORTAR_SOLDIER, NPC_SKYBREAKER_SORCERER, NPC_IGB_MURADIN_BRONZEBEARD};
|
||||||
|
|
||||||
|
static std::vector<ObjectGuid> sporeOrder;
|
||||||
|
|
||||||
|
//Lord Marrowgar
|
||||||
|
class IccLmTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccSpikeNearTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc spike near") {}
|
IccLmTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc lm") {}
|
||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -28,24 +233,10 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccRangedPositionLadyDeathwhisperTrigger : public Trigger
|
class IccLadyDeathwhisperTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccRangedPositionLadyDeathwhisperTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc ranged position lady deathwhisper") {}
|
IccLadyDeathwhisperTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc lady deathwhisper") {}
|
||||||
bool IsActive() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IccAddsLadyDeathwhisperTrigger : public Trigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IccAddsLadyDeathwhisperTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc adds lady deathwhisper") {}
|
|
||||||
bool IsActive() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IccShadeLadyDeathwhisperTrigger : public Trigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IccShadeLadyDeathwhisperTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc shade lady deathwhisper") {}
|
|
||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -86,10 +277,10 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//DBS
|
//DBS
|
||||||
class IccDbsTankPositionTrigger : public Trigger
|
class IccDbsTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccDbsTankPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc dbs tank position") {}
|
IccDbsTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc dbs") {}
|
||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -100,13 +291,6 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccAddsDbsTrigger : public Trigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IccAddsDbsTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc adds dbs") {}
|
|
||||||
bool IsActive() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
//DOGS
|
//DOGS
|
||||||
class IccStinkyPreciousMainTankMortalWoundTrigger : public Trigger
|
class IccStinkyPreciousMainTankMortalWoundTrigger : public Trigger
|
||||||
{
|
{
|
||||||
@@ -116,10 +300,10 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//FESTERGUT
|
//FESTERGUT
|
||||||
class IccFestergutTankPositionTrigger : public Trigger
|
class IccFestergutGroupPositionTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccFestergutTankPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc festergut tank position") {}
|
IccFestergutGroupPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc festergut group position") {}
|
||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -205,13 +389,6 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IccBpcNucleusTrigger : public Trigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IccBpcNucleusTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc bpc nucleus") {}
|
|
||||||
bool IsActive() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IccBpcMainTankTrigger : public Trigger
|
class IccBpcMainTankTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -233,11 +410,18 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Bql
|
class IccBpcBallOfFlameTrigger : public Trigger
|
||||||
class IccBqlTankPositionTrigger : public Trigger
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccBqlTankPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc bql tank position") {}
|
IccBpcBallOfFlameTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc bpc ball of flame") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Bql
|
||||||
|
class IccBqlGroupPositionTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IccBqlGroupPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc bql tank position") {}
|
||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -255,7 +439,7 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
//VDW
|
// Sister Svalna
|
||||||
class IccValkyreSpearTrigger : public Trigger
|
class IccValkyreSpearTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -270,6 +454,16 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Valithria Dreamwalker
|
||||||
|
|
||||||
|
class IccValithriaGroupTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IccValithriaGroupTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc valithria group") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
class IccValithriaPortalTrigger : public Trigger
|
class IccValithriaPortalTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -293,10 +487,10 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//SINDRAGOSA
|
//SINDRAGOSA
|
||||||
class IccSindragosaTankPositionTrigger : public Trigger
|
class IccSindragosaGroupPositionTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IccSindragosaTankPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc sindragosa tank position") {}
|
IccSindragosaGroupPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc sindragosa group position") {}
|
||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "HealthTriggers.h"
|
#include "HealthTriggers.h"
|
||||||
#include "RangeTriggers.h"
|
#include "RangeTriggers.h"
|
||||||
#include "Trigger.h"
|
#include "Trigger.h"
|
||||||
|
#include "Player.h"
|
||||||
|
|
||||||
class PlayerbotAI;
|
class PlayerbotAI;
|
||||||
class Unit;
|
class Unit;
|
||||||
@@ -922,4 +923,13 @@ public:
|
|||||||
public:
|
public:
|
||||||
virtual Value<Unit*>* GetTargetValue();
|
virtual Value<Unit*>* GetTargetValue();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SelfResurrectTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SelfResurrectTrigger(PlayerbotAI* ai) : Trigger(ai, "can self resurrect") {}
|
||||||
|
|
||||||
|
bool IsActive() override { return !bot->IsAlive() && bot->GetUInt32Value(PLAYER_SELF_RES_SPELL); }
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ public:
|
|||||||
creators["near random status"] = &TriggerContext::near_random_status;
|
creators["near random status"] = &TriggerContext::near_random_status;
|
||||||
creators["near npc status"] = &TriggerContext::near_npc_status;
|
creators["near npc status"] = &TriggerContext::near_npc_status;
|
||||||
creators["do quest status"] = &TriggerContext::do_quest_status;
|
creators["do quest status"] = &TriggerContext::do_quest_status;
|
||||||
|
creators["can self resurrect"] = &TriggerContext::can_self_resurrect;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -420,6 +421,7 @@ private:
|
|||||||
static Trigger* near_random_status(PlayerbotAI* botAI) { return new NewRpgStatusTrigger(botAI, RPG_NEAR_RANDOM); }
|
static Trigger* near_random_status(PlayerbotAI* botAI) { return new NewRpgStatusTrigger(botAI, RPG_NEAR_RANDOM); }
|
||||||
static Trigger* near_npc_status(PlayerbotAI* botAI) { return new NewRpgStatusTrigger(botAI, RPG_NEAR_NPC); }
|
static Trigger* near_npc_status(PlayerbotAI* botAI) { return new NewRpgStatusTrigger(botAI, RPG_NEAR_NPC); }
|
||||||
static Trigger* do_quest_status(PlayerbotAI* botAI) { return new NewRpgStatusTrigger(botAI, RPG_DO_QUEST); }
|
static Trigger* do_quest_status(PlayerbotAI* botAI) { return new NewRpgStatusTrigger(botAI, RPG_DO_QUEST); }
|
||||||
|
static Trigger* can_self_resurrect(PlayerbotAI* ai) { return new SelfResurrectTrigger(ai); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ bool IsDeadValue::Calculate()
|
|||||||
|
|
||||||
bool PetIsDeadValue::Calculate()
|
bool PetIsDeadValue::Calculate()
|
||||||
{
|
{
|
||||||
|
if ((bot->GetLevel() < 10 && bot->getClass() == CLASS_HUNTER) || bot->IsMounted())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!bot->GetPet())
|
if (!bot->GetPet())
|
||||||
{
|
{
|
||||||
uint32 ownerid = bot->GetGUID().GetCounter();
|
uint32 ownerid = bot->GetGUID().GetCounter();
|
||||||
|
|||||||
99
src/strategy/warlock/AfflictionWarlockStrategy.cpp
Normal file
99
src/strategy/warlock/AfflictionWarlockStrategy.cpp
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* 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 "AfflictionWarlockStrategy.h"
|
||||||
|
#include "Playerbots.h"
|
||||||
|
|
||||||
|
// ===== Action Node Factory =====
|
||||||
|
class AfflictionWarlockStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AfflictionWarlockStrategyActionNodeFactory()
|
||||||
|
{
|
||||||
|
creators["corruption"] = &corruption;
|
||||||
|
creators["corruption on attacker"] = &corruption;
|
||||||
|
creators["unstable affliction"] = &unstable_affliction;
|
||||||
|
creators["unstable affliction on attacker"] = &unstable_affliction;
|
||||||
|
creators["curse of agony"] = &curse_of_agony;
|
||||||
|
creators["curse of agony on attacker"] = &curse_of_agony;
|
||||||
|
creators["haunt"] = &haunt;
|
||||||
|
creators["shadow bolt"] = &shadow_bolt;
|
||||||
|
creators["drain soul"] = &drain_soul;
|
||||||
|
creators["life tap"] = &life_tap;
|
||||||
|
creators["shadowflame"] = &shadowflame;
|
||||||
|
creators["seed of corruption on attacker"] = &seed_of_corruption;
|
||||||
|
creators["seed of corruption"] = &seed_of_corruption;
|
||||||
|
creators["rain of fire"] = &rain_of_fire;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static ActionNode* corruption(PlayerbotAI*) { return new ActionNode("corruption", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* corruption_on_attacker(PlayerbotAI*) { return new ActionNode("corruption on attacker", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* unstable_affliction(PlayerbotAI*) { return new ActionNode("unstable affliction", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* unstable_affliction_on_attacker(PlayerbotAI*) { return new ActionNode("unstable affliction on attacker", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* curse_of_agony(PlayerbotAI*) { return new ActionNode("curse of agony", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* curse_of_agony_on_attacker(PlayerbotAI*) { return new ActionNode("curse of agony on attacker", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* haunt(PlayerbotAI*) { return new ActionNode("haunt", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* shadow_bolt(PlayerbotAI*) { return new ActionNode("shadow bolt", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* drain_soul(PlayerbotAI*) { return new ActionNode("drain soul", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* life_tap(PlayerbotAI*) { return new ActionNode("life tap", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* shadowflame(PlayerbotAI*) { return new ActionNode("shadowflame", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* seed_of_corruption_on_attacker(PlayerbotAI*) { return new ActionNode("seed of corruption on attacker", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* seed_of_corruption(PlayerbotAI*) { return new ActionNode("seed of corruption", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* rain_of_fire(PlayerbotAI*) { return new ActionNode("rain of fire", nullptr, nullptr, nullptr); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===== Single Target Strategy =====
|
||||||
|
AfflictionWarlockStrategy::AfflictionWarlockStrategy(PlayerbotAI* botAI) : GenericWarlockStrategy(botAI)
|
||||||
|
{
|
||||||
|
actionNodeFactories.Add(new AfflictionWarlockStrategyActionNodeFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== Default Actions =====
|
||||||
|
NextAction** AfflictionWarlockStrategy::getDefaultActions()
|
||||||
|
{
|
||||||
|
return NextAction::array( 0,
|
||||||
|
new NextAction("corruption", 5.6f),
|
||||||
|
new NextAction("unstable affliction", 5.5f),
|
||||||
|
new NextAction("curse of agony", 5.4f),
|
||||||
|
new NextAction("haunt", 5.3f),
|
||||||
|
new NextAction("shadow bolt", 5.2f),
|
||||||
|
new NextAction("shoot", 5.0f), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== Trigger Initialization ===
|
||||||
|
void AfflictionWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
GenericWarlockStrategy::InitTriggers(triggers);
|
||||||
|
|
||||||
|
// Main DoT triggers for high uptime
|
||||||
|
triggers.push_back(new TriggerNode("corruption on attacker", NextAction::array(0, new NextAction("corruption on attacker", 19.5f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("unstable affliction on attacker", NextAction::array(0, new NextAction("unstable affliction on attacker", 19.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("curse of agony on attacker", NextAction::array(0, new NextAction("curse of agony on attacker", 18.5f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("corruption", NextAction::array(0, new NextAction("corruption", 18.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("unstable affliction", NextAction::array(0, new NextAction("unstable affliction", 17.5f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("curse of agony", NextAction::array(0, new NextAction("curse of agony", 17.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("haunt", NextAction::array(0, new NextAction("haunt", 16.5f), nullptr)));
|
||||||
|
|
||||||
|
// Drain Soul as execute if target is low HP // Shadow Trance for free casts
|
||||||
|
triggers.push_back(new TriggerNode("shadow trance", NextAction::array(0, new NextAction("shadow bolt", 16.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("target critical health", NextAction::array(0, new NextAction("drain soul", 15.5f), nullptr)));
|
||||||
|
|
||||||
|
// Life Tap glyph buff, and Life Tap as filler
|
||||||
|
triggers.push_back(new TriggerNode("life tap glyph buff", NextAction::array(0, new NextAction("life tap", 29.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("life tap", NextAction::array(0, new NextAction("life tap", 5.1f), nullptr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== AoE Strategy, 3+ enemies =====
|
||||||
|
AfflictionWarlockAoeStrategy::AfflictionWarlockAoeStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||||
|
|
||||||
|
void AfflictionWarlockAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0,
|
||||||
|
new NextAction("shadowflame", 22.5f),
|
||||||
|
new NextAction("seed of corruption on attacker", 22.0f),
|
||||||
|
new NextAction("seed of corruption", 21.5f),
|
||||||
|
new NextAction("rain of fire", 21.0f), nullptr)));
|
||||||
|
}
|
||||||
32
src/strategy/warlock/AfflictionWarlockStrategy.h
Normal file
32
src/strategy/warlock/AfflictionWarlockStrategy.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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_AFFLICTIONWARLOCKSTRATEGY_H
|
||||||
|
#define _PLAYERBOT_AFFLICTIONWARLOCKSTRATEGY_H
|
||||||
|
|
||||||
|
#include "GenericWarlockStrategy.h"
|
||||||
|
#include "CombatStrategy.h"
|
||||||
|
|
||||||
|
class PlayerbotAI;
|
||||||
|
|
||||||
|
class AfflictionWarlockStrategy : public GenericWarlockStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AfflictionWarlockStrategy(PlayerbotAI* botAI);
|
||||||
|
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
std::string const getName() override { return "affli"; }
|
||||||
|
NextAction** getDefaultActions() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AfflictionWarlockAoeStrategy : public CombatStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AfflictionWarlockAoeStrategy(PlayerbotAI* botAI);
|
||||||
|
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
std::string const getName() override { return "affli aoe"; }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
127
src/strategy/warlock/DemonologyWarlockStrategy.cpp
Normal file
127
src/strategy/warlock/DemonologyWarlockStrategy.cpp
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* 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 "DemonologyWarlockStrategy.h"
|
||||||
|
#include "Playerbots.h"
|
||||||
|
|
||||||
|
// ===== Action Node Factory =====
|
||||||
|
class DemonologyWarlockStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DemonologyWarlockStrategyActionNodeFactory()
|
||||||
|
{
|
||||||
|
creators["metamorphosis"] = &metamorphosis;
|
||||||
|
creators["demonic empowerment"] = &demonic_empowerment;
|
||||||
|
creators["curse of agony"] = &curse_of_agony;
|
||||||
|
creators["curse of agony on attacker"] = &curse_of_agony_on_attacker;
|
||||||
|
creators["corruption"] = &corruption;
|
||||||
|
creators["corruption on attacker"] = &corruption_on_attacker;
|
||||||
|
creators["immolate"] = &immolate;
|
||||||
|
creators["immolate on attacker"] = &immolate_on_attacker;
|
||||||
|
creators["incinerate"] = &incinerate;
|
||||||
|
creators["soul fire"] = &soul_fire;
|
||||||
|
creators["shadow bolt"] = &shadow_bolt;
|
||||||
|
creators["life tap"] = &life_tap;
|
||||||
|
creators["immolation aura"] = &immolation_aura;
|
||||||
|
creators["shadowflame"] = &shadowflame;
|
||||||
|
creators["seed of corruption on attacker"] = &seed_of_corruption_on_attacker;
|
||||||
|
creators["seed of corruption"] = &seed_of_corruption;
|
||||||
|
creators["rain of fire"] = &rain_of_fire;
|
||||||
|
creators["demon charge"] = &demon_charge;
|
||||||
|
creators["shadow cleave"] = &shadow_cleave;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static ActionNode* metamorphosis(PlayerbotAI*) { return new ActionNode("metamorphosis", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* demonic_empowerment(PlayerbotAI*) { return new ActionNode("demonic empowerment", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* curse_of_agony(PlayerbotAI*) { return new ActionNode("curse of agony", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* curse_of_agony_on_attacker(PlayerbotAI*) { return new ActionNode("curse of agony on attacker", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* corruption(PlayerbotAI*) { return new ActionNode("corruption", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* corruption_on_attacker(PlayerbotAI*) { return new ActionNode("corruption on attacker", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* immolate(PlayerbotAI*) { return new ActionNode("immolate", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* immolate_on_attacker(PlayerbotAI*) { return new ActionNode("immolate on attacker", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* incinerate(PlayerbotAI*) { return new ActionNode("incinerate", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* soul_fire(PlayerbotAI*) { return new ActionNode("soul fire", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* shadow_bolt(PlayerbotAI*) { return new ActionNode("shadow bolt", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* life_tap(PlayerbotAI*) { return new ActionNode("life tap", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* immolation_aura(PlayerbotAI*) { return new ActionNode("immolation aura", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* shadowflame(PlayerbotAI*) { return new ActionNode("shadowflame", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* seed_of_corruption_on_attacker(PlayerbotAI*) { return new ActionNode("seed of corruption on attacker", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* seed_of_corruption(PlayerbotAI*) { return new ActionNode("seed of corruption", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* rain_of_fire(PlayerbotAI*) { return new ActionNode("rain of fire", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* demon_charge(PlayerbotAI*) { return new ActionNode("demon charge", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* shadow_cleave(PlayerbotAI*) { return new ActionNode("shadow cleave", nullptr, nullptr, nullptr); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===== Single Target Strategy =====
|
||||||
|
DemonologyWarlockStrategy::DemonologyWarlockStrategy(PlayerbotAI* botAI) : GenericWarlockStrategy(botAI)
|
||||||
|
{
|
||||||
|
actionNodeFactories.Add(new DemonologyWarlockStrategyActionNodeFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== Default Actions =====
|
||||||
|
NextAction** DemonologyWarlockStrategy::getDefaultActions()
|
||||||
|
{
|
||||||
|
return NextAction::array(0,
|
||||||
|
new NextAction("corruption", 5.6f),
|
||||||
|
new NextAction("curse of agony", 5.5f),
|
||||||
|
new NextAction("immolate", 5.4f),
|
||||||
|
new NextAction("shadow bolt", 5.3f),
|
||||||
|
new NextAction("incinerate", 5.2f),
|
||||||
|
new NextAction("shoot", 5.0f), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== Trigger Initialization ===
|
||||||
|
void DemonologyWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
GenericWarlockStrategy::InitTriggers(triggers);
|
||||||
|
|
||||||
|
// High priority cooldowns
|
||||||
|
triggers.push_back(new TriggerNode("metamorphosis", NextAction::array(0, new NextAction("metamorphosis", 28.5f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("demonic empowerment", NextAction::array(0, new NextAction("demonic empowerment", 28.0f), nullptr)));
|
||||||
|
|
||||||
|
// Main DoT triggers for high uptime
|
||||||
|
triggers.push_back(new TriggerNode("corruption on attacker", NextAction::array(0, new NextAction("corruption on attacker", 20.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("curse of agony on attacker", NextAction::array(0, new NextAction("curse of agony on attacker", 19.5f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("immolate on attacker", NextAction::array(0, new NextAction("immolate on attacker", 19.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("corruption", NextAction::array(0, new NextAction("corruption", 18.5f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("curse of agony", NextAction::array(0, new NextAction("curse of agony", 18.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("immolate", NextAction::array(0, new NextAction("immolate", 17.5f), nullptr)));
|
||||||
|
|
||||||
|
// Procs
|
||||||
|
triggers.push_back(new TriggerNode("decimation", NextAction::array(0, new NextAction("soul fire", 17.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("molten core", NextAction::array(0, new NextAction("incinerate", 16.5f), nullptr)));
|
||||||
|
|
||||||
|
// Life Tap glyph buff, and Life Tap as filler
|
||||||
|
triggers.push_back(new TriggerNode("life tap glyph buff", NextAction::array(0, new NextAction("life tap", 29.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("life tap", NextAction::array(0, new NextAction("life tap", 5.1f), nullptr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== AoE Strategy, 3+ enemies =====
|
||||||
|
DemonologyWarlockAoeStrategy::DemonologyWarlockAoeStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||||
|
|
||||||
|
void DemonologyWarlockAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0,
|
||||||
|
new NextAction("immolation aura", 26.0f),
|
||||||
|
new NextAction("shadowflame", 22.5f),
|
||||||
|
new NextAction("seed of corruption on attacker", 22.0f),
|
||||||
|
new NextAction("seed of corruption", 21.5f),
|
||||||
|
new NextAction("rain of fire", 21.0f), nullptr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combat strategy to run to melee for Immolation Aura
|
||||||
|
// Enabled by default for the Demonology spec
|
||||||
|
// To enable, type "co +meta melee"
|
||||||
|
// To disable, type "co -meta melee"
|
||||||
|
MetaMeleeAoeStrategy::MetaMeleeAoeStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||||
|
|
||||||
|
void MetaMeleeAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
triggers.push_back(new TriggerNode("immolation aura active", NextAction::array(0,
|
||||||
|
new NextAction("reach melee", 25.5f),
|
||||||
|
new NextAction("demon charge", 25.0f),
|
||||||
|
new NextAction("shadow cleave", 24.5f), nullptr)));
|
||||||
|
}
|
||||||
41
src/strategy/warlock/DemonologyWarlockStrategy.h
Normal file
41
src/strategy/warlock/DemonologyWarlockStrategy.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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_DEMONOLOGYWARLOCKSTRATEGY_H
|
||||||
|
#define _PLAYERBOT_DEMONOLOGYWARLOCKSTRATEGY_H
|
||||||
|
|
||||||
|
#include "GenericWarlockStrategy.h"
|
||||||
|
#include "CombatStrategy.h"
|
||||||
|
|
||||||
|
class PlayerbotAI;
|
||||||
|
|
||||||
|
class DemonologyWarlockStrategy : public GenericWarlockStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DemonologyWarlockStrategy(PlayerbotAI* botAI);
|
||||||
|
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
std::string const getName() override { return "demo"; }
|
||||||
|
NextAction** getDefaultActions() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DemonologyWarlockAoeStrategy : public CombatStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DemonologyWarlockAoeStrategy(PlayerbotAI* botAI);
|
||||||
|
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
std::string const getName() override { return "demo aoe"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class MetaMeleeAoeStrategy : public CombatStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MetaMeleeAoeStrategy(PlayerbotAI* botAI);
|
||||||
|
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
std::string const getName() override { return "meta melee"; }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
107
src/strategy/warlock/DestructionWarlockStrategy.cpp
Normal file
107
src/strategy/warlock/DestructionWarlockStrategy.cpp
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* 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 "DestructionWarlockStrategy.h"
|
||||||
|
#include "Playerbots.h"
|
||||||
|
|
||||||
|
// ===== Action Node Factory =====
|
||||||
|
class DestructionWarlockStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DestructionWarlockStrategyActionNodeFactory()
|
||||||
|
{
|
||||||
|
creators["immolate"] = &immolate;
|
||||||
|
creators["conflagrate"] = &conflagrate;
|
||||||
|
creators["chaos bolt"] = &chaos_bolt;
|
||||||
|
creators["incinerate"] = &incinerate;
|
||||||
|
creators["corruption"] = &corruption;
|
||||||
|
creators["corruption on attacker"] = &corruption_on_attacker;
|
||||||
|
creators["curse of agony"] = &curse_of_agony;
|
||||||
|
creators["curse of agony on attacker"] = &curse_of_agony_on_attacker;
|
||||||
|
creators["shadow bolt"] = &shadow_bolt;
|
||||||
|
creators["shadowburn"] = &shadowburn;
|
||||||
|
creators["life tap"] = &life_tap;
|
||||||
|
creators["shadowfury"] = &shadowfury;
|
||||||
|
creators["shadowflame"] = &shadowflame;
|
||||||
|
creators["seed of corruption"] = &seed_of_corruption;
|
||||||
|
creators["seed of corruption on attacker"] = &seed_of_corruption;
|
||||||
|
creators["rain of fire"] = &rain_of_fire;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static ActionNode* immolate(PlayerbotAI*) { return new ActionNode("immolate", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* conflagrate(PlayerbotAI*) { return new ActionNode("conflagrate", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* chaos_bolt(PlayerbotAI*) { return new ActionNode("chaos bolt", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* incinerate(PlayerbotAI*) { return new ActionNode("incinerate", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* corruption(PlayerbotAI*) { return new ActionNode("corruption", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* corruption_on_attacker(PlayerbotAI*) { return new ActionNode("corruption on attacker", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* curse_of_agony(PlayerbotAI*) { return new ActionNode("curse of agony", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* curse_of_agony_on_attacker(PlayerbotAI*) { return new ActionNode("curse of agony on attacker", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* shadow_bolt(PlayerbotAI*) { return new ActionNode("shadow bolt", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* shadowburn(PlayerbotAI*) { return new ActionNode("shadowburn", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* life_tap(PlayerbotAI*) { return new ActionNode("life tap", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* shadowfury(PlayerbotAI*) { return new ActionNode("shadowfury", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* shadowflame(PlayerbotAI*) { return new ActionNode("shadowflame", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* seed_of_corruption(PlayerbotAI*) { return new ActionNode("seed of corruption", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* seed_of_corruption_on_attacker(PlayerbotAI*) { return new ActionNode("seed of corruption on attacker", nullptr, nullptr, nullptr); }
|
||||||
|
static ActionNode* rain_of_fire(PlayerbotAI*) { return new ActionNode("rain of fire", nullptr, nullptr, nullptr); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===== Single Target Strategy =====
|
||||||
|
DestructionWarlockStrategy::DestructionWarlockStrategy(PlayerbotAI* botAI) : GenericWarlockStrategy(botAI)
|
||||||
|
{
|
||||||
|
actionNodeFactories.Add(new DestructionWarlockStrategyActionNodeFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== Default Actions =====
|
||||||
|
NextAction** DestructionWarlockStrategy::getDefaultActions()
|
||||||
|
{
|
||||||
|
return NextAction::array( 0,
|
||||||
|
new NextAction("immolate", 6.1f),
|
||||||
|
new NextAction("conflagrate", 6.0f),
|
||||||
|
new NextAction("chaos bolt", 5.9f),
|
||||||
|
new NextAction("incinerate", 5.8f),
|
||||||
|
new NextAction("corruption", 5.4f), // Note: Corruption, Curse of Agony, and Shadow Bolt won't be used after
|
||||||
|
new NextAction("curse of agony", 5.3f), // the character learns Incinerate at level 64
|
||||||
|
new NextAction("shadow bolt", 5.2f),
|
||||||
|
new NextAction("shoot", 5.0f), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== Trigger Initialization ===
|
||||||
|
void DestructionWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
GenericWarlockStrategy::InitTriggers(triggers);
|
||||||
|
|
||||||
|
// Main DoT triggers for high uptime + high priority cooldowns
|
||||||
|
triggers.push_back(new TriggerNode("immolate", NextAction::array(0, new NextAction("immolate", 20.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("conflagrate", NextAction::array(0, new NextAction("conflagrate", 19.5f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("chaos bolt", NextAction::array(0, new NextAction("chaos bolt", 19.0f), nullptr)));
|
||||||
|
|
||||||
|
// Note: These DoTs won't be used after the character learns Incinerate at level 64
|
||||||
|
triggers.push_back(new TriggerNode("corruption on attacker", NextAction::array(0, new NextAction("corruption on attacker", 5.6f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("curse of agony on attacker", NextAction::array(0, new NextAction("curse of agony on attacker", 5.5f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("corruption", NextAction::array(0, new NextAction("corruption", 5.4f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("curse of agony", NextAction::array(0, new NextAction("curse of agony", 5.3f), nullptr)));
|
||||||
|
|
||||||
|
// Shadowburn as execute if target is low HP
|
||||||
|
triggers.push_back(new TriggerNode("target critical health", NextAction::array(0, new NextAction("shadowburn", 18.0f), nullptr)));
|
||||||
|
|
||||||
|
// Life Tap glyph buff, and Life Tap as filler
|
||||||
|
triggers.push_back(new TriggerNode("life tap glyph buff", NextAction::array(0, new NextAction("life tap", 29.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("life tap", NextAction::array(0, new NextAction("life tap", 5.1f), nullptr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== AoE Strategy, 3+ enemies =====
|
||||||
|
DestructionWarlockAoeStrategy::DestructionWarlockAoeStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||||
|
|
||||||
|
void DestructionWarlockAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0,
|
||||||
|
new NextAction("shadowfury", 23.0f),
|
||||||
|
new NextAction("shadowflame", 22.5f),
|
||||||
|
new NextAction("seed of corruption on attacker", 22.0f),
|
||||||
|
new NextAction("seed of corruption", 21.5f),
|
||||||
|
new NextAction("rain of fire", 21.0f), nullptr)));
|
||||||
|
}
|
||||||
33
src/strategy/warlock/DestructionWarlockStrategy.h
Normal file
33
src/strategy/warlock/DestructionWarlockStrategy.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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_DESTRUCTIONWARLOCKSTRATEGY_H
|
||||||
|
#define _PLAYERBOT_DESTRUCTIONWARLOCKSTRATEGY_H
|
||||||
|
|
||||||
|
#include "GenericWarlockStrategy.h"
|
||||||
|
#include "CombatStrategy.h"
|
||||||
|
|
||||||
|
class PlayerbotAI;
|
||||||
|
|
||||||
|
class DestructionWarlockStrategy : public GenericWarlockStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DestructionWarlockStrategy(PlayerbotAI* botAI);
|
||||||
|
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
std::string const getName() override { return "destro"; }
|
||||||
|
NextAction** getDefaultActions() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DestructionWarlockAoeStrategy : public CombatStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DestructionWarlockAoeStrategy(PlayerbotAI* botAI);
|
||||||
|
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
std::string const getName() override { return "destro aoe"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -4,105 +4,85 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "DpsWarlockStrategy.h"
|
#include "DpsWarlockStrategy.h"
|
||||||
|
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
|
||||||
|
// This strategy is designed for low-level Warlocks without talents.
|
||||||
|
// All of the important spells/cooldowns have been migrated to
|
||||||
|
// their respective specs.
|
||||||
|
|
||||||
|
// ===== Action Node Factory =====
|
||||||
class DpsWarlockStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
class DpsWarlockStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DpsWarlockStrategyActionNodeFactory()
|
DpsWarlockStrategyActionNodeFactory()
|
||||||
{
|
{
|
||||||
|
creators["corruption"] = &corruption;
|
||||||
|
creators["curse of agony"] = &curse_of_agony;
|
||||||
|
creators["immolate"] = &immolate;
|
||||||
creators["shadow bolt"] = &shadow_bolt;
|
creators["shadow bolt"] = &shadow_bolt;
|
||||||
creators["unstable affliction"] = &unstable_affliction;
|
creators["life tap"] = &life_tap;
|
||||||
creators["unstable affliction on attacker"] = &unstable_affliction_on_attacker;
|
creators["shadowflame"] = &shadowflame;
|
||||||
|
creators["seed of corruption"] = &seed_of_corruption;
|
||||||
|
creators["rain of fire"] = &rain_of_fire;
|
||||||
|
creators["drain soul"] = &drain_soul;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static ActionNode* shadow_bolt([[maybe_unused]] PlayerbotAI* botAI)
|
static ActionNode* corruption(PlayerbotAI*) { return new ActionNode("corruption", nullptr, nullptr, nullptr); }
|
||||||
{
|
static ActionNode* curse_of_agony(PlayerbotAI*){return new ActionNode("curse of agony", nullptr, nullptr, nullptr);}
|
||||||
return new ActionNode("shadow bolt",
|
static ActionNode* immolate(PlayerbotAI*) { return new ActionNode("immolate", nullptr, nullptr, nullptr); }
|
||||||
/*P*/ nullptr,
|
static ActionNode* shadow_bolt(PlayerbotAI*) { return new ActionNode("shadow bolt", nullptr, nullptr, nullptr); }
|
||||||
/*A*/ NextAction::array(0, new NextAction("shoot"), nullptr),
|
static ActionNode* life_tap(PlayerbotAI*) { return new ActionNode("life tap", nullptr, nullptr, nullptr); }
|
||||||
/*C*/ nullptr);
|
static ActionNode* shadowflame(PlayerbotAI*) { return new ActionNode("shadowflame", nullptr, nullptr, nullptr); }
|
||||||
}
|
static ActionNode* seed_of_corruption(PlayerbotAI*){return new ActionNode("seed of corruption", nullptr, nullptr, nullptr);}
|
||||||
static ActionNode* unstable_affliction([[maybe_unused]] PlayerbotAI* botAI)
|
static ActionNode* rain_of_fire(PlayerbotAI*) { return new ActionNode("rain of fire", nullptr, nullptr, nullptr); }
|
||||||
{
|
static ActionNode* drain_soul(PlayerbotAI*) { return new ActionNode("drain soul", nullptr, nullptr, nullptr); }
|
||||||
return new ActionNode("unstable affliction",
|
|
||||||
/*P*/ NULL,
|
|
||||||
/*A*/ NextAction::array(0, new NextAction("immolate"), NULL),
|
|
||||||
/*C*/ NULL);
|
|
||||||
}
|
|
||||||
static ActionNode* unstable_affliction_on_attacker([[maybe_unused]] PlayerbotAI* botAI)
|
|
||||||
{
|
|
||||||
return new ActionNode("unstable affliction on attacker",
|
|
||||||
/*P*/ NULL,
|
|
||||||
/*A*/ NextAction::array(0, new NextAction("immolate on attacker"), NULL),
|
|
||||||
/*C*/ NULL);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ===== Single Target Strategy =====
|
||||||
DpsWarlockStrategy::DpsWarlockStrategy(PlayerbotAI* botAI) : GenericWarlockStrategy(botAI)
|
DpsWarlockStrategy::DpsWarlockStrategy(PlayerbotAI* botAI) : GenericWarlockStrategy(botAI)
|
||||||
{
|
{
|
||||||
actionNodeFactories.Add(new DpsWarlockStrategyActionNodeFactory());
|
actionNodeFactories.Add(new DpsWarlockStrategyActionNodeFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== Default Actions =====
|
||||||
NextAction** DpsWarlockStrategy::getDefaultActions()
|
NextAction** DpsWarlockStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(
|
return NextAction::array(0,
|
||||||
0, new NextAction("haunt", ACTION_DEFAULT + 0.4f), new NextAction("demonic empowerment", ACTION_DEFAULT + 0.3f),
|
new NextAction("immolate", 5.5f),
|
||||||
new NextAction("shadow bolt", ACTION_DEFAULT + 0.2f), new NextAction("shoot", ACTION_DEFAULT), nullptr);
|
new NextAction("corruption", 5.4f),
|
||||||
|
new NextAction("curse of agony", 5.3f),
|
||||||
|
new NextAction("shadow bolt", 5.2f),
|
||||||
|
new NextAction("shoot", 5.0f), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== Trigger Initialization ===
|
||||||
void DpsWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void DpsWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
GenericWarlockStrategy::InitTriggers(triggers);
|
GenericWarlockStrategy::InitTriggers(triggers);
|
||||||
|
|
||||||
triggers.push_back(
|
// Main DoT triggers for high uptime
|
||||||
new TriggerNode("backlash", NextAction::array(0, new NextAction("shadow bolt", 20.0f), nullptr)));
|
triggers.push_back(new TriggerNode("corruption on attacker", NextAction::array(0, new NextAction("corruption on attacker", 20.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("curse of agony on attacker", NextAction::array(0, new NextAction("curse of agony on attacker", 19.5f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("immolate on attacker", NextAction::array(0, new NextAction("immolate on attacker", 19.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("corruption", NextAction::array(0, new NextAction("corruption", 18.5f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("curse of agony", NextAction::array(0, new NextAction("curse of agony", 18.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("immolate", NextAction::array(0, new NextAction("immolate", 17.5f), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("haunt", NextAction::array(0, new NextAction("haunt", 26.0f), NULL)));
|
// Drain Soul as execute if target is low HP
|
||||||
|
triggers.push_back(new TriggerNode("target critical health", NextAction::array(0, new NextAction("drain soul", 17.0f), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(
|
// Cast during movement or to activate glyph buff
|
||||||
new TriggerNode("shadow trance", NextAction::array(0, new NextAction("shadow bolt", 15.0f), NULL)));
|
triggers.push_back(new TriggerNode("life tap", NextAction::array(0, new NextAction("life tap", ACTION_DEFAULT + 0.1f), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("backlash", NextAction::array(0, new NextAction("shadow bolt", 15.0f), NULL)));
|
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("molten core", NextAction::array(0, new NextAction("incinerate", 15.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(new TriggerNode("life tap glyph buff", NextAction::array(0, new NextAction("life tap", 28.0f), NULL)));
|
||||||
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("metamorphosis", NextAction::array(0, new NextAction("metamorphosis", 20.0f), NULL)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== AoE Strategy, 3+ enemies =====
|
||||||
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 TriggerNode("medium aoe", NextAction::array(0, new NextAction("seed of corruption", 33.0f),
|
new NextAction("shadowflame", 22.5f),
|
||||||
new NextAction("seed of corruption on attacker", 32.0f),
|
new NextAction("seed of corruption on attacker", 22.0f),
|
||||||
new NextAction("rain of fire", 31.0f), nullptr)));
|
new NextAction("seed of corruption", 21.5f),
|
||||||
triggers.push_back(new TriggerNode("corruption on attacker",
|
new NextAction("rain of fire", 21.0f), nullptr)));
|
||||||
NextAction::array(0, new NextAction("corruption on attacker", 27.0f), nullptr)));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("unstable affliction on attacker",
|
|
||||||
NextAction::array(0, new NextAction("unstable affliction on attacker", 26.0f), NULL)));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("curse of agony on attacker",
|
|
||||||
NextAction::array(0, new NextAction("curse of agony on attacker", 25.0f), nullptr)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void DpsWarlockDebuffStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|
||||||
{
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("corruption", NextAction::array(0, new NextAction("corruption", 22.0f), nullptr)));
|
|
||||||
triggers.push_back(new TriggerNode("unstable affliction",
|
|
||||||
NextAction::array(0, new NextAction("unstable affliction", 21.0f), NULL)));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("curse of agony", NextAction::array(0, new NextAction("curse of agony", 20.0f), nullptr)));
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,14 +30,4 @@ public:
|
|||||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
std::string const getName() override { return "aoe"; }
|
std::string const getName() override { return "aoe"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class DpsWarlockDebuffStrategy : public CombatStrategy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DpsWarlockDebuffStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
|
||||||
|
|
||||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
|
||||||
std::string const getName() override { return "dps debuff"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "GenericWarlockNonCombatStrategy.h"
|
#include "GenericWarlockNonCombatStrategy.h"
|
||||||
|
#include "AiFactory.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
|
||||||
class GenericWarlockNonCombatStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
class GenericWarlockNonCombatStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||||
@@ -20,6 +20,10 @@ public:
|
|||||||
creators["summon felhunter"] = &summon_felhunter;
|
creators["summon felhunter"] = &summon_felhunter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pet skills are setup in pass-through fashion, so if one fails, it attempts to cast the next one
|
||||||
|
// The order goes Felguard -> Felhunter -> Succubus -> Voidwalker -> Imp
|
||||||
|
// Pets are summoned based on the non-combat strategy you have active, the warlock's level, and if they have a soulstone available
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static ActionNode* fel_armor([[maybe_unused]] PlayerbotAI* botAI)
|
static ActionNode* fel_armor([[maybe_unused]] PlayerbotAI* botAI)
|
||||||
{
|
{
|
||||||
@@ -36,7 +40,6 @@ private:
|
|||||||
/*A*/ NextAction::array(0, new NextAction("demon skin"), nullptr),
|
/*A*/ NextAction::array(0, new NextAction("demon skin"), nullptr),
|
||||||
/*C*/ nullptr);
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ActionNode* summon_voidwalker([[maybe_unused]] PlayerbotAI* botAI)
|
static ActionNode* summon_voidwalker([[maybe_unused]] PlayerbotAI* botAI)
|
||||||
{
|
{
|
||||||
return new ActionNode("summon voidwalker",
|
return new ActionNode("summon voidwalker",
|
||||||
@@ -62,7 +65,7 @@ private:
|
|||||||
{
|
{
|
||||||
return new ActionNode("summon felguard",
|
return new ActionNode("summon felguard",
|
||||||
/*P*/ nullptr,
|
/*P*/ nullptr,
|
||||||
/*A*/ NextAction::array(0, new NextAction("summon succubus"), nullptr),
|
/*A*/ NextAction::array(0, new NextAction("summon felhunter"), nullptr),
|
||||||
/*C*/ nullptr);
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -75,45 +78,133 @@ GenericWarlockNonCombatStrategy::GenericWarlockNonCombatStrategy(PlayerbotAI* bo
|
|||||||
void GenericWarlockNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void GenericWarlockNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
NonCombatStrategy::InitTriggers(triggers);
|
NonCombatStrategy::InitTriggers(triggers);
|
||||||
|
triggers.push_back(new TriggerNode("has pet", NextAction::array(0, new NextAction("toggle pet spell", 60.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("no pet", NextAction::array(0, new NextAction("fel domination", 30.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("soul link", NextAction::array(0, new NextAction("soul link", 28.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("demon armor", NextAction::array(0, new NextAction("fel armor", 27.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("no healthstone", NextAction::array(0, new NextAction("create healthstone", 26.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("no soulstone", NextAction::array(0, new NextAction("create soulstone", 25.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("life tap", NextAction::array(0, new NextAction("life tap", 23.0f), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(
|
Player* bot = botAI->GetBot();
|
||||||
new TriggerNode("demon armor", NextAction::array(0, new NextAction("fel armor", 21.0f), nullptr)));
|
int tab = AiFactory::GetPlayerSpecTab(bot);
|
||||||
// triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("apply oil", 1.0f), nullptr)));
|
|
||||||
triggers.push_back(
|
if (tab == 2) // Destruction uses Firestone
|
||||||
new TriggerNode("has pet", NextAction::array(0, new NextAction("toggle pet spell", 60.0f), nullptr)));
|
{
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("no healthstone", NextAction::array(0, new NextAction("create healthstone", 15.0f), nullptr)));
|
new TriggerNode("no firestone", NextAction::array(0, new NextAction("create firestone", 24.0f), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("no spellstone", NextAction::array(0, new NextAction("create spellstone", 13.0f), nullptr)));
|
new TriggerNode("firestone", NextAction::array(0, new NextAction("firestone", 24.0f), nullptr)));
|
||||||
triggers.push_back(
|
}
|
||||||
new TriggerNode("spellstone", NextAction::array(0, new NextAction("spellstone", 13.0f), nullptr)));
|
else // Affliction and Demonology use Spellstone
|
||||||
}
|
{
|
||||||
|
triggers.push_back(new TriggerNode("no spellstone",
|
||||||
void WarlockPetStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
NextAction::array(0, new NextAction("create spellstone", 24.0f), nullptr)));
|
||||||
{
|
triggers.push_back(
|
||||||
// triggers.push_back(new TriggerNode("no pet", NextAction::array(0, new NextAction("summon felguard", 60.0f),
|
new TriggerNode("spellstone", NextAction::array(0, new NextAction("spellstone", 24.0f), nullptr)));
|
||||||
// nullptr)));
|
}
|
||||||
// TODO Warlock pets
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Non-combat strategy for summoning a Imp
|
||||||
|
// Enabled by default for the Destruction spec
|
||||||
|
// To enable, type "nc +imp"
|
||||||
|
// To disable, type "nc -imp"
|
||||||
SummonImpStrategy::SummonImpStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai) {}
|
SummonImpStrategy::SummonImpStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai) {}
|
||||||
|
|
||||||
void SummonImpStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void SummonImpStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
triggers.push_back(new TriggerNode("no pet", NextAction::array(0, new NextAction("summon imp", 11.0f), NULL)));
|
triggers.push_back(new TriggerNode("no pet", NextAction::array(0, new NextAction("summon imp", 29.0f), NULL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
SummonFelguardStrategy::SummonFelguardStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai) {}
|
// Non-combat strategy for summoning a Voidwalker
|
||||||
|
// Disabled by default
|
||||||
|
// To enable, type "nc +voidwalker"
|
||||||
|
// To disable, type "nc -voidwalker"
|
||||||
|
SummonVoidwalkerStrategy::SummonVoidwalkerStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai) {}
|
||||||
|
|
||||||
void SummonFelguardStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void SummonVoidwalkerStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
triggers.push_back(new TriggerNode("no pet", NextAction::array(0, new NextAction("summon felguard", 11.0f), NULL)));
|
triggers.push_back(
|
||||||
|
new TriggerNode("no pet", NextAction::array(0, new NextAction("summon voidwalker", 29.0f), NULL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Non-combat strategy for summoning a Succubus
|
||||||
|
// Disabled by default
|
||||||
|
// To enable, type "nc +succubus"
|
||||||
|
// To disable, type "nc -succubus"
|
||||||
|
SummonSuccubusStrategy::SummonSuccubusStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai) {}
|
||||||
|
|
||||||
|
void SummonSuccubusStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
triggers.push_back(new TriggerNode("no pet", NextAction::array(0, new NextAction("summon succubus", 29.0f), NULL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-combat strategy for summoning a Felhunter
|
||||||
|
// Enabled by default for the Affliction spec
|
||||||
|
// To enable, type "nc +felhunter"
|
||||||
|
// To disable, type "nc -felhunter"
|
||||||
SummonFelhunterStrategy::SummonFelhunterStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai) {}
|
SummonFelhunterStrategy::SummonFelhunterStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai) {}
|
||||||
|
|
||||||
void SummonFelhunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void SummonFelhunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("no pet", NextAction::array(0, new NextAction("summon felhunter", 11.0f), NULL)));
|
new TriggerNode("no pet", NextAction::array(0, new NextAction("summon felhunter", 29.0f), NULL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Non-combat strategy for summoning a Felguard
|
||||||
|
// Enabled by default for the Demonology spec
|
||||||
|
// To enable, type "nc +felguard"
|
||||||
|
// To disable, type "nc -felguard"
|
||||||
|
SummonFelguardStrategy::SummonFelguardStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai) {}
|
||||||
|
|
||||||
|
void SummonFelguardStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
triggers.push_back(new TriggerNode("no pet", NextAction::array(0, new NextAction("summon felguard", 29.0f), NULL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-combat strategy for selecting themselves to receive soulstone
|
||||||
|
// Disabled by default
|
||||||
|
// To enable, type "nc +ss self"
|
||||||
|
// To disable, type "nc -ss self"
|
||||||
|
SoulstoneSelfStrategy::SoulstoneSelfStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai) {}
|
||||||
|
|
||||||
|
void SoulstoneSelfStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
triggers.push_back(new TriggerNode("soulstone", NextAction::array(0, new NextAction("soulstone self", 24.0f), NULL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-combat strategy for selecting the master to receive soulstone
|
||||||
|
// Disabled by default
|
||||||
|
// To enable, type "nc +ss master"
|
||||||
|
// To disable, type "nc -ss master"
|
||||||
|
SoulstoneMasterStrategy::SoulstoneMasterStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai) {}
|
||||||
|
|
||||||
|
void SoulstoneMasterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("soulstone", NextAction::array(0, new NextAction("soulstone master", 24.0f), NULL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-combat strategy for selecting tanks to receive soulstone
|
||||||
|
// Disabled by default
|
||||||
|
// To enable, type "nc +ss tank"
|
||||||
|
// To disable, type "nc -ss tank"
|
||||||
|
SoulstoneTankStrategy::SoulstoneTankStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai) {}
|
||||||
|
|
||||||
|
void SoulstoneTankStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("soulstone", NextAction::array(0, new NextAction("soulstone tank", 24.0f), NULL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-combat strategy for selecting healers to receive soulstone
|
||||||
|
// Disabled by default
|
||||||
|
// To enable, type "nc +ss healer"
|
||||||
|
// To disable, type "nc -ss healer"
|
||||||
|
SoulstoneHealerStrategy::SoulstoneHealerStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai) {}
|
||||||
|
|
||||||
|
void SoulstoneHealerStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("soulstone", NextAction::array(0, new NextAction("soulstone healer", 24.0f), NULL)));
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,30 +19,31 @@ public:
|
|||||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WarlockPetStrategy : public Strategy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WarlockPetStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
|
||||||
|
|
||||||
std::string const getName() override { return "pet"; }
|
|
||||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SummonImpStrategy : public NonCombatStrategy
|
class SummonImpStrategy : public NonCombatStrategy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SummonImpStrategy(PlayerbotAI* ai);
|
SummonImpStrategy(PlayerbotAI* ai);
|
||||||
virtual std::string const getName() override { return "bhealth"; }
|
virtual std::string const getName() override { return "imp"; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SummonFelguardStrategy : public NonCombatStrategy
|
class SummonVoidwalkerStrategy : public NonCombatStrategy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SummonFelguardStrategy(PlayerbotAI* ai);
|
SummonVoidwalkerStrategy(PlayerbotAI* ai);
|
||||||
virtual std::string const getName() override { return "bdps"; }
|
virtual std::string const getName() override { return "voidwalker"; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SummonSuccubusStrategy : public NonCombatStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SummonSuccubusStrategy(PlayerbotAI* ai);
|
||||||
|
virtual std::string const getName() override { return "succubus"; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
@@ -52,7 +53,57 @@ class SummonFelhunterStrategy : public NonCombatStrategy
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SummonFelhunterStrategy(PlayerbotAI* ai);
|
SummonFelhunterStrategy(PlayerbotAI* ai);
|
||||||
virtual std::string const getName() override { return "bmana"; }
|
virtual std::string const getName() override { return "felhunter"; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SummonFelguardStrategy : public NonCombatStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SummonFelguardStrategy(PlayerbotAI* ai);
|
||||||
|
virtual std::string const getName() override { return "felguard"; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SoulstoneSelfStrategy : public NonCombatStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SoulstoneSelfStrategy(PlayerbotAI* ai);
|
||||||
|
virtual std::string const getName() override { return "ss self"; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SoulstoneMasterStrategy : public NonCombatStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SoulstoneMasterStrategy(PlayerbotAI* ai);
|
||||||
|
virtual std::string const getName() override { return "ss master"; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SoulstoneTankStrategy : public NonCombatStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SoulstoneTankStrategy(PlayerbotAI* ai);
|
||||||
|
virtual std::string const getName() override { return "ss tank"; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SoulstoneHealerStrategy : public NonCombatStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SoulstoneHealerStrategy(PlayerbotAI* ai);
|
||||||
|
virtual std::string const getName() override { return "ss healer"; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "GenericWarlockStrategy.h"
|
#include "GenericWarlockStrategy.h"
|
||||||
|
#include "Strategy.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
|
||||||
class GenericWarlockStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
class GenericWarlockStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||||
@@ -12,28 +12,22 @@ class GenericWarlockStrategyActionNodeFactory : public NamedObjectFactory<Action
|
|||||||
public:
|
public:
|
||||||
GenericWarlockStrategyActionNodeFactory()
|
GenericWarlockStrategyActionNodeFactory()
|
||||||
{
|
{
|
||||||
// creators["summon voidwalker"] = &summon_voidwalker;
|
creators["banish on cc"] = &banish_on_cc;
|
||||||
creators["banish"] = &banish;
|
creators["fear on cc"] = &fear_on_cc;
|
||||||
|
creators["spell lock"] = &spell_lock;
|
||||||
|
creators["devour magic purge"] = &devour_magic_purge;
|
||||||
|
creators["devour magic cleanse"] = &devour_magic_cleanse;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// static ActionNode* summon_voidwalker([[maybe_unused]] PlayerbotAI* botAI)
|
static ActionNode* banish_on_cc(PlayerbotAI*) { return new ActionNode("banish on cc", nullptr, nullptr, nullptr); }
|
||||||
//{
|
static ActionNode* fear_on_cc(PlayerbotAI*) { return new ActionNode("fear on cc", nullptr, nullptr, nullptr); }
|
||||||
// return new ActionNode ("summon voidwalker",
|
static ActionNode* spell_lock(PlayerbotAI*) { return new ActionNode("spell lock", nullptr, nullptr, nullptr); }
|
||||||
/*P*/ // nullptr,
|
static ActionNode* devour_magic_purge(PlayerbotAI*) { return new ActionNode("devour magic purge", nullptr, nullptr, nullptr); }
|
||||||
/*A*/ // NextAction::array(0, new NextAction("drain soul"), nullptr),
|
static ActionNode* devour_magic_cleanse(PlayerbotAI*) { return new ActionNode("devour magic cleanse", nullptr, nullptr, nullptr); }
|
||||||
/*C*/ // nullptr);
|
|
||||||
//}
|
|
||||||
static ActionNode* banish([[maybe_unused]] PlayerbotAI* botAI)
|
|
||||||
{
|
|
||||||
return new ActionNode("banish",
|
|
||||||
/*P*/ nullptr,
|
|
||||||
/*A*/ NextAction::array(0, new NextAction("fear"), nullptr),
|
|
||||||
/*C*/ nullptr);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GenericWarlockStrategy::GenericWarlockStrategy(PlayerbotAI* botAI) : RangedCombatStrategy(botAI)
|
GenericWarlockStrategy::GenericWarlockStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI)
|
||||||
{
|
{
|
||||||
actionNodeFactories.Add(new GenericWarlockStrategyActionNodeFactory());
|
actionNodeFactories.Add(new GenericWarlockStrategyActionNodeFactory());
|
||||||
}
|
}
|
||||||
@@ -42,28 +36,38 @@ NextAction** GenericWarlockStrategy::getDefaultActions() { return NextAction::ar
|
|||||||
|
|
||||||
void GenericWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void GenericWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
RangedCombatStrategy::InitTriggers(triggers);
|
CombatStrategy::InitTriggers(triggers);
|
||||||
|
|
||||||
// triggers.push_back(new TriggerNode("shadow trance", NextAction::array(0, new NextAction("shadow bolt", 20.0f),
|
triggers.push_back(new TriggerNode("low mana", NextAction::array(0, new NextAction("life tap", ACTION_EMERGENCY + 5), nullptr)));
|
||||||
// nullptr))); triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("drain
|
triggers.push_back(new TriggerNode("medium threat", NextAction::array(0, new NextAction("soulshatter", 55.0f), nullptr)));
|
||||||
// life", 40.0f), nullptr)));
|
triggers.push_back(new TriggerNode("spell lock", NextAction::array(0, new NextAction("spell lock", ACTION_INTERRUPT), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("devour magic purge", NextAction::array(0, new NextAction("devour magic purge", ACTION_DISPEL), nullptr)));
|
||||||
new TriggerNode("low mana", NextAction::array(0, new NextAction("life tap", ACTION_EMERGENCY + 5), nullptr)));
|
triggers.push_back(new TriggerNode("devour magic cleanse", NextAction::array(0, new NextAction("devour magic cleanse", ACTION_DISPEL), nullptr)));
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("target critical health", NextAction::array(0, new NextAction("drain soul", 30.0f), nullptr)));
|
|
||||||
// triggers.push_back(new TriggerNode("immolate", NextAction::array(0, new NextAction("immolate", 13.0f), new
|
|
||||||
// NextAction("conflagrate", 13.0f), nullptr))); triggers.push_back(new TriggerNode("enemy too close for spell",
|
|
||||||
// NextAction::array(0, new NextAction("flee", 49.0f), NULL)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WarlockBoostStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void WarlockBoostStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
triggers.push_back(
|
// Placeholder for future boost triggers
|
||||||
new TriggerNode("amplify curse", NextAction::array(0, new NextAction("amplify curse", 41.0f), nullptr)));
|
}
|
||||||
|
|
||||||
|
void WarlockPetStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
// Placeholder for future pet triggers
|
||||||
}
|
}
|
||||||
|
|
||||||
void WarlockCcStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void WarlockCcStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
triggers.push_back(new TriggerNode("banish", NextAction::array(0, new NextAction("banish on cc", 32.0f), nullptr)));
|
triggers.push_back(new TriggerNode("banish", NextAction::array(0, new NextAction("banish on cc", 33.0f), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("fear", NextAction::array(0, new NextAction("fear on cc", 33.0f), nullptr)));
|
triggers.push_back(new TriggerNode("fear", NextAction::array(0, new NextAction("fear on cc", 32.0f), nullptr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combat strategy for using Curse of the Elements
|
||||||
|
// Enabling this will turn off their use of Curse of Agony
|
||||||
|
// Enabled by default for the Destruction spec
|
||||||
|
// To enable, type "co +curse of elements"
|
||||||
|
// To disable, type "co -curse of elements"
|
||||||
|
|
||||||
|
void WarlockCurseOfTheElementsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
{
|
||||||
|
triggers.push_back(new TriggerNode("curse of the elements", NextAction::array(0, new NextAction("curse of the elements", 30.0f), nullptr)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,10 @@
|
|||||||
#define _PLAYERBOT_GENERICWARLOCKSTRATEGY_H
|
#define _PLAYERBOT_GENERICWARLOCKSTRATEGY_H
|
||||||
|
|
||||||
#include "CombatStrategy.h"
|
#include "CombatStrategy.h"
|
||||||
#include "RangedCombatStrategy.h"
|
|
||||||
|
|
||||||
class PlayerbotAI;
|
class PlayerbotAI;
|
||||||
|
|
||||||
class GenericWarlockStrategy : public RangedCombatStrategy
|
class GenericWarlockStrategy : public CombatStrategy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GenericWarlockStrategy(PlayerbotAI* botAI);
|
GenericWarlockStrategy(PlayerbotAI* botAI);
|
||||||
@@ -30,6 +29,15 @@ public:
|
|||||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WarlockPetStrategy : public Strategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WarlockPetStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||||
|
|
||||||
|
std::string const getName() override { return "pet"; }
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
};
|
||||||
|
|
||||||
class WarlockCcStrategy : public Strategy
|
class WarlockCcStrategy : public Strategy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -39,4 +47,13 @@ public:
|
|||||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WarlockCurseOfTheElementsStrategy : public Strategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WarlockCurseOfTheElementsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||||
|
|
||||||
|
std::string const getName() override { return "curse of elements"; }
|
||||||
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,65 +4,41 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "TankWarlockStrategy.h"
|
#include "TankWarlockStrategy.h"
|
||||||
|
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
|
||||||
class GenericWarlockStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
// Combat strategy for a Warlock Tank, for certain bosses like Twin Emperors
|
||||||
|
// Priority is set to spam Searing Pain and use Shadow Ward on CD
|
||||||
|
// Disabled by default
|
||||||
|
// To enable, type "co +tank"
|
||||||
|
// To disable, type "co -tank"
|
||||||
|
|
||||||
|
// ===== Action Node Factory =====
|
||||||
|
class TankWarlockStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GenericWarlockStrategyActionNodeFactory()
|
TankWarlockStrategyActionNodeFactory()
|
||||||
{
|
{
|
||||||
creators["summon voidwalker"] = &summon_voidwalker;
|
creators["shadow ward"] = &shadow_ward;
|
||||||
creators["summon felguard"] = &summon_felguard;
|
creators["searing pain"] = &searing_pain;
|
||||||
creators["summon succubus"] = &summon_succubus;
|
|
||||||
creators["summon felhunter"] = &summon_felhunter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static ActionNode* summon_voidwalker([[maybe_unused]] PlayerbotAI* botAI)
|
static ActionNode* shadow_ward(PlayerbotAI*) { return new ActionNode("shadow ward", nullptr, nullptr, nullptr); }
|
||||||
{
|
static ActionNode* searing_pain(PlayerbotAI*) { return new ActionNode("searing pain", nullptr, nullptr, nullptr); }
|
||||||
return new ActionNode("summon voidwalker",
|
|
||||||
/*P*/ nullptr,
|
|
||||||
/*A*/ NextAction::array(0, new NextAction("summon imp"), nullptr),
|
|
||||||
/*C*/ nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ActionNode* summon_felguard([[maybe_unused]] PlayerbotAI* botAI)
|
|
||||||
{
|
|
||||||
return new ActionNode("summon felguard",
|
|
||||||
/*P*/ nullptr,
|
|
||||||
/*A*/ NextAction::array(0, new NextAction("summon succubus"), nullptr),
|
|
||||||
/*C*/ nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ActionNode* summon_succubus([[maybe_unused]] PlayerbotAI* botAI)
|
|
||||||
{
|
|
||||||
return new ActionNode("summon succubus",
|
|
||||||
/*P*/ nullptr,
|
|
||||||
/*A*/ NextAction::array(0, new NextAction("summon voidwalker"), nullptr),
|
|
||||||
/*C*/ nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ActionNode* summon_felhunter([[maybe_unused]] PlayerbotAI* botAI)
|
|
||||||
{
|
|
||||||
return new ActionNode("summon felhunter",
|
|
||||||
/*P*/ nullptr,
|
|
||||||
/*A*/ NextAction::array(0, new NextAction("summon imp"), nullptr),
|
|
||||||
/*C*/ nullptr);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ===== Warlock Tank Combat Strategy =====
|
||||||
TankWarlockStrategy::TankWarlockStrategy(PlayerbotAI* botAI) : GenericWarlockStrategy(botAI)
|
TankWarlockStrategy::TankWarlockStrategy(PlayerbotAI* botAI) : GenericWarlockStrategy(botAI)
|
||||||
{
|
{
|
||||||
actionNodeFactories.Add(new GenericWarlockStrategyActionNodeFactory());
|
actionNodeFactories.Add(new TankWarlockStrategyActionNodeFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
NextAction** TankWarlockStrategy::getDefaultActions()
|
NextAction** TankWarlockStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(0, new NextAction("shoot", ACTION_DEFAULT), nullptr);
|
// Shadow Ward is the highest priority, Searing Pain next.
|
||||||
|
return NextAction::array(0, new NextAction("shadow ward", 27.5f), new NextAction("searing pain", 27.0f), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TankWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void TankWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
GenericWarlockStrategy::InitTriggers(triggers);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,23 +5,204 @@
|
|||||||
|
|
||||||
#include "WarlockActions.h"
|
#include "WarlockActions.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
|
#include "Item.h"
|
||||||
|
#include "ObjectGuid.h"
|
||||||
|
#include "Player.h"
|
||||||
|
#include "PlayerbotAI.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
#include "ServerFacade.h"
|
||||||
|
#include "Unit.h"
|
||||||
|
|
||||||
bool CastDrainSoulAction::isUseful() { return AI_VALUE2(uint32, "item count", "soul shard") < 10; }
|
// Checks if the bot has less than 32 soul shards, and if so, allows casting Drain Soul
|
||||||
|
bool CastDrainSoulAction::isUseful() { return AI_VALUE2(uint32, "item count", "soul shard") < 32; }
|
||||||
Value<Unit*>* CastBanishAction::GetTargetValue() { return context->GetValue<Unit*>("cc target", "banish"); }
|
|
||||||
|
|
||||||
bool CastBanishAction::Execute(Event event) { return botAI->CastSpell("banish", GetTarget()); }
|
|
||||||
|
|
||||||
Value<Unit*>* CastFearOnCcAction::GetTargetValue() { return context->GetValue<Unit*>("cc target", "fear"); }
|
|
||||||
|
|
||||||
bool CastFearOnCcAction::Execute(Event event) { return botAI->CastSpell("fear", GetTarget()); }
|
|
||||||
|
|
||||||
bool CastFearOnCcAction::isPossible() { return true; }
|
|
||||||
|
|
||||||
bool CastFearOnCcAction::isUseful() { return true; }
|
|
||||||
|
|
||||||
|
// Checks if the bot's health is above a certain threshold, and if so, allows casting Life Tap
|
||||||
bool CastLifeTapAction::isUseful() { return AI_VALUE2(uint8, "health", "self target") > sPlayerbotAIConfig->lowHealth; }
|
bool CastLifeTapAction::isUseful() { return AI_VALUE2(uint8, "health", "self target") > sPlayerbotAIConfig->lowHealth; }
|
||||||
|
|
||||||
Unit* UseSoulstoneAction::GetTarget() { return botAI->GetMaster(); }
|
// Checks if the target marked with the moon icon can be banished
|
||||||
|
bool CastBanishOnCcAction::isPossible()
|
||||||
|
{
|
||||||
|
Unit* target = GetTarget();
|
||||||
|
if (!target)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Only possible on elementals or demons
|
||||||
|
uint32 creatureType = target->GetCreatureType();
|
||||||
|
if (creatureType != CREATURE_TYPE_DEMON && creatureType != CREATURE_TYPE_ELEMENTAL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Use base class to check spell available, range, etc
|
||||||
|
return CastCrowdControlSpellAction::isPossible();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the target marked with the moon icon can be feared
|
||||||
|
bool CastFearOnCcAction::isPossible()
|
||||||
|
{
|
||||||
|
Unit* target = GetTarget();
|
||||||
|
if (!target)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Fear cannot be cast on mechanical or undead creatures
|
||||||
|
uint32 creatureType = target->GetCreatureType();
|
||||||
|
if (creatureType == CREATURE_TYPE_MECHANICAL || creatureType == CREATURE_TYPE_UNDEAD)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Use base class to check spell available, range, etc
|
||||||
|
return CastCrowdControlSpellAction::isPossible();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the enemies are close enough to use Shadowflame
|
||||||
|
bool CastShadowflameAction::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, 7.0f); // 7 yard cone
|
||||||
|
return facingTarget && targetClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the bot knows Seed of Corruption, and prevents the use of Rain of Fire if it does
|
||||||
|
bool CastRainOfFireAction::isUseful()
|
||||||
|
{
|
||||||
|
Unit* target = GetTarget();
|
||||||
|
if (!target)
|
||||||
|
return false;
|
||||||
|
if (bot->HasSpell(27243) || bot->HasSpell(47835) || bot->HasSpell(47836)) // Seed of Corruption spell IDs
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the enemies are close enough to use Hellfire
|
||||||
|
bool CastHellfireAction::isUseful()
|
||||||
|
{
|
||||||
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
if (!target)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return bot->IsWithinCombatRange(target, 5.0f); // 5 yard AoE radius
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the "meta melee aoe" strategy is active, OR if the bot is in melee range of the target
|
||||||
|
bool CastImmolationAuraAction::isUseful()
|
||||||
|
{
|
||||||
|
if (botAI->HasStrategy("meta melee", BOT_STATE_COMBAT))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
if (!target)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!bot->HasAura(47241)) // 47241 is Metamorphosis spell ID (WotLK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return bot->IsWithinCombatRange(target, 5.0f); // 5 yard AoE radius
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the "warlock tank" strategy is active, and if so, prevents the use of Soulshatter
|
||||||
|
bool CastSoulshatterAction::isUseful()
|
||||||
|
{
|
||||||
|
if (botAI->HasStrategy("tank", BOT_STATE_COMBAT))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the target has a soulstone aura
|
||||||
|
static bool HasSoulstoneAura(Unit* unit)
|
||||||
|
{
|
||||||
|
static const std::vector<uint32> soulstoneAuraIds = {20707, 20762, 20763, 20764, 20765, 27239, 47883};
|
||||||
|
for (uint32 spellId : soulstoneAuraIds)
|
||||||
|
if (unit->HasAura(spellId))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the soulstone item on the bot itself with nc strategy "ss self"
|
||||||
|
bool UseSoulstoneSelfAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
std::vector<Item*> items = AI_VALUE2(std::vector<Item*>, "inventory items", "soulstone");
|
||||||
|
if (items.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (HasSoulstoneAura(bot))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bot->SetSelection(bot->GetGUID());
|
||||||
|
return UseItem(items[0], ObjectGuid::Empty, nullptr, bot);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the soulstone item on the bot's master with nc strategy "ss master"
|
||||||
|
bool UseSoulstoneMasterAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
std::vector<Item*> items = AI_VALUE2(std::vector<Item*>, "inventory items", "soulstone");
|
||||||
|
if (items.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Player* master = botAI->GetMaster();
|
||||||
|
if (!master || HasSoulstoneAura(master))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bot->SetSelection(master->GetGUID());
|
||||||
|
return UseItem(items[0], ObjectGuid::Empty, nullptr, master);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the soulstone item on a tank in the group with nc strategy "ss tank"
|
||||||
|
bool UseSoulstoneTankAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
std::vector<Item*> items = AI_VALUE2(std::vector<Item*>, "inventory items", "soulstone");
|
||||||
|
if (items.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Player* tank = nullptr;
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (group)
|
||||||
|
{
|
||||||
|
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
||||||
|
{
|
||||||
|
Player* member = gref->GetSource();
|
||||||
|
if (member && member->IsAlive() && botAI->IsTank(member) && !HasSoulstoneAura(member))
|
||||||
|
{
|
||||||
|
tank = member;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tank)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bot->SetSelection(tank->GetGUID());
|
||||||
|
return UseItem(items[0], ObjectGuid::Empty, nullptr, tank);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the soulstone item on a healer in the group with nc strategy "ss healer"
|
||||||
|
bool UseSoulstoneHealerAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
std::vector<Item*> items = AI_VALUE2(std::vector<Item*>, "inventory items", "soulstone");
|
||||||
|
if (items.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Player* healer = nullptr;
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (group)
|
||||||
|
{
|
||||||
|
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
||||||
|
{
|
||||||
|
Player* member = gref->GetSource();
|
||||||
|
if (member && member->IsAlive() && botAI->IsHeal(member) && !HasSoulstoneAura(member))
|
||||||
|
{
|
||||||
|
healer = member;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!healer)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bot->SetSelection(healer->GetGUID());
|
||||||
|
return UseItem(items[0], ObjectGuid::Empty, nullptr, healer);
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,10 +8,13 @@
|
|||||||
|
|
||||||
#include "GenericSpellActions.h"
|
#include "GenericSpellActions.h"
|
||||||
#include "UseItemAction.h"
|
#include "UseItemAction.h"
|
||||||
|
#include "Action.h"
|
||||||
|
|
||||||
class PlayerbotAI;
|
class PlayerbotAI;
|
||||||
class Unit;
|
class Unit;
|
||||||
|
|
||||||
|
// Buff and Out of Combat Spells
|
||||||
|
|
||||||
class CastDemonSkinAction : public CastBuffSpellAction
|
class CastDemonSkinAction : public CastBuffSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -30,71 +33,67 @@ public:
|
|||||||
CastFelArmorAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "fel armor") {}
|
CastFelArmorAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "fel armor") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
BEGIN_RANGED_SPELL_ACTION(CastShadowBoltAction, "shadow bolt")
|
class CastSoulLinkAction : public CastBuffSpellAction
|
||||||
END_SPELL_ACTION()
|
|
||||||
|
|
||||||
class CastDrainSoulAction : public CastSpellAction
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastDrainSoulAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "drain soul") {}
|
CastSoulLinkAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "soul link", false, 5000) {}
|
||||||
|
std::string const GetTargetName() override { return "pet target"; }
|
||||||
bool isUseful() override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastDrainManaAction : public CastSpellAction
|
class CastCreateHealthstoneAction : public CastBuffSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastDrainManaAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "drain mana") {}
|
CastCreateHealthstoneAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "create healthstone") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastDrainLifeAction : public CastSpellAction
|
class CastCreateFirestoneAction : public CastBuffSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastDrainLifeAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "drain life") {}
|
CastCreateFirestoneAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "create firestone") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastCurseOfAgonyAction : public CastDebuffSpellAction
|
class CastCreateSpellstoneAction : public CastBuffSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastCurseOfAgonyAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "curse of agony", true) {}
|
CastCreateSpellstoneAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "create spellstone") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastCurseOfWeaknessAction : public CastDebuffSpellAction
|
class CastCreateSoulstoneAction : public CastBuffSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastCurseOfWeaknessAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "curse of weakness") {}
|
CastCreateSoulstoneAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "create soulstone") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastCorruptionAction : public CastDebuffSpellAction
|
class UseSoulstoneSelfAction : public UseSpellItemAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastCorruptionAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "corruption", true) {}
|
UseSoulstoneSelfAction(PlayerbotAI* botAI) : UseSpellItemAction(botAI, "soulstone") {}
|
||||||
bool isUseful() override
|
bool Execute(Event event) override;
|
||||||
{
|
|
||||||
return CastDebuffSpellAction::isUseful() && !botAI->HasAura("seed of corruption", GetTarget(), false, true);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastCorruptionOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
class UseSoulstoneMasterAction : public UseSpellItemAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastCorruptionOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "corruption", true) {}
|
UseSoulstoneMasterAction(PlayerbotAI* botAI) : UseSpellItemAction(botAI, "soulstone") {}
|
||||||
bool isUseful() override
|
bool Execute(Event event) override;
|
||||||
{
|
|
||||||
return CastDebuffSpellOnAttackerAction::isUseful() &&
|
|
||||||
!botAI->HasAura("seed of corruption", GetTarget(), false, true);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastCurseOfAgonyOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
class UseSoulstoneTankAction : public UseSpellItemAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastCurseOfAgonyOnAttackerAction(PlayerbotAI* botAI)
|
UseSoulstoneTankAction(PlayerbotAI* botAI) : UseSpellItemAction(botAI, "soulstone") {}
|
||||||
: CastDebuffSpellOnAttackerAction(botAI, "curse of agony", true)
|
bool Execute(Event event) override;
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UseSoulstoneHealerAction : public UseSpellItemAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UseSoulstoneHealerAction(PlayerbotAI* botAI) : UseSpellItemAction(botAI, "soulstone") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Summoning Spells
|
||||||
|
|
||||||
class CastSummonVoidwalkerAction : public CastBuffSpellAction
|
class CastSummonVoidwalkerAction : public CastBuffSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -124,41 +123,293 @@ class CastSummonSuccubusAction : public CastBuffSpellAction
|
|||||||
public:
|
public:
|
||||||
CastSummonSuccubusAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "summon succubus") {}
|
CastSummonSuccubusAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "summon succubus") {}
|
||||||
};
|
};
|
||||||
|
class CastFelDominationAction : public CastBuffSpellAction
|
||||||
class CastCreateHealthstoneAction : public CastBuffSpellAction
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastCreateHealthstoneAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "create healthstone") {}
|
CastFelDominationAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "fel domination") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastCreateFirestoneAction : public CastBuffSpellAction
|
// CC and Pet Spells
|
||||||
|
|
||||||
|
class CastBanishOnCcAction : public CastCrowdControlSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastCreateFirestoneAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "create firestone") {}
|
CastBanishOnCcAction(PlayerbotAI* botAI) : CastCrowdControlSpellAction(botAI, "banish") {}
|
||||||
|
bool isPossible() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastCreateSpellstoneAction : public CastBuffSpellAction
|
class CastFearOnCcAction : public CastCrowdControlSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastCreateSpellstoneAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "create spellstone") {}
|
CastFearOnCcAction(PlayerbotAI* botAI) : CastCrowdControlSpellAction(botAI, "fear") {}
|
||||||
|
bool isPossible() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastBanishAction : public CastBuffSpellAction
|
class CastSpellLockAction : public CastSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastBanishAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "banish on cc") {}
|
CastSpellLockAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "spell lock") {}
|
||||||
|
|
||||||
Value<Unit*>* GetTargetValue() override;
|
|
||||||
bool Execute(Event event) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CastDevourMagicPurgeAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastDevourMagicPurgeAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "devour magic") {}
|
||||||
|
|
||||||
|
std::string const GetTargetName() override { return "current target"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastDevourMagicCleanseAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastDevourMagicCleanseAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "devour magic cleanse") {}
|
||||||
|
std::string const getName() override { return "cleanse magic on party"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Utility Spells
|
||||||
|
|
||||||
|
class CastShadowWardAction : public CastBuffSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastShadowWardAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "shadow ward") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastSoulshatterAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastSoulshatterAction(PlayerbotAI* ai) : CastSpellAction(ai, "soulshatter") {}
|
||||||
|
bool isUseful() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastLifeTapAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastLifeTapAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "life tap") {}
|
||||||
|
|
||||||
|
std::string const GetTargetName() override { return "self target"; }
|
||||||
|
bool isUseful() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastCurseOfWeaknessAction : public CastDebuffSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastCurseOfWeaknessAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "curse of weakness") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastCurseOfTheElementsAction : public CastDebuffSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastCurseOfTheElementsAction(PlayerbotAI* ai) : CastDebuffSpellAction(ai, "curse of the elements", true) {}
|
||||||
|
bool isUseful() override
|
||||||
|
{
|
||||||
|
// Bypass TTL check
|
||||||
|
return CastAuraSpellAction::isUseful();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DemonChargeAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DemonChargeAction(PlayerbotAI* ai) : CastSpellAction(ai, "demon charge") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Cooldown Spells
|
||||||
|
|
||||||
|
class CastMetamorphosisAction : public CastBuffSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastMetamorphosisAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "metamorphosis") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastDemonicEmpowermentAction : public CastBuffSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastDemonicEmpowermentAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "demonic empowerment") {}
|
||||||
|
std::string const GetTargetName() override { return "pet target"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// DoT Spells
|
||||||
|
|
||||||
|
class CastCurseOfAgonyAction : public CastDebuffSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastCurseOfAgonyAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "curse of agony", true) {}
|
||||||
|
bool isUseful() override
|
||||||
|
{
|
||||||
|
if (botAI->HasStrategy(
|
||||||
|
"curse of elements", BOT_STATE_COMBAT)) // If Curse of the Elements strategy is active, do not cast Curse of Agony
|
||||||
|
return false;
|
||||||
|
// Bypass TTL check
|
||||||
|
return CastAuraSpellAction::isUseful();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastCurseOfAgonyOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastCurseOfAgonyOnAttackerAction(PlayerbotAI* botAI)
|
||||||
|
: CastDebuffSpellOnAttackerAction(botAI, "curse of agony", true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool isUseful() override
|
||||||
|
{
|
||||||
|
if (botAI->HasStrategy(
|
||||||
|
"curse of elements", BOT_STATE_COMBAT)) // If Curse of the Elements strategy is active, do not cast Curse of Agony
|
||||||
|
return false;
|
||||||
|
// Bypass TTL check
|
||||||
|
return CastAuraSpellAction::isUseful();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastCorruptionAction : public CastDebuffSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastCorruptionAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "corruption", true) {}
|
||||||
|
bool isUseful() override
|
||||||
|
{
|
||||||
|
// Bypass TTL check and prevent casting if Seed of Corruption is present
|
||||||
|
return CastAuraSpellAction::isUseful() && !botAI->HasAura("seed of corruption", GetTarget(), false, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastCorruptionOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastCorruptionOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "corruption", true) {}
|
||||||
|
bool isUseful() override
|
||||||
|
{
|
||||||
|
// Bypass TTL check and prevent casting if Seed of Corruption is present
|
||||||
|
return CastAuraSpellAction::isUseful() && !botAI->HasAura("seed of corruption", GetTarget(), false, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastImmolateAction : public CastDebuffSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastImmolateAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "immolate", true) {}
|
||||||
|
bool isUseful() override
|
||||||
|
{
|
||||||
|
// Bypass TTL check
|
||||||
|
return CastAuraSpellAction::isUseful();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastImmolateOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastImmolateOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "immolate", true) {}
|
||||||
|
bool isUseful() override
|
||||||
|
{
|
||||||
|
// Bypass TTL check
|
||||||
|
return CastAuraSpellAction::isUseful();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastUnstableAfflictionAction : public CastDebuffSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastUnstableAfflictionAction(PlayerbotAI* ai) : CastDebuffSpellAction(ai, "unstable affliction", true) {}
|
||||||
|
bool isUseful() override
|
||||||
|
{
|
||||||
|
// Bypass TTL check
|
||||||
|
return CastAuraSpellAction::isUseful();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastUnstableAfflictionOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastUnstableAfflictionOnAttackerAction(PlayerbotAI* ai)
|
||||||
|
: CastDebuffSpellOnAttackerAction(ai, "unstable affliction", true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool isUseful() override
|
||||||
|
{
|
||||||
|
// Bypass TTL check
|
||||||
|
return CastAuraSpellAction::isUseful();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Damage Spells
|
||||||
|
|
||||||
|
class CastShadowBoltAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastShadowBoltAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "shadow bolt") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastDrainSoulAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastDrainSoulAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "drain soul") {}
|
||||||
|
|
||||||
|
bool isUseful() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastDrainManaAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastDrainManaAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "drain mana") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastDrainLifeAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastDrainLifeAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "drain life") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastConflagrateAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastConflagrateAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "conflagrate") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastIncinerateAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastIncinerateAction(PlayerbotAI* ai) : CastSpellAction(ai, "incinerate") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastHauntAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastHauntAction(PlayerbotAI* ai) : CastSpellAction(ai, "haunt") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastSoulFireAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastSoulFireAction(PlayerbotAI* ai) : CastSpellAction(ai, "soul fire") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastShadowburnAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastShadowburnAction(PlayerbotAI* ai) : CastSpellAction(ai, "shadowburn") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastChaosBoltAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastChaosBoltAction(PlayerbotAI* ai) : CastSpellAction(ai, "chaos bolt") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastSearingPainAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastSearingPainAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "searing pain") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// AoE Spells
|
||||||
|
|
||||||
class CastSeedOfCorruptionAction : public CastDebuffSpellAction
|
class CastSeedOfCorruptionAction : public CastDebuffSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastSeedOfCorruptionAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "seed of corruption", true, 0) {}
|
CastSeedOfCorruptionAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "seed of corruption", true, 0) {}
|
||||||
bool isUseful() override
|
bool isUseful() override
|
||||||
{
|
{
|
||||||
return CastDebuffSpellAction::isUseful() && !botAI->HasAura("corruption", GetTarget(), false, true);
|
// Bypass TTL check
|
||||||
|
return CastAuraSpellAction::isUseful();
|
||||||
}
|
}
|
||||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||||
};
|
};
|
||||||
@@ -172,7 +423,8 @@ public:
|
|||||||
}
|
}
|
||||||
bool isUseful() override
|
bool isUseful() override
|
||||||
{
|
{
|
||||||
return CastDebuffSpellOnAttackerAction::isUseful() && !botAI->HasAura("corruption", GetTarget(), false, true);
|
// Bypass TTL check
|
||||||
|
return CastAuraSpellAction::isUseful();
|
||||||
}
|
}
|
||||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||||
};
|
};
|
||||||
@@ -182,6 +434,22 @@ class CastRainOfFireAction : public CastSpellAction
|
|||||||
public:
|
public:
|
||||||
CastRainOfFireAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "rain of fire") {}
|
CastRainOfFireAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "rain of fire") {}
|
||||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||||
|
bool isUseful() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastHellfireAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastHellfireAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "hellfire") {}
|
||||||
|
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||||
|
bool isUseful() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastShadowflameAction : public CastSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastShadowflameAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "shadowflame") {}
|
||||||
|
bool isUseful() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastShadowfuryAction : public CastSpellAction
|
class CastShadowfuryAction : public CastSpellAction
|
||||||
@@ -190,125 +458,17 @@ public:
|
|||||||
CastShadowfuryAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "shadowfury") {}
|
CastShadowfuryAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "shadowfury") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastImmolateAction : public CastDebuffSpellAction
|
class CastImmolationAuraAction : public CastSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastImmolateAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "immolate", true) {}
|
CastImmolationAuraAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "immolation aura") {}
|
||||||
};
|
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||||
|
|
||||||
class CastImmolateOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastImmolateOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "immolate", true) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastConflagrateAction : public CastSpellAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastConflagrateAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "conflagrate") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastIncinirateAction : public CastSpellAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastIncinirateAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "incinirate") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastFearAction : public CastDebuffSpellAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastFearAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "fear") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastFearOnCcAction : public CastBuffSpellAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastFearOnCcAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "fear on cc") {}
|
|
||||||
|
|
||||||
Value<Unit*>* GetTargetValue() override;
|
|
||||||
bool Execute(Event event) override;
|
|
||||||
bool isPossible() override;
|
|
||||||
bool isUseful() override;
|
bool isUseful() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastLifeTapAction : public CastSpellAction
|
class ShadowCleaveAction : public CastMeleeSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastLifeTapAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "life tap") {}
|
ShadowCleaveAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "shadow cleave") {}
|
||||||
|
|
||||||
std::string const GetTargetName() override { return "self target"; }
|
|
||||||
bool isUseful() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastAmplifyCurseAction : public CastBuffSpellAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastAmplifyCurseAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "amplify curse") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastSiphonLifeAction : public CastDebuffSpellAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastSiphonLifeAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "siphon life", true) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastSiphonLifeOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastSiphonLifeOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "siphon life") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastUnstableAfflictionAction : public CastDebuffSpellAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastUnstableAfflictionAction(PlayerbotAI* ai) : CastDebuffSpellAction(ai, "unstable affliction", true) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastHauntAction : public CastSpellAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastHauntAction(PlayerbotAI* ai) : CastSpellAction(ai, "haunt") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastDemonicEmpowermentAction : public CastBuffSpellAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastDemonicEmpowermentAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "demonic empowerment") {}
|
|
||||||
std::string const GetTargetName() override { return "pet target"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastMetamorphosisAction : public CastBuffSpellAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastMetamorphosisAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "metamorphosis") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastUnstableAfflictionOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastUnstableAfflictionOnAttackerAction(PlayerbotAI* ai)
|
|
||||||
: CastDebuffSpellOnAttackerAction(ai, "unstable affliction", true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastSoulFireAction : public CastSpellAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastSoulFireAction(PlayerbotAI* ai) : CastSpellAction(ai, "soul fire") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastIncinerateAction : public CastSpellAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastIncinerateAction(PlayerbotAI* ai) : CastSpellAction(ai, "incinerate") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class UseSoulstoneAction : public UseSpellItemAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UseSoulstoneAction(PlayerbotAI* ai) : UseSpellItemAction(ai, "soulstone") {}
|
|
||||||
|
|
||||||
Unit* GetTarget() override;
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,7 +4,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "WarlockAiObjectContext.h"
|
#include "WarlockAiObjectContext.h"
|
||||||
|
#include "AfflictionWarlockStrategy.h"
|
||||||
|
#include "DemonologyWarlockStrategy.h"
|
||||||
|
#include "DestructionWarlockStrategy.h"
|
||||||
|
#include "TankWarlockStrategy.h"
|
||||||
#include "DpsWarlockStrategy.h"
|
#include "DpsWarlockStrategy.h"
|
||||||
#include "GenericTriggers.h"
|
#include "GenericTriggers.h"
|
||||||
#include "GenericWarlockNonCombatStrategy.h"
|
#include "GenericWarlockNonCombatStrategy.h"
|
||||||
@@ -12,7 +15,6 @@
|
|||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
#include "PullStrategy.h"
|
#include "PullStrategy.h"
|
||||||
#include "Strategy.h"
|
#include "Strategy.h"
|
||||||
#include "TankWarlockStrategy.h"
|
|
||||||
#include "UseItemAction.h"
|
#include "UseItemAction.h"
|
||||||
#include "WarlockActions.h"
|
#include "WarlockActions.h"
|
||||||
#include "WarlockTriggers.h"
|
#include "WarlockTriggers.h"
|
||||||
@@ -21,24 +23,40 @@ class WarlockStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WarlockStrategyFactoryInternal()
|
WarlockStrategyFactoryInternal()
|
||||||
{
|
{
|
||||||
creators["nc"] = &WarlockStrategyFactoryInternal::nc;
|
creators["nc"] = &WarlockStrategyFactoryInternal::nc;
|
||||||
creators["pull"] = &WarlockStrategyFactoryInternal::pull;
|
creators["pull"] = &WarlockStrategyFactoryInternal::pull;
|
||||||
creators["aoe"] = &WarlockStrategyFactoryInternal::aoe;
|
|
||||||
creators["dps debuff"] = &WarlockStrategyFactoryInternal::dps_debuff;
|
|
||||||
creators["boost"] = &WarlockStrategyFactoryInternal::boost;
|
creators["boost"] = &WarlockStrategyFactoryInternal::boost;
|
||||||
creators["cc"] = &WarlockStrategyFactoryInternal::cc;
|
creators["cc"] = &WarlockStrategyFactoryInternal::cc;
|
||||||
creators["pet"] = &WarlockStrategyFactoryInternal::pet;
|
creators["pet"] = &WarlockStrategyFactoryInternal::pet;
|
||||||
|
creators["affli"] = &WarlockStrategyFactoryInternal::affliction;
|
||||||
|
creators["affli aoe"] = &WarlockStrategyFactoryInternal::affliction_aoe;
|
||||||
|
creators["demo"] = &WarlockStrategyFactoryInternal::demonology;
|
||||||
|
creators["demo aoe"] = &WarlockStrategyFactoryInternal::demonology_aoe;
|
||||||
|
creators["destro"] = &WarlockStrategyFactoryInternal::destruction;
|
||||||
|
creators["destro aoe"] = &WarlockStrategyFactoryInternal::destruction_aoe;
|
||||||
|
creators["meta melee"] = &WarlockStrategyFactoryInternal::meta_melee_aoe;
|
||||||
|
creators["dps"] = &WarlockStrategyFactoryInternal::dps;
|
||||||
|
creators["aoe"] = &WarlockStrategyFactoryInternal::aoe;
|
||||||
|
creators["curse of elements"] = &WarlockStrategyFactoryInternal::curse_of_elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Strategy* pet(PlayerbotAI* botAI) { return new WarlockPetStrategy(botAI); }
|
static Strategy* pet(PlayerbotAI* botAI) { return new WarlockPetStrategy(botAI); }
|
||||||
static Strategy* nc(PlayerbotAI* botAI) { return new GenericWarlockNonCombatStrategy(botAI); }
|
static Strategy* nc(PlayerbotAI* botAI) { return new GenericWarlockNonCombatStrategy(botAI); }
|
||||||
static Strategy* aoe(PlayerbotAI* botAI) { return new DpsAoeWarlockStrategy(botAI); }
|
|
||||||
static Strategy* dps_debuff(PlayerbotAI* botAI) { return new DpsWarlockDebuffStrategy(botAI); }
|
|
||||||
static Strategy* pull(PlayerbotAI* botAI) { return new PullStrategy(botAI, "shoot"); }
|
static Strategy* pull(PlayerbotAI* botAI) { return new PullStrategy(botAI, "shoot"); }
|
||||||
static Strategy* boost(PlayerbotAI* botAI) { return new WarlockBoostStrategy(botAI); }
|
static Strategy* boost(PlayerbotAI* botAI) { return new WarlockBoostStrategy(botAI); }
|
||||||
static Strategy* cc(PlayerbotAI* botAI) { return new WarlockCcStrategy(botAI); }
|
static Strategy* cc(PlayerbotAI* botAI) { return new WarlockCcStrategy(botAI); }
|
||||||
|
static Strategy* affliction(PlayerbotAI* botAI) { return new AfflictionWarlockStrategy(botAI); }
|
||||||
|
static Strategy* affliction_aoe(PlayerbotAI* botAI) { return new AfflictionWarlockAoeStrategy(botAI); }
|
||||||
|
static Strategy* demonology(PlayerbotAI* botAI) { return new DemonologyWarlockStrategy(botAI); }
|
||||||
|
static Strategy* demonology_aoe(PlayerbotAI* botAI) { return new DemonologyWarlockAoeStrategy(botAI); }
|
||||||
|
static Strategy* destruction(PlayerbotAI* botAI) { return new DestructionWarlockStrategy(botAI); }
|
||||||
|
static Strategy* destruction_aoe(PlayerbotAI* botAI) { return new DestructionWarlockAoeStrategy(botAI); }
|
||||||
|
static Strategy* meta_melee_aoe(PlayerbotAI* botAI) { return new MetaMeleeAoeStrategy(botAI); }
|
||||||
|
static Strategy* dps(PlayerbotAI* botAI) { return new DpsWarlockStrategy(botAI); }
|
||||||
|
static Strategy* aoe(PlayerbotAI* botAI) { return new DpsAoeWarlockStrategy(botAI); }
|
||||||
|
static Strategy* curse_of_elements(PlayerbotAI* botAI) { return new WarlockCurseOfTheElementsStrategy(botAI); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class WarlockCombatStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
class WarlockCombatStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||||
@@ -46,13 +64,11 @@ class WarlockCombatStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
|||||||
public:
|
public:
|
||||||
WarlockCombatStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
WarlockCombatStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||||
{
|
{
|
||||||
creators["dps"] = &WarlockCombatStrategyFactoryInternal::dps;
|
|
||||||
creators["tank"] = &WarlockCombatStrategyFactoryInternal::tank;
|
creators["tank"] = &WarlockCombatStrategyFactoryInternal::tank;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Strategy* tank(PlayerbotAI* botAI) { return new TankWarlockStrategy(botAI); }
|
static Strategy* tank(PlayerbotAI* botAI) { return new TankWarlockStrategy(botAI); }
|
||||||
static Strategy* dps(PlayerbotAI* botAI) { return new DpsWarlockStrategy(botAI); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class NonCombatBuffStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
class NonCombatBuffStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||||
@@ -60,15 +76,27 @@ class NonCombatBuffStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
|||||||
public:
|
public:
|
||||||
NonCombatBuffStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
NonCombatBuffStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||||
{
|
{
|
||||||
creators["bdps"] = &NonCombatBuffStrategyFactoryInternal::felguard;
|
creators["imp"] = &NonCombatBuffStrategyFactoryInternal::imp;
|
||||||
creators["bmana"] = &NonCombatBuffStrategyFactoryInternal::felhunter;
|
creators["voidwalker"] = &NonCombatBuffStrategyFactoryInternal::voidwalker;
|
||||||
creators["bhealth"] = &NonCombatBuffStrategyFactoryInternal::imp;
|
creators["succubus"] = &NonCombatBuffStrategyFactoryInternal::succubus;
|
||||||
|
creators["felhunter"] = &NonCombatBuffStrategyFactoryInternal::felhunter;
|
||||||
|
creators["felguard"] = &NonCombatBuffStrategyFactoryInternal::felguard;
|
||||||
|
creators["ss self"] = &NonCombatBuffStrategyFactoryInternal::soulstone_self;
|
||||||
|
creators["ss master"] = &NonCombatBuffStrategyFactoryInternal::soulstone_master;
|
||||||
|
creators["ss tank"] = &NonCombatBuffStrategyFactoryInternal::soulstone_tank;
|
||||||
|
creators["ss healer"] = &NonCombatBuffStrategyFactoryInternal::soulstone_healer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Strategy* imp(PlayerbotAI* ai) { return new SummonImpStrategy(ai); }
|
static Strategy* imp(PlayerbotAI* ai) { return new SummonImpStrategy(ai); }
|
||||||
|
static Strategy* voidwalker(PlayerbotAI* ai) { return new SummonVoidwalkerStrategy(ai); }
|
||||||
|
static Strategy* succubus(PlayerbotAI* ai) { return new SummonSuccubusStrategy(ai); }
|
||||||
static Strategy* felhunter(PlayerbotAI* ai) { return new SummonFelhunterStrategy(ai); }
|
static Strategy* felhunter(PlayerbotAI* ai) { return new SummonFelhunterStrategy(ai); }
|
||||||
static Strategy* felguard(PlayerbotAI* ai) { return new SummonFelguardStrategy(ai); }
|
static Strategy* felguard(PlayerbotAI* ai) { return new SummonFelguardStrategy(ai); }
|
||||||
|
static Strategy* soulstone_self(PlayerbotAI* ai) { return new SoulstoneSelfStrategy(ai); }
|
||||||
|
static Strategy* soulstone_master(PlayerbotAI* ai) { return new SoulstoneMasterStrategy(ai); }
|
||||||
|
static Strategy* soulstone_tank(PlayerbotAI* ai) { return new SoulstoneTankStrategy(ai); }
|
||||||
|
static Strategy* soulstone_healer(PlayerbotAI* ai) { return new SoulstoneHealerStrategy(ai); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class WarlockTriggerFactoryInternal : public NamedObjectContext<Trigger>
|
class WarlockTriggerFactoryInternal : public NamedObjectContext<Trigger>
|
||||||
@@ -78,64 +106,73 @@ public:
|
|||||||
{
|
{
|
||||||
creators["shadow trance"] = &WarlockTriggerFactoryInternal::shadow_trance;
|
creators["shadow trance"] = &WarlockTriggerFactoryInternal::shadow_trance;
|
||||||
creators["demon armor"] = &WarlockTriggerFactoryInternal::demon_armor;
|
creators["demon armor"] = &WarlockTriggerFactoryInternal::demon_armor;
|
||||||
|
creators["soul link"] = &WarlockTriggerFactoryInternal::soul_link;
|
||||||
creators["no healthstone"] = &WarlockTriggerFactoryInternal::HasHealthstone;
|
creators["no healthstone"] = &WarlockTriggerFactoryInternal::HasHealthstone;
|
||||||
creators["no firestone"] = &WarlockTriggerFactoryInternal::HasFirestone;
|
creators["no firestone"] = &WarlockTriggerFactoryInternal::HasFirestone;
|
||||||
creators["no spellstone"] = &WarlockTriggerFactoryInternal::HasSpellstone;
|
creators["no spellstone"] = &WarlockTriggerFactoryInternal::HasSpellstone;
|
||||||
|
creators["no soulstone"] = &WarlockTriggerFactoryInternal::HasSoulstone;
|
||||||
|
creators["firestone"] = &WarlockTriggerFactoryInternal::firestone;
|
||||||
|
creators["spellstone"] = &WarlockTriggerFactoryInternal::spellstone;
|
||||||
|
creators["soulstone"] = &WarlockTriggerFactoryInternal::soulstone;
|
||||||
|
creators["banish"] = &WarlockTriggerFactoryInternal::banish;
|
||||||
|
creators["fear"] = &WarlockTriggerFactoryInternal::fear;
|
||||||
|
creators["spell lock"] = &WarlockTriggerFactoryInternal::spell_lock;
|
||||||
|
creators["devour magic purge"] = &WarlockTriggerFactoryInternal::devour_magic_purge;
|
||||||
|
creators["devour magic cleanse"] = &WarlockTriggerFactoryInternal::devour_magic_cleanse;
|
||||||
|
creators["backlash"] = &WarlockTriggerFactoryInternal::backlash;
|
||||||
creators["corruption"] = &WarlockTriggerFactoryInternal::corruption;
|
creators["corruption"] = &WarlockTriggerFactoryInternal::corruption;
|
||||||
creators["corruption on attacker"] = &WarlockTriggerFactoryInternal::corruption_on_attacker;
|
creators["corruption on attacker"] = &WarlockTriggerFactoryInternal::corruption_on_attacker;
|
||||||
creators["curse of agony"] = &WarlockTriggerFactoryInternal::curse_of_agony;
|
creators["curse of agony"] = &WarlockTriggerFactoryInternal::curse_of_agony;
|
||||||
creators["curse of agony on attacker"] = &WarlockTriggerFactoryInternal::curse_of_agony_on_attacker;
|
creators["curse of agony on attacker"] = &WarlockTriggerFactoryInternal::curse_of_agony_on_attacker;
|
||||||
creators["banish"] = &WarlockTriggerFactoryInternal::banish;
|
|
||||||
creators["spellstone"] = &WarlockTriggerFactoryInternal::spellstone;
|
|
||||||
creators["backlash"] = &WarlockTriggerFactoryInternal::backlash;
|
|
||||||
creators["fear"] = &WarlockTriggerFactoryInternal::fear;
|
|
||||||
creators["immolate"] = &WarlockTriggerFactoryInternal::immolate;
|
creators["immolate"] = &WarlockTriggerFactoryInternal::immolate;
|
||||||
creators["amplify curse"] = &WarlockTriggerFactoryInternal::amplify_curse;
|
|
||||||
creators["siphon life"] = &WarlockTriggerFactoryInternal::siphon_life;
|
|
||||||
creators["siphon life on attacker"] = &WarlockTriggerFactoryInternal::siphon_life_on_attacker;
|
|
||||||
|
|
||||||
creators["immolate on attacker"] = &WarlockTriggerFactoryInternal::immolate_on_attacker;
|
creators["immolate on attacker"] = &WarlockTriggerFactoryInternal::immolate_on_attacker;
|
||||||
creators["unstable affliction"] = &WarlockTriggerFactoryInternal::unstable_affliction;
|
creators["unstable affliction"] = &WarlockTriggerFactoryInternal::unstable_affliction;
|
||||||
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["curse of the elements"] = &WarlockTriggerFactoryInternal::curse_of_the_elements;
|
||||||
creators["decimation"] = &WarlockTriggerFactoryInternal::decimation;
|
creators["decimation"] = &WarlockTriggerFactoryInternal::decimation;
|
||||||
|
creators["life tap"] = &WarlockTriggerFactoryInternal::life_tap;
|
||||||
creators["life tap glyph buff"] = &WarlockTriggerFactoryInternal::life_tap_glyph_buff;
|
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;
|
||||||
|
creators["demonic empowerment"] = &WarlockTriggerFactoryInternal::demonic_empowerment;
|
||||||
|
creators["immolation aura active"] = &WarlockTriggerFactoryInternal::immolation_aura_active;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Trigger* amplify_curse(PlayerbotAI* botAI) { return new AmplifyCurseTrigger(botAI); }
|
|
||||||
static Trigger* shadow_trance(PlayerbotAI* botAI) { return new ShadowTranceTrigger(botAI); }
|
static Trigger* shadow_trance(PlayerbotAI* botAI) { return new ShadowTranceTrigger(botAI); }
|
||||||
static Trigger* demon_armor(PlayerbotAI* botAI) { return new DemonArmorTrigger(botAI); }
|
static Trigger* demon_armor(PlayerbotAI* botAI) { return new DemonArmorTrigger(botAI); }
|
||||||
|
static Trigger* soul_link(PlayerbotAI* botAI) { return new SoulLinkTrigger(botAI); }
|
||||||
static Trigger* HasHealthstone(PlayerbotAI* botAI) { return new HasHealthstoneTrigger(botAI); }
|
static Trigger* HasHealthstone(PlayerbotAI* botAI) { return new HasHealthstoneTrigger(botAI); }
|
||||||
static Trigger* HasFirestone(PlayerbotAI* botAI) { return new HasFirestoneTrigger(botAI); }
|
static Trigger* HasFirestone(PlayerbotAI* botAI) { return new HasFirestoneTrigger(botAI); }
|
||||||
static Trigger* HasSpellstone(PlayerbotAI* botAI) { return new HasSpellstoneTrigger(botAI); }
|
static Trigger* HasSpellstone(PlayerbotAI* botAI) { return new HasSpellstoneTrigger(botAI); }
|
||||||
|
static Trigger* HasSoulstone(PlayerbotAI* botAI) { return new HasSoulstoneTrigger(botAI); }
|
||||||
|
static Trigger* firestone(PlayerbotAI* botAI) { return new FirestoneTrigger(botAI); }
|
||||||
|
static Trigger* spellstone(PlayerbotAI* botAI) { return new SpellstoneTrigger(botAI); }
|
||||||
|
static Trigger* soulstone(PlayerbotAI* botAI) { return new SoulstoneTrigger(botAI); }
|
||||||
static Trigger* corruption(PlayerbotAI* botAI) { return new CorruptionTrigger(botAI); }
|
static Trigger* corruption(PlayerbotAI* botAI) { return new CorruptionTrigger(botAI); }
|
||||||
static Trigger* corruption_on_attacker(PlayerbotAI* botAI) { return new CorruptionOnAttackerTrigger(botAI); }
|
static Trigger* corruption_on_attacker(PlayerbotAI* botAI) { return new CorruptionOnAttackerTrigger(botAI); }
|
||||||
static Trigger* siphon_life(PlayerbotAI* botAI) { return new SiphonLifeTrigger(botAI); }
|
|
||||||
static Trigger* siphon_life_on_attacker(PlayerbotAI* botAI) { return new SiphonLifeOnAttackerTrigger(botAI); }
|
|
||||||
static Trigger* curse_of_agony(PlayerbotAI* botAI) { return new CurseOfAgonyTrigger(botAI); }
|
static Trigger* curse_of_agony(PlayerbotAI* botAI) { return new CurseOfAgonyTrigger(botAI); }
|
||||||
static Trigger* curse_of_agony_on_attacker(PlayerbotAI* botAI)
|
static Trigger* curse_of_agony_on_attacker(PlayerbotAI* botAI) { return new CurseOfAgonyOnAttackerTrigger(botAI); }
|
||||||
{
|
|
||||||
return new CastCurseOfAgonyOnAttackerTrigger(botAI);
|
|
||||||
}
|
|
||||||
static Trigger* banish(PlayerbotAI* botAI) { return new BanishTrigger(botAI); }
|
static Trigger* banish(PlayerbotAI* botAI) { return new BanishTrigger(botAI); }
|
||||||
static Trigger* spellstone(PlayerbotAI* botAI) { return new SpellstoneTrigger(botAI); }
|
|
||||||
static Trigger* backlash(PlayerbotAI* botAI) { return new BacklashTrigger(botAI); }
|
|
||||||
static Trigger* fear(PlayerbotAI* botAI) { return new FearTrigger(botAI); }
|
static Trigger* fear(PlayerbotAI* botAI) { return new FearTrigger(botAI); }
|
||||||
|
static Trigger* spell_lock(PlayerbotAI* botAI) { return new SpellLockInterruptSpellTrigger(botAI); }
|
||||||
|
static Trigger* devour_magic_purge(PlayerbotAI* botAI) { return new DevourMagicPurgeTrigger(botAI); }
|
||||||
|
static Trigger* devour_magic_cleanse(PlayerbotAI* botAI) { return new DevourMagicCleanseTrigger(botAI); }
|
||||||
|
static Trigger* backlash(PlayerbotAI* botAI) { return new BacklashTrigger(botAI); }
|
||||||
static Trigger* immolate(PlayerbotAI* botAI) { return new ImmolateTrigger(botAI); }
|
static Trigger* immolate(PlayerbotAI* botAI) { return new ImmolateTrigger(botAI); }
|
||||||
static Trigger* immolate_on_attacker(PlayerbotAI* ai) { return new ImmolateOnAttackerTrigger(ai); }
|
static Trigger* immolate_on_attacker(PlayerbotAI* ai) { return new ImmolateOnAttackerTrigger(ai); }
|
||||||
static Trigger* unstable_affliction(PlayerbotAI* ai) { return new UnstableAfflictionTrigger(ai); }
|
static Trigger* unstable_affliction(PlayerbotAI* ai) { return new UnstableAfflictionTrigger(ai); }
|
||||||
static Trigger* unstable_affliction_on_attacker(PlayerbotAI* ai)
|
static Trigger* unstable_affliction_on_attacker(PlayerbotAI* ai) { return new UnstableAfflictionOnAttackerTrigger(ai); }
|
||||||
{
|
|
||||||
return new UnstableAfflictionOnAttackerTrigger(ai);
|
|
||||||
}
|
|
||||||
static Trigger* haunt(PlayerbotAI* ai) { return new HauntTrigger(ai); }
|
static Trigger* haunt(PlayerbotAI* ai) { return new HauntTrigger(ai); }
|
||||||
|
static Trigger* curse_of_the_elements(PlayerbotAI* ai) { return new CurseOfTheElementsTrigger(ai); }
|
||||||
static Trigger* decimation(PlayerbotAI* ai) { return new DecimationTrigger(ai); }
|
static Trigger* decimation(PlayerbotAI* ai) { return new DecimationTrigger(ai); }
|
||||||
|
static Trigger* life_tap(PlayerbotAI* ai) { return new LifeTapTrigger(ai); }
|
||||||
static Trigger* life_tap_glyph_buff(PlayerbotAI* ai) { return new LifeTapGlyphBuffTrigger(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); }
|
||||||
|
static Trigger* demonic_empowerment(PlayerbotAI* ai) { return new DemonicEmpowermentTrigger(ai); }
|
||||||
|
static Trigger* immolation_aura_active(PlayerbotAI* ai) { return new ImmolationAuraActiveTrigger(ai); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class WarlockAiObjectContextInternal : public NamedObjectContext<Action>
|
class WarlockAiObjectContextInternal : public NamedObjectContext<Action>
|
||||||
@@ -146,104 +183,125 @@ public:
|
|||||||
creators["fel armor"] = &WarlockAiObjectContextInternal::fel_armor;
|
creators["fel armor"] = &WarlockAiObjectContextInternal::fel_armor;
|
||||||
creators["demon armor"] = &WarlockAiObjectContextInternal::demon_armor;
|
creators["demon armor"] = &WarlockAiObjectContextInternal::demon_armor;
|
||||||
creators["demon skin"] = &WarlockAiObjectContextInternal::demon_skin;
|
creators["demon skin"] = &WarlockAiObjectContextInternal::demon_skin;
|
||||||
|
creators["soul link"] = &WarlockAiObjectContextInternal::soul_link;
|
||||||
creators["create healthstone"] = &WarlockAiObjectContextInternal::create_healthstone;
|
creators["create healthstone"] = &WarlockAiObjectContextInternal::create_healthstone;
|
||||||
creators["create firestone"] = &WarlockAiObjectContextInternal::create_firestone;
|
creators["create firestone"] = &WarlockAiObjectContextInternal::create_firestone;
|
||||||
creators["create spellstone"] = &WarlockAiObjectContextInternal::create_spellstone;
|
creators["create spellstone"] = &WarlockAiObjectContextInternal::create_spellstone;
|
||||||
|
creators["create soulstone"] = &WarlockAiObjectContextInternal::create_soulstone;
|
||||||
|
creators["firestone"] = &WarlockAiObjectContextInternal::firestone;
|
||||||
creators["spellstone"] = &WarlockAiObjectContextInternal::spellstone;
|
creators["spellstone"] = &WarlockAiObjectContextInternal::spellstone;
|
||||||
|
creators["soulstone self"] = &WarlockAiObjectContextInternal::soulstone_self;
|
||||||
|
creators["soulstone master"] = &WarlockAiObjectContextInternal::soulstone_master;
|
||||||
|
creators["soulstone tank"] = &WarlockAiObjectContextInternal::soulstone_tank;
|
||||||
|
creators["soulstone healer"] = &WarlockAiObjectContextInternal::soulstone_healer;
|
||||||
creators["summon voidwalker"] = &WarlockAiObjectContextInternal::summon_voidwalker;
|
creators["summon voidwalker"] = &WarlockAiObjectContextInternal::summon_voidwalker;
|
||||||
creators["summon felguard"] = &WarlockAiObjectContextInternal::summon_felguard;
|
creators["summon felguard"] = &WarlockAiObjectContextInternal::summon_felguard;
|
||||||
creators["summon felhunter"] = &WarlockAiObjectContextInternal::summon_felhunter;
|
creators["summon felhunter"] = &WarlockAiObjectContextInternal::summon_felhunter;
|
||||||
creators["summon succubus"] = &WarlockAiObjectContextInternal::summon_succubus;
|
creators["summon succubus"] = &WarlockAiObjectContextInternal::summon_succubus;
|
||||||
creators["summon imp"] = &WarlockAiObjectContextInternal::summon_imp;
|
creators["summon imp"] = &WarlockAiObjectContextInternal::summon_imp;
|
||||||
|
creators["fel domination"] = &WarlockAiObjectContextInternal::fel_domination;
|
||||||
creators["immolate"] = &WarlockAiObjectContextInternal::immolate;
|
creators["immolate"] = &WarlockAiObjectContextInternal::immolate;
|
||||||
|
creators["immolate on attacker"] = &WarlockAiObjectContextInternal::immolate_on_attacker;
|
||||||
creators["corruption"] = &WarlockAiObjectContextInternal::corruption;
|
creators["corruption"] = &WarlockAiObjectContextInternal::corruption;
|
||||||
creators["corruption on attacker"] = &WarlockAiObjectContextInternal::corruption_on_attacker;
|
creators["corruption on attacker"] = &WarlockAiObjectContextInternal::corruption_on_attacker;
|
||||||
creators["siphon life"] = &WarlockAiObjectContextInternal::siphon_life;
|
|
||||||
creators["siphon life on attacker"] = &WarlockAiObjectContextInternal::siphon_life_on_attacker;
|
|
||||||
creators["curse of agony"] = &WarlockAiObjectContextInternal::curse_of_agony;
|
creators["curse of agony"] = &WarlockAiObjectContextInternal::curse_of_agony;
|
||||||
creators["curse of agony on attacker"] = &WarlockAiObjectContextInternal::curse_of_agony_on_attacker;
|
creators["curse of agony on attacker"] = &WarlockAiObjectContextInternal::curse_of_agony_on_attacker;
|
||||||
creators["shadow bolt"] = &WarlockAiObjectContextInternal::shadow_bolt;
|
creators["shadow bolt"] = &WarlockAiObjectContextInternal::shadow_bolt;
|
||||||
creators["drain soul"] = &WarlockAiObjectContextInternal::drain_soul;
|
creators["drain soul"] = &WarlockAiObjectContextInternal::drain_soul;
|
||||||
creators["drain mana"] = &WarlockAiObjectContextInternal::drain_mana;
|
creators["drain mana"] = &WarlockAiObjectContextInternal::drain_mana;
|
||||||
creators["drain life"] = &WarlockAiObjectContextInternal::drain_life;
|
creators["drain life"] = &WarlockAiObjectContextInternal::drain_life;
|
||||||
creators["banish"] = &WarlockAiObjectContextInternal::banish;
|
|
||||||
creators["banish on cc"] = &WarlockAiObjectContextInternal::banish_on_cc;
|
creators["banish on cc"] = &WarlockAiObjectContextInternal::banish_on_cc;
|
||||||
|
creators["fear on cc"] = &WarlockAiObjectContextInternal::fear_on_cc;
|
||||||
|
creators["spell lock"] = &WarlockAiObjectContextInternal::spell_lock;
|
||||||
|
creators["devour magic purge"] = &WarlockAiObjectContextInternal::devour_magic_purge;
|
||||||
|
creators["devour magic cleanse"] = &WarlockAiObjectContextInternal::devour_magic_cleanse;
|
||||||
creators["seed of corruption"] = &WarlockAiObjectContextInternal::seed_of_corruption;
|
creators["seed of corruption"] = &WarlockAiObjectContextInternal::seed_of_corruption;
|
||||||
creators["seed of corruption on attacker"] = &WarlockAiObjectContextInternal::seed_of_corruption_on_attacker;
|
creators["seed of corruption on attacker"] = &WarlockAiObjectContextInternal::seed_of_corruption_on_attacker;
|
||||||
creators["rain of fire"] = &WarlockAiObjectContextInternal::rain_of_fire;
|
creators["rain of fire"] = &WarlockAiObjectContextInternal::rain_of_fire;
|
||||||
|
creators["hellfire"] = &WarlockAiObjectContextInternal::hellfire;
|
||||||
creators["shadowfury"] = &WarlockAiObjectContextInternal::shadowfury;
|
creators["shadowfury"] = &WarlockAiObjectContextInternal::shadowfury;
|
||||||
creators["life tap"] = &WarlockAiObjectContextInternal::life_tap;
|
creators["life tap"] = &WarlockAiObjectContextInternal::life_tap;
|
||||||
creators["fear"] = &WarlockAiObjectContextInternal::fear;
|
creators["incinerate"] = &WarlockAiObjectContextInternal::incinerate;
|
||||||
creators["fear on cc"] = &WarlockAiObjectContextInternal::fear_on_cc;
|
|
||||||
creators["incinirate"] = &WarlockAiObjectContextInternal::incinirate;
|
|
||||||
creators["conflagrate"] = &WarlockAiObjectContextInternal::conflagrate;
|
creators["conflagrate"] = &WarlockAiObjectContextInternal::conflagrate;
|
||||||
creators["amplify curse"] = &WarlockAiObjectContextInternal::amplify_curse;
|
|
||||||
|
|
||||||
creators["immolate on attacker"] = &WarlockAiObjectContextInternal::immolate_on_attacker;
|
|
||||||
creators["unstable affliction"] = &WarlockAiObjectContextInternal::unstable_affliction;
|
creators["unstable affliction"] = &WarlockAiObjectContextInternal::unstable_affliction;
|
||||||
creators["unstable affliction on attacker"] = &WarlockAiObjectContextInternal::unstable_affliction_on_attacker;
|
creators["unstable affliction on attacker"] = &WarlockAiObjectContextInternal::unstable_affliction_on_attacker;
|
||||||
creators["haunt"] = &WarlockAiObjectContextInternal::haunt;
|
creators["haunt"] = &WarlockAiObjectContextInternal::haunt;
|
||||||
|
creators["curse of the elements"] = &WarlockAiObjectContextInternal::curse_of_the_elements;
|
||||||
creators["demonic empowerment"] = &WarlockAiObjectContextInternal::demonic_empowerment;
|
creators["demonic empowerment"] = &WarlockAiObjectContextInternal::demonic_empowerment;
|
||||||
creators["metamorphosis"] = &WarlockAiObjectContextInternal::metamorphosis;
|
creators["metamorphosis"] = &WarlockAiObjectContextInternal::metamorphosis;
|
||||||
creators["soul fire"] = &WarlockAiObjectContextInternal::soul_fire;
|
creators["soul fire"] = &WarlockAiObjectContextInternal::soul_fire;
|
||||||
creators["incinerate"] = &WarlockAiObjectContextInternal::incinerate;
|
creators["incinerate"] = &WarlockAiObjectContextInternal::incinerate;
|
||||||
creators["soulstone"] = &WarlockAiObjectContextInternal::soulstone;
|
creators["demon charge"] = &WarlockAiObjectContextInternal::demon_charge;
|
||||||
}
|
creators["shadow cleave"] = &WarlockAiObjectContextInternal::shadow_cleave;
|
||||||
|
creators["shadowburn"] = &WarlockAiObjectContextInternal::shadowburn;
|
||||||
|
creators["shadowflame"] = &WarlockAiObjectContextInternal::shadowflame;
|
||||||
|
creators["immolation aura"] = &WarlockAiObjectContextInternal::immolation_aura;
|
||||||
|
creators["chaos bolt"] = &WarlockAiObjectContextInternal::chaos_bolt;
|
||||||
|
creators["soulshatter"] = &WarlockAiObjectContextInternal::soulshatter;
|
||||||
|
creators["searing pain"] = WarlockAiObjectContextInternal::searing_pain;
|
||||||
|
creators["shadow ward"] = &WarlockAiObjectContextInternal::shadow_ward;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Action* amplify_curse(PlayerbotAI* botAI) { return new CastAmplifyCurseAction(botAI); }
|
|
||||||
static Action* conflagrate(PlayerbotAI* botAI) { return new CastConflagrateAction(botAI); }
|
static Action* conflagrate(PlayerbotAI* botAI) { return new CastConflagrateAction(botAI); }
|
||||||
static Action* incinirate(PlayerbotAI* botAI) { return new CastIncinirateAction(botAI); }
|
static Action* incinerate(PlayerbotAI* botAI) { return new CastIncinerateAction(botAI); }
|
||||||
static Action* fear_on_cc(PlayerbotAI* botAI) { return new CastFearOnCcAction(botAI); }
|
|
||||||
static Action* fear(PlayerbotAI* botAI) { return new CastFearAction(botAI); }
|
|
||||||
static Action* immolate(PlayerbotAI* botAI) { return new CastImmolateAction(botAI); }
|
static Action* immolate(PlayerbotAI* botAI) { return new CastImmolateAction(botAI); }
|
||||||
static Action* summon_imp(PlayerbotAI* botAI) { return new CastSummonImpAction(botAI); }
|
static Action* immolate_on_attacker(PlayerbotAI* botAI) { return new CastImmolateOnAttackerAction(botAI); }
|
||||||
static Action* summon_succubus(PlayerbotAI* botAI) { return new CastSummonSuccubusAction(botAI); }
|
|
||||||
static Action* fel_armor(PlayerbotAI* botAI) { return new CastFelArmorAction(botAI); }
|
static Action* fel_armor(PlayerbotAI* botAI) { return new CastFelArmorAction(botAI); }
|
||||||
static Action* demon_armor(PlayerbotAI* botAI) { return new CastDemonArmorAction(botAI); }
|
static Action* demon_armor(PlayerbotAI* botAI) { return new CastDemonArmorAction(botAI); }
|
||||||
static Action* demon_skin(PlayerbotAI* botAI) { return new CastDemonSkinAction(botAI); }
|
static Action* demon_skin(PlayerbotAI* botAI) { return new CastDemonSkinAction(botAI); }
|
||||||
|
static Action* soul_link(PlayerbotAI* botAI) { return new CastSoulLinkAction(botAI); }
|
||||||
static Action* create_healthstone(PlayerbotAI* botAI) { return new CastCreateHealthstoneAction(botAI); }
|
static Action* create_healthstone(PlayerbotAI* botAI) { return new CastCreateHealthstoneAction(botAI); }
|
||||||
static Action* create_firestone(PlayerbotAI* botAI) { return new CastCreateFirestoneAction(botAI); }
|
static Action* create_firestone(PlayerbotAI* botAI) { return new CastCreateFirestoneAction(botAI); }
|
||||||
static Action* create_spellstone(PlayerbotAI* botAI) { return new CastCreateSpellstoneAction(botAI); }
|
static Action* create_spellstone(PlayerbotAI* botAI) { return new CastCreateSpellstoneAction(botAI); }
|
||||||
|
static Action* create_soulstone(PlayerbotAI* botAI) { return new CastCreateSoulstoneAction(botAI); }
|
||||||
|
static Action* firestone(PlayerbotAI* botAI) { return new UseSpellItemAction(botAI, "firestone", true); }
|
||||||
static Action* spellstone(PlayerbotAI* botAI) { return new UseSpellItemAction(botAI, "spellstone", true); }
|
static Action* spellstone(PlayerbotAI* botAI) { return new UseSpellItemAction(botAI, "spellstone", true); }
|
||||||
|
static Action* soulstone_self(PlayerbotAI* botAI) { return new UseSoulstoneSelfAction(botAI); }
|
||||||
|
static Action* soulstone_master(PlayerbotAI* botAI) { return new UseSoulstoneMasterAction(botAI); }
|
||||||
|
static Action* soulstone_tank(PlayerbotAI* botAI) { return new UseSoulstoneTankAction(botAI); }
|
||||||
|
static Action* soulstone_healer(PlayerbotAI* botAI) { return new UseSoulstoneHealerAction(botAI); }
|
||||||
static Action* summon_voidwalker(PlayerbotAI* botAI) { return new CastSummonVoidwalkerAction(botAI); }
|
static Action* summon_voidwalker(PlayerbotAI* botAI) { return new CastSummonVoidwalkerAction(botAI); }
|
||||||
static Action* summon_felguard(PlayerbotAI* botAI) { return new CastSummonFelguardAction(botAI); }
|
static Action* summon_felguard(PlayerbotAI* botAI) { return new CastSummonFelguardAction(botAI); }
|
||||||
static Action* summon_felhunter(PlayerbotAI* botAI) { return new CastSummonFelhunterAction(botAI); }
|
static Action* summon_felhunter(PlayerbotAI* botAI) { return new CastSummonFelhunterAction(botAI); }
|
||||||
|
static Action* summon_imp(PlayerbotAI* botAI) { return new CastSummonImpAction(botAI); }
|
||||||
|
static Action* summon_succubus(PlayerbotAI* botAI) { return new CastSummonSuccubusAction(botAI); }
|
||||||
|
static Action* fel_domination(PlayerbotAI* botAI) { return new CastFelDominationAction(botAI); }
|
||||||
static Action* corruption(PlayerbotAI* botAI) { return new CastCorruptionAction(botAI); }
|
static Action* corruption(PlayerbotAI* botAI) { return new CastCorruptionAction(botAI); }
|
||||||
static Action* corruption_on_attacker(PlayerbotAI* botAI) { return new CastCorruptionOnAttackerAction(botAI); }
|
static Action* corruption_on_attacker(PlayerbotAI* botAI) { return new CastCorruptionOnAttackerAction(botAI); }
|
||||||
static Action* siphon_life(PlayerbotAI* botAI) { return new CastSiphonLifeAction(botAI); }
|
|
||||||
static Action* siphon_life_on_attacker(PlayerbotAI* botAI) { return new CastSiphonLifeOnAttackerAction(botAI); }
|
|
||||||
static Action* curse_of_agony(PlayerbotAI* botAI) { return new CastCurseOfAgonyAction(botAI); }
|
static Action* curse_of_agony(PlayerbotAI* botAI) { return new CastCurseOfAgonyAction(botAI); }
|
||||||
static Action* curse_of_agony_on_attacker(PlayerbotAI* botAI)
|
static Action* curse_of_agony_on_attacker(PlayerbotAI* botAI) { return new CastCurseOfAgonyOnAttackerAction(botAI); }
|
||||||
{
|
|
||||||
return new CastCurseOfAgonyOnAttackerAction(botAI);
|
|
||||||
}
|
|
||||||
static Action* shadow_bolt(PlayerbotAI* botAI) { return new CastShadowBoltAction(botAI); }
|
static Action* shadow_bolt(PlayerbotAI* botAI) { return new CastShadowBoltAction(botAI); }
|
||||||
static Action* drain_soul(PlayerbotAI* botAI) { return new CastDrainSoulAction(botAI); }
|
static Action* drain_soul(PlayerbotAI* botAI) { return new CastDrainSoulAction(botAI); }
|
||||||
static Action* drain_mana(PlayerbotAI* botAI) { return new CastDrainManaAction(botAI); }
|
static Action* drain_mana(PlayerbotAI* botAI) { return new CastDrainManaAction(botAI); }
|
||||||
static Action* drain_life(PlayerbotAI* botAI) { return new CastDrainLifeAction(botAI); }
|
static Action* drain_life(PlayerbotAI* botAI) { return new CastDrainLifeAction(botAI); }
|
||||||
static Action* banish(PlayerbotAI* botAI) { return new CastBanishAction(botAI); }
|
static Action* banish_on_cc(PlayerbotAI* botAI) { return new CastBanishOnCcAction(botAI); }
|
||||||
static Action* banish_on_cc(PlayerbotAI* botAI) { return new CastBanishAction(botAI); }
|
static Action* fear_on_cc(PlayerbotAI* botAI) { return new CastFearOnCcAction(botAI); }
|
||||||
|
static Action* spell_lock(PlayerbotAI* botAI) { return new CastSpellLockAction(botAI); }
|
||||||
|
static Action* devour_magic_purge(PlayerbotAI* botAI) { return new CastDevourMagicPurgeAction(botAI); }
|
||||||
|
static Action* devour_magic_cleanse(PlayerbotAI* botAI) { return new CastDevourMagicCleanseAction(botAI); }
|
||||||
static Action* seed_of_corruption(PlayerbotAI* botAI) { return new CastSeedOfCorruptionAction(botAI); }
|
static Action* seed_of_corruption(PlayerbotAI* botAI) { return new CastSeedOfCorruptionAction(botAI); }
|
||||||
static Action* seed_of_corruption_on_attacker(PlayerbotAI* botAI)
|
static Action* seed_of_corruption_on_attacker(PlayerbotAI* botAI) { return new CastSeedOfCorruptionOnAttackerAction(botAI); }
|
||||||
{
|
|
||||||
return new CastSeedOfCorruptionOnAttackerAction(botAI);
|
|
||||||
}
|
|
||||||
static Action* rain_of_fire(PlayerbotAI* botAI) { return new CastRainOfFireAction(botAI); }
|
static Action* rain_of_fire(PlayerbotAI* botAI) { return new CastRainOfFireAction(botAI); }
|
||||||
|
static Action* hellfire(PlayerbotAI* botAI) { return new CastHellfireAction(botAI); }
|
||||||
static Action* shadowfury(PlayerbotAI* botAI) { return new CastShadowfuryAction(botAI); }
|
static Action* shadowfury(PlayerbotAI* botAI) { return new CastShadowfuryAction(botAI); }
|
||||||
static Action* life_tap(PlayerbotAI* botAI) { return new CastLifeTapAction(botAI); }
|
static Action* life_tap(PlayerbotAI* botAI) { return new CastLifeTapAction(botAI); }
|
||||||
static Action* immolate_on_attacker(PlayerbotAI* ai) { return new CastImmolateOnAttackerAction(ai); }
|
|
||||||
static Action* unstable_affliction(PlayerbotAI* ai) { return new CastUnstableAfflictionAction(ai); }
|
static Action* unstable_affliction(PlayerbotAI* ai) { return new CastUnstableAfflictionAction(ai); }
|
||||||
static Action* unstable_affliction_on_attacker(PlayerbotAI* ai)
|
static Action* unstable_affliction_on_attacker(PlayerbotAI* ai) { return new CastUnstableAfflictionOnAttackerAction(ai); }
|
||||||
{
|
|
||||||
return new CastUnstableAfflictionOnAttackerAction(ai);
|
|
||||||
}
|
|
||||||
static Action* haunt(PlayerbotAI* ai) { return new CastHauntAction(ai); }
|
static Action* haunt(PlayerbotAI* ai) { return new CastHauntAction(ai); }
|
||||||
|
static Action* curse_of_the_elements(PlayerbotAI* ai) { return new CastCurseOfTheElementsAction(ai); }
|
||||||
static Action* demonic_empowerment(PlayerbotAI* ai) { return new CastDemonicEmpowermentAction(ai); }
|
static Action* demonic_empowerment(PlayerbotAI* ai) { return new CastDemonicEmpowermentAction(ai); }
|
||||||
static Action* metamorphosis(PlayerbotAI* ai) { return new CastMetamorphosisAction(ai); }
|
static Action* metamorphosis(PlayerbotAI* ai) { return new CastMetamorphosisAction(ai); }
|
||||||
static Action* soul_fire(PlayerbotAI* ai) { return new CastSoulFireAction(ai); }
|
static Action* soul_fire(PlayerbotAI* ai) { return new CastSoulFireAction(ai); }
|
||||||
static Action* incinerate(PlayerbotAI* ai) { return new CastIncinerateAction(ai); }
|
static Action* demon_charge(PlayerbotAI* ai) { return new DemonChargeAction(ai); }
|
||||||
static Action* soulstone(PlayerbotAI* ai) { return new UseSoulstoneAction(ai); }
|
static Action* shadow_cleave(PlayerbotAI* ai) { return new ShadowCleaveAction(ai); }
|
||||||
|
static Action* shadowburn(PlayerbotAI* ai) { return new CastShadowburnAction(ai); }
|
||||||
|
static Action* shadowflame(PlayerbotAI* botAI) { return new CastShadowflameAction(botAI); }
|
||||||
|
static Action* immolation_aura(PlayerbotAI* botAI) { return new CastImmolationAuraAction(botAI); }
|
||||||
|
static Action* chaos_bolt(PlayerbotAI* botAI) { return new CastChaosBoltAction(botAI); }
|
||||||
|
static Action* soulshatter(PlayerbotAI* botAI) { return new CastSoulshatterAction(botAI);}
|
||||||
|
static Action* searing_pain(PlayerbotAI* botAI) { return new CastSearingPainAction(botAI); }
|
||||||
|
static Action* shadow_ward(PlayerbotAI* botAI) { return new CastShadowWardAction(botAI); }
|
||||||
};
|
};
|
||||||
|
|
||||||
WarlockAiObjectContext::WarlockAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
|
WarlockAiObjectContext::WarlockAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
|
||||||
|
|||||||
@@ -4,10 +4,34 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "WarlockTriggers.h"
|
#include "WarlockTriggers.h"
|
||||||
|
|
||||||
#include "GenericTriggers.h"
|
#include "GenericTriggers.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
|
||||||
|
bool SpellstoneTrigger::IsActive() { return BuffTrigger::IsActive() && AI_VALUE2(uint32, "item count", getName()) > 0; }
|
||||||
|
|
||||||
|
bool FirestoneTrigger::IsActive() { return BuffTrigger::IsActive() && AI_VALUE2(uint32, "item count", getName()) > 0; }
|
||||||
|
|
||||||
|
bool WarlockConjuredItemTrigger::IsActive()
|
||||||
|
{
|
||||||
|
return ItemCountTrigger::IsActive() && AI_VALUE2(uint32, "item count", "soul shard") > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the target marked with the moon icon can be banished
|
||||||
|
bool BanishTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* ccTarget = context->GetValue<Unit*>("cc target", "banish")->Get();
|
||||||
|
Unit* moonTarget = context->GetValue<Unit*>("rti cc target")->Get();
|
||||||
|
return ccTarget && moonTarget && ccTarget == moonTarget && HasCcTargetTrigger::IsActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the target marked with the moon icon can be feared
|
||||||
|
bool FearTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* ccTarget = context->GetValue<Unit*>("cc target", "fear")->Get();
|
||||||
|
Unit* moonTarget = context->GetValue<Unit*>("rti cc target")->Get();
|
||||||
|
return ccTarget && moonTarget && ccTarget == moonTarget && HasCcTargetTrigger::IsActive();
|
||||||
|
}
|
||||||
|
|
||||||
bool DemonArmorTrigger::IsActive()
|
bool DemonArmorTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Unit* target = GetTarget();
|
Unit* target = GetTarget();
|
||||||
@@ -15,30 +39,18 @@ bool DemonArmorTrigger::IsActive()
|
|||||||
!botAI->HasAura("fel armor", target);
|
!botAI->HasAura("fel armor", target);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpellstoneTrigger::IsActive() { return BuffTrigger::IsActive() && AI_VALUE2(uint32, "item count", getName()) > 0; }
|
bool SoulLinkTrigger::IsActive()
|
||||||
|
|
||||||
bool WarlockConjuredItemTrigger::IsActive()
|
|
||||||
{
|
{
|
||||||
return ItemCountTrigger::IsActive() && AI_VALUE2(uint32, "item count", "soul shard") > 0;
|
Unit* target = GetTarget();
|
||||||
|
return !botAI->HasAura("soul link", target);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImmolateOnAttackerTrigger::IsActive()
|
bool DemonicEmpowermentTrigger::IsActive()
|
||||||
{
|
{
|
||||||
return DebuffOnAttackerTrigger::IsActive() &&
|
Pet* pet = bot->GetPet();
|
||||||
// !botAI->HasAura("immolate", GetTarget(), false, true) &&
|
if (!pet)
|
||||||
!botAI->HasAura("unstable affliction", GetTarget(), false, true);
|
return false;
|
||||||
}
|
return !botAI->HasAura("demonic empowerment", pet);
|
||||||
|
|
||||||
bool UnstableAfflictionTrigger::IsActive()
|
|
||||||
{
|
|
||||||
return DebuffTrigger::IsActive() && !botAI->HasAura("immolate", GetTarget(), false, true);
|
|
||||||
// !botAI->HasAura("unstable affliction", GetTarget(), false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UnstableAfflictionOnAttackerTrigger::IsActive()
|
|
||||||
{
|
|
||||||
return DebuffOnAttackerTrigger::IsActive() && !botAI->HasAura("immolate", GetTarget(), false, true);
|
|
||||||
// !botAI->HasAura("unstable affliction", GetTarget(), false, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DecimationTrigger::IsActive()
|
bool DecimationTrigger::IsActive()
|
||||||
@@ -47,11 +59,51 @@ bool DecimationTrigger::IsActive()
|
|||||||
return aura && aura->GetDuration() > 3000;
|
return aura && aura->GetDuration() > 3000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if the bot's mana is below 85% and health is above a low health threshold
|
||||||
|
bool LifeTapTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (AI_VALUE2(uint8, "health", "self target") <= sPlayerbotAIConfig->lowHealth)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!AI_VALUE2(bool, "has mana", "self target"))
|
||||||
|
return false;
|
||||||
|
if (AI_VALUE2(uint8, "mana", "self target") >= 85)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the Life Tap Glyph buff is active
|
||||||
bool LifeTapGlyphBuffTrigger::IsActive()
|
bool LifeTapGlyphBuffTrigger::IsActive()
|
||||||
{
|
{
|
||||||
// Check life tap glyph first
|
|
||||||
if (!botAI->HasAura(63320, bot))
|
if (!botAI->HasAura(63320, bot))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return BuffTrigger::IsActive();
|
return BuffTrigger::IsActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if the target has a conflicting debuff that is equal to Curse of the Elements
|
||||||
|
bool CurseOfTheElementsTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* target = GetTarget();
|
||||||
|
if (!target || !target->IsAlive() || !target->IsInWorld())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// List of all spell IDs for Ebon Plague, Earth and Moon, and Curse of the Elements
|
||||||
|
static const uint32 CurseOfTheElementsExclusiveDebuffs[] = {// Ebon Plague
|
||||||
|
51735, 51734, 51726,
|
||||||
|
// Earth and Moon
|
||||||
|
48511, 48513, 48514,
|
||||||
|
// Curse of the Elements
|
||||||
|
1490, 11721, 11722, 27228, 47865};
|
||||||
|
|
||||||
|
// Check if target has any of the exclusive debuffs
|
||||||
|
for (uint32 spellId : CurseOfTheElementsExclusiveDebuffs)
|
||||||
|
{
|
||||||
|
if (target->HasAura(spellId))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use default BuffTrigger logic for the rest (only trigger if debuff is missing or expiring)
|
||||||
|
return BuffTrigger::IsActive();
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,9 +8,13 @@
|
|||||||
|
|
||||||
#include "GenericTriggers.h"
|
#include "GenericTriggers.h"
|
||||||
#include "PlayerbotAI.h"
|
#include "PlayerbotAI.h"
|
||||||
|
#include "Playerbots.h"
|
||||||
|
#include "CureTriggers.h"
|
||||||
|
|
||||||
class PlayerbotAI;
|
class PlayerbotAI;
|
||||||
|
|
||||||
|
// Buff and Out of Combat Triggers
|
||||||
|
|
||||||
class DemonArmorTrigger : public BuffTrigger
|
class DemonArmorTrigger : public BuffTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -19,90 +23,50 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SoulLinkTrigger : public BuffTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SoulLinkTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "soul link") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FirestoneTrigger : public BuffTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FirestoneTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "firestone") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
class SpellstoneTrigger : public BuffTrigger
|
class SpellstoneTrigger : public BuffTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpellstoneTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "spellstone") {}
|
SpellstoneTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "spellstone") {}
|
||||||
|
|
||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// DEBUFF_CHECKISOWNER_TRIGGER(CurseOfAgonyTrigger, "curse of agony");
|
class HasSoulstoneTrigger : public Trigger
|
||||||
class CurseOfAgonyTrigger : public DebuffTrigger
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CurseOfAgonyTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "curse of agony", 1, true, 20.0f) {}
|
HasSoulstoneTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no soulstone") {}
|
||||||
|
bool IsActive() override { return AI_VALUE2(uint32, "item count", "soulstone") == 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CorruptionTrigger : public DebuffTrigger
|
class SoulstoneTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CorruptionTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "corruption", 1, true) {}
|
SoulstoneTrigger(PlayerbotAI* botAI) : Trigger(botAI, "soulstone") {}
|
||||||
|
|
||||||
bool IsActive() override
|
bool IsActive() override
|
||||||
{
|
{
|
||||||
return DebuffTrigger::IsActive() && !botAI->HasAura("seed of corruption", GetTarget(), false, true);
|
// Just check if we have a soulstone item available
|
||||||
|
return AI_VALUE2(uint32, "item count", "soulstone") > 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DEBUFF_CHECKISOWNER_TRIGGER(SiphonLifeTrigger, "siphon life");
|
|
||||||
|
|
||||||
class CorruptionOnAttackerTrigger : public DebuffOnAttackerTrigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CorruptionOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "corruption", true) {}
|
|
||||||
bool IsActive() override
|
|
||||||
{
|
|
||||||
return DebuffOnAttackerTrigger::IsActive() && !botAI->HasAura("seed of corruption", GetTarget(), false, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CastCurseOfAgonyOnAttackerTrigger : public DebuffOnAttackerTrigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CastCurseOfAgonyOnAttackerTrigger(PlayerbotAI* botAI)
|
|
||||||
: DebuffOnAttackerTrigger(botAI, "curse of agony", true, 20.0f)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class SiphonLifeOnAttackerTrigger : public DebuffOnAttackerTrigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SiphonLifeOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "siphon life") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
DEBUFF_CHECKISOWNER_TRIGGER(ImmolateTrigger, "immolate");
|
|
||||||
|
|
||||||
class ImmolateOnAttackerTrigger : public DebuffOnAttackerTrigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ImmolateOnAttackerTrigger(PlayerbotAI* ai) : DebuffOnAttackerTrigger(ai, "immolate") {}
|
|
||||||
virtual bool IsActive();
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShadowTranceTrigger : public HasAuraTrigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ShadowTranceTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "shadow trance") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class BacklashTrigger : public HasAuraTrigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BacklashTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "backlash") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class BanishTrigger : public HasCcTargetTrigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BanishTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "banish") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class WarlockConjuredItemTrigger : public ItemCountTrigger
|
class WarlockConjuredItemTrigger : public ItemCountTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WarlockConjuredItemTrigger(PlayerbotAI* botAI, std::string const item) : ItemCountTrigger(botAI, item, 1) {}
|
WarlockConjuredItemTrigger(PlayerbotAI* botAI, std::string const item) : ItemCountTrigger(botAI, item, 1) {}
|
||||||
|
|
||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -124,30 +88,114 @@ public:
|
|||||||
HasHealthstoneTrigger(PlayerbotAI* botAI) : WarlockConjuredItemTrigger(botAI, "healthstone") {}
|
HasHealthstoneTrigger(PlayerbotAI* botAI) : WarlockConjuredItemTrigger(botAI, "healthstone") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// CC and Pet Triggers
|
||||||
|
|
||||||
|
class BanishTrigger : public HasCcTargetTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BanishTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "banish") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
class FearTrigger : public HasCcTargetTrigger
|
class FearTrigger : public HasCcTargetTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FearTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "fear") {}
|
FearTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "fear") {}
|
||||||
};
|
|
||||||
|
|
||||||
class AmplifyCurseTrigger : public BuffTrigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AmplifyCurseTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "amplify curse") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class UnstableAfflictionTrigger : public DebuffTrigger // SpellTrigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UnstableAfflictionTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "unstable affliction", 1, true) {}
|
|
||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SpellLockInterruptSpellTrigger : public InterruptSpellTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SpellLockInterruptSpellTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "spell lock") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DevourMagicPurgeTrigger : public TargetAuraDispelTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DevourMagicPurgeTrigger(PlayerbotAI* botAI) : TargetAuraDispelTrigger(botAI, "devour magic", DISPEL_MAGIC) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DevourMagicCleanseTrigger : public PartyMemberNeedCureTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DevourMagicCleanseTrigger(PlayerbotAI* botAI) : PartyMemberNeedCureTrigger(botAI, "devour magic", DISPEL_MAGIC) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// DoT/Debuff Triggers
|
||||||
|
|
||||||
|
class CurseOfAgonyTrigger : public DebuffTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CurseOfAgonyTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "curse of agony", 1, true, 0.5f) {}
|
||||||
|
bool IsActive() override
|
||||||
|
{
|
||||||
|
if (botAI->HasStrategy(
|
||||||
|
"curse of elements", BOT_STATE_COMBAT)) // If Curse of the Elements strategy is active, do not cast Curse of Agony
|
||||||
|
return false;
|
||||||
|
return BuffTrigger::IsActive();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CurseOfAgonyOnAttackerTrigger : public DebuffOnAttackerTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CurseOfAgonyOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "curse of agony", true) {}
|
||||||
|
bool IsActive() override
|
||||||
|
{
|
||||||
|
if (botAI->HasStrategy(
|
||||||
|
"curse of elements", BOT_STATE_COMBAT)) // If Curse of the Elements strategy is active, do not cast Curse of Agony
|
||||||
|
return false;
|
||||||
|
return BuffTrigger::IsActive();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CorruptionTrigger : public DebuffTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CorruptionTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "corruption", 1, true, 0.5f) {}
|
||||||
|
bool IsActive() override
|
||||||
|
{
|
||||||
|
return BuffTrigger::IsActive() && !botAI->HasAura("seed of corruption", GetTarget(), false, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CorruptionOnAttackerTrigger : public DebuffOnAttackerTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CorruptionOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "corruption", true) {}
|
||||||
|
bool IsActive() override
|
||||||
|
{
|
||||||
|
return BuffTrigger::IsActive() && !botAI->HasAura("seed of corruption", GetTarget(), false, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImmolateTrigger : public DebuffTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImmolateTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "immolate", 1, true, 0.5f) {}
|
||||||
|
bool IsActive() override { return BuffTrigger::IsActive(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImmolateOnAttackerTrigger : public DebuffOnAttackerTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImmolateOnAttackerTrigger(PlayerbotAI* ai) : DebuffOnAttackerTrigger(ai, "immolate", true) {}
|
||||||
|
bool IsActive() override { return BuffTrigger::IsActive(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class UnstableAfflictionTrigger : public DebuffTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UnstableAfflictionTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "unstable affliction", 1, true, 0.5f) {}
|
||||||
|
bool IsActive() override { return BuffTrigger::IsActive(); }
|
||||||
|
};
|
||||||
|
|
||||||
class UnstableAfflictionOnAttackerTrigger : public DebuffOnAttackerTrigger
|
class UnstableAfflictionOnAttackerTrigger : public DebuffOnAttackerTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UnstableAfflictionOnAttackerTrigger(PlayerbotAI* ai) : DebuffOnAttackerTrigger(ai, "unstable affliction", true) {}
|
UnstableAfflictionOnAttackerTrigger(PlayerbotAI* ai) : DebuffOnAttackerTrigger(ai, "unstable affliction", true) {}
|
||||||
bool IsActive() override;
|
bool IsActive() override { return BuffTrigger::IsActive(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class HauntTrigger : public DebuffTrigger
|
class HauntTrigger : public DebuffTrigger
|
||||||
@@ -156,10 +204,20 @@ public:
|
|||||||
HauntTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "haunt", 1, true, 0) {}
|
HauntTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "haunt", 1, true, 0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DecimationTrigger : public HasAuraTrigger
|
class CurseOfTheElementsTrigger : public DebuffTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DecimationTrigger(PlayerbotAI* ai) : HasAuraTrigger(ai, "decimation") {}
|
CurseOfTheElementsTrigger(PlayerbotAI* botAI)
|
||||||
|
: DebuffTrigger(botAI, "curse of the elements", 1, true, 0.5f) {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Proc/Cooldown Triggers
|
||||||
|
|
||||||
|
class LifeTapTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LifeTapTrigger(PlayerbotAI* ai) : Trigger(ai, "life tap") {}
|
||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -170,15 +228,47 @@ public:
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MoltenCoreTrigger : public HasAuraTrigger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MoltenCoreTrigger(PlayerbotAI* ai) : HasAuraTrigger(ai, "molten core") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class MetamorphosisTrigger : public BoostTrigger
|
class MetamorphosisTrigger : public BoostTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MetamorphosisTrigger(PlayerbotAI* ai) : BoostTrigger(ai, "metamorphosis") {}
|
MetamorphosisTrigger(PlayerbotAI* ai) : BoostTrigger(ai, "metamorphosis") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DemonicEmpowermentTrigger : public BuffTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DemonicEmpowermentTrigger(PlayerbotAI* ai) : BuffTrigger(ai, "demonic empowerment") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImmolationAuraActiveTrigger : public HasAuraTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImmolationAuraActiveTrigger(PlayerbotAI* ai) : HasAuraTrigger(ai, "immolation aura") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShadowTranceTrigger : public HasAuraTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ShadowTranceTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "shadow trance") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BacklashTrigger : public HasAuraTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BacklashTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "backlash") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DecimationTrigger : public HasAuraTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DecimationTrigger(PlayerbotAI* ai) : HasAuraTrigger(ai, "decimation") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MoltenCoreTrigger : public HasAuraTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MoltenCoreTrigger(PlayerbotAI* ai) : HasAuraTrigger(ai, "molten core") {}
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user