mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-02-11 22:41:34 +00:00
Removed unnecessary spaces
This commit is contained in:
@@ -319,7 +319,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
||||
{
|
||||
engine->addStrategiesNoInit("fire", nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Frost
|
||||
engine->addStrategiesNoInit("frost", nullptr);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
|
||||
static std::string ToLower(const std::string& str)
|
||||
static std::string ToLower(const std::string& str)
|
||||
{
|
||||
std::string out = str;
|
||||
std::transform(out.begin(), out.end(), out.begin(), [](unsigned char c){ return std::tolower(c); });
|
||||
@@ -393,12 +393,12 @@ private:
|
||||
int specTab = AiFactory::GetPlayerSpecTab(bot);
|
||||
std::string botSpecClass;
|
||||
// For druids, specTab==1 is always feral; distinguish bear/cat at runtime by role
|
||||
if (cls == CLASS_DRUID && specTab == 1)
|
||||
if (cls == CLASS_DRUID && specTab == 1)
|
||||
{
|
||||
botSpecClass = botAI->IsTank(bot) ? "bear" : "cat";
|
||||
}
|
||||
// For death knights, specTab==0 is always blood; distinguish tank/dps at runtime by role
|
||||
else if (cls == CLASS_DEATH_KNIGHT && specTab == 0)
|
||||
else if (cls == CLASS_DEATH_KNIGHT && specTab == 0)
|
||||
{
|
||||
botSpecClass = botAI->IsTank(bot) ? "bdkt" : "bdkd";
|
||||
}
|
||||
@@ -482,7 +482,7 @@ public:
|
||||
std::string msgLower = ToLower(message);
|
||||
const std::string prefix = "@aggroby";
|
||||
size_t prefixLen = prefix.length();
|
||||
if (msgLower.find(prefix) != 0)
|
||||
if (msgLower.find(prefix) != 0)
|
||||
{
|
||||
return message;
|
||||
}
|
||||
@@ -601,12 +601,12 @@ CompositeChatFilter::~CompositeChatFilter()
|
||||
|
||||
std::string const CompositeChatFilter::Filter(std::string& message)
|
||||
{
|
||||
for (auto* filter : filters)
|
||||
for (auto* filter : filters)
|
||||
{
|
||||
message = filter->Filter(message);
|
||||
if (message.empty())
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
@@ -308,25 +308,25 @@ ItemIds ChatHelper::parseItems(std::string const text)
|
||||
ItemWithRandomProperty ChatHelper::parseItemWithRandomProperty(std::string const text)
|
||||
{
|
||||
ItemWithRandomProperty res;
|
||||
|
||||
|
||||
size_t itemStart = text.find("Hitem:");
|
||||
if (itemStart == std::string::npos)
|
||||
return res;
|
||||
|
||||
|
||||
itemStart += 6;
|
||||
if (itemStart >= text.length())
|
||||
return res;
|
||||
|
||||
|
||||
size_t colonPos = text.find(':', itemStart);
|
||||
if (colonPos == std::string::npos)
|
||||
return res;
|
||||
|
||||
|
||||
std::string itemIdStr = text.substr(itemStart, colonPos - itemStart);
|
||||
res.itemId = atoi(itemIdStr.c_str());
|
||||
|
||||
|
||||
std::vector<std::string> params;
|
||||
size_t currentPos = colonPos + 1;
|
||||
|
||||
|
||||
while (currentPos < text.length()) {
|
||||
size_t nextColon = text.find(':', currentPos);
|
||||
if (nextColon == std::string::npos) {
|
||||
@@ -336,15 +336,15 @@ ItemWithRandomProperty ChatHelper::parseItemWithRandomProperty(std::string const
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
params.push_back(text.substr(currentPos, nextColon - currentPos));
|
||||
currentPos = nextColon + 1;
|
||||
}
|
||||
|
||||
|
||||
if (params.size() >= 6) {
|
||||
res.randomPropertyId = atoi(params[5].c_str());
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -364,7 +364,7 @@ std::string const ChatHelper::FormatQuest(Quest const* quest)
|
||||
|
||||
if (questTitle.empty())
|
||||
questTitle = quest->GetTitle();
|
||||
|
||||
|
||||
out << "|cFFFFFF00|Hquest:" << quest->GetQuestId() << ':' << quest->GetQuestLevel() << "|h[" << questTitle << "]|h|r";
|
||||
return out.str();
|
||||
}
|
||||
@@ -432,7 +432,7 @@ std::string const ChatHelper::FormatItem(ItemTemplate const* proto, uint32 count
|
||||
|
||||
if (locale && locale->Name.size() > sWorld->GetDefaultDbcLocale())
|
||||
itemName = locale->Name[sWorld->GetDefaultDbcLocale()];
|
||||
|
||||
|
||||
if (itemName.empty())
|
||||
itemName = proto->Name1;
|
||||
|
||||
@@ -677,7 +677,7 @@ std::set<uint32> extractGeneric(std::string_view text, std::string_view prefix)
|
||||
std::string_view number_str = text_view.substr(pos, end_pos - pos);
|
||||
|
||||
uint32 number = 0;
|
||||
|
||||
|
||||
auto [ptr, ec] = std::from_chars(number_str.data(), number_str.data() + number_str.size(), number);
|
||||
|
||||
if (ec == std::errc())
|
||||
|
||||
@@ -590,7 +590,7 @@ uint32 GuildTaskMgr::GetTaskValue(uint32 owner, uint32 guildId, std::string cons
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint32 value = 0;
|
||||
|
||||
PlayerbotsDatabasePreparedStatement* stmt =
|
||||
|
||||
@@ -1051,7 +1051,7 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet)
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (chanName == "World")
|
||||
return;
|
||||
|
||||
|
||||
@@ -554,7 +554,7 @@ public:
|
||||
bool IsSafe(Player* player);
|
||||
bool IsSafe(WorldObject* obj);
|
||||
ChatChannelSource GetChatChannelSource(Player* bot, uint32 type, std::string channelName);
|
||||
|
||||
|
||||
bool CheckLocationDistanceByLevel(Player* player, const WorldLocation &loc, bool fromStartUp = false);
|
||||
|
||||
bool HasCheat(BotCheatMask mask)
|
||||
|
||||
@@ -1132,7 +1132,7 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
|
||||
{
|
||||
std::string g = genderArg;
|
||||
std::transform(g.begin(), g.end(), g.begin(), ::tolower);
|
||||
|
||||
|
||||
if (g == "male" || g == "0")
|
||||
gender = GENDER_MALE; // 0
|
||||
else if (g == "female" || g == "1")
|
||||
@@ -1155,7 +1155,7 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
|
||||
{
|
||||
// If the user requested a specific gender, skip any character that doesn't match.
|
||||
if (gender != -1 && GetOfflinePlayerGender(guid) != gender)
|
||||
continue;
|
||||
continue;
|
||||
if (botLoading.find(guid) != botLoading.end())
|
||||
continue;
|
||||
if (ObjectAccessor::FindConnectedPlayer(guid))
|
||||
|
||||
@@ -164,7 +164,7 @@ PlayerbotSecurityLevel PlayerbotSecurity::LevelFor(Player* from, DenyReason* rea
|
||||
|
||||
if (reason)
|
||||
*reason = PLAYERBOT_DENY_INVITE;
|
||||
|
||||
|
||||
return PLAYERBOT_SECURITY_INVITE;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
roundedTime = roundedTime.substr(0, roundedTime.find('.') + 2);
|
||||
|
||||
ChatHandler(player->GetSession()).SendSysMessage(
|
||||
"|cff00ff00Playerbots:|r bot initialization at server startup takes about '"
|
||||
"|cff00ff00Playerbots:|r bot initialization at server startup takes about '"
|
||||
+ roundedTime + "' minutes.");
|
||||
}
|
||||
}
|
||||
@@ -299,7 +299,7 @@ public:
|
||||
LOG_INFO("server.loading", "╚══════════════════════════════════════════════════════════╝");
|
||||
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
|
||||
LOG_INFO("server.loading", " ");
|
||||
LOG_INFO("server.loading", "Load Playerbots Config...");
|
||||
|
||||
|
||||
@@ -2360,7 +2360,7 @@ void RandomItemMgr::BuildPotionCache()
|
||||
(proto->SubClass != ITEM_SUBCLASS_POTION && proto->SubClass != ITEM_SUBCLASS_FLASK) ||
|
||||
proto->Bonding != NO_BIND)
|
||||
continue;
|
||||
|
||||
|
||||
uint32 requiredLevel = proto->RequiredLevel;
|
||||
if (requiredLevel > level || (level > 13 && requiredLevel < level - 13))
|
||||
continue;
|
||||
@@ -2374,10 +2374,10 @@ void RandomItemMgr::BuildPotionCache()
|
||||
if (proto->Duration & 0x80000000)
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
if (proto->AllowableClass != -1)
|
||||
continue;
|
||||
|
||||
|
||||
bool hybrid = false;
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(proto->Spells[0].SpellId);
|
||||
if (!spellInfo)
|
||||
|
||||
@@ -79,8 +79,8 @@ static const std::unordered_map<uint16, std::pair<CityId, FactionId>> bankerToCi
|
||||
{2996, {CityId::THUNDER_BLUFF, FactionId::HORDE}}, {8356, {CityId::THUNDER_BLUFF, FactionId::HORDE}}, {8357, {CityId::THUNDER_BLUFF, FactionId::HORDE}},
|
||||
{17631, {CityId::SILVERMOON_CITY, FactionId::HORDE}}, {17632, {CityId::SILVERMOON_CITY, FactionId::HORDE}}, {17633, {CityId::SILVERMOON_CITY, FactionId::HORDE}},
|
||||
{16615, {CityId::SILVERMOON_CITY, FactionId::HORDE}}, {16616, {CityId::SILVERMOON_CITY, FactionId::HORDE}}, {16617, {CityId::SILVERMOON_CITY, FactionId::HORDE}},
|
||||
{19246, {CityId::SHATTRATH_CITY, FactionId::NEUTRAL}}, {19338, {CityId::SHATTRATH_CITY, FactionId::NEUTRAL}},
|
||||
{19034, {CityId::SHATTRATH_CITY, FactionId::NEUTRAL}}, {19318, {CityId::SHATTRATH_CITY, FactionId::NEUTRAL}},
|
||||
{19246, {CityId::SHATTRATH_CITY, FactionId::NEUTRAL}}, {19338, {CityId::SHATTRATH_CITY, FactionId::NEUTRAL}},
|
||||
{19034, {CityId::SHATTRATH_CITY, FactionId::NEUTRAL}}, {19318, {CityId::SHATTRATH_CITY, FactionId::NEUTRAL}},
|
||||
{30604, {CityId::DALARAN, FactionId::NEUTRAL}}, {30605, {CityId::DALARAN, FactionId::NEUTRAL}}, {30607, {CityId::DALARAN, FactionId::NEUTRAL}},
|
||||
{28675, {CityId::DALARAN, FactionId::NEUTRAL}}, {28676, {CityId::DALARAN, FactionId::NEUTRAL}}, {28677, {CityId::DALARAN, FactionId::NEUTRAL}}
|
||||
};
|
||||
@@ -95,7 +95,7 @@ static const std::unordered_map<CityId, std::vector<uint16>> cityToBankers = {
|
||||
{CityId::UNDERCITY, {4549, 2459, 2458, 4550}},
|
||||
{CityId::THUNDER_BLUFF, {2996, 8356, 8357}},
|
||||
{CityId::SILVERMOON_CITY, {17631, 17632, 17633, 16615, 16616, 16617}},
|
||||
{CityId::SHATTRATH_CITY, {19246, 19338, 19034, 19318}},
|
||||
{CityId::SHATTRATH_CITY, {19246, 19338, 19034, 19318}},
|
||||
{CityId::DALARAN, {30604, 30605, 30607, 28675, 28676, 28677, 29530}}
|
||||
};
|
||||
|
||||
@@ -2190,7 +2190,7 @@ void RandomPlayerbotMgr::RandomTeleportForLevel(Player* bot)
|
||||
RandomTeleport(bot, fallbackLocs, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Collect valid cities based on bot faction.
|
||||
std::unordered_set<CityId> validBankerCities;
|
||||
for (auto& loc : bankerLocsPerLevelCache[level])
|
||||
|
||||
@@ -168,33 +168,33 @@ void PlayerbotFactory::Init()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(gemId);
|
||||
if (!proto)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (proto->ItemLevel < 60)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (proto->Flags & ITEM_FLAG_UNIQUE_EQUIPPABLE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (sRandomItemMgr->IsTestItem(gemId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (!sGemPropertiesStore.LookupEntry(proto->GemProperties))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// LOG_INFO("playerbots", "Add {} to enchantment gems", gemId);
|
||||
enchantGemIdCache.push_back(gemId);
|
||||
}
|
||||
@@ -736,7 +736,7 @@ void PlayerbotFactory::InitConsumables()
|
||||
int count = (int)item.second - (int)bot->GetItemCount(item.first);
|
||||
if (count > 0)
|
||||
StoreItem(item.first, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerbotFactory::InitPetTalents()
|
||||
@@ -1032,10 +1032,10 @@ void PlayerbotFactory::ClearSkills()
|
||||
}
|
||||
bot->SetUInt32Value(PLAYER_SKILL_INDEX(0), 0);
|
||||
bot->SetUInt32Value(PLAYER_SKILL_INDEX(1), 0);
|
||||
|
||||
|
||||
// unlearn default race/class skills
|
||||
if (PlayerInfo const* info = sObjectMgr->GetPlayerInfo(bot->getRace(), bot->getClass()))
|
||||
{
|
||||
{
|
||||
for (PlayerCreateInfoSkills::const_iterator itr = info->skills.begin(); itr != info->skills.end(); ++itr)
|
||||
{
|
||||
uint32 skillId = itr->SkillId;
|
||||
@@ -1043,7 +1043,7 @@ void PlayerbotFactory::ClearSkills()
|
||||
continue;
|
||||
bot->SetSkill(skillId, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerbotFactory::ClearEverything()
|
||||
@@ -1095,7 +1095,7 @@ void PlayerbotFactory::ResetQuests()
|
||||
uint32 entry = quest->GetQuestId();
|
||||
if (bot->GetQuestStatus(entry) == QUEST_STATUS_NONE)
|
||||
continue;
|
||||
|
||||
|
||||
bot->RemoveRewardedQuest(entry);
|
||||
bot->RemoveActiveQuest(entry, false);
|
||||
|
||||
@@ -1171,7 +1171,7 @@ void PlayerbotFactory::InitTalentsTree(bool increment /*false*/, bool use_templa
|
||||
|
||||
if (bot->GetFreeTalentPoints())
|
||||
InitTalents((specTab + 2) % 3);
|
||||
|
||||
|
||||
bot->SendTalentsInfoData(false);
|
||||
}
|
||||
|
||||
@@ -1704,7 +1704,7 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance)
|
||||
{
|
||||
if (incremental && !sPlayerbotAIConfig->incrementalGearInit)
|
||||
return;
|
||||
|
||||
|
||||
if (level < 5) {
|
||||
// original items
|
||||
if (CharStartOutfitEntry const* oEntry = GetCharStartOutfitEntry(bot->getRace(), bot->getClass(), bot->getGender()))
|
||||
@@ -1715,11 +1715,11 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance)
|
||||
continue;
|
||||
|
||||
uint32 itemId = oEntry->ItemId[j];
|
||||
|
||||
|
||||
// skip hearthstone
|
||||
if (itemId == 6948)
|
||||
continue;
|
||||
|
||||
|
||||
// just skip, reported in ObjectMgr::LoadItemTemplates
|
||||
ItemTemplate const* iProto = sObjectMgr->GetItemTemplate(itemId);
|
||||
if (!iProto)
|
||||
@@ -1743,10 +1743,10 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::unordered_map<uint8, std::vector<uint32>> items;
|
||||
// int tab = AiFactory::GetPlayerSpecTab(bot);
|
||||
|
||||
|
||||
uint32 blevel = bot->GetLevel();
|
||||
int32 delta = std::min(blevel, 10u);
|
||||
|
||||
@@ -1814,7 +1814,7 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance)
|
||||
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId);
|
||||
if (!proto)
|
||||
continue;
|
||||
|
||||
|
||||
bool shouldCheckGS = desiredQuality > ITEM_QUALITY_NORMAL;
|
||||
|
||||
if (shouldCheckGS && gearScoreLimit != 0 &&
|
||||
@@ -2923,7 +2923,7 @@ void PlayerbotFactory::InitQuests(std::list<uint32>& questMap, bool withRewardIt
|
||||
// set reward to 5 to skip majority quest reward
|
||||
uint32 reward = withRewardItem ? 0 : 5;
|
||||
bot->RewardQuest(quest, reward, bot, false);
|
||||
|
||||
|
||||
if (!withRewardItem)
|
||||
{
|
||||
// destroy the quest reward item
|
||||
@@ -3010,10 +3010,10 @@ void PlayerbotFactory::InitAmmo()
|
||||
// disable next expansion ammo
|
||||
if (sPlayerbotAIConfig->limitGearExpansion && bot->GetLevel() <= 60 && tEntry >= 23728)
|
||||
continue;
|
||||
|
||||
|
||||
if (sPlayerbotAIConfig->limitGearExpansion && bot->GetLevel() <= 70 && tEntry >= 35570)
|
||||
continue;
|
||||
|
||||
|
||||
entry = tEntry;
|
||||
break;
|
||||
}
|
||||
@@ -3177,7 +3177,7 @@ void PlayerbotFactory::InitPotions()
|
||||
|
||||
if (effect == SPELL_EFFECT_ENERGIZE && !bot->GetPower(POWER_MANA))
|
||||
continue;
|
||||
|
||||
|
||||
FindPotionVisitor visitor(bot, effect);
|
||||
IterateItems(&visitor);
|
||||
if (!visitor.GetResult().empty())
|
||||
@@ -3319,7 +3319,7 @@ void PlayerbotFactory::InitReagents()
|
||||
switch (bot->getClass())
|
||||
{
|
||||
case CLASS_DEATH_KNIGHT:
|
||||
if (level >= 56)
|
||||
if (level >= 56)
|
||||
items.push_back({37201, 40}); // Corpse Dust
|
||||
break;
|
||||
case CLASS_DRUID:
|
||||
@@ -4345,7 +4345,7 @@ void PlayerbotFactory::ApplyEnchantAndGemsNew(bool destoryOld)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (item->GetTemplate() && item->GetTemplate()->Quality < ITEM_QUALITY_UNCOMMON)
|
||||
continue;
|
||||
int32 bestEnchantId = -1;
|
||||
@@ -4661,12 +4661,12 @@ void PlayerbotFactory::InitKeyring()
|
||||
{
|
||||
if (!bot)
|
||||
return;
|
||||
|
||||
|
||||
if (bot->GetLevel() < 70)
|
||||
return;
|
||||
|
||||
ReputationMgr& repMgr = bot->GetReputationMgr(); // Reference, use . instead of ->
|
||||
|
||||
|
||||
std::vector<std::pair<uint32, uint32>> keysToCheck;
|
||||
|
||||
// Reputation-based Keys (Honored requirement)
|
||||
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
void InitKeyring();
|
||||
void InitReputation();
|
||||
void InitAttunementQuests();
|
||||
|
||||
|
||||
private:
|
||||
void Prepare();
|
||||
// void InitSecondEquipmentSet();
|
||||
|
||||
@@ -571,7 +571,7 @@ void StatsWeightCalculator::CalculateItemTypePenalty(ItemTemplate const* proto)
|
||||
{
|
||||
weight_ *= 0.1;
|
||||
}
|
||||
|
||||
|
||||
if (lvl >= 10 && cls == CLASS_ROGUE && (tab == ROGUE_TAB_ASSASSINATION || tab == ROGUE_TAB_SUBTLETY) &&
|
||||
proto->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
|
||||
{
|
||||
|
||||
@@ -30,16 +30,16 @@ public:
|
||||
void Reset();
|
||||
float CalculateItem(uint32 itemId, int32 randomPropertyId = 0);
|
||||
float CalculateEnchant(uint32 enchantId);
|
||||
|
||||
|
||||
void SetOverflowPenalty(bool apply) { enable_overflow_penalty_ = apply; }
|
||||
void SetItemSetBonus(bool apply) { enable_item_set_bonus_ = apply; }
|
||||
void SetQualityBlend(bool apply) { enable_quality_blend_ = apply; }
|
||||
|
||||
|
||||
private:
|
||||
void GenerateWeights(Player* player);
|
||||
void GenerateBasicWeights(Player* player);
|
||||
void GenerateAdditionalWeights(Player* player);
|
||||
|
||||
|
||||
void CalculateRandomProperty(int32 randomPropertyId, uint32 itemId);
|
||||
void CalculateItemSetMod(Player* player, ItemTemplate const* proto);
|
||||
void CalculateSocketBonus(Player* player, ItemTemplate const* proto);
|
||||
|
||||
@@ -88,7 +88,7 @@ Engine::~Engine(void)
|
||||
void Engine::Reset()
|
||||
{
|
||||
strategyTypeMask = 0;
|
||||
|
||||
|
||||
ActionNode* action = nullptr;
|
||||
|
||||
while ((action = queue.Pop()) != nullptr)
|
||||
@@ -154,7 +154,7 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal)
|
||||
|
||||
uint32 iterations = 0;
|
||||
uint32 iterationsPerTick = queue.Size() * (minimal ? 2 : sPlayerbotAIConfig->iterationsPerTick);
|
||||
|
||||
|
||||
while (++iterations <= iterationsPerTick)
|
||||
{
|
||||
basket = queue.Peek();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
/**
|
||||
* @class Queue
|
||||
* @brief Manages a priority queue of actions for the playerbot system
|
||||
*
|
||||
*
|
||||
* This queue maintains a list of ActionBasket objects, each containing an action
|
||||
* and its relevance score. Actions with higher relevance scores are prioritized.
|
||||
*/
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
/**
|
||||
* @brief Adds an action to the queue or updates existing action's relevance
|
||||
* @param action Pointer to the ActionBasket to be added
|
||||
*
|
||||
*
|
||||
* If an action with the same name exists, updates its relevance if the new
|
||||
* relevance is higher, then deletes the new action. Otherwise, adds the new
|
||||
* action to the queue.
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
/**
|
||||
* @brief Removes and returns the action with highest relevance
|
||||
* @return Pointer to the highest relevance ActionNode, or nullptr if queue is empty
|
||||
*
|
||||
*
|
||||
* Ownership of the returned ActionNode is transferred to the caller.
|
||||
* The associated ActionBasket is deleted.
|
||||
*/
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Removes and deletes expired actions from the queue
|
||||
*
|
||||
*
|
||||
* Uses sPlayerbotAIConfig->expireActionTime to determine if actions have expired.
|
||||
* Both the ActionNode and ActionBasket are deleted for expired actions.
|
||||
*/
|
||||
|
||||
@@ -55,11 +55,11 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
|
||||
{
|
||||
Unit* oldTarget = context->GetValue<Unit*>("current target")->Get();
|
||||
bool shouldMelee = bot->IsWithinMeleeRange(target) || botAI->IsMelee(bot);
|
||||
|
||||
|
||||
bool sameTarget = oldTarget == target && bot->GetVictim() == target;
|
||||
bool inCombat = botAI->GetState() == BOT_STATE_COMBAT;
|
||||
bool sameAttackMode = bot->HasUnitState(UNIT_STATE_MELEE_ATTACKING) == shouldMelee;
|
||||
|
||||
|
||||
if (bot->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE ||
|
||||
bot->HasUnitState(UNIT_STATE_IN_FLIGHT))
|
||||
{
|
||||
@@ -84,7 +84,7 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((sPlayerbotAIConfig->IsInPvpProhibitedZone(bot->GetZoneId()) ||
|
||||
if ((sPlayerbotAIConfig->IsInPvpProhibitedZone(bot->GetZoneId()) ||
|
||||
sPlayerbotAIConfig->IsInPvpProhibitedArea(bot->GetAreaId()))
|
||||
&& (target->IsPlayer() || target->IsPet()))
|
||||
{
|
||||
@@ -158,7 +158,7 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
|
||||
sServerFacade->SetFacingTo(bot, target);
|
||||
}
|
||||
botAI->ChangeEngine(BOT_STATE_COMBAT);
|
||||
|
||||
|
||||
bot->Attack(target, shouldMelee);
|
||||
/* prevent pet dead immediately in group */
|
||||
// if (bot->GetMap()->IsDungeon() && bot->GetGroup() && !target->IsInCombat()) {
|
||||
|
||||
@@ -158,7 +158,7 @@ void AutoMaintenanceOnLevelupAction::AutoUpgradeEquip()
|
||||
{
|
||||
if (!sPlayerbotAIConfig->autoUpgradeEquip || !sRandomPlayerbotMgr->IsRandomBot(bot))
|
||||
return;
|
||||
|
||||
|
||||
PlayerbotFactory factory(bot, bot->GetLevel());
|
||||
|
||||
// Clean up old consumables before adding new ones
|
||||
|
||||
@@ -543,7 +543,7 @@ bool BGJoinAction::JoinQueue(uint32 type)
|
||||
}
|
||||
|
||||
botAI->GetAiObjectContext()->GetValue<uint32>("bg type")->Set(0);
|
||||
|
||||
|
||||
if (!isArena)
|
||||
{
|
||||
WorldPacket* packet = new WorldPacket(CMSG_BATTLEMASTER_JOIN, 20);
|
||||
|
||||
@@ -2903,7 +2903,7 @@ bool BGTactics::selectObjective(bool reset)
|
||||
{
|
||||
// just make bot stay where it is if already close
|
||||
// (stops them shifting around between the random spots)
|
||||
if (bot->GetDistance(IC_GATE_ATTACK_POS_HORDE) < 8.0f)
|
||||
if (bot->GetDistance(IC_GATE_ATTACK_POS_HORDE) < 8.0f)
|
||||
pos.Set(bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), bot->GetMapId());
|
||||
else
|
||||
pos.Set(IC_GATE_ATTACK_POS_HORDE.GetPositionX() + frand(-5.0f, +5.0f),
|
||||
@@ -3213,7 +3213,7 @@ bool BGTactics::moveToObjective(bool ignoreDist)
|
||||
// sServerFacade->GetDistance2d(bot, pos.x, pos.y); bot->Say(out.str(), LANG_UNIVERSAL);
|
||||
|
||||
// dont increase from 1.5 will cause bugs with horde capping AV towers
|
||||
return MoveNear(bot->GetMapId(), pos.x, pos.y, pos.z, 1.5f);
|
||||
return MoveNear(bot->GetMapId(), pos.x, pos.y, pos.z, 1.5f);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -3549,14 +3549,14 @@ bool BGTactics::startNewPathFree(std::vector<BattleBotPath*> const& vPaths)
|
||||
|
||||
/**
|
||||
* @brief Handles flag/base capturing gameplay in battlegrounds
|
||||
*
|
||||
*
|
||||
* This function manages the logic for capturing flags and bases in various battlegrounds.
|
||||
* It handles:
|
||||
* - Enemy detection and combat near objectives
|
||||
* - Coordination with friendly players who are capturing
|
||||
* - Different capture mechanics for each battleground type
|
||||
* - Proper positioning and movement
|
||||
*
|
||||
*
|
||||
* @param vPaths Vector of possible paths the bot can take
|
||||
* @param vFlagIds Vector of flag/base GameObjects that can be captured
|
||||
* @return true if handling a flag/base action, false otherwise
|
||||
@@ -3687,7 +3687,7 @@ bool BGTactics::atFlag(std::vector<BattleBotPath*> const& vPaths, std::vector<ui
|
||||
float y = bot->GetPositionY() + 5.0f * sin(angle);
|
||||
MoveTo(bot->GetMapId(), x, y, bot->GetPositionZ());
|
||||
}
|
||||
|
||||
|
||||
// Reset objective and take new path for defending
|
||||
resetObjective();
|
||||
if (!startNewPathBegin(vPaths))
|
||||
@@ -3895,7 +3895,7 @@ bool BGTactics::protectFC()
|
||||
float fcY = teamFC->GetPositionY();
|
||||
float fcZ = teamFC->GetPositionZ();
|
||||
uint32 mapId = bot->GetMapId();
|
||||
|
||||
|
||||
return MoveNear(mapId, fcX, fcY, fcZ, 5.0f, MovementPriority::MOVEMENT_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,14 +67,14 @@ bool BuyAction::Execute(Event event)
|
||||
calculator.SetOverflowPenalty(false);
|
||||
|
||||
std::sort(m_items_sorted.begin(), m_items_sorted.end(),
|
||||
[&calculator](VendorItem* i, VendorItem* j)
|
||||
[&calculator](VendorItem* i, VendorItem* j)
|
||||
{
|
||||
ItemTemplate const* item1 = sObjectMgr->GetItemTemplate(i->item);
|
||||
ItemTemplate const* item2 = sObjectMgr->GetItemTemplate(j->item);
|
||||
|
||||
|
||||
if (!item1 || !item2)
|
||||
return false;
|
||||
|
||||
|
||||
float score1 = calculator.CalculateItem(item1->ItemId);
|
||||
float score2 = calculator.CalculateItem(item2->ItemId);
|
||||
|
||||
@@ -88,19 +88,19 @@ bool BuyAction::Execute(Event event)
|
||||
});
|
||||
|
||||
std::unordered_map<uint32, float> bestPurchasedItemScore; // Track best item score per InventoryType
|
||||
|
||||
|
||||
for (auto& tItem : m_items_sorted)
|
||||
{
|
||||
uint32 maxPurchases = 1; // Default to buying once
|
||||
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(tItem->item);
|
||||
if (!proto)
|
||||
continue;
|
||||
|
||||
|
||||
if (proto->Class == ITEM_CLASS_CONSUMABLE || proto->Class == ITEM_CLASS_PROJECTILE)
|
||||
{
|
||||
maxPurchases = 10; // Allow up to 10 purchases if it's a consumable or projectile
|
||||
}
|
||||
|
||||
|
||||
for (uint32 i = 0; i < maxPurchases; i++)
|
||||
{
|
||||
ItemUsage usage = AI_VALUE2(ItemUsage, "item usage", tItem->item);
|
||||
|
||||
@@ -47,10 +47,10 @@ bool CastCustomSpellAction::Execute(Event event)
|
||||
{
|
||||
if (!target)
|
||||
target = botAI->GetUnit(go);
|
||||
|
||||
|
||||
if (!botAI->GetUnit(go) || !botAI->GetUnit(go)->IsInWorld())
|
||||
continue;
|
||||
|
||||
|
||||
chat->eraseAllSubStr(text, chat->FormatWorldobject(botAI->GetUnit(go)));
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "PlayerbotFactory.h"
|
||||
#include "Playerbots.h"
|
||||
#include "AiObjectContext.h"
|
||||
#include "Log.h"
|
||||
#include "Log.h"
|
||||
|
||||
bool ChangeTalentsAction::Execute(Event event)
|
||||
{
|
||||
|
||||
@@ -66,7 +66,7 @@ bool CheckMountStateAction::isUseful()
|
||||
|
||||
// Get shapeshift states, only applicable when there's a master
|
||||
if (master)
|
||||
{
|
||||
{
|
||||
botInShapeshiftForm = bot->GetShapeshiftForm();
|
||||
masterInShapeshiftForm = master->GetShapeshiftForm();
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ bool ChooseRpgTargetAction::Execute(Event event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if (possiblePlayers.size() > 200 || HasSameTarget(guidP, urand(5, 15), possiblePlayers))
|
||||
// continue;
|
||||
|
||||
|
||||
@@ -86,11 +86,11 @@ bool DropTargetAction::Execute(Event event)
|
||||
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
|
||||
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();
|
||||
|
||||
// if (Pet* pet = bot->GetPet())
|
||||
|
||||
@@ -16,7 +16,7 @@ bool ChooseTravelTargetAction::Execute(Event event)
|
||||
//Get the current travel target. This target is no longer active.
|
||||
TravelTarget* oldTarget = context->GetValue<TravelTarget*>("travel target")->Get();
|
||||
|
||||
//Select a new target to travel to.
|
||||
//Select a new target to travel to.
|
||||
TravelTarget newTarget = TravelTarget(botAI);
|
||||
|
||||
if (!oldTarget) return false;
|
||||
@@ -146,7 +146,7 @@ void ChooseTravelTargetAction::getNewTarget(TravelTarget* newTarget, TravelTarge
|
||||
foundTarget = SetBossTarget(newTarget);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Do quests (start, do, end) 95% chance
|
||||
if (!foundTarget && urand(1, 100) > 5)
|
||||
{
|
||||
|
||||
@@ -110,7 +110,7 @@ void EquipAction::EquipItem(Item* item)
|
||||
WorldPackets::Item::AutoEquipItemSlot nicePacket(std::move(packet));
|
||||
nicePacket.Read();
|
||||
bot->GetSession()->HandleAutoEquipItemSlotOpcode(nicePacket);
|
||||
|
||||
|
||||
std::ostringstream out;
|
||||
out << "Equipping " << chat->FormatItem(itemProto) << " in ranged slot";
|
||||
botAI->TellMaster(out);
|
||||
@@ -123,7 +123,7 @@ void EquipAction::EquipItem(Item* item)
|
||||
bool isWeapon = (itemProto->Class == ITEM_CLASS_WEAPON);
|
||||
bool canTitanGrip = bot->CanTitanGrip();
|
||||
bool canDualWield = bot->CanDualWield();
|
||||
|
||||
|
||||
bool isTwoHander = (invType == INVTYPE_2HWEAPON);
|
||||
bool isValidTGWeapon = false;
|
||||
if (canTitanGrip && isTwoHander)
|
||||
@@ -208,24 +208,24 @@ void EquipAction::EquipItem(Item* item)
|
||||
nicePacket.Read();
|
||||
bot->GetSession()->HandleAutoEquipItemSlotOpcode(nicePacket);
|
||||
}
|
||||
|
||||
|
||||
// Try moving old main hand weapon to offhand if beneficial
|
||||
if (mainHandItem && mainHandCanGoOff && (!offHandItem || mainHandScore > offHandScore))
|
||||
{
|
||||
const ItemTemplate* oldMHProto = mainHandItem->GetTemplate();
|
||||
|
||||
|
||||
WorldPacket offhandPacket(CMSG_AUTOEQUIP_ITEM_SLOT, 2);
|
||||
ObjectGuid oldMHGuid = mainHandItem->GetGUID();
|
||||
offhandPacket << oldMHGuid << uint8(EQUIPMENT_SLOT_OFFHAND);
|
||||
WorldPackets::Item::AutoEquipItemSlot nicePacket(std::move(offhandPacket));
|
||||
nicePacket.Read();
|
||||
bot->GetSession()->HandleAutoEquipItemSlotOpcode(nicePacket);
|
||||
|
||||
|
||||
std::ostringstream moveMsg;
|
||||
moveMsg << "Main hand upgrade found. Moving " << chat->FormatItem(oldMHProto) << " to offhand";
|
||||
botAI->TellMaster(moveMsg);
|
||||
}
|
||||
|
||||
|
||||
std::ostringstream out;
|
||||
out << "Equipping " << chat->FormatItem(itemProto) << " in main hand";
|
||||
botAI->TellMaster(out);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "SpellMgr.h"
|
||||
#include "DBCStores.h"
|
||||
#include "AiObjectContext.h"
|
||||
#include "Log.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <sstream>
|
||||
@@ -154,6 +154,6 @@ bool EquipGlyphsAction::Execute(Event event)
|
||||
// Flag for custom glyphs
|
||||
botAI->GetAiObjectContext()->GetValue<bool>("custom_glyphs")->Set(true);
|
||||
LOG_INFO("playerbots", "Custom Glyph Flag set to ON");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -30,13 +30,13 @@ bool FollowAction::Execute(Event event)
|
||||
WorldLocation loc = formation->GetLocation();
|
||||
if (Formation::IsNullLocation(loc) || loc.GetMapId() == -1)
|
||||
return false;
|
||||
|
||||
|
||||
MovementPriority priority = botAI->GetState() == BOT_STATE_COMBAT ? MovementPriority::MOVEMENT_COMBAT : MovementPriority::MOVEMENT_NORMAL;
|
||||
moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), false, false, false,
|
||||
true, priority, true);
|
||||
}
|
||||
|
||||
// This section has been commented out because it was forcing the pet to
|
||||
// This section has been commented out because it was forcing the pet to
|
||||
// follow the bot on every "follow" action tick, overriding any attack or
|
||||
// stay commands that might have been issued by the player.
|
||||
// if (Pet* pet = bot->GetPet())
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* 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 "GenericBuffUtils.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace ai::buff
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return castName;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -243,7 +243,7 @@ bool BuffOnPartyAction::Execute(Event event)
|
||||
return botAI->CastSpell(castName, GetTarget());
|
||||
}
|
||||
// End greater buff fix
|
||||
|
||||
|
||||
CastShootAction::CastShootAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "shoot")
|
||||
{
|
||||
if (Item* const pItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
|
||||
@@ -322,14 +322,14 @@ bool CastVehicleSpellAction::Execute(Event event)
|
||||
bool UseTrinketAction::Execute(Event event)
|
||||
{
|
||||
Item* trinket1 = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_TRINKET1);
|
||||
|
||||
|
||||
if (trinket1 && UseTrinket(trinket1))
|
||||
return true;
|
||||
|
||||
Item* trinket2 = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_TRINKET2);
|
||||
if (trinket2 && UseTrinket(trinket2))
|
||||
return true;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -359,7 +359,7 @@ bool UseTrinketAction::UseTrinket(Item* item)
|
||||
|
||||
if (!spellInfo || !spellInfo->IsPositive())
|
||||
return false;
|
||||
|
||||
|
||||
bool applyAura = false;
|
||||
for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
|
||||
{
|
||||
@@ -369,12 +369,12 @@ bool UseTrinketAction::UseTrinket(Item* item)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!applyAura)
|
||||
return false;
|
||||
|
||||
|
||||
uint32 spellProcFlag = spellInfo->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
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
|
||||
NextAction** getPrerequisites() override;
|
||||
std::string const getSpell() { return spell; }
|
||||
|
||||
|
||||
protected:
|
||||
std::string spell;
|
||||
float range;
|
||||
|
||||
@@ -209,7 +209,7 @@ bool GuildManageNearbyAction::Execute(Event event)
|
||||
if (botAi->GetGuilderType() == GuilderType::SOLO && !botAi->HasRealPlayerMaster()) //Do not invite solo players.
|
||||
continue;
|
||||
|
||||
if (botAi->HasActivePlayerMaster() && !sRandomPlayerbotMgr->IsRandomBot(player)) //Do not invite alts of active players.
|
||||
if (botAi->HasActivePlayerMaster() && !sRandomPlayerbotMgr->IsRandomBot(player)) //Do not invite alts of active players.
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ bool PartyCommandAction::Execute(Event event)
|
||||
Player* master = GetMaster();
|
||||
if (master && member == master->GetName())
|
||||
return Leave(bot);
|
||||
|
||||
|
||||
botAI->Reset();
|
||||
|
||||
return false;
|
||||
@@ -64,7 +64,7 @@ bool UninviteAction::Execute(Event event)
|
||||
if (bot->GetGUID() == guid)
|
||||
return Leave(bot);
|
||||
}
|
||||
|
||||
|
||||
botAI->Reset();
|
||||
|
||||
return false;
|
||||
@@ -162,7 +162,7 @@ bool LeaveFarAwayAction::isUseful()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
botAI->Reset();
|
||||
|
||||
return false;
|
||||
|
||||
@@ -151,7 +151,7 @@ bool LfgJoinAction::JoinLFG()
|
||||
|
||||
// Set RbotAId Browser comment
|
||||
std::string const _gs = std::to_string(botAI->GetEquipGearScore(bot/*, false, false*/));
|
||||
|
||||
|
||||
// JoinLfg is not threadsafe, so make packet and queue into session
|
||||
// sLFGMgr->JoinLfg(bot, roleMask, list, _gs);
|
||||
|
||||
@@ -180,7 +180,7 @@ bool LfgRoleCheckAction::Execute(Event event)
|
||||
// if (currentRoles == newRoles)
|
||||
// return false;
|
||||
|
||||
|
||||
|
||||
WorldPacket* packet = new WorldPacket(CMSG_LFG_SET_ROLES);
|
||||
*packet << (uint8)newRoles;
|
||||
bot->GetSession()->QueuePacket(packet);
|
||||
@@ -317,7 +317,7 @@ bool LfgJoinAction::isUseful()
|
||||
|
||||
if (bot->GetLevel() < 15)
|
||||
return false;
|
||||
|
||||
|
||||
// don't use if active player master
|
||||
if (GET_PLAYERBOT_AI(bot)->IsRealPlayer())
|
||||
return false;
|
||||
|
||||
@@ -139,17 +139,17 @@ std::vector<std::pair<uint32, std::string>> ListSpellsAction::GetSpellList(std::
|
||||
{
|
||||
if (itr->second->State == PLAYERSPELL_REMOVED || !itr->second->Active)
|
||||
continue;
|
||||
|
||||
|
||||
if (!(itr->second->specMask & bot->GetActiveSpecMask()))
|
||||
continue;
|
||||
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
|
||||
if (!spellInfo)
|
||||
continue;
|
||||
|
||||
|
||||
if (spellInfo->IsPassive())
|
||||
continue;
|
||||
|
||||
|
||||
SkillLineAbilityEntry const* skillLine = skillSpells[itr->first];
|
||||
if (skill != SKILL_NONE && (!skillLine || skillLine->SkillLine != skill))
|
||||
continue;
|
||||
@@ -273,7 +273,7 @@ std::vector<std::pair<uint32, std::string>> ListSpellsAction::GetSpellList(std::
|
||||
|
||||
if (out.str().empty())
|
||||
continue;
|
||||
|
||||
|
||||
if (itr->first == 0)
|
||||
{
|
||||
LOG_ERROR("playerbots", "?! {}", itr->first);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "BroadcastHelper.h"
|
||||
|
||||
bool LootAction::Execute(Event /*event*/)
|
||||
{
|
||||
{
|
||||
if (!AI_VALUE(bool, "has available loot"))
|
||||
return false;
|
||||
|
||||
@@ -156,7 +156,7 @@ bool OpenLootAction::DoLoot(LootObject& lootObject)
|
||||
uint32 spellId = GetOpeningSpell(lootObject);
|
||||
if (!spellId)
|
||||
return false;
|
||||
|
||||
|
||||
return botAI->CastSpell(spellId, bot);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ bool LootRollAction::Execute(Event event)
|
||||
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId);
|
||||
if (!proto)
|
||||
continue;
|
||||
|
||||
|
||||
std::string itemUsageParam;
|
||||
if (randomProperty != 0) {
|
||||
itemUsageParam = std::to_string(itemId) + "," + std::to_string(randomProperty);
|
||||
@@ -47,7 +47,7 @@ bool LootRollAction::Execute(Event event)
|
||||
itemUsageParam = std::to_string(itemId);
|
||||
}
|
||||
ItemUsage usage = AI_VALUE2(ItemUsage, "item usage", itemUsageParam);
|
||||
|
||||
|
||||
// Armor Tokens are classed as MISC JUNK (Class 15, Subclass 0), luckily no other items I found have class bits and epic quality.
|
||||
if (proto->Class == ITEM_CLASS_MISC && proto->SubClass == ITEM_SUBCLASS_JUNK && proto->Quality == ITEM_QUALITY_EPIC)
|
||||
{
|
||||
@@ -93,7 +93,7 @@ bool LootRollAction::Execute(Event event)
|
||||
{
|
||||
vote = PASS;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
vote = GREED;
|
||||
}
|
||||
@@ -228,7 +228,7 @@ bool RollUniqueCheck(ItemTemplate const* proto, Player* bot)
|
||||
bool RollAction::Execute(Event event)
|
||||
{
|
||||
std::string link = event.getParam();
|
||||
|
||||
|
||||
if (link.empty())
|
||||
{
|
||||
bot->DoRandomRoll(0,100);
|
||||
@@ -245,7 +245,7 @@ bool RollAction::Execute(Event event)
|
||||
}
|
||||
std::string itemUsageParam;
|
||||
itemUsageParam = std::to_string(itemId);
|
||||
|
||||
|
||||
ItemUsage usage = AI_VALUE2(ItemUsage, "item usage", itemUsageParam);
|
||||
switch (proto->Class)
|
||||
{
|
||||
|
||||
@@ -1040,7 +1040,7 @@ void MovementAction::UpdateMovementState()
|
||||
|
||||
// Save current state for the next check
|
||||
wasMovementRestricted = isCurrentlyRestricted;
|
||||
|
||||
|
||||
// Temporary speed increase in group
|
||||
// if (botAI->HasRealPlayerMaster()) {
|
||||
// bot->SetSpeedRate(MOVE_RUN, 1.1f);
|
||||
@@ -2412,7 +2412,7 @@ bool TankFaceAction::Execute(Event event)
|
||||
|
||||
if (!AI_VALUE2(bool, "has aggro", "current target"))
|
||||
return false;
|
||||
|
||||
|
||||
float averageAngle = AverageGroupAngle(target, true);
|
||||
|
||||
if (averageAngle == 0.0f)
|
||||
@@ -2435,7 +2435,7 @@ bool TankFaceAction::Execute(Event event)
|
||||
std::vector<Position> availablePos;
|
||||
float x, y, z;
|
||||
target->GetNearPoint(bot, x, y, z, 0.0f, dist, goodAngle1);
|
||||
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
||||
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
||||
x, y, z))
|
||||
{
|
||||
/// @todo: movement control now is a mess, prepare to rewrite
|
||||
@@ -2448,7 +2448,7 @@ bool TankFaceAction::Execute(Event event)
|
||||
}
|
||||
}
|
||||
target->GetNearPoint(bot, x, y, z, 0.0f, dist, goodAngle2);
|
||||
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
||||
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
||||
x, y, z))
|
||||
{
|
||||
std::list<FleeInfo>& infoList = AI_VALUE(std::list<FleeInfo>&, "recently flee info");
|
||||
@@ -2500,7 +2500,7 @@ bool RearFlankAction::Execute(Event event)
|
||||
{
|
||||
destination = &rightFlank;
|
||||
}
|
||||
|
||||
|
||||
return MoveTo(bot->GetMapId(), destination->GetPositionX(), destination->GetPositionY(), destination->GetPositionZ(),
|
||||
false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
@@ -2666,7 +2666,7 @@ bool SetBehindTargetAction::Execute(Event event)
|
||||
std::vector<Position> availablePos;
|
||||
float x, y, z;
|
||||
target->GetNearPoint(bot, x, y, z, 0.0f, dist, goodAngle1);
|
||||
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
||||
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
||||
x, y, z))
|
||||
{
|
||||
/// @todo: movement control now is a mess, prepare to rewrite
|
||||
@@ -2679,7 +2679,7 @@ bool SetBehindTargetAction::Execute(Event event)
|
||||
}
|
||||
}
|
||||
target->GetNearPoint(bot, x, y, z, 0.0f, dist, goodAngle2);
|
||||
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
||||
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
||||
x, y, z))
|
||||
{
|
||||
std::list<FleeInfo>& infoList = AI_VALUE(std::list<FleeInfo>&, "recently flee info");
|
||||
|
||||
@@ -186,7 +186,7 @@ void OutfitAction::Update(std::string const name)
|
||||
{
|
||||
ListItemsVisitor visitor;
|
||||
IterateItems(&visitor, ITERATE_ITEMS_IN_EQUIP);
|
||||
|
||||
|
||||
ItemIds items;
|
||||
for (std::map<uint32, uint32>::iterator i = visitor.items.begin(); i != visitor.items.end(); ++i)
|
||||
items.insert(i->first);
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
|
||||
private:
|
||||
bool warningEnabled = true;
|
||||
std::string defaultCmd;
|
||||
std::string defaultCmd;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -113,7 +113,7 @@ bool QueryQuestAction::Execute(Event event)
|
||||
void QueryQuestAction::TellObjectives(uint32 questId)
|
||||
{
|
||||
Quest const* questTemplate = sObjectMgr->GetQuestTemplate(questId);
|
||||
|
||||
|
||||
// Checks if the questTemplate is valid
|
||||
if (!questTemplate)
|
||||
{
|
||||
|
||||
@@ -278,7 +278,7 @@ bool QuestUpdateCompleteAction::Execute(Event event)
|
||||
{
|
||||
// std::map<std::string, std::string> placeholders;
|
||||
// placeholders["%quest_link"] = format;
|
||||
|
||||
|
||||
// if (botAI->HasStrategy("debug quest", BotState::BOT_STATE_NON_COMBAT) || botAI->HasStrategy("debug rpg", BotState::BOT_STATE_COMBAT))
|
||||
// {
|
||||
// LOG_INFO("playerbots", "{} => Quest [ {} ] completed", bot->GetName(), qInfo->GetTitle());
|
||||
@@ -338,7 +338,7 @@ bool QuestUpdateAddKillAction::Execute(Event event)
|
||||
botAI->TellMasterNoFacing(out.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ bool QuestUpdateAddItemAction::Execute(Event event)
|
||||
|
||||
BroadcastHelper::BroadcastQuestUpdateAddItem(botAI, bot, pair.first, availableItemsCount, requiredItemsCount, itemPrototype);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -390,7 +390,7 @@ bool QuestItemPushResultAction::Execute(Event event)
|
||||
|
||||
if (guid != bot->GetGUID())
|
||||
return false;
|
||||
|
||||
|
||||
const ItemTemplate* proto = sObjectMgr->GetItemTemplate(itemEntry);
|
||||
if (!proto)
|
||||
return false;
|
||||
@@ -406,13 +406,13 @@ bool QuestItemPushResultAction::Execute(Event event)
|
||||
return false;
|
||||
|
||||
const QuestStatusData& q_status = bot->getQuestStatusMap().at(questId);
|
||||
|
||||
|
||||
for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; i++)
|
||||
{
|
||||
uint32 itemId = quest->RequiredItemId[i];
|
||||
if (!itemId)
|
||||
continue;
|
||||
|
||||
|
||||
int32 previousCount = itemCount - count;
|
||||
if (itemId == itemEntry && previousCount < quest->RequiredItemCount[i])
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@ bool ReleaseSpiritAction::Execute(Event event)
|
||||
{
|
||||
if (bot->IsAlive())
|
||||
{
|
||||
if (!bot->InBattleground())
|
||||
if (!bot->InBattleground())
|
||||
{
|
||||
botAI->TellMasterNoFacing("I am not dead, will wait here");
|
||||
// -follow in bg is overwriten each tick with +follow
|
||||
@@ -38,8 +38,8 @@ bool ReleaseSpiritAction::Execute(Event event)
|
||||
}
|
||||
|
||||
const WorldPacket& packet = event.getPacket();
|
||||
const std::string message = !packet.empty() && packet.GetOpcode() == CMSG_REPOP_REQUEST
|
||||
? "Releasing..."
|
||||
const std::string message = !packet.empty() && packet.GetOpcode() == CMSG_REPOP_REQUEST
|
||||
? "Releasing..."
|
||||
: "Meet me at the graveyard";
|
||||
botAI->TellMasterNoFacing(message);
|
||||
|
||||
@@ -89,7 +89,7 @@ bool AutoReleaseSpiritAction::Execute(Event event)
|
||||
bot->GetSession()->HandleRepopRequestOpcode(packet);
|
||||
|
||||
LogRelease("releases spirit", true);
|
||||
|
||||
|
||||
if (bot->InBattleground())
|
||||
{
|
||||
return HandleBattlegroundSpiritHealer();
|
||||
@@ -117,8 +117,8 @@ bool AutoReleaseSpiritAction::HandleBattlegroundSpiritHealer()
|
||||
{
|
||||
constexpr uint32_t RESURRECT_DELAY = 15;
|
||||
const time_t now = time(nullptr);
|
||||
|
||||
if ((now - m_bgGossipTime < RESURRECT_DELAY) &&
|
||||
|
||||
if ((now - m_bgGossipTime < RESURRECT_DELAY) &&
|
||||
bot->HasAura(SPELL_WAITING_FOR_RESURRECT))
|
||||
{
|
||||
return false;
|
||||
@@ -174,9 +174,9 @@ bool AutoReleaseSpiritAction::ShouldAutoRelease() const
|
||||
if (!botAI->HasActivePlayerMaster())
|
||||
return true;
|
||||
|
||||
if (botAI->HasActivePlayerMaster() &&
|
||||
if (botAI->HasActivePlayerMaster() &&
|
||||
groupMaster->GetMapId() == bot->GetMapId() &&
|
||||
bot->GetMap() &&
|
||||
bot->GetMap() &&
|
||||
(bot->GetMap()->IsRaid() || bot->GetMap()->IsDungeon()))
|
||||
{
|
||||
return false;
|
||||
@@ -218,7 +218,7 @@ bool AutoReleaseSpiritAction::ShouldDelayBattlegroundRelease() const
|
||||
bool RepopAction::Execute(Event event)
|
||||
{
|
||||
const GraveyardStruct* graveyard = GetGrave(
|
||||
AI_VALUE(uint32, "death count") > 10 ||
|
||||
AI_VALUE(uint32, "death count") > 10 ||
|
||||
CalculateDeadTime() > 30 * MINUTE
|
||||
);
|
||||
|
||||
@@ -238,7 +238,7 @@ int64 RepopAction::CalculateDeadTime() const
|
||||
{
|
||||
if (Corpse* corpse = bot->GetCorpse())
|
||||
return time(nullptr) - corpse->GetGhostTime();
|
||||
|
||||
|
||||
return bot->isDead() ? 0 : 60 * MINUTE;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ protected:
|
||||
void toxicLinks();
|
||||
void somethingToxic();
|
||||
void thunderfury();
|
||||
|
||||
|
||||
std::vector<uint32> GetIncompletedQuests();
|
||||
|
||||
private:
|
||||
|
||||
@@ -102,7 +102,7 @@ void TalkToQuestGiverAction::RewardNoItem(Quest const* quest, Object* questGiver
|
||||
{
|
||||
std::map<std::string, std::string> args;
|
||||
args["%quest"] = chat->FormatQuest(quest);
|
||||
|
||||
|
||||
if (bot->CanRewardQuest(quest, false))
|
||||
{
|
||||
out << BOT_TEXT2("quest_status_completed", args);
|
||||
|
||||
@@ -13,13 +13,13 @@ bool TeleportAction::Execute(Event event)
|
||||
{
|
||||
/*
|
||||
// List of allowed portal entries (you can populate this dynamically)
|
||||
std::vector<uint32> allowedPortals = {
|
||||
187055, 195142, 195141, 201797, 202079, 194481, 195682, 191164, 176498, 182351,
|
||||
178404, 176497, 181146, 184605, 176499, 195140, 193948, 193427, 193052, 193206,
|
||||
192786, 184594, 183384, 182352, 184604, 189994, 193053, 193207, 193956, 195139,
|
||||
176296, 194011, 194012, 189993, 176500, 176501, 193955, 193425, 193772, 193604,
|
||||
191006, 191007, 191008, 191009, 191013, 191014, 191010, 190960, 191011, 191012,
|
||||
183317, 183321, 183322, 187056, 183323, 183324, 183325, 183326, 183327, 190203,
|
||||
std::vector<uint32> allowedPortals = {
|
||||
187055, 195142, 195141, 201797, 202079, 194481, 195682, 191164, 176498, 182351,
|
||||
178404, 176497, 181146, 184605, 176499, 195140, 193948, 193427, 193052, 193206,
|
||||
192786, 184594, 183384, 182352, 184604, 189994, 193053, 193207, 193956, 195139,
|
||||
176296, 194011, 194012, 189993, 176500, 176501, 193955, 193425, 193772, 193604,
|
||||
191006, 191007, 191008, 191009, 191013, 191014, 191010, 190960, 191011, 191012,
|
||||
183317, 183321, 183322, 187056, 183323, 183324, 183325, 183326, 183327, 190203,
|
||||
190204, 190205, 190206, 193908, 181575, 181576, 181577, 181578, 202277, 202278
|
||||
};
|
||||
|
||||
@@ -60,7 +60,7 @@ bool TeleportAction::Execute(Event event)
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// If no portal was found, fallback to spellcaster-type game objects
|
||||
GuidVector gos = *context->GetValue<GuidVector>("nearest game objects");
|
||||
for (ObjectGuid const guid : gos)
|
||||
@@ -91,7 +91,7 @@ bool TeleportAction::Execute(Event event)
|
||||
spell->cast(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// If no game objects were found, try using the last area trigger
|
||||
LastMovement& movement = context->GetValue<LastMovement&>("last area trigger")->Get();
|
||||
if (movement.lastAreaTrigger)
|
||||
|
||||
@@ -24,7 +24,7 @@ bool TradeStatusAction::Execute(Event event)
|
||||
return false;
|
||||
|
||||
PlayerbotAI* traderBotAI = GET_PLAYERBOT_AI(trader);
|
||||
|
||||
|
||||
// Allow the master and group members to trade
|
||||
if (trader != master && !traderBotAI && (!bot->GetGroup() || !bot->GetGroup()->IsMember(trader->GetGUID())))
|
||||
{
|
||||
@@ -181,7 +181,7 @@ bool TradeStatusAction::CheckTrade()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isGettingItem)
|
||||
{
|
||||
if (bot->GetGroup() && bot->GetGroup()->IsMember(bot->GetTrader()->GetGUID()) &&
|
||||
|
||||
@@ -66,7 +66,7 @@ bool UnlockTradedItemAction::CanUnlockItem(Item* item)
|
||||
else
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "Lockpicking skill too low (" << botSkill << "/" << requiredSkill << ") to unlock: "
|
||||
out << "Lockpicking skill too low (" << botSkill << "/" << requiredSkill << ") to unlock: "
|
||||
<< item->GetTemplate()->Name1;
|
||||
botAI->TellMaster(out.str());
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ bool SummonAction::Teleport(Player* summoner, Player* player)
|
||||
// Player* master = GetMaster();
|
||||
if (!summoner)
|
||||
return false;
|
||||
|
||||
|
||||
if (player->GetVehicle())
|
||||
{
|
||||
botAI->TellError("You cannot summon me while I'm on a vehicle");
|
||||
|
||||
@@ -23,7 +23,7 @@ bool EnterVehicleAction::Execute(Event event)
|
||||
// do not switch vehicles yet
|
||||
if (bot->GetVehicle())
|
||||
return false;
|
||||
|
||||
|
||||
Player* master = botAI->GetMaster();
|
||||
// Triggered by a chat command
|
||||
if (event.getOwner() && master && master->GetTarget())
|
||||
@@ -45,7 +45,7 @@ bool EnterVehicleAction::Execute(Event event)
|
||||
Unit* vehicleBase = botAI->GetUnit(*i);
|
||||
if (!vehicleBase)
|
||||
continue;
|
||||
|
||||
|
||||
if (vehicleBase->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
creators["quest update complete"] = &WorldPacketActionContext::quest_update_complete;
|
||||
creators["turn in query quest"] = &WorldPacketActionContext::turn_in_query_quest;
|
||||
creators["quest item push result"] = &WorldPacketActionContext::quest_item_push_result;
|
||||
|
||||
|
||||
creators["party command"] = &WorldPacketActionContext::party_command;
|
||||
creators["tell cast failed"] = &WorldPacketActionContext::tell_cast_failed;
|
||||
creators["accept duel"] = &WorldPacketActionContext::accept_duel;
|
||||
|
||||
@@ -43,7 +43,7 @@ bool XpGainAction::Execute(Event event)
|
||||
// randomBotXPRate is now implemented in OnPlayerGiveXP script
|
||||
// if (!sRandomPlayerbotMgr->IsRandomBot(bot) || sPlayerbotAIConfig->randomBotXPRate == 1)
|
||||
// return true;
|
||||
|
||||
|
||||
// Unit* victim = nullptr;
|
||||
// if (guid)
|
||||
// victim = botAI->GetUnit(guid);
|
||||
|
||||
@@ -73,6 +73,6 @@ bool DeathAndDecayCooldownTrigger::IsActive()
|
||||
uint32 spellId = AI_VALUE2(uint32, "spell id", name);
|
||||
if (!spellId)
|
||||
return true;
|
||||
|
||||
|
||||
return bot->GetSpellCooldownDelay(spellId) >= 2000;
|
||||
}
|
||||
@@ -184,7 +184,7 @@ void GenericDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
"horn of winter", NextAction::array(0, new NextAction("horn of winter", ACTION_NORMAL + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("critical health",
|
||||
NextAction::array(0, new NextAction("death pact", ACTION_HIGH + 5), nullptr)));
|
||||
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("low health", NextAction::array(0, new NextAction("icebound fortitude", ACTION_HIGH + 5),
|
||||
new NextAction("rune tap", ACTION_HIGH + 4), nullptr)));
|
||||
|
||||
@@ -90,7 +90,7 @@ void UnholyDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericDKStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode(
|
||||
"death and decay cooldown", NextAction::array(0,
|
||||
"death and decay cooldown", NextAction::array(0,
|
||||
new NextAction("ghoul frenzy", ACTION_DEFAULT + 0.9f),
|
||||
new NextAction("scourge strike", ACTION_DEFAULT + 0.8f),
|
||||
new NextAction("icy touch", ACTION_DEFAULT + 0.7f),
|
||||
@@ -107,7 +107,7 @@ void UnholyDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
// "plague strike", NextAction::array(0, new NextAction("plague strike", ACTION_HIGH + 1), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"high frost rune", NextAction::array(0,
|
||||
"high frost rune", NextAction::array(0,
|
||||
new NextAction("icy touch", ACTION_NORMAL + 3), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
|
||||
@@ -133,7 +133,7 @@ void CasterDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
NextAction::array(0, new NextAction("starfire", ACTION_DEFAULT + 0.2f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("eclipse (solar) cooldown",
|
||||
NextAction::array(0, new NextAction("wrath", ACTION_DEFAULT + 0.2f), nullptr)));
|
||||
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"insect swarm", NextAction::array(0, new NextAction("insect swarm", ACTION_NORMAL + 5), nullptr)));
|
||||
triggers.push_back(
|
||||
|
||||
@@ -14,7 +14,7 @@ class DruidAiObjectContext : public AiObjectContext
|
||||
{
|
||||
public:
|
||||
DruidAiObjectContext(PlayerbotAI* botAI);
|
||||
|
||||
|
||||
static void BuildSharedContexts();
|
||||
static void BuildSharedStrategyContexts(SharedNamedObjectContextList<Strategy>& strategyContexts);
|
||||
static void BuildSharedActionContexts(SharedNamedObjectContextList<Action>& actionContexts);
|
||||
|
||||
@@ -132,7 +132,7 @@ void GenericDruidNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& trig
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member low health",
|
||||
NextAction::array(0,
|
||||
NextAction::array(0,
|
||||
new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 5),
|
||||
new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 4),
|
||||
new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 3),
|
||||
@@ -160,7 +160,7 @@ void GenericDruidNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& trig
|
||||
new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 6),
|
||||
new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 5),
|
||||
nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member low health", NextAction::array(0,
|
||||
triggers.push_back(new TriggerNode("party member low health", NextAction::array(0,
|
||||
new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 5),
|
||||
new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 4),
|
||||
new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 3),
|
||||
@@ -174,8 +174,8 @@ void GenericDruidNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& trig
|
||||
new NextAction("wild growth on party", ACTION_LIGHT_HEAL + 3),
|
||||
new NextAction("rejuvenation on party", ACTION_LIGHT_HEAL + 2),
|
||||
nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member remove curse", NextAction::array(0,
|
||||
new NextAction("remove curse on party", ACTION_DISPEL + 7),
|
||||
triggers.push_back(new TriggerNode("party member remove curse", NextAction::array(0,
|
||||
new NextAction("remove curse on party", ACTION_DISPEL + 7),
|
||||
nullptr)));
|
||||
|
||||
int specTab = AiFactory::GetPlayerSpecTab(botAI->GetBot());
|
||||
@@ -196,12 +196,12 @@ void GenericDruidBuffStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("mark of the wild on party", NextAction::array(0,
|
||||
new NextAction("mark of the wild on party", 13.0f),
|
||||
new NextAction("mark of the wild on party", 13.0f),
|
||||
nullptr)));
|
||||
triggers.push_back(new TriggerNode("thorns on main tank", NextAction::array(0,
|
||||
new NextAction("thorns on main tank", 11.0f),
|
||||
triggers.push_back(new TriggerNode("thorns on main tank", NextAction::array(0,
|
||||
new NextAction("thorns on main tank", 11.0f),
|
||||
nullptr)));
|
||||
triggers.push_back(new TriggerNode("thorns", NextAction::array(0,
|
||||
new NextAction("thorns", 10.0f),
|
||||
triggers.push_back(new TriggerNode("thorns", NextAction::array(0,
|
||||
new NextAction("thorns", 10.0f),
|
||||
nullptr)));
|
||||
}
|
||||
|
||||
@@ -133,11 +133,11 @@ void DruidCureStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member cure poison",
|
||||
NextAction::array(0, new NextAction("abolish poison on party", ACTION_DISPEL + 1), nullptr)));
|
||||
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member remove curse",
|
||||
NextAction::array(0, new NextAction("remove curse on party", ACTION_DISPEL + 7), NULL)));
|
||||
|
||||
|
||||
}
|
||||
|
||||
void DruidBoostStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
|
||||
@@ -82,7 +82,7 @@ void HealDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"group heal setting",
|
||||
NextAction::array(0,
|
||||
NextAction::array(0,
|
||||
new NextAction("tree form", ACTION_MEDIUM_HEAL + 2.3f),
|
||||
new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 2.2f),
|
||||
new NextAction("rejuvenation on not full", ACTION_MEDIUM_HEAL + 2.1f),
|
||||
@@ -90,7 +90,7 @@ void HealDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("medium group heal setting",
|
||||
NextAction::array(0,
|
||||
NextAction::array(0,
|
||||
new NextAction("tree form", ACTION_CRITICAL_HEAL + 0.6f),
|
||||
new NextAction("tranquility", ACTION_CRITICAL_HEAL + 0.5f), nullptr)));
|
||||
|
||||
@@ -107,7 +107,7 @@ void HealDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
// MEDIUM
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member medium health",
|
||||
NextAction::array(0,
|
||||
NextAction::array(0,
|
||||
new NextAction("tree form", ACTION_MEDIUM_HEAL + 0.5f),
|
||||
new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 0.4f),
|
||||
new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 0.3f),
|
||||
|
||||
@@ -47,7 +47,7 @@ class DungeonStrategyContext : public NamedObjectContext<Strategy>
|
||||
|
||||
// Burning Crusade
|
||||
// ...
|
||||
|
||||
|
||||
// Wrath of the Lich King
|
||||
creators["wotlk-uk"] = &DungeonStrategyContext::wotlk_uk; // Utgarde Keep
|
||||
creators["wotlk-nex"] = &DungeonStrategyContext::wotlk_nex; // The Nexus
|
||||
@@ -84,8 +84,8 @@ class DungeonStrategyContext : public NamedObjectContext<Strategy>
|
||||
static Strategy* wotlk_toc(PlayerbotAI* botAI) { return new WotlkDungeonToCStrategy(botAI); }
|
||||
// NYI from here down
|
||||
static Strategy* wotlk_hor(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,7 @@ bool AttackWebWrapAction::Execute(Event event)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return Attack(webWrap);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
float KrikthirMultiplier::GetValue(Action* action)
|
||||
{
|
||||
if (!botAI->IsDps(bot)) { return 1.0f; }
|
||||
|
||||
|
||||
// Target is not findable from threat table using AI_VALUE2(),
|
||||
// therefore need to search manually for the unit name
|
||||
Unit* boss = nullptr;
|
||||
|
||||
@@ -11,7 +11,7 @@ void WotlkDungeonANStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
NextAction::array(0, new NextAction("attack web wrap", ACTION_RAID + 5), nullptr)));
|
||||
triggers.push_back(new TriggerNode("krik'thir watchers",
|
||||
NextAction::array(0, new NextAction("krik'thir priority", ACTION_RAID + 4), nullptr)));
|
||||
|
||||
|
||||
// Hadronox
|
||||
// The core AC triggers are very buggy with this boss, but default strat seems to play correctly
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "AiObjectContext.h"
|
||||
#include "AzjolNerubTriggers.h"
|
||||
|
||||
class WotlkDungeonANTriggerContext : public NamedObjectContext<Trigger>
|
||||
class WotlkDungeonANTriggerContext : public NamedObjectContext<Trigger>
|
||||
{
|
||||
public:
|
||||
WotlkDungeonANTriggerContext()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
bool KrikthirWebWrapTrigger::IsActive()
|
||||
{
|
||||
if (!botAI->IsDps(bot)) { return false; }
|
||||
|
||||
|
||||
// Target is not findable from threat table using AI_VALUE2(),
|
||||
// therefore need to search manually for the unit name
|
||||
GuidVector targets = AI_VALUE(GuidVector, "possible targets no los");
|
||||
@@ -51,7 +51,7 @@ bool KrikthirWatchersTrigger::IsActive()
|
||||
// for (auto i = triggers.begin(); i != triggers.end(); i++)
|
||||
// {
|
||||
// Unit* unit = botAI->GetUnit(*i);
|
||||
|
||||
|
||||
// if (unit)
|
||||
// {
|
||||
// bot->Yell("TRIGGER="+unit->GetName(), LANG_UNIVERSAL);
|
||||
@@ -64,6 +64,6 @@ bool AnubarakPoundTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "anub'arak");
|
||||
if (!boss) { return false; }
|
||||
|
||||
|
||||
return boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(SPELL_POUND);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ float EpochMultiplier::GetValue(Action* action)
|
||||
if (!boss) { return 1.0f; }
|
||||
|
||||
if (bot->getClass() == CLASS_HUNTER) { return 1.0f; }
|
||||
|
||||
|
||||
if (dynamic_cast<FleeAction*>(action)) { return 0.0f; }
|
||||
|
||||
return 1.0f;
|
||||
|
||||
@@ -10,12 +10,12 @@ void WotlkDungeonCoSStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
// Salramm the Fleshcrafter
|
||||
triggers.push_back(new TriggerNode("explode ghoul",
|
||||
NextAction::array(0, new NextAction("explode ghoul spread", ACTION_MOVE + 5), nullptr)));
|
||||
|
||||
|
||||
// Chrono-Lord Epoch
|
||||
// Not sure if this actually works, I think I've seen him charge melee characters..?
|
||||
triggers.push_back(new TriggerNode("epoch ranged",
|
||||
NextAction::array(0, new NextAction("epoch stack", ACTION_MOVE + 5), nullptr)));
|
||||
|
||||
|
||||
// Mal'Ganis
|
||||
|
||||
// Infinite Corruptor (Heroic only)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "AiObjectContext.h"
|
||||
#include "CullingOfStratholmeTriggers.h"
|
||||
|
||||
class WotlkDungeonCoSTriggerContext : public NamedObjectContext<Trigger>
|
||||
class WotlkDungeonCoSTriggerContext : public NamedObjectContext<Trigger>
|
||||
{
|
||||
public:
|
||||
WotlkDungeonCoSTriggerContext()
|
||||
|
||||
@@ -64,11 +64,11 @@ bool NovosTargetPriorityAction::Execute(Event event)
|
||||
{
|
||||
// TODO: This can be improved, some parts are still buggy.
|
||||
// But it works for now and this fight is very easy
|
||||
|
||||
|
||||
// Designate a dps char to handle the stairs adds.
|
||||
// This is probably better as a melee, so just pick the first
|
||||
// melee dps in the party. If none exist, pick the first ranged.
|
||||
|
||||
|
||||
// TODO: Switch to botAI->Index instead, cleaner
|
||||
Player* stairsDps = nullptr;
|
||||
GuidVector members = AI_VALUE(GuidVector, "group members");
|
||||
@@ -76,7 +76,7 @@ bool NovosTargetPriorityAction::Execute(Event event)
|
||||
{
|
||||
Player* groupMember = botAI->GetPlayer(member);
|
||||
if (!groupMember) { continue; }
|
||||
|
||||
|
||||
if (botAI->IsDps(groupMember))
|
||||
{
|
||||
if (botAI->IsMelee(groupMember))
|
||||
@@ -131,7 +131,7 @@ bool NovosTargetPriorityAction::Execute(Event event)
|
||||
{
|
||||
selectedTargets[0] = unit;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if (creatureId == NPC_FETID_TROLL_CORPSE)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ float NovosMultiplier::GetValue(Action* action)
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "novos the summoner");
|
||||
if (!boss) { return 1.0f; }
|
||||
|
||||
|
||||
if (boss->FindCurrentSpellBySpellId(SPELL_ARCANE_FIELD) && bot->GetTarget())
|
||||
{
|
||||
if (dynamic_cast<DpsAssistAction*>(action)
|
||||
@@ -25,7 +25,7 @@ float NovosMultiplier::GetValue(Action* action)
|
||||
float TharonjaMultiplier::GetValue(Action* action)
|
||||
{
|
||||
if (!bot->HasAura(SPELL_GIFT_OF_THARONJA)) { return 1.0f; }
|
||||
|
||||
|
||||
// Suppress all skills that are not enabled in skeleton form.
|
||||
// Still allow non-ability actions such as movement
|
||||
if (dynamic_cast<CastSpellAction*>(action)
|
||||
|
||||
@@ -7,7 +7,7 @@ void WotlkDungeonDTKStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
// Trollgore
|
||||
triggers.push_back(new TriggerNode("corpse explode",
|
||||
NextAction::array(0, new NextAction("corpse explode spread", ACTION_MOVE + 5), nullptr)));
|
||||
|
||||
|
||||
// Novos the Summoner
|
||||
// TODO: Can be improved - it's a pretty easy fight but complex to program, revisit if needed
|
||||
triggers.push_back(new TriggerNode("arcane field",
|
||||
@@ -16,7 +16,7 @@ void WotlkDungeonDTKStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
NextAction::array(0, new NextAction("novos positioning", ACTION_MOVE + 4), nullptr)));
|
||||
triggers.push_back(new TriggerNode("arcane field",
|
||||
NextAction::array(0, new NextAction("novos target priority", ACTION_NORMAL + 1), nullptr)));
|
||||
|
||||
|
||||
// King Dred
|
||||
// TODO: Fear ward / tremor totem, or general anti-fear strat development
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "AiObjectContext.h"
|
||||
#include "DrakTharonKeepTriggers.h"
|
||||
|
||||
class WotlkDungeonDTKTriggerContext : public NamedObjectContext<Trigger>
|
||||
class WotlkDungeonDTKTriggerContext : public NamedObjectContext<Trigger>
|
||||
{
|
||||
public:
|
||||
WotlkDungeonDTKTriggerContext()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "SharedDefines.h"
|
||||
|
||||
bool MoveFromBronjahmAction::Execute(Event event)
|
||||
{
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "bronjahm");
|
||||
if (!boss)
|
||||
return false;
|
||||
@@ -46,10 +46,10 @@ bool AttackCorruptedSoulFragmentAction::Execute(Event event)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ bool BronjahmGroupPositionAction::Execute(Event event)
|
||||
// If soul is near boss, flee from boss
|
||||
if (soulToBossDist < 10.0f)
|
||||
return FleePosition(unit->GetPosition(), 13.0f, 1000U);
|
||||
|
||||
|
||||
// If soul exists but none of the above conditions, don't move to tank position yet
|
||||
bot->SetFacingToObject(boss);
|
||||
return true;
|
||||
|
||||
@@ -30,7 +30,7 @@ bool SwitchToSoulFragment::IsActive()
|
||||
if (!activeSoulExists)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BronjahmPositionTrigger::IsActive()
|
||||
|
||||
@@ -15,11 +15,11 @@ void WotlkDungeonGDStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
NextAction::array(0, new NextAction("avoid poison nova", ACTION_RAID + 5), nullptr)));
|
||||
triggers.push_back(new TriggerNode("snake wrap",
|
||||
NextAction::array(0, new NextAction("attack snake wrap", ACTION_RAID + 4), nullptr)));
|
||||
|
||||
|
||||
// Gal'darah
|
||||
triggers.push_back(new TriggerNode("whirling slash",
|
||||
NextAction::array(0, new NextAction("avoid whirling slash", ACTION_RAID + 5), nullptr)));
|
||||
|
||||
|
||||
// Eck the Ferocious (Heroic only)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "AiObjectContext.h"
|
||||
#include "GundrakTriggers.h"
|
||||
|
||||
class WotlkDungeonGDTriggerContext : public NamedObjectContext<Trigger>
|
||||
class WotlkDungeonGDTriggerContext : public NamedObjectContext<Trigger>
|
||||
{
|
||||
public:
|
||||
WotlkDungeonGDTriggerContext()
|
||||
|
||||
@@ -7,7 +7,7 @@ bool SladranPoisonNovaTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "slad'ran");
|
||||
if (!boss) { return false; }
|
||||
|
||||
|
||||
return bool(boss->FindCurrentSpellBySpellId(SPELL_POISON_NOVA));
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ enum GundrakIDs
|
||||
SPELL_POISON_NOVA_N = 55081,
|
||||
SPELL_POISON_NOVA_H = 59842,
|
||||
NPC_SNAKE_WRAP = 29742,
|
||||
|
||||
|
||||
// Gal'darah
|
||||
SPELL_WHIRLING_SLASH_N = 55250,
|
||||
SPELL_WHIRLING_SLASH_H = 59824,
|
||||
|
||||
@@ -59,7 +59,7 @@ bool VolkhanTargetAction::Execute(Event event)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return Attack(boss);
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ bool LokenStackAction::Execute(Event event)
|
||||
// else
|
||||
return Move(bot->GetAngle(boss), fmin(bot->GetExactDist2d(boss), maxMovement));
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ float BjarngrimMultiplier::GetValue(Action* action)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ float VolkhanMultiplier::GetValue(Action* action)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ void WotlkDungeonHoLStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
// Volkhan
|
||||
triggers.push_back(new TriggerNode("volkhan",
|
||||
NextAction::array(0, new NextAction("volkhan target", ACTION_RAID + 5), nullptr)));
|
||||
|
||||
|
||||
// Ionar
|
||||
triggers.push_back(new TriggerNode("ionar disperse",
|
||||
NextAction::array(0, new NextAction("disperse position", ACTION_MOVE + 5), nullptr)));
|
||||
@@ -24,7 +24,7 @@ void WotlkDungeonHoLStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
// TODO: Targeted player can dodge the ball, but a single player soaking it isn't too bad to heal
|
||||
triggers.push_back(new TriggerNode("ball lightning",
|
||||
NextAction::array(0, new NextAction("ball lightning spread", ACTION_MOVE + 2), nullptr)));
|
||||
|
||||
|
||||
// Loken
|
||||
triggers.push_back(new TriggerNode("lightning nova",
|
||||
NextAction::array(0, new NextAction("avoid lightning nova", ACTION_MOVE + 5), nullptr)));
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "AiObjectContext.h"
|
||||
#include "HallsOfLightningTriggers.h"
|
||||
|
||||
class WotlkDungeonHoLTriggerContext : public NamedObjectContext<Trigger>
|
||||
class WotlkDungeonHoLTriggerContext : public NamedObjectContext<Trigger>
|
||||
{
|
||||
public:
|
||||
WotlkDungeonHoLTriggerContext()
|
||||
|
||||
@@ -27,7 +27,7 @@ bool BjarngrimWhirlwindTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "general bjarngrim");
|
||||
if (!boss) { return false; }
|
||||
|
||||
|
||||
return boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(SPELL_WHIRLWIND_BJARNGRIM);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ bool IonarBallLightningTrigger::IsActive()
|
||||
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "ionar");
|
||||
if (!boss) { return false; }
|
||||
|
||||
|
||||
return boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(SPELL_BALL_LIGHTNING);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ bool IonarTankAggroTrigger::IsActive()
|
||||
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "ionar");
|
||||
if (!boss) { return false; }
|
||||
|
||||
|
||||
return AI_VALUE2(bool, "has aggro", "current target");
|
||||
}
|
||||
|
||||
@@ -88,6 +88,6 @@ bool LokenLightningNovaTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "loken");
|
||||
if (!boss) { return false; }
|
||||
|
||||
|
||||
return boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(SPELL_LIGHTNING_NOVA);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ bool ShatterSpreadAction::Execute(Event event)
|
||||
|
||||
float radius = 40.0f;
|
||||
Unit* closestMember = nullptr;
|
||||
|
||||
|
||||
GuidVector members = AI_VALUE(GuidVector, "group members");
|
||||
for (auto& member : members)
|
||||
{
|
||||
@@ -31,7 +31,7 @@ bool ShatterSpreadAction::Execute(Event event)
|
||||
// return MoveAway(closestMember, radius - bot->GetExactDist2d(closestMember));
|
||||
return MoveAway(closestMember, 5.0f);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ float KrystallusMultiplier::GetValue(Action* action)
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "krystallus");
|
||||
if (!boss) { return 1.0f; }
|
||||
|
||||
|
||||
// Check both of these... the spell is applied first, debuff later.
|
||||
// Neither is active for the full duration so we need to trigger off both
|
||||
if (bot->HasAura(SPELL_GROUND_SLAM) || bot->HasAura(DEBUFF_GROUND_SLAM))
|
||||
|
||||
@@ -11,7 +11,7 @@ void WotlkDungeonHoSStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
// TODO: I think bots need to dismiss pets on this, or they nuke players they are standing close to
|
||||
triggers.push_back(new TriggerNode("ground slam",
|
||||
NextAction::array(0, new NextAction("shatter spread", ACTION_RAID + 5), nullptr)));
|
||||
|
||||
|
||||
// Tribunal of Ages
|
||||
// Seems fine, maybe add focus targeting strat if needed on heroic.
|
||||
// Main issue is dps will immediately rambo in and sometimes die before tank gets aggro,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "AiObjectContext.h"
|
||||
#include "HallsOfStoneTriggers.h"
|
||||
|
||||
class WotlkDungeonHoSTriggerContext : public NamedObjectContext<Trigger>
|
||||
class WotlkDungeonHoSTriggerContext : public NamedObjectContext<Trigger>
|
||||
{
|
||||
public:
|
||||
WotlkDungeonHoSTriggerContext()
|
||||
|
||||
@@ -7,7 +7,7 @@ bool KrystallusGroundSlamTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "krystallus");
|
||||
if (!boss) { return false; }
|
||||
|
||||
|
||||
// Check both of these... the spell is applied first, debuff later.
|
||||
// Neither is active for the full duration so we need to trigger off both
|
||||
return bot->HasAura(SPELL_GROUND_SLAM) || bot->HasAura(DEBUFF_GROUND_SLAM);
|
||||
@@ -17,6 +17,6 @@ bool SjonnirLightningRingTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "sjonnir the ironshaper");
|
||||
if (!boss) { return false; }
|
||||
|
||||
|
||||
return boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(SPELL_LIGHTNING_RING);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ bool MoveFromWhirlwindAction::Execute(Event event)
|
||||
}
|
||||
|
||||
float bossDistance = bot->GetExactDist2d(boss->GetPosition());
|
||||
|
||||
|
||||
// Check if the bot is already at a safe distance
|
||||
if (bossDistance > targetDist)
|
||||
{
|
||||
@@ -156,7 +156,7 @@ bool DodgeSpikesAction::Execute(Event event)
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "ormorok the tree-shaper");
|
||||
if (!boss) { return false; }
|
||||
|
||||
|
||||
return Move(bot->GetAngle(boss), bot->GetExactDist2d(boss) - 0.3f);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ float FactionCommanderMultiplier::GetValue(Action* action)
|
||||
{
|
||||
Unit* boss = nullptr;
|
||||
uint8 faction = bot->GetTeamId();
|
||||
|
||||
|
||||
switch (bot->GetMap()->GetDifficulty())
|
||||
{
|
||||
case DUNGEON_DIFFICULTY_NORMAL:
|
||||
@@ -78,7 +78,7 @@ float OrmorokMultiplier::GetValue(Action* action)
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "ormorok the tree-shaper");
|
||||
if (!boss) { return 1.0f; }
|
||||
|
||||
|
||||
// These are used for auto ranged repositioning, need to suppress so ranged dps don't ping-pong
|
||||
if (dynamic_cast<FleeAction*>(action))
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ void WotlkDungeonNexStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
triggers.push_back(new TriggerNode("faction commander whirlwind",
|
||||
NextAction::array(0, new NextAction("move from whirlwind", ACTION_MOVE + 5), nullptr)));
|
||||
// TODO: Handle fear? (tremor totems, fear ward etc.)
|
||||
|
||||
|
||||
// Grand Magus Telestra
|
||||
triggers.push_back(new TriggerNode("telestra firebomb",
|
||||
NextAction::array(0, new NextAction("firebomb spread", ACTION_MOVE + 5), nullptr)));
|
||||
@@ -21,7 +21,7 @@ void WotlkDungeonNexStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
// Anomalus
|
||||
triggers.push_back(new TriggerNode("chaotic rift",
|
||||
NextAction::array(0, new NextAction("chaotic rift target", ACTION_RAID + 1), nullptr)));
|
||||
|
||||
|
||||
// Ormorok the Tree-Shaper
|
||||
// Tank trigger to stack inside boss. Can also add return action to prevent boss repositioning
|
||||
// if it becomes too much of a problem. He usually dies before he's up against a wall though
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "AiObjectContext.h"
|
||||
#include "NexusTriggers.h"
|
||||
|
||||
class WotlkDungeonNexTriggerContext : public NamedObjectContext<Trigger>
|
||||
class WotlkDungeonNexTriggerContext : public NamedObjectContext<Trigger>
|
||||
{
|
||||
public:
|
||||
WotlkDungeonNexTriggerContext()
|
||||
|
||||
@@ -7,7 +7,7 @@ bool FactionCommanderWhirlwindTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = nullptr;
|
||||
uint8 faction = bot->GetTeamId();
|
||||
|
||||
|
||||
switch (bot->GetMap()->GetDifficulty())
|
||||
{
|
||||
case DUNGEON_DIFFICULTY_NORMAL:
|
||||
|
||||
@@ -327,7 +327,7 @@ bool AvoidArcaneExplosionAction::Execute(Event event)
|
||||
}
|
||||
|
||||
if (!closestPos) { return false; }
|
||||
|
||||
|
||||
return MoveNear(bot->GetMapId(), closestPos->GetPositionX(), closestPos->GetPositionY(), closestPos->GetPositionZ(), 2.0f, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ float MountingDrakeMultiplier::GetValue(Action* action)
|
||||
// If we suppress everything, they seem to mount properly. A bit of a ham-fisted solution but it works
|
||||
Player* master = botAI->GetMaster();
|
||||
if (!master) { return 1.0f; }
|
||||
|
||||
|
||||
if (bot->GetMapId() != OCULUS_MAP_ID || !master->GetVehicleBase() || bot->GetVehicleBase()) { return 1.0f; }
|
||||
|
||||
if (!dynamic_cast<MountDrakeAction*>(action))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user